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