返回 DeepSeek-Reasonix
lock_unix.go
根目录 / internal / filelock / lock_unix.go
1 //go:build !windows
2
3 package filelock
4
5 import (
6 "errors"
7 "os"
8
9 "golang.org/x/sys/unix"
10 )
11
12 func tryLockFile(path string) (func(), error) {
13 return tryLockFileMode(path, ModeExclusive)
14 }
15
16 func tryLockFileMode(path string, mode Mode) (func(), error) {
17 f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
18 if err != nil {
19 return nil, err
20 }
21 flag := unix.LOCK_EX | unix.LOCK_NB
22 if mode == ModeShared {
23 flag = unix.LOCK_SH | unix.LOCK_NB
24 }
25 if err := unix.Flock(int(f.Fd()), flag); err != nil {
26 _ = f.Close()
27 if errors.Is(err, unix.EWOULDBLOCK) || errors.Is(err, unix.EAGAIN) {
28 return nil, ErrHeld
29 }
30 return nil, err
31 }
32 return func() {
33 _ = unix.Flock(int(f.Fd()), unix.LOCK_UN)
34 _ = f.Close()
35 }, nil
36 }
37
37 lines GO