github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/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)