github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/os/file_posix.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows 6 7 package os 8 9 import ( 10 "dara" 11 "runtime" 12 "syscall" 13 "time" 14 ) 15 16 func sigpipe() // implemented in package runtime 17 18 // Readlink returns the destination of the named symbolic link. 19 // If there is an error, it will be of type *PathError. 20 func Readlink(name string) (string, error) { 21 for len := 128; ; len *= 2 { 22 b := make([]byte, len) 23 n, e := fixCount(syscall.Readlink(fixLongPath(name), b)) 24 if e != nil { 25 // DARA Instrumentation 26 if runtime.Is_dara_profiling_on() { 27 runtime.Dara_Debug_Print(func() { 28 print("[READLINK] : ") 29 println(name) 30 }) 31 argInfo := dara.GeneralType{Type: dara.STRING} 32 copy(argInfo.String[:], name) 33 retInfo1 := dara.GeneralType{Type: dara.STRING} 34 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported : dara.UNSUPPORTEDVAL} 35 syscallInfo := dara.GeneralSyscall{dara.DSYS_READLINK, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}} 36 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READLINK, syscallInfo) 37 } 38 return "", &PathError{"readlink", name, e} 39 } 40 if n < len { 41 // DARA Instrumentation 42 if runtime.Is_dara_profiling_on() { 43 runtime.Dara_Debug_Print(func() { 44 print("[READLINK] : ") 45 println(name) 46 }) 47 argInfo := dara.GeneralType{Type: dara.STRING} 48 copy(argInfo.String[:], name) 49 retInfo1 := dara.GeneralType{Type: dara.STRING} 50 copy(retInfo1.String[:], b[0:n]) 51 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported : dara.UNSUPPORTEDVAL} 52 syscallInfo := dara.GeneralSyscall{dara.DSYS_READLINK, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}} 53 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READLINK, syscallInfo) 54 } 55 return string(b[0:n]), nil 56 } 57 } 58 } 59 60 // syscallMode returns the syscall-specific mode bits from Go's portable mode bits. 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 // No mapping for Go's ModeTemporary (plan9 only). 73 return 74 } 75 76 // See docs in file.go:Chmod. 77 func chmod(name string, mode FileMode) error { 78 // DARA Instrumentation 79 if runtime.Is_dara_profiling_on() { 80 runtime.Dara_Debug_Print(func() { 81 print("[CHMOD] : ") 82 print(name) 83 print(" ") 84 println(mode) 85 }) 86 argInfo1 := dara.GeneralType{Type: dara.STRING} 87 copy(argInfo1.String[:], name) 88 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: int(mode)} 89 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 90 syscallInfo := dara.GeneralSyscall{dara.DSYS_CHMOD, 1, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 91 runtime.Report_Syscall_To_Scheduler(dara.DSYS_CHMOD, syscallInfo) 92 } 93 if e := syscall.Chmod(fixLongPath(name), syscallMode(mode)); e != nil { 94 return &PathError{"chmod", name, e} 95 } 96 return nil 97 } 98 99 // See docs in file.go:(*File).Chmod. 100 func (f *File) chmod(mode FileMode) error { 101 // DARA Instrumentation 102 if runtime.Is_dara_profiling_on() { 103 runtime.Dara_Debug_Print(func() { 104 print("[FCHMOD] : ") 105 print(f.file.name) 106 print(" ") 107 println(mode) 108 }) 109 argInfo1 := dara.GeneralType{Type: dara.FILE} 110 copy(argInfo1.String[:], f.name) 111 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: int(mode)} 112 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 113 syscallInfo := dara.GeneralSyscall{dara.DSYS_FCHMOD, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 114 runtime.Report_Syscall_To_Scheduler(dara.DSYS_FCHMOD, syscallInfo) 115 } 116 if err := f.checkValid("chmod"); err != nil { 117 return err 118 } 119 if e := f.pfd.Fchmod(syscallMode(mode)); e != nil { 120 return f.wrapErr("chmod", e) 121 } 122 return nil 123 } 124 125 // Chown changes the numeric uid and gid of the named file. 126 // If the file is a symbolic link, it changes the uid and gid of the link's target. 127 // If there is an error, it will be of type *PathError. 128 // 129 // On Windows, it always returns the syscall.EWINDOWS error, wrapped 130 // in *PathError. 131 func Chown(name string, uid, gid int) error { 132 // DARA Instrumentation 133 if runtime.Is_dara_profiling_on() { 134 runtime.Dara_Debug_Print(func() { 135 print("[CHOWN] : ") 136 print(name) 137 print(" ") 138 print(uid) 139 print(" ") 140 println(gid) 141 }) 142 argInfo1 := dara.GeneralType{Type: dara.STRING} 143 copy(argInfo1.String[:], name) 144 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: int(uid)} 145 argInfo3 := dara.GeneralType{Type: dara.INTEGER, Integer: int(gid)} 146 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 147 syscallInfo := dara.GeneralSyscall{dara.DSYS_CHOWN, 3, 1, [10]dara.GeneralType{argInfo1, argInfo2, argInfo3}, [10]dara.GeneralType{retInfo}} 148 runtime.Report_Syscall_To_Scheduler(dara.DSYS_CHOWN, syscallInfo) 149 } 150 if e := syscall.Chown(name, uid, gid); e != nil { 151 return &PathError{"chown", name, e} 152 } 153 return nil 154 } 155 156 // Lchown changes the numeric uid and gid of the named file. 157 // If the file is a symbolic link, it changes the uid and gid of the link itself. 158 // If there is an error, it will be of type *PathError. 159 // 160 // On Windows, it always returns the syscall.EWINDOWS error, wrapped 161 // in *PathError. 162 func Lchown(name string, uid, gid int) error { 163 // DARA Instrumentation 164 if runtime.Is_dara_profiling_on() { 165 runtime.Dara_Debug_Print(func() { 166 print("[LCHOWN] : ") 167 print(name) 168 print(" ") 169 print(uid) 170 print(" ") 171 println(gid) 172 }) 173 argInfo1 := dara.GeneralType{Type: dara.STRING} 174 copy(argInfo1.String[:], name) 175 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: int(uid)} 176 argInfo3 := dara.GeneralType{Type: dara.INTEGER, Integer: int(gid)} 177 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 178 syscallInfo := dara.GeneralSyscall{dara.DSYS_LCHOWN, 3, 1, [10]dara.GeneralType{argInfo1, argInfo2, argInfo3}, [10]dara.GeneralType{retInfo}} 179 runtime.Report_Syscall_To_Scheduler(dara.DSYS_LCHOWN, syscallInfo) 180 } 181 if e := syscall.Lchown(name, uid, gid); e != nil { 182 return &PathError{"lchown", name, e} 183 } 184 return nil 185 } 186 187 // Chown changes the numeric uid and gid of the named file. 188 // If there is an error, it will be of type *PathError. 189 // 190 // On Windows, it always returns the syscall.EWINDOWS error, wrapped 191 // in *PathError. 192 func (f *File) Chown(uid, gid int) error { 193 // DARA Instrumentation 194 if runtime.Is_dara_profiling_on() { 195 runtime.Dara_Debug_Print(func() { 196 print("[FCHOWN] : ") 197 print(f.file.name) 198 print(" ") 199 print(uid) 200 print(" ") 201 println(gid) 202 }) 203 argInfo1 := dara.GeneralType{Type: dara.STRING} 204 copy(argInfo1.String[:], f.name) 205 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: int(uid)} 206 argInfo3 := dara.GeneralType{Type: dara.INTEGER, Integer: int(gid)} 207 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 208 syscallInfo := dara.GeneralSyscall{dara.DSYS_FCHOWN, 3, 1, [10]dara.GeneralType{argInfo1, argInfo2, argInfo3}, [10]dara.GeneralType{retInfo}} 209 runtime.Report_Syscall_To_Scheduler(dara.DSYS_FCHOWN, syscallInfo) 210 } 211 if err := f.checkValid("chown"); err != nil { 212 return err 213 } 214 if e := f.pfd.Fchown(uid, gid); e != nil { 215 return f.wrapErr("chown", e) 216 } 217 return nil 218 } 219 220 // Truncate changes the size of the file. 221 // It does not change the I/O offset. 222 // If there is an error, it will be of type *PathError. 223 func (f *File) Truncate(size int64) error { 224 // DARA Instrumentation 225 if runtime.Is_dara_profiling_on() { 226 runtime.Dara_Debug_Print(func() { 227 print("[FTRUNCATE] : ") 228 print(f.file.name) 229 print(" ") 230 println(size) 231 }) 232 argInfo1 := dara.GeneralType{Type: dara.FILE} 233 copy(argInfo1.String[:], f.name) 234 argInfo2 := dara.GeneralType{Type: dara.INTEGER64, Integer64: size} 235 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 236 syscallInfo := dara.GeneralSyscall{dara.DSYS_FTRUNCATE, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 237 runtime.Report_Syscall_To_Scheduler(dara.DSYS_FTRUNCATE, syscallInfo) 238 } 239 if err := f.checkValid("truncate"); err != nil { 240 return err 241 } 242 if e := f.pfd.Ftruncate(size); e != nil { 243 return f.wrapErr("truncate", e) 244 } 245 return nil 246 } 247 248 // Sync commits the current contents of the file to stable storage. 249 // Typically, this means flushing the file system's in-memory copy 250 // of recently written data to disk. 251 func (f *File) Sync() error { 252 // DARA Instrumentation 253 if runtime.Is_dara_profiling_on() { 254 runtime.Dara_Debug_Print(func() { 255 print("[FSYNC] : ") 256 println(f.file.name) 257 }) 258 argInfo1 := dara.GeneralType{Type: dara.FILE} 259 copy(argInfo1.String[:], f.name) 260 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 261 syscallInfo := dara.GeneralSyscall{dara.DSYS_FSYNC, 1, 1, [10]dara.GeneralType{argInfo1}, [10]dara.GeneralType{retInfo}} 262 runtime.Report_Syscall_To_Scheduler(dara.DSYS_FSYNC, syscallInfo) 263 } 264 if err := f.checkValid("sync"); err != nil { 265 return err 266 } 267 if e := f.pfd.Fsync(); e != nil { 268 return f.wrapErr("sync", e) 269 } 270 return nil 271 } 272 273 // Chtimes changes the access and modification times of the named 274 // file, similar to the Unix utime() or utimes() functions. 275 // 276 // The underlying filesystem may truncate or round the values to a 277 // less precise time unit. 278 // If there is an error, it will be of type *PathError. 279 func Chtimes(name string, atime time.Time, mtime time.Time) error { 280 // DARA Instrumentation 281 if runtime.Is_dara_profiling_on() { 282 runtime.Dara_Debug_Print(func() { 283 print("[UTIMES] : ") 284 print(name) 285 print(" ") 286 print(atime.String()) 287 print(" ") 288 println(mtime.String()) 289 }) 290 argInfo1 := dara.GeneralType{Type:dara.STRING} 291 copy(argInfo1.String[:], name) 292 argInfo2 := dara.GeneralType{Type:dara.TIME} 293 copy(argInfo2.String[:], atime.String()) 294 argInfo3 := dara.GeneralType{Type:dara.TIME} 295 copy(argInfo3.String[:], mtime.String()) 296 retInfo := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 297 syscallInfo := dara.GeneralSyscall{dara.DSYS_UTIMES, 3, 1, [10]dara.GeneralType{argInfo1, argInfo2, argInfo3}, [10]dara.GeneralType{retInfo}} 298 runtime.Report_Syscall_To_Scheduler(dara.DSYS_UTIMES, syscallInfo) 299 } 300 var utimes [2]syscall.Timespec 301 utimes[0] = syscall.NsecToTimespec(atime.UnixNano()) 302 utimes[1] = syscall.NsecToTimespec(mtime.UnixNano()) 303 if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil { 304 return &PathError{"chtimes", name, e} 305 } 306 return nil 307 } 308 309 // Chdir changes the current working directory to the file, 310 // which must be a directory. 311 // If there is an error, it will be of type *PathError. 312 func (f *File) Chdir() error { 313 // DARA Instrumentation 314 if runtime.Is_dara_profiling_on() { 315 runtime.Dara_Debug_Print(func() { 316 print("[FCHDIR] : ") 317 println(f.file.name) 318 }) 319 argInfo1 := dara.GeneralType{Type:dara.FILE} 320 copy(argInfo1.String[:], f.name) 321 retInfo := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 322 syscallInfo := dara.GeneralSyscall{dara.DSYS_FCHDIR, 1, 1, [10]dara.GeneralType{argInfo1}, [10]dara.GeneralType{retInfo}} 323 runtime.Report_Syscall_To_Scheduler(dara.DSYS_FCHDIR, syscallInfo) 324 } 325 if err := f.checkValid("chdir"); err != nil { 326 return err 327 } 328 if e := f.pfd.Fchdir(); e != nil { 329 return f.wrapErr("chdir", e) 330 } 331 return nil 332 } 333 334 // setDeadline sets the read and write deadline. 335 func (f *File) setDeadline(t time.Time) error { 336 // DARA Instrumentation 337 if runtime.Is_dara_profiling_on() { 338 runtime.Dara_Debug_Print(func() { 339 print("[SetDeadline] : ") 340 print(f.file.name) 341 print(" ") 342 println(t.String()) 343 }) 344 argInfo1 := dara.GeneralType{Type:dara.FILE} 345 copy(argInfo1.String[:], f.name) 346 argInfo2 := dara.GeneralType{Type:dara.TIME} 347 copy(argInfo2.String[:], t.String()) 348 retInfo := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 349 syscallInfo := dara.GeneralSyscall{dara.DSYS_SETDEADLINE, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 350 runtime.Report_Syscall_To_Scheduler(dara.DSYS_SETDEADLINE, syscallInfo) 351 } 352 if err := f.checkValid("SetDeadline"); err != nil { 353 return err 354 } 355 return f.pfd.SetDeadline(t) 356 } 357 358 // setReadDeadline sets the read deadline. 359 func (f *File) setReadDeadline(t time.Time) error { 360 // DARA Instrumentation 361 if runtime.Is_dara_profiling_on() { 362 runtime.Dara_Debug_Print(func() { 363 print("[SetReadDeadline] : ") 364 print(f.file.name) 365 print(" ") 366 println(t.String()) 367 }) 368 argInfo1 := dara.GeneralType{Type:dara.FILE} 369 copy(argInfo1.String[:], f.name) 370 argInfo2 := dara.GeneralType{Type:dara.TIME} 371 copy(argInfo2.String[:], t.String()) 372 retInfo := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 373 syscallInfo := dara.GeneralSyscall{dara.DSYS_SETREADDEADLINE, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 374 runtime.Report_Syscall_To_Scheduler(dara.DSYS_SETREADDEADLINE, syscallInfo) 375 } 376 if err := f.checkValid("SetReadDeadline"); err != nil { 377 return err 378 } 379 return f.pfd.SetReadDeadline(t) 380 } 381 382 // setWriteDeadline sets the write deadline. 383 func (f *File) setWriteDeadline(t time.Time) error { 384 // DARA Instrumentation 385 if runtime.Is_dara_profiling_on() { 386 runtime.Dara_Debug_Print(func() { 387 print("[SetWriteDeadline] : ") 388 print(f.file.name) 389 print(" ") 390 println(t.String()) 391 }) 392 argInfo1 := dara.GeneralType{Type:dara.FILE} 393 copy(argInfo1.String[:], f.name) 394 argInfo2 := dara.GeneralType{Type:dara.TIME} 395 copy(argInfo2.String[:], t.String()) 396 retInfo := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 397 syscallInfo := dara.GeneralSyscall{dara.DSYS_SETWRITEDEADLINE, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 398 runtime.Report_Syscall_To_Scheduler(dara.DSYS_SETWRITEDEADLINE, syscallInfo) 399 } 400 if err := f.checkValid("SetWriteDeadline"); err != nil { 401 return err 402 } 403 return f.pfd.SetWriteDeadline(t) 404 } 405 406 // checkValid checks whether f is valid for use. 407 // If not, it returns an appropriate error, perhaps incorporating the operation name op. 408 func (f *File) checkValid(op string) error { 409 if f == nil { 410 return ErrInvalid 411 } 412 return nil 413 }