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