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.
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.
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.
16 // Here is a simple example, opening a file and reading some of it.
18 // file, err := os.Open("file.go") // For read access.
23 // If the open fails, the error string will be self-explanatory, like
25 // open file.go: no such file or directory
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.
30 // data := make([]byte, 100)
31 // count, err := file.Read(data)
35 // fmt.Printf("read %d bytes: %q\n", count, data[:count])
37 // Note: The maximum number of concurrent operations on a File may be limited by
38 // the OS or the system. The number should be high, but exceeding it may degrade
39 // performance or cause other issues.
47 "internal/unsafeheader"
56 // Name returns the name of the file as presented to Open.
57 func (f
*File
) Name() string { return f
.name
}
59 // Stdin, Stdout, and Stderr are open Files pointing to the standard input,
60 // standard output, and standard error file descriptors.
62 // Note that the Go runtime writes to standard error for panics and crashes;
63 // closing Stderr may cause those messages to go elsewhere, perhaps
64 // to a file opened later.
66 Stdin
= NewFile(uintptr(syscall
.Stdin
), "/dev/stdin")
67 Stdout
= NewFile(uintptr(syscall
.Stdout
), "/dev/stdout")
68 Stderr
= NewFile(uintptr(syscall
.Stderr
), "/dev/stderr")
71 // Flags to OpenFile wrapping those of the underlying system. Not all
72 // flags may be implemented on a given system.
74 // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
75 O_RDONLY
int = syscall
.O_RDONLY
// open the file read-only.
76 O_WRONLY
int = syscall
.O_WRONLY
// open the file write-only.
77 O_RDWR
int = syscall
.O_RDWR
// open the file read-write.
78 // The remaining values may be or'ed in to control behavior.
79 O_APPEND
int = syscall
.O_APPEND
// append data to the file when writing.
80 O_CREATE
int = syscall
.O_CREAT
// create a new file if none exists.
81 O_EXCL
int = syscall
.O_EXCL
// used with O_CREATE, file must not exist.
82 O_SYNC
int = syscall
.O_SYNC
// open for synchronous I/O.
83 O_TRUNC
int = syscall
.O_TRUNC
// truncate regular writable file when opened.
86 // Seek whence values.
88 // Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd.
90 SEEK_SET
int = 0 // seek relative to the origin of the file
91 SEEK_CUR
int = 1 // seek relative to the current offset
92 SEEK_END
int = 2 // seek relative to the end
95 // LinkError records an error during a link or symlink or rename
96 // system call and the paths that caused it.
97 type LinkError
struct {
104 func (e
*LinkError
) Error() string {
105 return e
.Op
+ " " + e
.Old
+ " " + e
.New
+ ": " + e
.Err
.Error()
108 func (e
*LinkError
) Unwrap() error
{
112 // Read reads up to len(b) bytes from the File and stores them in b.
113 // It returns the number of bytes read and any error encountered.
114 // At end of file, Read returns 0, io.EOF.
115 func (f
*File
) Read(b
[]byte) (n
int, err error
) {
116 if err
:= f
.checkValid("read"); err
!= nil {
120 return n
, f
.wrapErr("read", e
)
123 // ReadAt reads len(b) bytes from the File starting at byte offset off.
124 // It returns the number of bytes read and the error, if any.
125 // ReadAt always returns a non-nil error when n < len(b).
126 // At end of file, that error is io.EOF.
127 func (f
*File
) ReadAt(b
[]byte, off
int64) (n
int, err error
) {
128 if err
:= f
.checkValid("read"); err
!= nil {
133 return 0, &PathError
{Op
: "readat", Path
: f
.name
, Err
: errors
.New("negative offset")}
137 m
, e
:= f
.pread(b
, off
)
139 err
= f
.wrapErr("read", e
)
149 // ReadFrom implements io.ReaderFrom.
150 func (f
*File
) ReadFrom(r io
.Reader
) (n
int64, err error
) {
151 if err
:= f
.checkValid("write"); err
!= nil {
154 n
, handled
, e
:= f
.readFrom(r
)
156 return genericReadFrom(f
, r
) // without wrapping
158 return n
, f
.wrapErr("write", e
)
161 func genericReadFrom(f
*File
, r io
.Reader
) (int64, error
) {
162 return io
.Copy(onlyWriter
{f
}, r
)
165 type onlyWriter
struct {
169 // Write writes len(b) bytes from b to the File.
170 // It returns the number of bytes written and an error, if any.
171 // Write returns a non-nil error when n != len(b).
172 func (f
*File
) Write(b
[]byte) (n
int, err error
) {
173 if err
:= f
.checkValid("write"); err
!= nil {
181 err
= io
.ErrShortWrite
187 err
= f
.wrapErr("write", e
)
193 var errWriteAtInAppendMode
= errors
.New("os: invalid use of WriteAt on file opened with O_APPEND")
195 // WriteAt writes len(b) bytes to the File starting at byte offset off.
196 // It returns the number of bytes written and an error, if any.
197 // WriteAt returns a non-nil error when n != len(b).
199 // If file was opened with the O_APPEND flag, WriteAt returns an error.
200 func (f
*File
) WriteAt(b
[]byte, off
int64) (n
int, err error
) {
201 if err
:= f
.checkValid("write"); err
!= nil {
205 return 0, errWriteAtInAppendMode
209 return 0, &PathError
{Op
: "writeat", Path
: f
.name
, Err
: errors
.New("negative offset")}
213 m
, e
:= f
.pwrite(b
, off
)
215 err
= f
.wrapErr("write", e
)
225 // Seek sets the offset for the next Read or Write on file to offset, interpreted
226 // according to whence: 0 means relative to the origin of the file, 1 means
227 // relative to the current offset, and 2 means relative to the end.
228 // It returns the new offset and an error, if any.
229 // The behavior of Seek on a file opened with O_APPEND is not specified.
231 // If f is a directory, the behavior of Seek varies by operating
232 // system; you can seek to the beginning of the directory on Unix-like
233 // operating systems, but not on Windows.
234 func (f
*File
) Seek(offset
int64, whence
int) (ret
int64, err error
) {
235 if err
:= f
.checkValid("seek"); err
!= nil {
238 r
, e
:= f
.seek(offset
, whence
)
239 if e
== nil && f
.dirinfo
!= nil && r
!= 0 {
243 return 0, f
.wrapErr("seek", e
)
248 // WriteString is like Write, but writes the contents of string s rather than
250 func (f
*File
) WriteString(s
string) (n
int, err error
) {
252 hdr
:= (*unsafeheader
.Slice
)(unsafe
.Pointer(&b
))
253 hdr
.Data
= (*unsafeheader
.String
)(unsafe
.Pointer(&s
)).Data
259 // Mkdir creates a new directory with the specified name and permission
260 // bits (before umask).
261 // If there is an error, it will be of type *PathError.
262 func Mkdir(name
string, perm FileMode
) error
{
263 if runtime
.GOOS
== "windows" && isWindowsNulName(name
) {
264 return &PathError
{Op
: "mkdir", Path
: name
, Err
: syscall
.ENOTDIR
}
266 longName
:= fixLongPath(name
)
267 e
:= ignoringEINTR(func() error
{
268 return syscall
.Mkdir(longName
, syscallMode(perm
))
272 return &PathError
{Op
: "mkdir", Path
: name
, Err
: e
}
275 // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
276 if !supportsCreateWithStickyBit
&& perm
&ModeSticky
!= 0 {
277 e
= setStickyBit(name
)
288 // setStickyBit adds ModeSticky to the permission bits of path, non atomic.
289 func setStickyBit(name
string) error
{
290 fi
, err
:= Stat(name
)
294 return Chmod(name
, fi
.Mode()|ModeSticky
)
297 // Chdir changes the current working directory to the named directory.
298 // If there is an error, it will be of type *PathError.
299 func Chdir(dir
string) error
{
300 if e
:= syscall
.Chdir(dir
); e
!= nil {
301 testlog
.Open(dir
) // observe likely non-existent directory
302 return &PathError
{Op
: "chdir", Path
: dir
, Err
: e
}
304 if log
:= testlog
.Logger(); log
!= nil {
313 // Open opens the named file for reading. If successful, methods on
314 // the returned file can be used for reading; the associated file
315 // descriptor has mode O_RDONLY.
316 // If there is an error, it will be of type *PathError.
317 func Open(name
string) (*File
, error
) {
318 return OpenFile(name
, O_RDONLY
, 0)
321 // Create creates or truncates the named file. If the file already exists,
322 // it is truncated. If the file does not exist, it is created with mode 0666
323 // (before umask). If successful, methods on the returned File can
324 // be used for I/O; the associated file descriptor has mode O_RDWR.
325 // If there is an error, it will be of type *PathError.
326 func Create(name
string) (*File
, error
) {
327 return OpenFile(name
, O_RDWR|O_CREATE|O_TRUNC
, 0666)
330 // OpenFile is the generalized open call; most users will use Open
331 // or Create instead. It opens the named file with specified flag
332 // (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag
333 // is passed, it is created with mode perm (before umask). If successful,
334 // methods on the returned File can be used for I/O.
335 // If there is an error, it will be of type *PathError.
336 func OpenFile(name
string, flag
int, perm FileMode
) (*File
, error
) {
338 f
, err
:= openFileNolog(name
, flag
, perm
)
342 f
.appendMode
= flag
&O_APPEND
!= 0
347 // lstat is overridden in tests.
350 // Rename renames (moves) oldpath to newpath.
351 // If newpath already exists and is not a directory, Rename replaces it.
352 // OS-specific restrictions may apply when oldpath and newpath are in different directories.
353 // If there is an error, it will be of type *LinkError.
354 func Rename(oldpath
, newpath
string) error
{
355 return rename(oldpath
, newpath
)
358 // Many functions in package syscall return a count of -1 instead of 0.
359 // Using fixCount(call()) instead of call() corrects the count.
360 func fixCount(n
int, err error
) (int, error
) {
367 // wrapErr wraps an error that occurred during an operation on an open file.
368 // It passes io.EOF through unchanged, otherwise converts
369 // poll.ErrFileClosing to ErrClosed and wraps the error in a PathError.
370 func (f
*File
) wrapErr(op
string, err error
) error
{
371 if err
== nil || err
== io
.EOF
{
374 if err
== poll
.ErrFileClosing
{
377 return &PathError
{Op
: op
, Path
: f
.name
, Err
: err
}
380 // TempDir returns the default directory to use for temporary files.
382 // On Unix systems, it returns $TMPDIR if non-empty, else /tmp.
383 // On Windows, it uses GetTempPath, returning the first non-empty
384 // value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
385 // On Plan 9, it returns /tmp.
387 // The directory is neither guaranteed to exist nor have accessible
389 func TempDir() string {
393 // UserCacheDir returns the default root directory to use for user-specific
394 // cached data. Users should create their own application-specific subdirectory
395 // within this one and use that.
397 // On Unix systems, it returns $XDG_CACHE_HOME as specified by
398 // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
399 // non-empty, else $HOME/.cache.
400 // On Darwin, it returns $HOME/Library/Caches.
401 // On Windows, it returns %LocalAppData%.
402 // On Plan 9, it returns $home/lib/cache.
404 // If the location cannot be determined (for example, $HOME is not defined),
405 // then it will return an error.
406 func UserCacheDir() (string, error
) {
409 switch runtime
.GOOS
{
411 dir
= Getenv("LocalAppData")
413 return "", errors
.New("%LocalAppData% is not defined")
416 case "darwin", "ios":
419 return "", errors
.New("$HOME is not defined")
421 dir
+= "/Library/Caches"
426 return "", errors
.New("$home is not defined")
431 dir
= Getenv("XDG_CACHE_HOME")
435 return "", errors
.New("neither $XDG_CACHE_HOME nor $HOME are defined")
444 // UserConfigDir returns the default root directory to use for user-specific
445 // configuration data. Users should create their own application-specific
446 // subdirectory within this one and use that.
448 // On Unix systems, it returns $XDG_CONFIG_HOME as specified by
449 // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
450 // non-empty, else $HOME/.config.
451 // On Darwin, it returns $HOME/Library/Application Support.
452 // On Windows, it returns %AppData%.
453 // On Plan 9, it returns $home/lib.
455 // If the location cannot be determined (for example, $HOME is not defined),
456 // then it will return an error.
457 func UserConfigDir() (string, error
) {
460 switch runtime
.GOOS
{
462 dir
= Getenv("AppData")
464 return "", errors
.New("%AppData% is not defined")
467 case "darwin", "ios":
470 return "", errors
.New("$HOME is not defined")
472 dir
+= "/Library/Application Support"
477 return "", errors
.New("$home is not defined")
482 dir
= Getenv("XDG_CONFIG_HOME")
486 return "", errors
.New("neither $XDG_CONFIG_HOME nor $HOME are defined")
495 // UserHomeDir returns the current user's home directory.
497 // On Unix, including macOS, it returns the $HOME environment variable.
498 // On Windows, it returns %USERPROFILE%.
499 // On Plan 9, it returns the $home environment variable.
500 func UserHomeDir() (string, error
) {
501 env
, enverr
:= "HOME", "$HOME"
502 switch runtime
.GOOS
{
504 env
, enverr
= "USERPROFILE", "%userprofile%"
506 env
, enverr
= "home", "$home"
508 if v
:= Getenv(env
); v
!= "" {
511 // On some geese the home directory is not always defined.
512 switch runtime
.GOOS
{
514 return "/sdcard", nil
518 return "", errors
.New(enverr
+ " is not defined")
521 // Chmod changes the mode of the named file to mode.
522 // If the file is a symbolic link, it changes the mode of the link's target.
523 // If there is an error, it will be of type *PathError.
525 // A different subset of the mode bits are used, depending on the
528 // On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
529 // ModeSticky are used.
531 // On Windows, only the 0200 bit (owner writable) of mode is used; it
532 // controls whether the file's read-only attribute is set or cleared.
533 // The other bits are currently unused. For compatibility with Go 1.12
534 // and earlier, use a non-zero mode. Use mode 0400 for a read-only
535 // file and 0600 for a readable+writable file.
537 // On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
538 // and ModeTemporary are used.
539 func Chmod(name
string, mode FileMode
) error
{ return chmod(name
, mode
) }
541 // Chmod changes the mode of the file to mode.
542 // If there is an error, it will be of type *PathError.
543 func (f
*File
) Chmod(mode FileMode
) error
{ return f
.chmod(mode
) }
545 // SetDeadline sets the read and write deadlines for a File.
546 // It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
548 // Only some kinds of files support setting a deadline. Calls to SetDeadline
549 // for files that do not support deadlines will return ErrNoDeadline.
550 // On most systems ordinary files do not support deadlines, but pipes do.
552 // A deadline is an absolute time after which I/O operations fail with an
553 // error instead of blocking. The deadline applies to all future and pending
554 // I/O, not just the immediately following call to Read or Write.
555 // After a deadline has been exceeded, the connection can be refreshed
556 // by setting a deadline in the future.
558 // If the deadline is exceeded a call to Read or Write or to other I/O
559 // methods will return an error that wraps ErrDeadlineExceeded.
560 // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
561 // That error implements the Timeout method, and calling the Timeout
562 // method will return true, but there are other possible errors for which
563 // the Timeout will return true even if the deadline has not been exceeded.
565 // An idle timeout can be implemented by repeatedly extending
566 // the deadline after successful Read or Write calls.
568 // A zero value for t means I/O operations will not time out.
569 func (f
*File
) SetDeadline(t time
.Time
) error
{
570 return f
.setDeadline(t
)
573 // SetReadDeadline sets the deadline for future Read calls and any
574 // currently-blocked Read call.
575 // A zero value for t means Read will not time out.
576 // Not all files support setting deadlines; see SetDeadline.
577 func (f
*File
) SetReadDeadline(t time
.Time
) error
{
578 return f
.setReadDeadline(t
)
581 // SetWriteDeadline sets the deadline for any future Write calls and any
582 // currently-blocked Write call.
583 // Even if Write times out, it may return n > 0, indicating that
584 // some of the data was successfully written.
585 // A zero value for t means Write will not time out.
586 // Not all files support setting deadlines; see SetDeadline.
587 func (f
*File
) SetWriteDeadline(t time
.Time
) error
{
588 return f
.setWriteDeadline(t
)
591 // SyscallConn returns a raw file.
592 // This implements the syscall.Conn interface.
593 func (f
*File
) SyscallConn() (syscall
.RawConn
, error
) {
594 if err
:= f
.checkValid("SyscallConn"); err
!= nil {
600 // isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
601 // True is returned if name is 'NUL' whatever the case.
602 func isWindowsNulName(name
string) bool {
606 if name
[0] != 'n' && name
[0] != 'N' {
609 if name
[1] != 'u' && name
[1] != 'U' {
612 if name
[2] != 'l' && name
[2] != 'L' {
618 // DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir.
620 // Note that DirFS("/prefix") only guarantees that the Open calls it makes to the
621 // operating system will begin with "/prefix": DirFS("/prefix").Open("file") is the
622 // same as os.Open("/prefix/file"). So if /prefix/file is a symbolic link pointing outside
623 // the /prefix tree, then using DirFS does not stop the access any more than using
624 // os.Open does. DirFS is therefore not a general substitute for a chroot-style security
625 // mechanism when the directory tree contains arbitrary content.
626 func DirFS(dir
string) fs
.FS
{
630 func containsAny(s
, chars
string) bool {
631 for i
:= 0; i
< len(s
); i
++ {
632 for j
:= 0; j
< len(chars
); j
++ {
633 if s
[i
] == chars
[j
] {
643 func (dir dirFS
) Open(name
string) (fs
.File
, error
) {
644 if !fs
.ValidPath(name
) || runtime
.GOOS
== "windows" && containsAny(name
, `\:`) {
645 return nil, &PathError
{Op
: "open", Path
: name
, Err
: ErrInvalid
}
647 f
, err
:= Open(string(dir
) + "/" + name
)
649 return nil, err
// nil fs.File
654 func (dir dirFS
) Stat(name
string) (fs
.FileInfo
, error
) {
655 if !fs
.ValidPath(name
) || runtime
.GOOS
== "windows" && containsAny(name
, `\:`) {
656 return nil, &PathError
{Op
: "stat", Path
: name
, Err
: ErrInvalid
}
658 f
, err
:= Stat(string(dir
) + "/" + name
)
665 // ReadFile reads the named file and returns the contents.
666 // A successful call returns err == nil, not err == EOF.
667 // Because ReadFile reads the whole file, it does not treat an EOF from Read
668 // as an error to be reported.
669 func ReadFile(name
string) ([]byte, error
) {
677 if info
, err
:= f
.Stat(); err
== nil {
678 size64
:= info
.Size()
679 if int64(int(size64
)) == size64
{
683 size
++ // one byte for final read at EOF
685 // If a file claims a small size, read at least 512 bytes.
686 // In particular, files in Linux's /proc claim size 0 but
687 // then do not work right if read in small pieces,
688 // so an initial read of 1 byte would not work correctly.
693 data
:= make([]byte, 0, size
)
695 if len(data
) >= cap(data
) {
696 d
:= append(data
[:cap(data
)], 0)
699 n
, err
:= f
.Read(data
[len(data
):cap(data
)])
700 data
= data
[:len(data
)+n
]
710 // WriteFile writes data to the named file, creating it if necessary.
711 // If the file does not exist, WriteFile creates it with permissions perm (before umask);
712 // otherwise WriteFile truncates it before writing, without changing permissions.
713 func WriteFile(name
string, data
[]byte, perm FileMode
) error
{
714 f
, err
:= OpenFile(name
, O_WRONLY|O_CREATE|O_TRUNC
, perm
)
718 _
, err
= f
.Write(data
)
719 if err1
:= f
.Close(); err1
!= nil && err
== nil {