Black Lives Matter. Support the Equal Justice Initiative.

Source file src/os/file_posix.go

Documentation: os

     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 aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
     6  
     7  package os
     8  
     9  import (
    10  	"runtime"
    11  	"syscall"
    12  	"time"
    13  )
    14  
    15  func sigpipe() // implemented in package runtime
    16  
    17  // Close closes the File, rendering it unusable for I/O.
    18  // On files that support SetDeadline, any pending I/O operations will
    19  // be canceled and return immediately with an error.
    20  // Close will return an error if it has already been called.
    21  func (f *File) Close() error {
    22  	if f == nil {
    23  		return ErrInvalid
    24  	}
    25  	return f.file.close()
    26  }
    27  
    28  // read reads up to len(b) bytes from the File.
    29  // It returns the number of bytes read and an error, if any.
    30  func (f *File) read(b []byte) (n int, err error) {
    31  	n, err = f.pfd.Read(b)
    32  	runtime.KeepAlive(f)
    33  	return n, err
    34  }
    35  
    36  // pread reads len(b) bytes from the File starting at byte offset off.
    37  // It returns the number of bytes read and the error, if any.
    38  // EOF is signaled by a zero count with err set to nil.
    39  func (f *File) pread(b []byte, off int64) (n int, err error) {
    40  	n, err = f.pfd.Pread(b, off)
    41  	runtime.KeepAlive(f)
    42  	return n, err
    43  }
    44  
    45  // write writes len(b) bytes to the File.
    46  // It returns the number of bytes written and an error, if any.
    47  func (f *File) write(b []byte) (n int, err error) {
    48  	n, err = f.pfd.Write(b)
    49  	runtime.KeepAlive(f)
    50  	return n, err
    51  }
    52  
    53  // pwrite writes len(b) bytes to the File starting at byte offset off.
    54  // It returns the number of bytes written and an error, if any.
    55  func (f *File) pwrite(b []byte, off int64) (n int, err error) {
    56  	n, err = f.pfd.Pwrite(b, off)
    57  	runtime.KeepAlive(f)
    58  	return n, err
    59  }
    60  
    61  // syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
    62  func syscallMode(i FileMode) (o uint32) {
    63  	o |= uint32(i.Perm())
    64  	if i&ModeSetuid != 0 {
    65  		o |= syscall.S_ISUID
    66  	}
    67  	if i&ModeSetgid != 0 {
    68  		o |= syscall.S_ISGID
    69  	}
    70  	if i&ModeSticky != 0 {
    71  		o |= syscall.S_ISVTX
    72  	}
    73  	// No mapping for Go's ModeTemporary (plan9 only).
    74  	return
    75  }
    76  
    77  // See docs in file.go:Chmod.
    78  func chmod(name string, mode FileMode) error {
    79  	if e := syscall.Chmod(fixLongPath(name), syscallMode(mode)); e != nil {
    80  		return &PathError{"chmod", name, e}
    81  	}
    82  	return nil
    83  }
    84  
    85  // See docs in file.go:(*File).Chmod.
    86  func (f *File) chmod(mode FileMode) error {
    87  	if err := f.checkValid("chmod"); err != nil {
    88  		return err
    89  	}
    90  	if e := f.pfd.Fchmod(syscallMode(mode)); e != nil {
    91  		return f.wrapErr("chmod", e)
    92  	}
    93  	return nil
    94  }
    95  
    96  // Chown changes the numeric uid and gid of the named file.
    97  // If the file is a symbolic link, it changes the uid and gid of the link's target.
    98  // A uid or gid of -1 means to not change that value.
    99  // If there is an error, it will be of type *PathError.
   100  //
   101  // On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
   102  // EPLAN9 error, wrapped in *PathError.
   103  func Chown(name string, uid, gid int) error {
   104  	if e := syscall.Chown(name, uid, gid); e != nil {
   105  		return &PathError{"chown", name, e}
   106  	}
   107  	return nil
   108  }
   109  
   110  // Lchown changes the numeric uid and gid of the named file.
   111  // If the file is a symbolic link, it changes the uid and gid of the link itself.
   112  // If there is an error, it will be of type *PathError.
   113  //
   114  // On Windows, it always returns the syscall.EWINDOWS error, wrapped
   115  // in *PathError.
   116  func Lchown(name string, uid, gid int) error {
   117  	if e := syscall.Lchown(name, uid, gid); e != nil {
   118  		return &PathError{"lchown", name, e}
   119  	}
   120  	return nil
   121  }
   122  
   123  // Chown changes the numeric uid and gid of the named file.
   124  // If there is an error, it will be of type *PathError.
   125  //
   126  // On Windows, it always returns the syscall.EWINDOWS error, wrapped
   127  // in *PathError.
   128  func (f *File) Chown(uid, gid int) error {
   129  	if err := f.checkValid("chown"); err != nil {
   130  		return err
   131  	}
   132  	if e := f.pfd.Fchown(uid, gid); e != nil {
   133  		return f.wrapErr("chown", e)
   134  	}
   135  	return nil
   136  }
   137  
   138  // Truncate changes the size of the file.
   139  // It does not change the I/O offset.
   140  // If there is an error, it will be of type *PathError.
   141  func (f *File) Truncate(size int64) error {
   142  	if err := f.checkValid("truncate"); err != nil {
   143  		return err
   144  	}
   145  	if e := f.pfd.Ftruncate(size); e != nil {
   146  		return f.wrapErr("truncate", e)
   147  	}
   148  	return nil
   149  }
   150  
   151  // Sync commits the current contents of the file to stable storage.
   152  // Typically, this means flushing the file system's in-memory copy
   153  // of recently written data to disk.
   154  func (f *File) Sync() error {
   155  	if err := f.checkValid("sync"); err != nil {
   156  		return err
   157  	}
   158  	if e := f.pfd.Fsync(); e != nil {
   159  		return f.wrapErr("sync", e)
   160  	}
   161  	return nil
   162  }
   163  
   164  // Chtimes changes the access and modification times of the named
   165  // file, similar to the Unix utime() or utimes() functions.
   166  //
   167  // The underlying filesystem may truncate or round the values to a
   168  // less precise time unit.
   169  // If there is an error, it will be of type *PathError.
   170  func Chtimes(name string, atime time.Time, mtime time.Time) error {
   171  	var utimes [2]syscall.Timespec
   172  	utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
   173  	utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
   174  	if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
   175  		return &PathError{"chtimes", name, e}
   176  	}
   177  	return nil
   178  }
   179  
   180  // Chdir changes the current working directory to the file,
   181  // which must be a directory.
   182  // If there is an error, it will be of type *PathError.
   183  func (f *File) Chdir() error {
   184  	if err := f.checkValid("chdir"); err != nil {
   185  		return err
   186  	}
   187  	if e := f.pfd.Fchdir(); e != nil {
   188  		return f.wrapErr("chdir", e)
   189  	}
   190  	return nil
   191  }
   192  
   193  // setDeadline sets the read and write deadline.
   194  func (f *File) setDeadline(t time.Time) error {
   195  	if err := f.checkValid("SetDeadline"); err != nil {
   196  		return err
   197  	}
   198  	return f.pfd.SetDeadline(t)
   199  }
   200  
   201  // setReadDeadline sets the read deadline.
   202  func (f *File) setReadDeadline(t time.Time) error {
   203  	if err := f.checkValid("SetReadDeadline"); err != nil {
   204  		return err
   205  	}
   206  	return f.pfd.SetReadDeadline(t)
   207  }
   208  
   209  // setWriteDeadline sets the write deadline.
   210  func (f *File) setWriteDeadline(t time.Time) error {
   211  	if err := f.checkValid("SetWriteDeadline"); err != nil {
   212  		return err
   213  	}
   214  	return f.pfd.SetWriteDeadline(t)
   215  }
   216  
   217  // checkValid checks whether f is valid for use.
   218  // If not, it returns an appropriate error, perhaps incorporating the operation name op.
   219  func (f *File) checkValid(op string) error {
   220  	if f == nil {
   221  		return ErrInvalid
   222  	}
   223  	return nil
   224  }
   225  

View as plain text