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