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