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