...
▽

Source file src/cmd/vendor/golang.org/x/sys/plan9/syscall_plan9.go

Documentation: cmd/vendor/golang.org/x/sys/plan9

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

View as plain text