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