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.
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.
20 // A Note is a string describing a process note.
21 // It implements the os.Signal interface.
24 func (n Note) Signal() {}
26 func (n Note) String() string {
36 // For testing: clients can set this flag to force
37 // creation of IPv6 sockets to return EAFNOSUPPORT.
38 var SocketDisableIPv6 bool
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)
45 func atoi(b []byte) (n uint) {
47 for i := 0; i < len(b); i++ {
48 n = n*10 + uint(b[i]-'0')
53 func cstring(s []byte) string {
54 i := bytes.IndexByte(s, 0)
61 func errstr() string {
64 RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
67 return cstring(buf[:])
70 // Implemented in assembly to import from runtime.
73 func Exit(code int) { exit(code) }
75 func readnum(path string) (uint, error) {
78 fd, e := Open(path, O_RDONLY)
84 n, e := Pread(fd, b[:], 0)
91 for ; m < n && b[m] == ' '; m++ {
94 return atoi(b[m : n-1]), nil
97 func Getpid() (pid int) {
98 n, _ := readnum("#c/pid")
102 func Getppid() (ppid int) {
103 n, _ := readnum("#c/ppid")
107 func Read(fd int, p []byte) (n int, err error) {
108 return Pread(fd, p, -1)
111 func Write(fd int, p []byte) (n int, err error) {
112 return Pwrite(fd, p, -1)
117 //sys fd2path(fd int, buf []byte) (err error)
118 func Fd2path(fd int) (path string, err error) {
121 e := fd2path(fd, buf[:])
125 return cstring(buf[:]), nil
128 //sys pipe(p *[2]int32) (err error)
129 func Pipe(p []int) (err error) {
131 return syscall.ErrorString("bad arg in system call")
140 // Underlying system call writes to newoffset via pointer.
141 // Implemented in assembly to avoid allocation.
142 func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
144 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
145 newoffset, e := seek(0, fd, offset, whence)
148 err = syscall.ErrorString(e)
153 func Mkdir(path string, mode uint32) (err error) {
154 fd, err := Create(path, O_RDONLY, DMDIR|mode)
163 type Waitmsg struct {
169 func (w Waitmsg) Exited() bool { return true }
170 func (w Waitmsg) Signaled() bool { return false }
172 func (w Waitmsg) ExitStatus() int {
174 // a normal exit returns no message
180 //sys await(s []byte) (n int, err error)
181 func Await(w *Waitmsg) (err error) {
185 n, err := await(buf[:])
187 if err != nil || w == nil {
193 for i := 0; i < n && nf < len(f)-1; i++ {
204 return syscall.ErrorString("invalid wait message")
206 w.Pid = int(atoi(f[0]))
207 w.Time[0] = uint32(atoi(f[1]))
208 w.Time[1] = uint32(atoi(f[2]))
209 w.Time[2] = uint32(atoi(f[3]))
210 w.Msg = cstring(f[4])
212 // await() returns '' for no error
218 func Unmount(name, old string) (err error) {
220 oldp, err := BytePtrFromString(old)
224 oldptr := uintptr(unsafe.Pointer(oldp))
227 var e syscall.ErrorString
229 // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
231 r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
233 namep, err := BytePtrFromString(name)
237 r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
246 func Fchdir(fd int) (err error) {
247 path, err := Fd2path(fd)
256 type Timespec struct {
261 type Timeval struct {
266 func NsecToTimeval(nsec int64) (tv Timeval) {
267 nsec += 999 // round up to microsecond
268 tv.Usec = int32(nsec % 1e9 / 1e3)
269 tv.Sec = int32(nsec / 1e9)
276 r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
277 // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
284 func Gettimeofday(tv *Timeval) error {
286 *tv = NsecToTimeval(nsec)
290 func Getpagesize() int { return 0x1000 }
292 func Getegid() (egid int) { return -1 }
293 func Geteuid() (euid int) { return -1 }
294 func Getgid() (gid int) { return -1 }
295 func Getuid() (uid int) { return -1 }
297 func Getgroups() (gids []int, err error) {
298 return make([]int, 0), nil
301 //sys open(path string, mode int) (fd int, err error)
302 func Open(path string, mode int) (fd int, err error) {
304 return open(path, mode)
307 //sys create(path string, mode int, perm uint32) (fd int, err error)
308 func Create(path string, mode int, perm uint32) (fd int, err error) {
310 return create(path, mode, perm)
313 //sys remove(path string) (err error)
314 func Remove(path string) error {
319 //sys stat(path string, edir []byte) (n int, err error)
320 func Stat(path string, edir []byte) (n int, err error) {
322 return stat(path, edir)
325 //sys bind(name string, old string, flag int) (err error)
326 func Bind(name string, old string, flag int) (err error) {
328 return bind(name, old, flag)
331 //sys mount(fd int, afd int, old string, flag int, aname string) (err error)
332 func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
334 return mount(fd, afd, old, flag, aname)
337 //sys wstat(path string, edir []byte) (err error)
338 func Wstat(path string, edir []byte) (err error) {
340 return wstat(path, edir)
343 //sys chdir(path string) (err error)
344 //sys Dup(oldfd int, newfd int) (fd int, err error)
345 //sys Pread(fd int, p []byte, offset int64) (n int, err error)
346 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
347 //sys Close(fd int) (err error)
348 //sys Fstat(fd int, edir []byte) (n int, err error)
349 //sys Fwstat(fd int, edir []byte) (err error)