github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/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 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 }