github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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(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  // Chmod changes the mode of the named file to mode.
    48  // If the file is a symbolic link, it changes the mode of the link's target.
    49  // If there is an error, it will be of type *PathError.
    50  func Chmod(name string, mode FileMode) error {
    51  	if e := syscall.Chmod(name, syscallMode(mode)); e != nil {
    52  		return &PathError{"chmod", name, e}
    53  	}
    54  	return nil
    55  }
    56  
    57  // Chmod changes the mode of the file to mode.
    58  // If there is an error, it will be of type *PathError.
    59  func (f *File) Chmod(mode FileMode) error {
    60  	if f == nil {
    61  		return ErrInvalid
    62  	}
    63  	if e := syscall.Fchmod(f.fd, syscallMode(mode)); e != nil {
    64  		return &PathError{"chmod", f.name, e}
    65  	}
    66  	return nil
    67  }
    68  
    69  // Chown changes the numeric uid and gid of the named file.
    70  // If the file is a symbolic link, it changes the uid and gid of the link's target.
    71  // If there is an error, it will be of type *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  func Lchown(name string, uid, gid int) error {
    83  	if e := syscall.Lchown(name, uid, gid); e != nil {
    84  		return &PathError{"lchown", name, e}
    85  	}
    86  	return nil
    87  }
    88  
    89  // Chown changes the numeric uid and gid of the named file.
    90  // If there is an error, it will be of type *PathError.
    91  func (f *File) Chown(uid, gid int) error {
    92  	if f == nil {
    93  		return ErrInvalid
    94  	}
    95  	if e := syscall.Fchown(f.fd, uid, gid); e != nil {
    96  		return &PathError{"chown", f.name, e}
    97  	}
    98  	return nil
    99  }
   100  
   101  // Truncate changes the size of the file.
   102  // It does not change the I/O offset.
   103  // If there is an error, it will be of type *PathError.
   104  func (f *File) Truncate(size int64) error {
   105  	if f == nil {
   106  		return ErrInvalid
   107  	}
   108  	if e := syscall.Ftruncate(f.fd, size); e != nil {
   109  		return &PathError{"truncate", f.name, e}
   110  	}
   111  	return nil
   112  }
   113  
   114  // Sync commits the current contents of the file to stable storage.
   115  // Typically, this means flushing the file system's in-memory copy
   116  // of recently written data to disk.
   117  func (f *File) Sync() error {
   118  	if f == nil {
   119  		return ErrInvalid
   120  	}
   121  	if e := syscall.Fsync(f.fd); e != nil {
   122  		return NewSyscallError("fsync", e)
   123  	}
   124  	return nil
   125  }
   126  
   127  // Chtimes changes the access and modification times of the named
   128  // file, similar to the Unix utime() or utimes() functions.
   129  //
   130  // The underlying filesystem may truncate or round the values to a
   131  // less precise time unit.
   132  // If there is an error, it will be of type *PathError.
   133  func Chtimes(name string, atime time.Time, mtime time.Time) error {
   134  	var utimes [2]syscall.Timespec
   135  	utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
   136  	utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
   137  	if e := syscall.UtimesNano(name, utimes[0:]); e != nil {
   138  		return &PathError{"chtimes", name, e}
   139  	}
   140  	return nil
   141  }