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