From fe91af5e09b802cec76d7c5cd6a646c38e9bbfa9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 14 Oct 2022 15:06:11 +0530 Subject: [PATCH] Go stdlib doesnt even have a way to lock files --- tools/utils/filelock.go | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tools/utils/filelock.go diff --git a/tools/utils/filelock.go b/tools/utils/filelock.go new file mode 100644 index 000000000..69c566603 --- /dev/null +++ b/tools/utils/filelock.go @@ -0,0 +1,48 @@ +// License: GPLv3 Copyright: 2022, Kovid Goyal, + +package utils + +import ( + "fmt" + "io/fs" + "os" + "syscall" +) + +var _ = fmt.Print + +func lock(fd, op int, path string) (err error) { + for { + err = syscall.Flock(fd, op) + if err != syscall.EINTR { + break + } + } + if err != nil { + opname := "exclusive flock()" + switch op { + case syscall.LOCK_UN: + opname = "unlock flock()" + case syscall.LOCK_SH: + opname = "shared flock()" + } + return &fs.PathError{ + Op: opname, + Path: path, + Err: err, + } + } + return nil +} + +func LockFileShared(f *os.File) error { + return lock(int(f.Fd()), syscall.LOCK_SH, f.Name()) +} + +func LockFileExclusive(f *os.File) error { + return lock(int(f.Fd()), syscall.LOCK_EX, f.Name()) +} + +func UnlockFile(f *os.File) error { + return lock(int(f.Fd()), syscall.LOCK_UN, f.Name()) +}