Source file
src/os/file_posix.go
1
2
3
4
5
6
7 package os
8
9 import (
10 "runtime"
11 "syscall"
12 "time"
13 )
14
15
16
17
18
19 func (f *File) Close() error {
20 if f == nil {
21 return ErrInvalid
22 }
23 return f.file.close()
24 }
25
26
27
28 func (f *File) read(b []byte) (n int, err error) {
29 n, err = f.pfd.Read(b)
30 runtime.KeepAlive(f)
31 return n, err
32 }
33
34
35
36
37 func (f *File) pread(b []byte, off int64) (n int, err error) {
38 n, err = f.pfd.Pread(b, off)
39 runtime.KeepAlive(f)
40 return n, err
41 }
42
43
44
45 func (f *File) write(b []byte) (n int, err error) {
46 n, err = f.pfd.Write(b)
47 runtime.KeepAlive(f)
48 return n, err
49 }
50
51
52
53 func (f *File) pwrite(b []byte, off int64) (n int, err error) {
54 n, err = f.pfd.Pwrite(b, off)
55 runtime.KeepAlive(f)
56 return n, err
57 }
58
59
60 func syscallMode(i FileMode) (o uint32) {
61 o |= uint32(i.Perm())
62 if i&ModeSetuid != 0 {
63 o |= syscall.S_ISUID
64 }
65 if i&ModeSetgid != 0 {
66 o |= syscall.S_ISGID
67 }
68 if i&ModeSticky != 0 {
69 o |= syscall.S_ISVTX
70 }
71
72 return
73 }
74
75
76 func chmod(name string, mode FileMode) error {
77 longName := fixLongPath(name)
78 e := ignoringEINTR(func() error {
79 return syscall.Chmod(longName, syscallMode(mode))
80 })
81 if e != nil {
82 return &PathError{Op: "chmod", Path: name, Err: e}
83 }
84 return nil
85 }
86
87
88 func (f *File) chmod(mode FileMode) error {
89 if err := f.checkValid("chmod"); err != nil {
90 return err
91 }
92 if e := f.pfd.Fchmod(syscallMode(mode)); e != nil {
93 return f.wrapErr("chmod", e)
94 }
95 return nil
96 }
97
98
99
100
101
102
103
104
105 func Chown(name string, uid, gid int) error {
106 e := ignoringEINTR(func() error {
107 return syscall.Chown(name, uid, gid)
108 })
109 if e != nil {
110 return &PathError{Op: "chown", Path: name, Err: e}
111 }
112 return nil
113 }
114
115
116
117
118
119
120
121 func Lchown(name string, uid, gid int) error {
122 e := ignoringEINTR(func() error {
123 return syscall.Lchown(name, uid, gid)
124 })
125 if e != nil {
126 return &PathError{Op: "lchown", Path: name, Err: e}
127 }
128 return nil
129 }
130
131
132
133
134
135
136 func (f *File) Chown(uid, gid int) error {
137 if err := f.checkValid("chown"); err != nil {
138 return err
139 }
140 if e := f.pfd.Fchown(uid, gid); e != nil {
141 return f.wrapErr("chown", e)
142 }
143 return nil
144 }
145
146
147
148
149 func (f *File) Truncate(size int64) error {
150 if err := f.checkValid("truncate"); err != nil {
151 return err
152 }
153 if e := f.pfd.Ftruncate(size); e != nil {
154 return f.wrapErr("truncate", e)
155 }
156 return nil
157 }
158
159
160
161
162 func (f *File) Sync() error {
163 if err := f.checkValid("sync"); err != nil {
164 return err
165 }
166 if e := f.pfd.Fsync(); e != nil {
167 return f.wrapErr("sync", e)
168 }
169 return nil
170 }
171
172
173
174
175
176
177
178
179 func Chtimes(name string, atime time.Time, mtime time.Time) error {
180 utimes := chtimesUtimes(atime, mtime)
181 if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
182 return &PathError{Op: "chtimes", Path: name, Err: e}
183 }
184 return nil
185 }
186
187 func chtimesUtimes(atime, mtime time.Time) [2]syscall.Timespec {
188 var utimes [2]syscall.Timespec
189 set := func(i int, t time.Time) {
190 if t.IsZero() {
191 utimes[i] = syscall.Timespec{Sec: _UTIME_OMIT, Nsec: _UTIME_OMIT}
192 } else {
193 utimes[i] = syscall.NsecToTimespec(t.UnixNano())
194 }
195 }
196 set(0, atime)
197 set(1, mtime)
198 return utimes
199 }
200
201
202
203
204 func (f *File) Chdir() error {
205 if err := f.checkValid("chdir"); err != nil {
206 return err
207 }
208 if e := f.pfd.Fchdir(); e != nil {
209 return f.wrapErr("chdir", e)
210 }
211 return nil
212 }
213
214
215 func (f *File) setDeadline(t time.Time) error {
216 if err := f.checkValid("SetDeadline"); err != nil {
217 return err
218 }
219 return f.pfd.SetDeadline(t)
220 }
221
222
223 func (f *File) setReadDeadline(t time.Time) error {
224 if err := f.checkValid("SetReadDeadline"); err != nil {
225 return err
226 }
227 return f.pfd.SetReadDeadline(t)
228 }
229
230
231 func (f *File) setWriteDeadline(t time.Time) error {
232 if err := f.checkValid("SetWriteDeadline"); err != nil {
233 return err
234 }
235 return f.pfd.SetWriteDeadline(t)
236 }
237
238
239
240 func (f *File) checkValid(op string) error {
241 if f == nil {
242 return ErrInvalid
243 }
244 return nil
245 }
246
247
248
249
250
251
252
253
254 func ignoringEINTR(fn func() error) error {
255 for {
256 err := fn()
257 if err != syscall.EINTR {
258 return err
259 }
260 }
261 }
262
263
264 func ignoringEINTR2[T any](fn func() (T, error)) (T, error) {
265 for {
266 v, err := fn()
267 if err != syscall.EINTR {
268 return v, err
269 }
270 }
271 }
272
View as plain text