1
2
3
4
5
6
7 package lockedfile
8
9 import (
10 "io/fs"
11 "os"
12
13 "cmd/go/internal/lockedfile/internal/filelock"
14 )
15
16 func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
17
18
19
20
21
22 f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
23 if err != nil {
24 return nil, err
25 }
26
27 switch flag & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) {
28 case os.O_WRONLY, os.O_RDWR:
29 err = filelock.Lock(f)
30 default:
31 err = filelock.RLock(f)
32 }
33 if err != nil {
34 f.Close()
35 return nil, err
36 }
37
38 if flag&os.O_TRUNC == os.O_TRUNC {
39 if err := f.Truncate(0); err != nil {
40
41
42
43
44 if fi, statErr := f.Stat(); statErr != nil || fi.Mode().IsRegular() {
45 filelock.Unlock(f)
46 f.Close()
47 return nil, err
48 }
49 }
50 }
51
52 return f, nil
53 }
54
55 func closeFile(f *os.File) error {
56
57
58
59 err := filelock.Unlock(f)
60
61 if closeErr := f.Close(); err == nil {
62 err = closeErr
63 }
64 return err
65 }
66
View as plain text