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)