filelock.go 835 B

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