filelock.go 849 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package utils
  3. import (
  4. "errors"
  5. "fmt"
  6. "io/fs"
  7. "os"
  8. "golang.org/x/sys/unix"
  9. )
  10. var _ = fmt.Print
  11. func lock(fd, op int, path string) (err error) {
  12. for {
  13. err = unix.Flock(fd, op)
  14. if !errors.Is(err, unix.EINTR) {
  15. break
  16. }
  17. }
  18. if err != nil {
  19. opname := "exclusive flock()"
  20. switch op {
  21. case unix.LOCK_UN:
  22. opname = "unlock flock()"
  23. case unix.LOCK_SH:
  24. opname = "shared flock()"
  25. }
  26. return &fs.PathError{
  27. Op: opname,
  28. Path: path,
  29. Err: err,
  30. }
  31. }
  32. return nil
  33. }
  34. func LockFileShared(f *os.File) error {
  35. return lock(int(f.Fd()), unix.LOCK_SH, f.Name())
  36. }
  37. func LockFileExclusive(f *os.File) error {
  38. return lock(int(f.Fd()), unix.LOCK_EX, f.Name())
  39. }
  40. func UnlockFile(f *os.File) error {
  41. return lock(int(f.Fd()), unix.LOCK_UN, f.Name())
  42. }