1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
//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
}
|