github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 use(unsafe.Pointer(namep)) 255 } 256 use(unsafe.Pointer(oldp)) 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 Getpagesize() int { return 0x1000 } 309 310 func Getegid() (egid int) { return -1 } 311 func Geteuid() (euid int) { return -1 } 312 func Getgid() (gid int) { return -1 } 313 func Getuid() (uid int) { return -1 } 314 315 func Getgroups() (gids []int, err error) { 316 return make([]int, 0), nil 317 } 318 319 //sys open(path string, mode int) (fd int, err error) 320 func Open(path string, mode int) (fd int, err error) { 321 Fixwd() 322 return open(path, mode) 323 } 324 325 //sys create(path string, mode int, perm uint32) (fd int, err error) 326 func Create(path string, mode int, perm uint32) (fd int, err error) { 327 Fixwd() 328 return create(path, mode, perm) 329 } 330 331 //sys remove(path string) (err error) 332 func Remove(path string) error { 333 Fixwd() 334 return remove(path) 335 } 336 337 //sys stat(path string, edir []byte) (n int, err error) 338 func Stat(path string, edir []byte) (n int, err error) { 339 Fixwd() 340 return stat(path, edir) 341 } 342 343 //sys bind(name string, old string, flag int) (err error) 344 func Bind(name string, old string, flag int) (err error) { 345 Fixwd() 346 return bind(name, old, flag) 347 } 348 349 //sys mount(fd int, afd int, old string, flag int, aname string) (err error) 350 func Mount(fd int, afd int, old string, flag int, aname string) (err error) { 351 Fixwd() 352 return mount(fd, afd, old, flag, aname) 353 } 354 355 //sys wstat(path string, edir []byte) (err error) 356 func Wstat(path string, edir []byte) (err error) { 357 Fixwd() 358 return wstat(path, edir) 359 } 360 361 //sys chdir(path string) (err error) 362 //sys Dup(oldfd int, newfd int) (fd int, err error) 363 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 364 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 365 //sys Close(fd int) (err error) 366 //sys Fstat(fd int, edir []byte) (n int, err error) 367 //sys Fwstat(fd int, edir []byte) (err error)