github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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(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 } 264 265 if int32(r0) == -1 { 266 err = e 267 } 268 return 269 } 270 271 func Fchdir(fd int) (err error) { 272 path, err := Fd2path(fd) 273 274 if err != nil { 275 return 276 } 277 278 return Chdir(path) 279 } 280 281 type Timespec struct { 282 Sec int32 283 Nsec int32 284 } 285 286 type Timeval struct { 287 Sec int32 288 Usec int32 289 } 290 291 func NsecToTimeval(nsec int64) (tv Timeval) { 292 nsec += 999 // round up to microsecond 293 tv.Usec = int32(nsec % 1e9 / 1e3) 294 tv.Sec = int32(nsec / 1e9) 295 return 296 } 297 298 func DecodeBintime(b []byte) (nsec int64, err error) { 299 if len(b) != 8 { 300 return -1, NewError("bad /dev/bintime format") 301 } 302 nsec = int64(b[0])<<56 | 303 int64(b[1])<<48 | 304 int64(b[2])<<40 | 305 int64(b[3])<<32 | 306 int64(b[4])<<24 | 307 int64(b[5])<<16 | 308 int64(b[6])<<8 | 309 int64(b[7]) 310 return 311 } 312 313 func Gettimeofday(tv *Timeval) error { 314 nsec, e := nanotime() 315 if e != nil { 316 return e 317 } 318 *tv = NsecToTimeval(nsec) 319 return e 320 } 321 322 func Getegid() (egid int) { return -1 } 323 func Geteuid() (euid int) { return -1 } 324 func Getgid() (gid int) { return -1 } 325 func Getuid() (uid int) { return -1 } 326 327 func Getgroups() (gids []int, err error) { 328 return make([]int, 0), nil 329 } 330 331 //sys Dup(oldfd int, newfd int) (fd int, err error) 332 //sys Open(path string, mode int) (fd int, err error) 333 //sys Create(path string, mode int, perm uint32) (fd int, err error) 334 //sys Remove(path string) (err error) 335 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 336 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 337 //sys Close(fd int) (err error) 338 //sys Chdir(path string) (err error) 339 //sys Bind(name string, old string, flag int) (err error) 340 //sys Mount(fd int, afd int, old string, flag int, aname string) (err error) 341 //sys Stat(path string, edir []byte) (n int, err error) 342 //sys Fstat(fd int, edir []byte) (n int, err error) 343 //sys Wstat(path string, edir []byte) (err error) 344 //sys Fwstat(fd int, edir []byte) (err error)