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

View as plain text