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