github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/syscall/syscall_plan9.go (about) 1 // Copyright 2011 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 // Plan 9 system calls. 6 // This file is compiled as ordinary Go code, 7 // but it is also input to mksyscall, 8 // which parses the //sys lines and generates system call stubs. 9 // Note that sometimes we use a lowercase //sys name and 10 // wrap it in our own nicer implementation. 11 12 package syscall 13 14 import "unsafe" 15 16 const ImplementsGetwd = true 17 const bitSize16 = 2 18 19 // ErrorString implements Error's String method by returning itself. 20 type ErrorString string 21 22 func (e ErrorString) Error() string { return string(e) } 23 24 // NewError converts s to an ErrorString, which satisfies the Error interface. 25 func NewError(s string) error { return ErrorString(s) } 26 27 func (e ErrorString) Temporary() bool { 28 return e == EINTR || e == EMFILE || e.Timeout() 29 } 30 31 func (e ErrorString) Timeout() bool { 32 return e == EBUSY || e == ETIMEDOUT 33 } 34 35 var emptystring string 36 37 // A Note is a string describing a process note. 38 // It implements the os.Signal interface. 39 type Note string 40 41 func (n Note) Signal() {} 42 43 func (n Note) String() string { 44 return string(n) 45 } 46 47 var ( 48 Stdin = 0 49 Stdout = 1 50 Stderr = 2 51 ) 52 53 // For testing: clients can set this flag to force 54 // creation of IPv6 sockets to return EAFNOSUPPORT. 55 var SocketDisableIPv6 bool 56 57 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString) 58 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString) 59 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) 60 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) 61 62 //go:nosplit 63 func atoi(b []byte) (n uint) { 64 n = 0 65 for i := 0; i < len(b); i++ { 66 n = n*10 + uint(b[i]-'0') 67 } 68 return 69 } 70 71 func cstring(s []byte) string { 72 for i := range s { 73 if s[i] == 0 { 74 return string(s[0:i]) 75 } 76 } 77 return string(s) 78 } 79 80 func errstr() string { 81 var buf [ERRMAX]byte 82 83 RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) 84 85 buf[len(buf)-1] = 0 86 return cstring(buf[:]) 87 } 88 89 func readnum(path string) (uint, error) { 90 var b [12]byte 91 92 fd, e := Open(path, O_RDONLY) 93 if e != nil { 94 return 0, e 95 } 96 defer Close(fd) 97 98 n, e := Pread(fd, b[:], 0) 99 100 if e != nil { 101 return 0, e 102 } 103 104 m := 0 105 for ; m < n && b[m] == ' '; m++ { 106 } 107 108 return atoi(b[m : n-1]), nil 109 } 110 111 func Getpid() (pid int) { 112 n, _ := readnum("#c/pid") 113 return int(n) 114 } 115 116 func Getppid() (ppid int) { 117 n, _ := readnum("#c/ppid") 118 return int(n) 119 } 120 121 func Read(fd int, p []byte) (n int, err error) { 122 return Pread(fd, p, -1) 123 } 124 125 func Write(fd int, p []byte) (n int, err error) { 126 return Pwrite(fd, p, -1) 127 } 128 129 var ioSync int64 130 131 //sys fd2path(fd int, buf []byte) (err error) 132 func Fd2path(fd int) (path string, err error) { 133 var buf [512]byte 134 135 e := fd2path(fd, buf[:]) 136 if e != nil { 137 return "", e 138 } 139 return cstring(buf[:]), nil 140 } 141 142 //sys pipe(p *[2]int32) (err error) 143 func Pipe(p []int) (err error) { 144 if len(p) != 2 { 145 return NewError("bad arg in system call") 146 } 147 var pp [2]int32 148 err = pipe(&pp) 149 p[0] = int(pp[0]) 150 p[1] = int(pp[1]) 151 return 152 } 153 154 // Underlying system call writes to newoffset via pointer. 155 // Implemented in assembly to avoid allocation. 156 func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string) 157 158 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { 159 newoffset, e := seek(0, fd, offset, whence) 160 161 if newoffset == -1 { 162 err = NewError(e) 163 } 164 return 165 } 166 167 func Mkdir(path string, mode uint32) (err error) { 168 // If path exists and is not a directory, Create will fail silently. 169 // Work around this by rejecting Mkdir if path exists. 170 statbuf := make([]byte, bitSize16) 171 // Remove any trailing slashes from path, otherwise the Stat will 172 // fail with ENOTDIR. 173 n := len(path) 174 for n > 1 && path[n-1] == '/' { 175 n-- 176 } 177 _, err = Stat(path[0:n], statbuf) 178 if err == nil { 179 return EEXIST 180 } 181 182 fd, err := Create(path, O_RDONLY, DMDIR|mode) 183 184 if fd != -1 { 185 Close(fd) 186 } 187 188 return 189 } 190 191 type Waitmsg struct { 192 Pid int 193 Time [3]uint32 194 Msg string 195 } 196 197 func (w Waitmsg) Exited() bool { return true } 198 func (w Waitmsg) Signaled() bool { return false } 199 200 func (w Waitmsg) ExitStatus() int { 201 if len(w.Msg) == 0 { 202 // a normal exit returns no message 203 return 0 204 } 205 return 1 206 } 207 208 //sys await(s []byte) (n int, err error) 209 func Await(w *Waitmsg) (err error) { 210 var buf [512]byte 211 var f [5][]byte 212 213 n, err := await(buf[:]) 214 215 if err != nil || w == nil { 216 return 217 } 218 219 nf := 0 220 p := 0 221 for i := 0; i < n && nf < len(f)-1; i++ { 222 if buf[i] == ' ' { 223 f[nf] = buf[p:i] 224 p = i + 1 225 nf++ 226 } 227 } 228 f[nf] = buf[p:] 229 nf++ 230 231 if nf != len(f) { 232 return NewError("invalid wait message") 233 } 234 w.Pid = int(atoi(f[0])) 235 w.Time[0] = uint32(atoi(f[1])) 236 w.Time[1] = uint32(atoi(f[2])) 237 w.Time[2] = uint32(atoi(f[3])) 238 w.Msg = cstring(f[4]) 239 if w.Msg == "''" { 240 // await() returns '' for no error 241 w.Msg = "" 242 } 243 return 244 } 245 246 func Unmount(name, old string) (err error) { 247 fixwd(name, old) 248 oldp, err := BytePtrFromString(old) 249 if err != nil { 250 return err 251 } 252 oldptr := uintptr(unsafe.Pointer(oldp)) 253 254 var r0 uintptr 255 var e ErrorString 256 257 // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted. 258 if name == "" { 259 r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0) 260 } else { 261 namep, err := BytePtrFromString(name) 262 if err != nil { 263 return err 264 } 265 r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0) 266 } 267 268 if int32(r0) == -1 { 269 err = e 270 } 271 return 272 } 273 274 func Fchdir(fd int) (err error) { 275 path, err := Fd2path(fd) 276 277 if err != nil { 278 return 279 } 280 281 return Chdir(path) 282 } 283 284 type Timespec struct { 285 Sec int32 286 Nsec int32 287 } 288 289 type Timeval struct { 290 Sec int32 291 Usec int32 292 } 293 294 func NsecToTimeval(nsec int64) (tv Timeval) { 295 nsec += 999 // round up to microsecond 296 tv.Usec = int32(nsec % 1e9 / 1e3) 297 tv.Sec = int32(nsec / 1e9) 298 return 299 } 300 301 func nsec() int64 { 302 var scratch int64 303 304 r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0) 305 // TODO(aram): remove hack after I fix _nsec in the pc64 kernel. 306 if r0 == 0 { 307 return scratch 308 } 309 return int64(r0) 310 } 311 312 func Gettimeofday(tv *Timeval) error { 313 nsec := nsec() 314 *tv = NsecToTimeval(nsec) 315 return nil 316 } 317 318 func Getegid() (egid int) { return -1 } 319 func Geteuid() (euid int) { return -1 } 320 func Getgid() (gid int) { return -1 } 321 func Getuid() (uid int) { return -1 } 322 323 func Getgroups() (gids []int, err error) { 324 return make([]int, 0), nil 325 } 326 327 //sys open(path string, mode int) (fd int, err error) 328 func Open(path string, mode int) (fd int, err error) { 329 fixwd(path) 330 return open(path, mode) 331 } 332 333 //sys create(path string, mode int, perm uint32) (fd int, err error) 334 func Create(path string, mode int, perm uint32) (fd int, err error) { 335 fixwd(path) 336 return create(path, mode, perm) 337 } 338 339 //sys remove(path string) (err error) 340 func Remove(path string) error { 341 fixwd(path) 342 return remove(path) 343 } 344 345 //sys stat(path string, edir []byte) (n int, err error) 346 func Stat(path string, edir []byte) (n int, err error) { 347 fixwd(path) 348 return stat(path, edir) 349 } 350 351 //sys bind(name string, old string, flag int) (err error) 352 func Bind(name string, old string, flag int) (err error) { 353 fixwd(name, old) 354 return bind(name, old, flag) 355 } 356 357 //sys mount(fd int, afd int, old string, flag int, aname string) (err error) 358 func Mount(fd int, afd int, old string, flag int, aname string) (err error) { 359 fixwd(old) 360 return mount(fd, afd, old, flag, aname) 361 } 362 363 //sys wstat(path string, edir []byte) (err error) 364 func Wstat(path string, edir []byte) (err error) { 365 fixwd(path) 366 return wstat(path, edir) 367 } 368 369 //sys chdir(path string) (err error) 370 //sys Dup(oldfd int, newfd int) (fd int, err error) 371 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 372 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 373 //sys Close(fd int) (err error) 374 //sys Fstat(fd int, edir []byte) (n int, err error) 375 //sys Fwstat(fd int, edir []byte) (err error)