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