github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/os/file.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 // Package os provides a platform-independent interface to operating system 6 // functionality. The design is Unix-like, although the error handling is 7 // Go-like; failing calls return values of type error rather than error numbers. 8 // Often, more information is available within the error. For example, 9 // if a call that takes a file name fails, such as Open or Stat, the error 10 // will include the failing file name when printed and will be of type 11 // *PathError, which may be unpacked for more information. 12 // 13 // The os interface is intended to be uniform across all operating systems. 14 // Features not generally available appear in the system-specific package syscall. 15 // 16 // Here is a simple example, opening a file and reading some of it. 17 // 18 // file, err := os.Open("file.go") // For read access. 19 // if err != nil { 20 // log.Fatal(err) 21 // } 22 // 23 // If the open fails, the error string will be self-explanatory, like 24 // 25 // open file.go: no such file or directory 26 // 27 // The file's data can then be read into a slice of bytes. Read and 28 // Write take their byte counts from the length of the argument slice. 29 // 30 // data := make([]byte, 100) 31 // count, err := file.Read(data) 32 // if err != nil { 33 // log.Fatal(err) 34 // } 35 // fmt.Printf("read %d bytes: %q\n", count, data[:count]) 36 // 37 package os 38 39 import ( 40 "errors" 41 "internal/poll" 42 "internal/testlog" 43 "io" 44 "runtime" 45 "syscall" 46 "time" 47 ) 48 49 // Name returns the name of the file as presented to Open. 50 func (f *File) Name() string { return f.name } 51 52 // Stdin, Stdout, and Stderr are open Files pointing to the standard input, 53 // standard output, and standard error file descriptors. 54 // 55 // Note that the Go runtime writes to standard error for panics and crashes; 56 // closing Stderr may cause those messages to go elsewhere, perhaps 57 // to a file opened later. 58 var ( 59 Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") 60 Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout") 61 Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr") 62 ) 63 64 // Flags to OpenFile wrapping those of the underlying system. Not all 65 // flags may be implemented on a given system. 66 const ( 67 // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified. 68 O_RDONLY int = syscall.O_RDONLY // open the file read-only. 69 O_WRONLY int = syscall.O_WRONLY // open the file write-only. 70 O_RDWR int = syscall.O_RDWR // open the file read-write. 71 // The remaining values may be or'ed in to control behavior. 72 O_APPEND int = syscall.O_APPEND // append data to the file when writing. 73 O_CREATE int = syscall.O_CREAT // create a new file if none exists. 74 O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist. 75 O_SYNC int = syscall.O_SYNC // open for synchronous I/O. 76 O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened. 77 ) 78 79 // Seek whence values. 80 // 81 // Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd. 82 const ( 83 SEEK_SET int = 0 // seek relative to the origin of the file 84 SEEK_CUR int = 1 // seek relative to the current offset 85 SEEK_END int = 2 // seek relative to the end 86 ) 87 88 // LinkError records an error during a link or symlink or rename 89 // system call and the paths that caused it. 90 type LinkError struct { 91 Op string 92 Old string 93 New string 94 Err error 95 } 96 97 func (e *LinkError) Error() string { 98 return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error() 99 } 100 101 // Read reads up to len(b) bytes from the File. 102 // It returns the number of bytes read and any error encountered. 103 // At end of file, Read returns 0, io.EOF. 104 func (f *File) Read(b []byte) (n int, err error) { 105 if err := f.checkValid("read"); err != nil { 106 return 0, err 107 } 108 n, e := f.read(b) 109 return n, f.wrapErr("read", e) 110 } 111 112 // ReadAt reads len(b) bytes from the File starting at byte offset off. 113 // It returns the number of bytes read and the error, if any. 114 // ReadAt always returns a non-nil error when n < len(b). 115 // At end of file, that error is io.EOF. 116 func (f *File) ReadAt(b []byte, off int64) (n int, err error) { 117 if err := f.checkValid("read"); err != nil { 118 return 0, err 119 } 120 121 if off < 0 { 122 return 0, &PathError{"readat", f.name, errors.New("negative offset")} 123 } 124 125 for len(b) > 0 { 126 m, e := f.pread(b, off) 127 if e != nil { 128 err = f.wrapErr("read", e) 129 break 130 } 131 n += m 132 b = b[m:] 133 off += int64(m) 134 } 135 return 136 } 137 138 // Write writes len(b) bytes to the File. 139 // It returns the number of bytes written and an error, if any. 140 // Write returns a non-nil error when n != len(b). 141 func (f *File) Write(b []byte) (n int, err error) { 142 if err := f.checkValid("write"); err != nil { 143 return 0, err 144 } 145 n, e := f.write(b) 146 if n < 0 { 147 n = 0 148 } 149 if n != len(b) { 150 err = io.ErrShortWrite 151 } 152 153 epipecheck(f, e) 154 155 if e != nil { 156 err = f.wrapErr("write", e) 157 } 158 159 return n, err 160 } 161 162 // WriteAt writes len(b) bytes to the File starting at byte offset off. 163 // It returns the number of bytes written and an error, if any. 164 // WriteAt returns a non-nil error when n != len(b). 165 func (f *File) WriteAt(b []byte, off int64) (n int, err error) { 166 if err := f.checkValid("write"); err != nil { 167 return 0, err 168 } 169 170 if off < 0 { 171 return 0, &PathError{"writeat", f.name, errors.New("negative offset")} 172 } 173 174 for len(b) > 0 { 175 m, e := f.pwrite(b, off) 176 if e != nil { 177 err = f.wrapErr("write", e) 178 break 179 } 180 n += m 181 b = b[m:] 182 off += int64(m) 183 } 184 return 185 } 186 187 // Seek sets the offset for the next Read or Write on file to offset, interpreted 188 // according to whence: 0 means relative to the origin of the file, 1 means 189 // relative to the current offset, and 2 means relative to the end. 190 // It returns the new offset and an error, if any. 191 // The behavior of Seek on a file opened with O_APPEND is not specified. 192 func (f *File) Seek(offset int64, whence int) (ret int64, err error) { 193 if err := f.checkValid("seek"); err != nil { 194 return 0, err 195 } 196 r, e := f.seek(offset, whence) 197 if e == nil && f.dirinfo != nil && r != 0 { 198 e = syscall.EISDIR 199 } 200 if e != nil { 201 return 0, f.wrapErr("seek", e) 202 } 203 return r, nil 204 } 205 206 // WriteString is like Write, but writes the contents of string s rather than 207 // a slice of bytes. 208 func (f *File) WriteString(s string) (n int, err error) { 209 return f.Write([]byte(s)) 210 } 211 212 // Mkdir creates a new directory with the specified name and permission 213 // bits (before umask). 214 // If there is an error, it will be of type *PathError. 215 func Mkdir(name string, perm FileMode) error { 216 e := syscall.Mkdir(fixLongPath(name), syscallMode(perm)) 217 218 if e != nil { 219 return &PathError{"mkdir", name, e} 220 } 221 222 // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris 223 if !supportsCreateWithStickyBit && perm&ModeSticky != 0 { 224 e = setStickyBit(name) 225 226 if e != nil { 227 Remove(name) 228 return e 229 } 230 } 231 232 return nil 233 } 234 235 // setStickyBit adds ModeSticky to the permision bits of path, non atomic. 236 func setStickyBit(name string) error { 237 fi, err := Stat(name) 238 if err != nil { 239 return err 240 } 241 return Chmod(name, fi.Mode()|ModeSticky) 242 } 243 244 // Chdir changes the current working directory to the named directory. 245 // If there is an error, it will be of type *PathError. 246 func Chdir(dir string) error { 247 if e := syscall.Chdir(dir); e != nil { 248 testlog.Open(dir) // observe likely non-existent directory 249 return &PathError{"chdir", dir, e} 250 } 251 if log := testlog.Logger(); log != nil { 252 wd, err := Getwd() 253 if err == nil { 254 log.Chdir(wd) 255 } 256 } 257 return nil 258 } 259 260 // Open opens the named file for reading. If successful, methods on 261 // the returned file can be used for reading; the associated file 262 // descriptor has mode O_RDONLY. 263 // If there is an error, it will be of type *PathError. 264 func Open(name string) (*File, error) { 265 return OpenFile(name, O_RDONLY, 0) 266 } 267 268 // Create creates the named file with mode 0666 (before umask), truncating 269 // it if it already exists. If successful, methods on the returned 270 // File can be used for I/O; the associated file descriptor has mode 271 // O_RDWR. 272 // If there is an error, it will be of type *PathError. 273 func Create(name string) (*File, error) { 274 return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) 275 } 276 277 // OpenFile is the generalized open call; most users will use Open 278 // or Create instead. It opens the named file with specified flag 279 // (O_RDONLY etc.) and perm (before umask), if applicable. If successful, 280 // methods on the returned File can be used for I/O. 281 // If there is an error, it will be of type *PathError. 282 func OpenFile(name string, flag int, perm FileMode) (*File, error) { 283 testlog.Open(name) 284 return openFileNolog(name, flag, perm) 285 } 286 287 // lstat is overridden in tests. 288 var lstat = Lstat 289 290 // Rename renames (moves) oldpath to newpath. 291 // If newpath already exists and is not a directory, Rename replaces it. 292 // OS-specific restrictions may apply when oldpath and newpath are in different directories. 293 // If there is an error, it will be of type *LinkError. 294 func Rename(oldpath, newpath string) error { 295 return rename(oldpath, newpath) 296 } 297 298 // Many functions in package syscall return a count of -1 instead of 0. 299 // Using fixCount(call()) instead of call() corrects the count. 300 func fixCount(n int, err error) (int, error) { 301 if n < 0 { 302 n = 0 303 } 304 return n, err 305 } 306 307 // wrapErr wraps an error that occurred during an operation on an open file. 308 // It passes io.EOF through unchanged, otherwise converts 309 // poll.ErrFileClosing to ErrClosed and wraps the error in a PathError. 310 func (f *File) wrapErr(op string, err error) error { 311 if err == nil || err == io.EOF { 312 return err 313 } 314 if err == poll.ErrFileClosing { 315 err = ErrClosed 316 } 317 return &PathError{op, f.name, err} 318 } 319 320 // TempDir returns the default directory to use for temporary files. 321 // 322 // On Unix systems, it returns $TMPDIR if non-empty, else /tmp. 323 // On Windows, it uses GetTempPath, returning the first non-empty 324 // value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory. 325 // On Plan 9, it returns /tmp. 326 // 327 // The directory is neither guaranteed to exist nor have accessible 328 // permissions. 329 func TempDir() string { 330 return tempDir() 331 } 332 333 // UserCacheDir returns the default root directory to use for user-specific 334 // cached data. Users should create their own application-specific subdirectory 335 // within this one and use that. 336 // 337 // On Unix systems, it returns $XDG_CACHE_HOME as specified by 338 // https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html if 339 // non-empty, else $HOME/.cache. 340 // On Darwin, it returns $HOME/Library/Caches. 341 // On Windows, it returns %LocalAppData%. 342 // On Plan 9, it returns $home/lib/cache. 343 // 344 // If the location cannot be determined (for example, $HOME is not defined), 345 // then it will return an error. 346 func UserCacheDir() (string, error) { 347 var dir string 348 349 switch runtime.GOOS { 350 case "windows": 351 dir = Getenv("LocalAppData") 352 if dir == "" { 353 return "", errors.New("%LocalAppData% is not defined") 354 } 355 356 case "darwin": 357 dir = Getenv("HOME") 358 if dir == "" { 359 return "", errors.New("$HOME is not defined") 360 } 361 dir += "/Library/Caches" 362 363 case "plan9": 364 dir = Getenv("home") 365 if dir == "" { 366 return "", errors.New("$home is not defined") 367 } 368 dir += "/lib/cache" 369 370 default: // Unix 371 dir = Getenv("XDG_CACHE_HOME") 372 if dir == "" { 373 dir = Getenv("HOME") 374 if dir == "" { 375 return "", errors.New("neither $XDG_CACHE_HOME nor $HOME are defined") 376 } 377 dir += "/.cache" 378 } 379 } 380 381 return dir, nil 382 } 383 384 // UserHomeDir returns the current user's home directory. 385 // 386 // On Unix, including macOS, it returns the $HOME environment variable. 387 // On Windows, it returns %USERPROFILE%. 388 // On Plan 9, it returns the $home environment variable. 389 func UserHomeDir() (string, error) { 390 env, enverr := "HOME", "$HOME" 391 switch runtime.GOOS { 392 case "windows": 393 env, enverr = "USERPROFILE", "%userprofile%" 394 case "plan9": 395 env, enverr = "home", "$home" 396 case "nacl", "android": 397 return "/", nil 398 case "darwin": 399 if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { 400 return "/", nil 401 } 402 } 403 if v := Getenv(env); v != "" { 404 return v, nil 405 } 406 return "", errors.New(enverr + " is not defined") 407 } 408 409 // Chmod changes the mode of the named file to mode. 410 // If the file is a symbolic link, it changes the mode of the link's target. 411 // If there is an error, it will be of type *PathError. 412 // 413 // A different subset of the mode bits are used, depending on the 414 // operating system. 415 // 416 // On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and 417 // ModeSticky are used. 418 // 419 // On Windows, the mode must be non-zero but otherwise only the 0200 420 // bit (owner writable) of mode is used; it controls whether the 421 // file's read-only attribute is set or cleared. attribute. The other 422 // bits are currently unused. Use mode 0400 for a read-only file and 423 // 0600 for a readable+writable file. 424 // 425 // On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive, 426 // and ModeTemporary are used. 427 func Chmod(name string, mode FileMode) error { return chmod(name, mode) } 428 429 // Chmod changes the mode of the file to mode. 430 // If there is an error, it will be of type *PathError. 431 func (f *File) Chmod(mode FileMode) error { return f.chmod(mode) } 432 433 // SetDeadline sets the read and write deadlines for a File. 434 // It is equivalent to calling both SetReadDeadline and SetWriteDeadline. 435 // 436 // Only some kinds of files support setting a deadline. Calls to SetDeadline 437 // for files that do not support deadlines will return ErrNoDeadline. 438 // On most systems ordinary files do not support deadlines, but pipes do. 439 // 440 // A deadline is an absolute time after which I/O operations fail with an 441 // error instead of blocking. The deadline applies to all future and pending 442 // I/O, not just the immediately following call to Read or Write. 443 // After a deadline has been exceeded, the connection can be refreshed 444 // by setting a deadline in the future. 445 // 446 // An error returned after a timeout fails will implement the 447 // Timeout method, and calling the Timeout method will return true. 448 // The PathError and SyscallError types implement the Timeout method. 449 // In general, call IsTimeout to test whether an error indicates a timeout. 450 // 451 // An idle timeout can be implemented by repeatedly extending 452 // the deadline after successful Read or Write calls. 453 // 454 // A zero value for t means I/O operations will not time out. 455 func (f *File) SetDeadline(t time.Time) error { 456 return f.setDeadline(t) 457 } 458 459 // SetReadDeadline sets the deadline for future Read calls and any 460 // currently-blocked Read call. 461 // A zero value for t means Read will not time out. 462 // Not all files support setting deadlines; see SetDeadline. 463 func (f *File) SetReadDeadline(t time.Time) error { 464 return f.setReadDeadline(t) 465 } 466 467 // SetWriteDeadline sets the deadline for any future Write calls and any 468 // currently-blocked Write call. 469 // Even if Write times out, it may return n > 0, indicating that 470 // some of the data was successfully written. 471 // A zero value for t means Write will not time out. 472 // Not all files support setting deadlines; see SetDeadline. 473 func (f *File) SetWriteDeadline(t time.Time) error { 474 return f.setWriteDeadline(t) 475 } 476 477 // SyscallConn returns a raw file. 478 // This implements the syscall.Conn interface. 479 func (f *File) SyscallConn() (syscall.RawConn, error) { 480 if err := f.checkValid("SyscallConn"); err != nil { 481 return nil, err 482 } 483 return newRawConn(f) 484 }