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