github.com/juelite/golang.org-x-sys@v0.0.0-20181121071242-7b69e1c5db33/unix/syscall_solaris.go (about)

     1  // Copyright 2009 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  // Solaris 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 wrap
    10  // it in our own nicer implementation, either here or in
    11  // syscall_solaris.go or syscall_unix.go.
    12  
    13  package unix
    14  
    15  import (
    16  	"sync/atomic"
    17  	"syscall"
    18  	"unsafe"
    19  )
    20  
    21  // Implemented in runtime/syscall_solaris.go.
    22  type syscallFunc uintptr
    23  
    24  func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
    25  func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
    26  
    27  type SockaddrDatalink struct {
    28  	Family uint16
    29  	Index  uint16
    30  	Type   uint8
    31  	Nlen   uint8
    32  	Alen   uint8
    33  	Slen   uint8
    34  	Data   [244]int8
    35  	raw    RawSockaddrDatalink
    36  }
    37  
    38  func clen(n []byte) int {
    39  	for i := 0; i < len(n); i++ {
    40  		if n[i] == 0 {
    41  			return i
    42  		}
    43  	}
    44  	return len(n)
    45  }
    46  
    47  // ParseDirent parses up to max directory entries in buf,
    48  // appending the names to names.  It returns the number
    49  // bytes consumed from buf, the number of entries added
    50  // to names, and the new names slice.
    51  func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
    52  	origlen := len(buf)
    53  	for max != 0 && len(buf) > 0 {
    54  		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
    55  		if dirent.Reclen == 0 {
    56  			buf = nil
    57  			break
    58  		}
    59  		buf = buf[dirent.Reclen:]
    60  		if dirent.Ino == 0 { // File absent in directory.
    61  			continue
    62  		}
    63  		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
    64  		var name = string(bytes[0:clen(bytes[:])])
    65  		if name == "." || name == ".." { // Useless names
    66  			continue
    67  		}
    68  		max--
    69  		count++
    70  		names = append(names, name)
    71  	}
    72  	return origlen - len(buf), count, names
    73  }
    74  
    75  //sysnb	pipe(p *[2]_C_int) (n int, err error)
    76  
    77  func Pipe(p []int) (err error) {
    78  	if len(p) != 2 {
    79  		return EINVAL
    80  	}
    81  	var pp [2]_C_int
    82  	n, err := pipe(&pp)
    83  	if n != 0 {
    84  		return err
    85  	}
    86  	p[0] = int(pp[0])
    87  	p[1] = int(pp[1])
    88  	return nil
    89  }
    90  
    91  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    92  	if sa.Port < 0 || sa.Port > 0xFFFF {
    93  		return nil, 0, EINVAL
    94  	}
    95  	sa.raw.Family = AF_INET
    96  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    97  	p[0] = byte(sa.Port >> 8)
    98  	p[1] = byte(sa.Port)
    99  	for i := 0; i < len(sa.Addr); i++ {
   100  		sa.raw.Addr[i] = sa.Addr[i]
   101  	}
   102  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
   103  }
   104  
   105  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
   106  	if sa.Port < 0 || sa.Port > 0xFFFF {
   107  		return nil, 0, EINVAL
   108  	}
   109  	sa.raw.Family = AF_INET6
   110  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   111  	p[0] = byte(sa.Port >> 8)
   112  	p[1] = byte(sa.Port)
   113  	sa.raw.Scope_id = sa.ZoneId
   114  	for i := 0; i < len(sa.Addr); i++ {
   115  		sa.raw.Addr[i] = sa.Addr[i]
   116  	}
   117  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
   118  }
   119  
   120  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
   121  	name := sa.Name
   122  	n := len(name)
   123  	if n >= len(sa.raw.Path) {
   124  		return nil, 0, EINVAL
   125  	}
   126  	sa.raw.Family = AF_UNIX
   127  	for i := 0; i < n; i++ {
   128  		sa.raw.Path[i] = int8(name[i])
   129  	}
   130  	// length is family (uint16), name, NUL.
   131  	sl := _Socklen(2)
   132  	if n > 0 {
   133  		sl += _Socklen(n) + 1
   134  	}
   135  	if sa.raw.Path[0] == '@' {
   136  		sa.raw.Path[0] = 0
   137  		// Don't count trailing NUL for abstract address.
   138  		sl--
   139  	}
   140  
   141  	return unsafe.Pointer(&sa.raw), sl, nil
   142  }
   143  
   144  //sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
   145  
   146  func Getsockname(fd int) (sa Sockaddr, err error) {
   147  	var rsa RawSockaddrAny
   148  	var len _Socklen = SizeofSockaddrAny
   149  	if err = getsockname(fd, &rsa, &len); err != nil {
   150  		return
   151  	}
   152  	return anyToSockaddr(&rsa)
   153  }
   154  
   155  const ImplementsGetwd = true
   156  
   157  //sys	Getcwd(buf []byte) (n int, err error)
   158  
   159  func Getwd() (wd string, err error) {
   160  	var buf [PathMax]byte
   161  	// Getcwd will return an error if it failed for any reason.
   162  	_, err = Getcwd(buf[0:])
   163  	if err != nil {
   164  		return "", err
   165  	}
   166  	n := clen(buf[:])
   167  	if n < 1 {
   168  		return "", EINVAL
   169  	}
   170  	return string(buf[:n]), nil
   171  }
   172  
   173  /*
   174   * Wrapped
   175   */
   176  
   177  //sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
   178  //sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
   179  
   180  func Getgroups() (gids []int, err error) {
   181  	n, err := getgroups(0, nil)
   182  	// Check for error and sanity check group count.  Newer versions of
   183  	// Solaris allow up to 1024 (NGROUPS_MAX).
   184  	if n < 0 || n > 1024 {
   185  		if err != nil {
   186  			return nil, err
   187  		}
   188  		return nil, EINVAL
   189  	} else if n == 0 {
   190  		return nil, nil
   191  	}
   192  
   193  	a := make([]_Gid_t, n)
   194  	n, err = getgroups(n, &a[0])
   195  	if n == -1 {
   196  		return nil, err
   197  	}
   198  	gids = make([]int, n)
   199  	for i, v := range a[0:n] {
   200  		gids[i] = int(v)
   201  	}
   202  	return
   203  }
   204  
   205  func Setgroups(gids []int) (err error) {
   206  	if len(gids) == 0 {
   207  		return setgroups(0, nil)
   208  	}
   209  
   210  	a := make([]_Gid_t, len(gids))
   211  	for i, v := range gids {
   212  		a[i] = _Gid_t(v)
   213  	}
   214  	return setgroups(len(a), &a[0])
   215  }
   216  
   217  func ReadDirent(fd int, buf []byte) (n int, err error) {
   218  	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
   219  	// TODO(rsc): Can we use a single global basep for all calls?
   220  	return Getdents(fd, buf, new(uintptr))
   221  }
   222  
   223  // Wait status is 7 bits at bottom, either 0 (exited),
   224  // 0x7F (stopped), or a signal number that caused an exit.
   225  // The 0x80 bit is whether there was a core dump.
   226  // An extra number (exit code, signal causing a stop)
   227  // is in the high bits.
   228  
   229  type WaitStatus uint32
   230  
   231  const (
   232  	mask  = 0x7F
   233  	core  = 0x80
   234  	shift = 8
   235  
   236  	exited  = 0
   237  	stopped = 0x7F
   238  )
   239  
   240  func (w WaitStatus) Exited() bool { return w&mask == exited }
   241  
   242  func (w WaitStatus) ExitStatus() int {
   243  	if w&mask != exited {
   244  		return -1
   245  	}
   246  	return int(w >> shift)
   247  }
   248  
   249  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
   250  
   251  func (w WaitStatus) Signal() syscall.Signal {
   252  	sig := syscall.Signal(w & mask)
   253  	if sig == stopped || sig == 0 {
   254  		return -1
   255  	}
   256  	return sig
   257  }
   258  
   259  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
   260  
   261  func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
   262  
   263  func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
   264  
   265  func (w WaitStatus) StopSignal() syscall.Signal {
   266  	if !w.Stopped() {
   267  		return -1
   268  	}
   269  	return syscall.Signal(w>>shift) & 0xFF
   270  }
   271  
   272  func (w WaitStatus) TrapCause() int { return -1 }
   273  
   274  //sys	wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
   275  
   276  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
   277  	var status _C_int
   278  	rpid, err := wait4(int32(pid), &status, options, rusage)
   279  	wpid := int(rpid)
   280  	if wpid == -1 {
   281  		return wpid, err
   282  	}
   283  	if wstatus != nil {
   284  		*wstatus = WaitStatus(status)
   285  	}
   286  	return wpid, nil
   287  }
   288  
   289  //sys	gethostname(buf []byte) (n int, err error)
   290  
   291  func Gethostname() (name string, err error) {
   292  	var buf [MaxHostNameLen]byte
   293  	n, err := gethostname(buf[:])
   294  	if n != 0 {
   295  		return "", err
   296  	}
   297  	n = clen(buf[:])
   298  	if n < 1 {
   299  		return "", EFAULT
   300  	}
   301  	return string(buf[:n]), nil
   302  }
   303  
   304  //sys	utimes(path string, times *[2]Timeval) (err error)
   305  
   306  func Utimes(path string, tv []Timeval) (err error) {
   307  	if tv == nil {
   308  		return utimes(path, nil)
   309  	}
   310  	if len(tv) != 2 {
   311  		return EINVAL
   312  	}
   313  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   314  }
   315  
   316  //sys	utimensat(fd int, path string, times *[2]Timespec, flag int) (err error)
   317  
   318  func UtimesNano(path string, ts []Timespec) error {
   319  	if ts == nil {
   320  		return utimensat(AT_FDCWD, path, nil, 0)
   321  	}
   322  	if len(ts) != 2 {
   323  		return EINVAL
   324  	}
   325  	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
   326  }
   327  
   328  func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
   329  	if ts == nil {
   330  		return utimensat(dirfd, path, nil, flags)
   331  	}
   332  	if len(ts) != 2 {
   333  		return EINVAL
   334  	}
   335  	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
   336  }
   337  
   338  //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
   339  
   340  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
   341  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
   342  	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
   343  	if e1 != 0 {
   344  		return e1
   345  	}
   346  	return nil
   347  }
   348  
   349  //sys	futimesat(fildes int, path *byte, times *[2]Timeval) (err error)
   350  
   351  func Futimesat(dirfd int, path string, tv []Timeval) error {
   352  	pathp, err := BytePtrFromString(path)
   353  	if err != nil {
   354  		return err
   355  	}
   356  	if tv == nil {
   357  		return futimesat(dirfd, pathp, nil)
   358  	}
   359  	if len(tv) != 2 {
   360  		return EINVAL
   361  	}
   362  	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   363  }
   364  
   365  // Solaris doesn't have an futimes function because it allows NULL to be
   366  // specified as the path for futimesat.  However, Go doesn't like
   367  // NULL-style string interfaces, so this simple wrapper is provided.
   368  func Futimes(fd int, tv []Timeval) error {
   369  	if tv == nil {
   370  		return futimesat(fd, nil, nil)
   371  	}
   372  	if len(tv) != 2 {
   373  		return EINVAL
   374  	}
   375  	return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   376  }
   377  
   378  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
   379  	switch rsa.Addr.Family {
   380  	case AF_UNIX:
   381  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   382  		sa := new(SockaddrUnix)
   383  		// Assume path ends at NUL.
   384  		// This is not technically the Solaris semantics for
   385  		// abstract Unix domain sockets -- they are supposed
   386  		// to be uninterpreted fixed-size binary blobs -- but
   387  		// everyone uses this convention.
   388  		n := 0
   389  		for n < len(pp.Path) && pp.Path[n] != 0 {
   390  			n++
   391  		}
   392  		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
   393  		sa.Name = string(bytes)
   394  		return sa, nil
   395  
   396  	case AF_INET:
   397  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   398  		sa := new(SockaddrInet4)
   399  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   400  		sa.Port = int(p[0])<<8 + int(p[1])
   401  		for i := 0; i < len(sa.Addr); i++ {
   402  			sa.Addr[i] = pp.Addr[i]
   403  		}
   404  		return sa, nil
   405  
   406  	case AF_INET6:
   407  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   408  		sa := new(SockaddrInet6)
   409  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   410  		sa.Port = int(p[0])<<8 + int(p[1])
   411  		sa.ZoneId = pp.Scope_id
   412  		for i := 0; i < len(sa.Addr); i++ {
   413  			sa.Addr[i] = pp.Addr[i]
   414  		}
   415  		return sa, nil
   416  	}
   417  	return nil, EAFNOSUPPORT
   418  }
   419  
   420  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
   421  
   422  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   423  	var rsa RawSockaddrAny
   424  	var len _Socklen = SizeofSockaddrAny
   425  	nfd, err = accept(fd, &rsa, &len)
   426  	if nfd == -1 {
   427  		return
   428  	}
   429  	sa, err = anyToSockaddr(&rsa)
   430  	if err != nil {
   431  		Close(nfd)
   432  		nfd = 0
   433  	}
   434  	return
   435  }
   436  
   437  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg
   438  
   439  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
   440  	var msg Msghdr
   441  	var rsa RawSockaddrAny
   442  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
   443  	msg.Namelen = uint32(SizeofSockaddrAny)
   444  	var iov Iovec
   445  	if len(p) > 0 {
   446  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   447  		iov.SetLen(len(p))
   448  	}
   449  	var dummy int8
   450  	if len(oob) > 0 {
   451  		// receive at least one normal byte
   452  		if len(p) == 0 {
   453  			iov.Base = &dummy
   454  			iov.SetLen(1)
   455  		}
   456  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   457  	}
   458  	msg.Iov = &iov
   459  	msg.Iovlen = 1
   460  	if n, err = recvmsg(fd, &msg, flags); n == -1 {
   461  		return
   462  	}
   463  	oobn = int(msg.Accrightslen)
   464  	// source address is only specified if the socket is unconnected
   465  	if rsa.Addr.Family != AF_UNSPEC {
   466  		from, err = anyToSockaddr(&rsa)
   467  	}
   468  	return
   469  }
   470  
   471  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
   472  	_, err = SendmsgN(fd, p, oob, to, flags)
   473  	return
   474  }
   475  
   476  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.sendmsg
   477  
   478  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
   479  	var ptr unsafe.Pointer
   480  	var salen _Socklen
   481  	if to != nil {
   482  		ptr, salen, err = to.sockaddr()
   483  		if err != nil {
   484  			return 0, err
   485  		}
   486  	}
   487  	var msg Msghdr
   488  	msg.Name = (*byte)(unsafe.Pointer(ptr))
   489  	msg.Namelen = uint32(salen)
   490  	var iov Iovec
   491  	if len(p) > 0 {
   492  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   493  		iov.SetLen(len(p))
   494  	}
   495  	var dummy int8
   496  	if len(oob) > 0 {
   497  		// send at least one normal byte
   498  		if len(p) == 0 {
   499  			iov.Base = &dummy
   500  			iov.SetLen(1)
   501  		}
   502  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   503  	}
   504  	msg.Iov = &iov
   505  	msg.Iovlen = 1
   506  	if n, err = sendmsg(fd, &msg, flags); err != nil {
   507  		return 0, err
   508  	}
   509  	if len(oob) > 0 && len(p) == 0 {
   510  		n = 0
   511  	}
   512  	return n, nil
   513  }
   514  
   515  //sys	acct(path *byte) (err error)
   516  
   517  func Acct(path string) (err error) {
   518  	if len(path) == 0 {
   519  		// Assume caller wants to disable accounting.
   520  		return acct(nil)
   521  	}
   522  
   523  	pathp, err := BytePtrFromString(path)
   524  	if err != nil {
   525  		return err
   526  	}
   527  	return acct(pathp)
   528  }
   529  
   530  /*
   531   * Expose the ioctl function
   532   */
   533  
   534  //sys	ioctl(fd int, req int, arg uintptr) (err error)
   535  
   536  func IoctlSetInt(fd int, req int, value int) (err error) {
   537  	return ioctl(fd, req, uintptr(value))
   538  }
   539  
   540  func IoctlSetWinsize(fd int, req int, value *Winsize) (err error) {
   541  	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
   542  }
   543  
   544  func IoctlSetTermios(fd int, req int, value *Termios) (err error) {
   545  	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
   546  }
   547  
   548  func IoctlSetTermio(fd int, req int, value *Termio) (err error) {
   549  	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
   550  }
   551  
   552  func IoctlGetInt(fd int, req int) (int, error) {
   553  	var value int
   554  	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   555  	return value, err
   556  }
   557  
   558  func IoctlGetWinsize(fd int, req int) (*Winsize, error) {
   559  	var value Winsize
   560  	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   561  	return &value, err
   562  }
   563  
   564  func IoctlGetTermios(fd int, req int) (*Termios, error) {
   565  	var value Termios
   566  	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   567  	return &value, err
   568  }
   569  
   570  func IoctlGetTermio(fd int, req int) (*Termio, error) {
   571  	var value Termio
   572  	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   573  	return &value, err
   574  }
   575  
   576  /*
   577   * Exposed directly
   578   */
   579  //sys	Access(path string, mode uint32) (err error)
   580  //sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
   581  //sys	Chdir(path string) (err error)
   582  //sys	Chmod(path string, mode uint32) (err error)
   583  //sys	Chown(path string, uid int, gid int) (err error)
   584  //sys	Chroot(path string) (err error)
   585  //sys	Close(fd int) (err error)
   586  //sys	Creat(path string, mode uint32) (fd int, err error)
   587  //sys	Dup(fd int) (nfd int, err error)
   588  //sys	Dup2(oldfd int, newfd int) (err error)
   589  //sys	Exit(code int)
   590  //sys	Fchdir(fd int) (err error)
   591  //sys	Fchmod(fd int, mode uint32) (err error)
   592  //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
   593  //sys	Fchown(fd int, uid int, gid int) (err error)
   594  //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
   595  //sys	Fdatasync(fd int) (err error)
   596  //sys	Fpathconf(fd int, name int) (val int, err error)
   597  //sys	Fstat(fd int, stat *Stat_t) (err error)
   598  //sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
   599  //sysnb	Getgid() (gid int)
   600  //sysnb	Getpid() (pid int)
   601  //sysnb	Getpgid(pid int) (pgid int, err error)
   602  //sysnb	Getpgrp() (pgid int, err error)
   603  //sys	Geteuid() (euid int)
   604  //sys	Getegid() (egid int)
   605  //sys	Getppid() (ppid int)
   606  //sys	Getpriority(which int, who int) (n int, err error)
   607  //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
   608  //sysnb	Getrusage(who int, rusage *Rusage) (err error)
   609  //sysnb	Gettimeofday(tv *Timeval) (err error)
   610  //sysnb	Getuid() (uid int)
   611  //sys	Kill(pid int, signum syscall.Signal) (err error)
   612  //sys	Lchown(path string, uid int, gid int) (err error)
   613  //sys	Link(path string, link string) (err error)
   614  //sys	Listen(s int, backlog int) (err error) = libsocket.listen
   615  //sys	Lstat(path string, stat *Stat_t) (err error)
   616  //sys	Madvise(b []byte, advice int) (err error)
   617  //sys	Mkdir(path string, mode uint32) (err error)
   618  //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
   619  //sys	Mkfifo(path string, mode uint32) (err error)
   620  //sys	Mkfifoat(dirfd int, path string, mode uint32) (err error)
   621  //sys	Mknod(path string, mode uint32, dev int) (err error)
   622  //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
   623  //sys	Mlock(b []byte) (err error)
   624  //sys	Mlockall(flags int) (err error)
   625  //sys	Mprotect(b []byte, prot int) (err error)
   626  //sys	Munlock(b []byte) (err error)
   627  //sys	Munlockall() (err error)
   628  //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
   629  //sys	Open(path string, mode int, perm uint32) (fd int, err error)
   630  //sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
   631  //sys	Pathconf(path string, name int) (val int, err error)
   632  //sys	Pause() (err error)
   633  //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
   634  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
   635  //sys	read(fd int, p []byte) (n int, err error)
   636  //sys	Readlink(path string, buf []byte) (n int, err error)
   637  //sys	Rename(from string, to string) (err error)
   638  //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
   639  //sys	Rmdir(path string) (err error)
   640  //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
   641  //sysnb	Setegid(egid int) (err error)
   642  //sysnb	Seteuid(euid int) (err error)
   643  //sysnb	Setgid(gid int) (err error)
   644  //sys	Sethostname(p []byte) (err error)
   645  //sysnb	Setpgid(pid int, pgid int) (err error)
   646  //sys	Setpriority(which int, who int, prio int) (err error)
   647  //sysnb	Setregid(rgid int, egid int) (err error)
   648  //sysnb	Setreuid(ruid int, euid int) (err error)
   649  //sysnb	Setrlimit(which int, lim *Rlimit) (err error)
   650  //sysnb	Setsid() (pid int, err error)
   651  //sysnb	Setuid(uid int) (err error)
   652  //sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
   653  //sys	Stat(path string, stat *Stat_t) (err error)
   654  //sys	Symlink(path string, link string) (err error)
   655  //sys	Sync() (err error)
   656  //sysnb	Times(tms *Tms) (ticks uintptr, err error)
   657  //sys	Truncate(path string, length int64) (err error)
   658  //sys	Fsync(fd int) (err error)
   659  //sys	Ftruncate(fd int, length int64) (err error)
   660  //sys	Umask(mask int) (oldmask int)
   661  //sysnb	Uname(buf *Utsname) (err error)
   662  //sys	Unmount(target string, flags int) (err error) = libc.umount
   663  //sys	Unlink(path string) (err error)
   664  //sys	Unlinkat(dirfd int, path string, flags int) (err error)
   665  //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
   666  //sys	Utime(path string, buf *Utimbuf) (err error)
   667  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind
   668  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect
   669  //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
   670  //sys	munmap(addr uintptr, length uintptr) (err error)
   671  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.sendto
   672  //sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.socket
   673  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.socketpair
   674  //sys	write(fd int, p []byte) (n int, err error)
   675  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt
   676  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
   677  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
   678  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
   679  
   680  func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
   681  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   682  	n = int(r0)
   683  	if e1 != 0 {
   684  		err = e1
   685  	}
   686  	return
   687  }
   688  
   689  func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
   690  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwrite)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   691  	n = int(r0)
   692  	if e1 != 0 {
   693  		err = e1
   694  	}
   695  	return
   696  }
   697  
   698  var mapper = &mmapper{
   699  	active: make(map[*byte][]byte),
   700  	mmap:   mmap,
   701  	munmap: munmap,
   702  }
   703  
   704  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   705  	return mapper.Mmap(fd, offset, length, prot, flags)
   706  }
   707  
   708  func Munmap(b []byte) (err error) {
   709  	return mapper.Munmap(b)
   710  }
   711  
   712  //sys	sysconf(name int) (n int64, err error)
   713  
   714  // pageSize caches the value of Getpagesize, since it can't change
   715  // once the system is booted.
   716  var pageSize int64 // accessed atomically
   717  
   718  func Getpagesize() int {
   719  	n := atomic.LoadInt64(&pageSize)
   720  	if n == 0 {
   721  		n, _ = sysconf(_SC_PAGESIZE)
   722  		atomic.StoreInt64(&pageSize, n)
   723  	}
   724  	return int(n)
   725  }