github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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 }