//go:build unix package fikenauth import ( "fmt" "os" "path/filepath" "syscall" ) // lock takes an exclusive lock beside the token file, held until unlock is // called. It is advisory: it only orders programs that also take it, which is // every program using this package. func (s *Store) lock() (unlock func(), err error) { if err := os.MkdirAll(filepath.Dir(s.path), 0o700); err != nil { return nil, fmt.Errorf("create %s: %w", filepath.Dir(s.path), err) } f, err := os.OpenFile(s.path+".lock", os.O_CREATE|os.O_RDWR, 0o600) if err != nil { return nil, fmt.Errorf("lock %s: %w", s.path, err) } if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil { f.Close() return nil, fmt.Errorf("lock %s: %w", s.path, err) } return func() { syscall.Flock(int(f.Fd()), syscall.LOCK_UN) //nolint:errcheck // closing releases it anyway f.Close() }, nil }