...
1
2
3
4
5
6
7
8
9
10 package storage
11
12 import (
13 "os"
14 "syscall"
15 )
16
17 type unixFileLock struct {
18 f *os.File
19 }
20
21 func (fl *unixFileLock) release() error {
22 if err := setFileLock(fl.f, false, false); err != nil {
23 return err
24 }
25 return fl.f.Close()
26 }
27
28 func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
29 var flag int
30 if readOnly {
31 flag = os.O_RDONLY
32 } else {
33 flag = os.O_RDWR
34 }
35 f, err := os.OpenFile(path, flag, 0)
36 if os.IsNotExist(err) {
37 f, err = os.OpenFile(path, flag|os.O_CREATE, 0644)
38 }
39 if err != nil {
40 return
41 }
42 err = setFileLock(f, readOnly, true)
43 if err != nil {
44 f.Close()
45 return
46 }
47 fl = &unixFileLock{f: f}
48 return
49 }
50
51 func setFileLock(f *os.File, readOnly, lock bool) error {
52 flock := syscall.Flock_t{
53 Type: syscall.F_UNLCK,
54 Start: 0,
55 Len: 0,
56 Whence: 1,
57 }
58 if lock {
59 if readOnly {
60 flock.Type = syscall.F_RDLCK
61 } else {
62 flock.Type = syscall.F_WRLCK
63 }
64 }
65 return syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &flock)
66 }
67
68 func rename(oldpath, newpath string) error {
69 return os.Rename(oldpath, newpath)
70 }
71
72 func syncDir(name string) error {
73 f, err := os.Open(name)
74 if err != nil {
75 return err
76 }
77 defer f.Close()
78 if err := f.Sync(); err != nil {
79 return err
80 }
81 return nil
82 }
83
View as plain text