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