src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

syscall_solaris.go (33998B)


      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 	"fmt"
     17 	"os"
     18 	"runtime"
     19 	"sync"
     20 	"syscall"
     21 	"unsafe"
     22 )
     23 
     24 // Implemented in runtime/syscall_solaris.go.
     25 type syscallFunc uintptr
     26 
     27 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
     28 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
     29 
     30 // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
     31 type SockaddrDatalink struct {
     32 	Family uint16
     33 	Index  uint16
     34 	Type   uint8
     35 	Nlen   uint8
     36 	Alen   uint8
     37 	Slen   uint8
     38 	Data   [244]int8
     39 	raw    RawSockaddrDatalink
     40 }
     41 
     42 func direntIno(buf []byte) (uint64, bool) {
     43 	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
     44 }
     45 
     46 func direntReclen(buf []byte) (uint64, bool) {
     47 	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
     48 }
     49 
     50 func direntNamlen(buf []byte) (uint64, bool) {
     51 	reclen, ok := direntReclen(buf)
     52 	if !ok {
     53 		return 0, false
     54 	}
     55 	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
     56 }
     57 
     58 //sysnb	pipe(p *[2]_C_int) (n int, err error)
     59 
     60 func Pipe(p []int) (err error) {
     61 	if len(p) != 2 {
     62 		return EINVAL
     63 	}
     64 	var pp [2]_C_int
     65 	n, err := pipe(&pp)
     66 	if n != 0 {
     67 		return err
     68 	}
     69 	if err == nil {
     70 		p[0] = int(pp[0])
     71 		p[1] = int(pp[1])
     72 	}
     73 	return nil
     74 }
     75 
     76 //sysnb	pipe2(p *[2]_C_int, flags int) (err error)
     77 
     78 func Pipe2(p []int, flags int) error {
     79 	if len(p) != 2 {
     80 		return EINVAL
     81 	}
     82 	var pp [2]_C_int
     83 	err := pipe2(&pp, flags)
     84 	if err == nil {
     85 		p[0] = int(pp[0])
     86 		p[1] = int(pp[1])
     87 	}
     88 	return err
     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 	sa.raw.Addr = sa.Addr
    100 	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
    101 }
    102 
    103 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
    104 	if sa.Port < 0 || sa.Port > 0xFFFF {
    105 		return nil, 0, EINVAL
    106 	}
    107 	sa.raw.Family = AF_INET6
    108 	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    109 	p[0] = byte(sa.Port >> 8)
    110 	p[1] = byte(sa.Port)
    111 	sa.raw.Scope_id = sa.ZoneId
    112 	sa.raw.Addr = sa.Addr
    113 	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
    114 }
    115 
    116 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
    117 	name := sa.Name
    118 	n := len(name)
    119 	if n >= len(sa.raw.Path) {
    120 		return nil, 0, EINVAL
    121 	}
    122 	sa.raw.Family = AF_UNIX
    123 	for i := 0; i < n; i++ {
    124 		sa.raw.Path[i] = int8(name[i])
    125 	}
    126 	// length is family (uint16), name, NUL.
    127 	sl := _Socklen(2)
    128 	if n > 0 {
    129 		sl += _Socklen(n) + 1
    130 	}
    131 	if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
    132 		// Check sl > 3 so we don't change unnamed socket behavior.
    133 		sa.raw.Path[0] = 0
    134 		// Don't count trailing NUL for abstract address.
    135 		sl--
    136 	}
    137 
    138 	return unsafe.Pointer(&sa.raw), sl, nil
    139 }
    140 
    141 //sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
    142 
    143 func Getsockname(fd int) (sa Sockaddr, err error) {
    144 	var rsa RawSockaddrAny
    145 	var len _Socklen = SizeofSockaddrAny
    146 	if err = getsockname(fd, &rsa, &len); err != nil {
    147 		return
    148 	}
    149 	return anyToSockaddr(fd, &rsa)
    150 }
    151 
    152 // GetsockoptString returns the string value of the socket option opt for the
    153 // socket associated with fd at the given socket level.
    154 func GetsockoptString(fd, level, opt int) (string, error) {
    155 	buf := make([]byte, 256)
    156 	vallen := _Socklen(len(buf))
    157 	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
    158 	if err != nil {
    159 		return "", err
    160 	}
    161 	return ByteSliceToString(buf[:vallen]), nil
    162 }
    163 
    164 const ImplementsGetwd = true
    165 
    166 //sys	Getcwd(buf []byte) (n int, err error)
    167 
    168 func Getwd() (wd string, err error) {
    169 	var buf [PathMax]byte
    170 	// Getcwd will return an error if it failed for any reason.
    171 	_, err = Getcwd(buf[0:])
    172 	if err != nil {
    173 		return "", err
    174 	}
    175 	n := clen(buf[:])
    176 	if n < 1 {
    177 		return "", EINVAL
    178 	}
    179 	return string(buf[:n]), nil
    180 }
    181 
    182 /*
    183  * Wrapped
    184  */
    185 
    186 //sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
    187 //sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
    188 
    189 func Getgroups() (gids []int, err error) {
    190 	n, err := getgroups(0, nil)
    191 	// Check for error and sanity check group count. Newer versions of
    192 	// Solaris allow up to 1024 (NGROUPS_MAX).
    193 	if n < 0 || n > 1024 {
    194 		if err != nil {
    195 			return nil, err
    196 		}
    197 		return nil, EINVAL
    198 	} else if n == 0 {
    199 		return nil, nil
    200 	}
    201 
    202 	a := make([]_Gid_t, n)
    203 	n, err = getgroups(n, &a[0])
    204 	if n == -1 {
    205 		return nil, err
    206 	}
    207 	gids = make([]int, n)
    208 	for i, v := range a[0:n] {
    209 		gids[i] = int(v)
    210 	}
    211 	return
    212 }
    213 
    214 func Setgroups(gids []int) (err error) {
    215 	if len(gids) == 0 {
    216 		return setgroups(0, nil)
    217 	}
    218 
    219 	a := make([]_Gid_t, len(gids))
    220 	for i, v := range gids {
    221 		a[i] = _Gid_t(v)
    222 	}
    223 	return setgroups(len(a), &a[0])
    224 }
    225 
    226 // ReadDirent reads directory entries from fd and writes them into buf.
    227 func ReadDirent(fd int, buf []byte) (n int, err error) {
    228 	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
    229 	// TODO(rsc): Can we use a single global basep for all calls?
    230 	return Getdents(fd, buf, new(uintptr))
    231 }
    232 
    233 // Wait status is 7 bits at bottom, either 0 (exited),
    234 // 0x7F (stopped), or a signal number that caused an exit.
    235 // The 0x80 bit is whether there was a core dump.
    236 // An extra number (exit code, signal causing a stop)
    237 // is in the high bits.
    238 
    239 type WaitStatus uint32
    240 
    241 const (
    242 	mask  = 0x7F
    243 	core  = 0x80
    244 	shift = 8
    245 
    246 	exited  = 0
    247 	stopped = 0x7F
    248 )
    249 
    250 func (w WaitStatus) Exited() bool { return w&mask == exited }
    251 
    252 func (w WaitStatus) ExitStatus() int {
    253 	if w&mask != exited {
    254 		return -1
    255 	}
    256 	return int(w >> shift)
    257 }
    258 
    259 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
    260 
    261 func (w WaitStatus) Signal() syscall.Signal {
    262 	sig := syscall.Signal(w & mask)
    263 	if sig == stopped || sig == 0 {
    264 		return -1
    265 	}
    266 	return sig
    267 }
    268 
    269 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
    270 
    271 func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
    272 
    273 func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
    274 
    275 func (w WaitStatus) StopSignal() syscall.Signal {
    276 	if !w.Stopped() {
    277 		return -1
    278 	}
    279 	return syscall.Signal(w>>shift) & 0xFF
    280 }
    281 
    282 func (w WaitStatus) TrapCause() int { return -1 }
    283 
    284 //sys	wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
    285 
    286 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
    287 	var status _C_int
    288 	rpid, err := wait4(int32(pid), &status, options, rusage)
    289 	wpid := int(rpid)
    290 	if wpid == -1 {
    291 		return wpid, err
    292 	}
    293 	if wstatus != nil {
    294 		*wstatus = WaitStatus(status)
    295 	}
    296 	return wpid, nil
    297 }
    298 
    299 //sys	gethostname(buf []byte) (n int, err error)
    300 
    301 func Gethostname() (name string, err error) {
    302 	var buf [MaxHostNameLen]byte
    303 	n, err := gethostname(buf[:])
    304 	if n != 0 {
    305 		return "", err
    306 	}
    307 	n = clen(buf[:])
    308 	if n < 1 {
    309 		return "", EFAULT
    310 	}
    311 	return string(buf[:n]), nil
    312 }
    313 
    314 //sys	utimes(path string, times *[2]Timeval) (err error)
    315 
    316 func Utimes(path string, tv []Timeval) (err error) {
    317 	if tv == nil {
    318 		return utimes(path, nil)
    319 	}
    320 	if len(tv) != 2 {
    321 		return EINVAL
    322 	}
    323 	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
    324 }
    325 
    326 //sys	utimensat(fd int, path string, times *[2]Timespec, flag int) (err error)
    327 
    328 func UtimesNano(path string, ts []Timespec) error {
    329 	if ts == nil {
    330 		return utimensat(AT_FDCWD, path, nil, 0)
    331 	}
    332 	if len(ts) != 2 {
    333 		return EINVAL
    334 	}
    335 	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
    336 }
    337 
    338 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
    339 	if ts == nil {
    340 		return utimensat(dirfd, path, nil, flags)
    341 	}
    342 	if len(ts) != 2 {
    343 		return EINVAL
    344 	}
    345 	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
    346 }
    347 
    348 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
    349 
    350 // FcntlInt performs a fcntl syscall on fd with the provided command and argument.
    351 func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
    352 	valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
    353 	var err error
    354 	if errno != 0 {
    355 		err = errno
    356 	}
    357 	return int(valptr), err
    358 }
    359 
    360 // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
    361 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
    362 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
    363 	if e1 != 0 {
    364 		return e1
    365 	}
    366 	return nil
    367 }
    368 
    369 //sys	futimesat(fildes int, path *byte, times *[2]Timeval) (err error)
    370 
    371 func Futimesat(dirfd int, path string, tv []Timeval) error {
    372 	pathp, err := BytePtrFromString(path)
    373 	if err != nil {
    374 		return err
    375 	}
    376 	if tv == nil {
    377 		return futimesat(dirfd, pathp, nil)
    378 	}
    379 	if len(tv) != 2 {
    380 		return EINVAL
    381 	}
    382 	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
    383 }
    384 
    385 // Solaris doesn't have an futimes function because it allows NULL to be
    386 // specified as the path for futimesat. However, Go doesn't like
    387 // NULL-style string interfaces, so this simple wrapper is provided.
    388 func Futimes(fd int, tv []Timeval) error {
    389 	if tv == nil {
    390 		return futimesat(fd, nil, nil)
    391 	}
    392 	if len(tv) != 2 {
    393 		return EINVAL
    394 	}
    395 	return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
    396 }
    397 
    398 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
    399 	switch rsa.Addr.Family {
    400 	case AF_UNIX:
    401 		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
    402 		sa := new(SockaddrUnix)
    403 		// Assume path ends at NUL.
    404 		// This is not technically the Solaris semantics for
    405 		// abstract Unix domain sockets -- they are supposed
    406 		// to be uninterpreted fixed-size binary blobs -- but
    407 		// everyone uses this convention.
    408 		n := 0
    409 		for n < len(pp.Path) && pp.Path[n] != 0 {
    410 			n++
    411 		}
    412 		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
    413 		return sa, nil
    414 
    415 	case AF_INET:
    416 		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
    417 		sa := new(SockaddrInet4)
    418 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
    419 		sa.Port = int(p[0])<<8 + int(p[1])
    420 		sa.Addr = pp.Addr
    421 		return sa, nil
    422 
    423 	case AF_INET6:
    424 		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
    425 		sa := new(SockaddrInet6)
    426 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
    427 		sa.Port = int(p[0])<<8 + int(p[1])
    428 		sa.ZoneId = pp.Scope_id
    429 		sa.Addr = pp.Addr
    430 		return sa, nil
    431 	}
    432 	return nil, EAFNOSUPPORT
    433 }
    434 
    435 //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
    436 
    437 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
    438 	var rsa RawSockaddrAny
    439 	var len _Socklen = SizeofSockaddrAny
    440 	nfd, err = accept(fd, &rsa, &len)
    441 	if nfd == -1 {
    442 		return
    443 	}
    444 	sa, err = anyToSockaddr(fd, &rsa)
    445 	if err != nil {
    446 		Close(nfd)
    447 		nfd = 0
    448 	}
    449 	return
    450 }
    451 
    452 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
    453 
    454 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
    455 	var msg Msghdr
    456 	msg.Name = (*byte)(unsafe.Pointer(rsa))
    457 	msg.Namelen = uint32(SizeofSockaddrAny)
    458 	var dummy byte
    459 	if len(oob) > 0 {
    460 		// receive at least one normal byte
    461 		if emptyIovecs(iov) {
    462 			var iova [1]Iovec
    463 			iova[0].Base = &dummy
    464 			iova[0].SetLen(1)
    465 			iov = iova[:]
    466 		}
    467 		msg.Accrightslen = int32(len(oob))
    468 	}
    469 	if len(iov) > 0 {
    470 		msg.Iov = &iov[0]
    471 		msg.SetIovlen(len(iov))
    472 	}
    473 	if n, err = recvmsg(fd, &msg, flags); n == -1 {
    474 		return
    475 	}
    476 	oobn = int(msg.Accrightslen)
    477 	return
    478 }
    479 
    480 //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
    481 
    482 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
    483 	var msg Msghdr
    484 	msg.Name = (*byte)(unsafe.Pointer(ptr))
    485 	msg.Namelen = uint32(salen)
    486 	var dummy byte
    487 	var empty bool
    488 	if len(oob) > 0 {
    489 		// send at least one normal byte
    490 		empty = emptyIovecs(iov)
    491 		if empty {
    492 			var iova [1]Iovec
    493 			iova[0].Base = &dummy
    494 			iova[0].SetLen(1)
    495 			iov = iova[:]
    496 		}
    497 		msg.Accrightslen = int32(len(oob))
    498 	}
    499 	if len(iov) > 0 {
    500 		msg.Iov = &iov[0]
    501 		msg.SetIovlen(len(iov))
    502 	}
    503 	if n, err = sendmsg(fd, &msg, flags); err != nil {
    504 		return 0, err
    505 	}
    506 	if len(oob) > 0 && empty {
    507 		n = 0
    508 	}
    509 	return n, nil
    510 }
    511 
    512 //sys	acct(path *byte) (err error)
    513 
    514 func Acct(path string) (err error) {
    515 	if len(path) == 0 {
    516 		// Assume caller wants to disable accounting.
    517 		return acct(nil)
    518 	}
    519 
    520 	pathp, err := BytePtrFromString(path)
    521 	if err != nil {
    522 		return err
    523 	}
    524 	return acct(pathp)
    525 }
    526 
    527 //sys	__makedev(version int, major uint, minor uint) (val uint64)
    528 
    529 func Mkdev(major, minor uint32) uint64 {
    530 	return __makedev(NEWDEV, uint(major), uint(minor))
    531 }
    532 
    533 //sys	__major(version int, dev uint64) (val uint)
    534 
    535 func Major(dev uint64) uint32 {
    536 	return uint32(__major(NEWDEV, dev))
    537 }
    538 
    539 //sys	__minor(version int, dev uint64) (val uint)
    540 
    541 func Minor(dev uint64) uint32 {
    542 	return uint32(__minor(NEWDEV, dev))
    543 }
    544 
    545 /*
    546  * Expose the ioctl function
    547  */
    548 
    549 //sys	ioctlRet(fd int, req int, arg uintptr) (ret int, err error) = libc.ioctl
    550 //sys	ioctlPtrRet(fd int, req int, arg unsafe.Pointer) (ret int, err error) = libc.ioctl
    551 
    552 func ioctl(fd int, req int, arg uintptr) (err error) {
    553 	_, err = ioctlRet(fd, req, arg)
    554 	return err
    555 }
    556 
    557 func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) {
    558 	_, err = ioctlPtrRet(fd, req, arg)
    559 	return err
    560 }
    561 
    562 func IoctlSetTermio(fd int, req int, value *Termio) error {
    563 	return ioctlPtr(fd, req, unsafe.Pointer(value))
    564 }
    565 
    566 func IoctlGetTermio(fd int, req int) (*Termio, error) {
    567 	var value Termio
    568 	err := ioctlPtr(fd, req, unsafe.Pointer(&value))
    569 	return &value, err
    570 }
    571 
    572 //sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
    573 
    574 func Poll(fds []PollFd, timeout int) (n int, err error) {
    575 	if len(fds) == 0 {
    576 		return poll(nil, 0, timeout)
    577 	}
    578 	return poll(&fds[0], len(fds), timeout)
    579 }
    580 
    581 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
    582 	if raceenabled {
    583 		raceReleaseMerge(unsafe.Pointer(&ioSync))
    584 	}
    585 	return sendfile(outfd, infd, offset, count)
    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	ClockGettime(clockid int32, time *Timespec) (err error)
    598 //sys	Close(fd int) (err error)
    599 //sys	Creat(path string, mode uint32) (fd int, err error)
    600 //sys	Dup(fd int) (nfd int, err error)
    601 //sys	Dup2(oldfd int, newfd int) (err error)
    602 //sys	Exit(code int)
    603 //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
    604 //sys	Fchdir(fd int) (err error)
    605 //sys	Fchmod(fd int, mode uint32) (err error)
    606 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
    607 //sys	Fchown(fd int, uid int, gid int) (err error)
    608 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
    609 //sys	Fdatasync(fd int) (err error)
    610 //sys	Flock(fd int, how int) (err error)
    611 //sys	Fpathconf(fd int, name int) (val int, err error)
    612 //sys	Fstat(fd int, stat *Stat_t) (err error)
    613 //sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
    614 //sys	Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
    615 //sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
    616 //sysnb	Getgid() (gid int)
    617 //sysnb	Getpid() (pid int)
    618 //sysnb	Getpgid(pid int) (pgid int, err error)
    619 //sysnb	Getpgrp() (pgid int, err error)
    620 //sys	Geteuid() (euid int)
    621 //sys	Getegid() (egid int)
    622 //sys	Getppid() (ppid int)
    623 //sys	Getpriority(which int, who int) (n int, err error)
    624 //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
    625 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
    626 //sysnb	Getsid(pid int) (sid int, err error)
    627 //sysnb	Gettimeofday(tv *Timeval) (err error)
    628 //sysnb	Getuid() (uid int)
    629 //sys	Kill(pid int, signum syscall.Signal) (err error)
    630 //sys	Lchown(path string, uid int, gid int) (err error)
    631 //sys	Link(path string, link string) (err error)
    632 //sys	Listen(s int, backlog int) (err error) = libsocket.__xnet_listen
    633 //sys	Lstat(path string, stat *Stat_t) (err error)
    634 //sys	Madvise(b []byte, advice int) (err error)
    635 //sys	Mkdir(path string, mode uint32) (err error)
    636 //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
    637 //sys	Mkfifo(path string, mode uint32) (err error)
    638 //sys	Mkfifoat(dirfd int, path string, mode uint32) (err error)
    639 //sys	Mknod(path string, mode uint32, dev int) (err error)
    640 //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
    641 //sys	Mlock(b []byte) (err error)
    642 //sys	Mlockall(flags int) (err error)
    643 //sys	Mprotect(b []byte, prot int) (err error)
    644 //sys	Msync(b []byte, flags int) (err error)
    645 //sys	Munlock(b []byte) (err error)
    646 //sys	Munlockall() (err error)
    647 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
    648 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
    649 //sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
    650 //sys	Pathconf(path string, name int) (val int, err error)
    651 //sys	Pause() (err error)
    652 //sys	pread(fd int, p []byte, offset int64) (n int, err error)
    653 //sys	pwrite(fd int, p []byte, offset int64) (n int, err error)
    654 //sys	read(fd int, p []byte) (n int, err error)
    655 //sys	Readlink(path string, buf []byte) (n int, err error)
    656 //sys	Rename(from string, to string) (err error)
    657 //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
    658 //sys	Rmdir(path string) (err error)
    659 //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
    660 //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
    661 //sysnb	Setegid(egid int) (err error)
    662 //sysnb	Seteuid(euid int) (err error)
    663 //sysnb	Setgid(gid int) (err error)
    664 //sys	Sethostname(p []byte) (err error)
    665 //sysnb	Setpgid(pid int, pgid int) (err error)
    666 //sys	Setpriority(which int, who int, prio int) (err error)
    667 //sysnb	Setregid(rgid int, egid int) (err error)
    668 //sysnb	Setreuid(ruid int, euid int) (err error)
    669 //sysnb	Setsid() (pid int, err error)
    670 //sysnb	Setuid(uid int) (err error)
    671 //sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
    672 //sys	Stat(path string, stat *Stat_t) (err error)
    673 //sys	Statvfs(path string, vfsstat *Statvfs_t) (err error)
    674 //sys	Symlink(path string, link string) (err error)
    675 //sys	Sync() (err error)
    676 //sys	Sysconf(which int) (n int64, err error)
    677 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
    678 //sys	Truncate(path string, length int64) (err error)
    679 //sys	Fsync(fd int) (err error)
    680 //sys	Ftruncate(fd int, length int64) (err error)
    681 //sys	Umask(mask int) (oldmask int)
    682 //sysnb	Uname(buf *Utsname) (err error)
    683 //sys	Unmount(target string, flags int) (err error) = libc.umount
    684 //sys	Unlink(path string) (err error)
    685 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
    686 //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
    687 //sys	Utime(path string, buf *Utimbuf) (err error)
    688 //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind
    689 //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
    690 //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
    691 //sys	munmap(addr uintptr, length uintptr) (err error)
    692 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
    693 //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
    694 //sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
    695 //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
    696 //sys	write(fd int, p []byte) (n int, err error)
    697 //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt
    698 //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
    699 //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
    700 //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
    701 
    702 // Event Ports
    703 
    704 type fileObjCookie struct {
    705 	fobj   *fileObj
    706 	cookie interface{}
    707 }
    708 
    709 // EventPort provides a safe abstraction on top of Solaris/illumos Event Ports.
    710 type EventPort struct {
    711 	port  int
    712 	mu    sync.Mutex
    713 	fds   map[uintptr]*fileObjCookie
    714 	paths map[string]*fileObjCookie
    715 	// The user cookie presents an interesting challenge from a memory management perspective.
    716 	// There are two paths by which we can discover that it is no longer in use:
    717 	// 1. The user calls port_dissociate before any events fire
    718 	// 2. An event fires and we return it to the user
    719 	// The tricky situation is if the event has fired in the kernel but
    720 	// the user hasn't requested/received it yet.
    721 	// If the user wants to port_dissociate before the event has been processed,
    722 	// we should handle things gracefully. To do so, we need to keep an extra
    723 	// reference to the cookie around until the event is processed
    724 	// thus the otherwise seemingly extraneous "cookies" map
    725 	// The key of this map is a pointer to the corresponding fCookie
    726 	cookies map[*fileObjCookie]struct{}
    727 }
    728 
    729 // PortEvent is an abstraction of the port_event C struct.
    730 // Compare Source against PORT_SOURCE_FILE or PORT_SOURCE_FD
    731 // to see if Path or Fd was the event source. The other will be
    732 // uninitialized.
    733 type PortEvent struct {
    734 	Cookie interface{}
    735 	Events int32
    736 	Fd     uintptr
    737 	Path   string
    738 	Source uint16
    739 	fobj   *fileObj
    740 }
    741 
    742 // NewEventPort creates a new EventPort including the
    743 // underlying call to port_create(3c).
    744 func NewEventPort() (*EventPort, error) {
    745 	port, err := port_create()
    746 	if err != nil {
    747 		return nil, err
    748 	}
    749 	e := &EventPort{
    750 		port:    port,
    751 		fds:     make(map[uintptr]*fileObjCookie),
    752 		paths:   make(map[string]*fileObjCookie),
    753 		cookies: make(map[*fileObjCookie]struct{}),
    754 	}
    755 	return e, nil
    756 }
    757 
    758 //sys	port_create() (n int, err error)
    759 //sys	port_associate(port int, source int, object uintptr, events int, user *byte) (n int, err error)
    760 //sys	port_dissociate(port int, source int, object uintptr) (n int, err error)
    761 //sys	port_get(port int, pe *portEvent, timeout *Timespec) (n int, err error)
    762 //sys	port_getn(port int, pe *portEvent, max uint32, nget *uint32, timeout *Timespec) (n int, err error)
    763 
    764 // Close closes the event port.
    765 func (e *EventPort) Close() error {
    766 	e.mu.Lock()
    767 	defer e.mu.Unlock()
    768 	err := Close(e.port)
    769 	if err != nil {
    770 		return err
    771 	}
    772 	e.fds = nil
    773 	e.paths = nil
    774 	e.cookies = nil
    775 	return nil
    776 }
    777 
    778 // PathIsWatched checks to see if path is associated with this EventPort.
    779 func (e *EventPort) PathIsWatched(path string) bool {
    780 	e.mu.Lock()
    781 	defer e.mu.Unlock()
    782 	_, found := e.paths[path]
    783 	return found
    784 }
    785 
    786 // FdIsWatched checks to see if fd is associated with this EventPort.
    787 func (e *EventPort) FdIsWatched(fd uintptr) bool {
    788 	e.mu.Lock()
    789 	defer e.mu.Unlock()
    790 	_, found := e.fds[fd]
    791 	return found
    792 }
    793 
    794 // AssociatePath wraps port_associate(3c) for a filesystem path including
    795 // creating the necessary file_obj from the provided stat information.
    796 func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, cookie interface{}) error {
    797 	e.mu.Lock()
    798 	defer e.mu.Unlock()
    799 	if _, found := e.paths[path]; found {
    800 		return fmt.Errorf("%v is already associated with this Event Port", path)
    801 	}
    802 	fCookie, err := createFileObjCookie(path, stat, cookie)
    803 	if err != nil {
    804 		return err
    805 	}
    806 	_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
    807 	if err != nil {
    808 		return err
    809 	}
    810 	e.paths[path] = fCookie
    811 	e.cookies[fCookie] = struct{}{}
    812 	return nil
    813 }
    814 
    815 // DissociatePath wraps port_dissociate(3c) for a filesystem path.
    816 func (e *EventPort) DissociatePath(path string) error {
    817 	e.mu.Lock()
    818 	defer e.mu.Unlock()
    819 	f, ok := e.paths[path]
    820 	if !ok {
    821 		return fmt.Errorf("%v is not associated with this Event Port", path)
    822 	}
    823 	_, err := port_dissociate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(f.fobj)))
    824 	// If the path is no longer associated with this event port (ENOENT)
    825 	// we should delete it from our map. We can still return ENOENT to the caller.
    826 	// But we need to save the cookie
    827 	if err != nil && err != ENOENT {
    828 		return err
    829 	}
    830 	if err == nil {
    831 		// dissociate was successful, safe to delete the cookie
    832 		fCookie := e.paths[path]
    833 		delete(e.cookies, fCookie)
    834 	}
    835 	delete(e.paths, path)
    836 	return err
    837 }
    838 
    839 // AssociateFd wraps calls to port_associate(3c) on file descriptors.
    840 func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) error {
    841 	e.mu.Lock()
    842 	defer e.mu.Unlock()
    843 	if _, found := e.fds[fd]; found {
    844 		return fmt.Errorf("%v is already associated with this Event Port", fd)
    845 	}
    846 	fCookie, err := createFileObjCookie("", nil, cookie)
    847 	if err != nil {
    848 		return err
    849 	}
    850 	_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
    851 	if err != nil {
    852 		return err
    853 	}
    854 	e.fds[fd] = fCookie
    855 	e.cookies[fCookie] = struct{}{}
    856 	return nil
    857 }
    858 
    859 // DissociateFd wraps calls to port_dissociate(3c) on file descriptors.
    860 func (e *EventPort) DissociateFd(fd uintptr) error {
    861 	e.mu.Lock()
    862 	defer e.mu.Unlock()
    863 	_, ok := e.fds[fd]
    864 	if !ok {
    865 		return fmt.Errorf("%v is not associated with this Event Port", fd)
    866 	}
    867 	_, err := port_dissociate(e.port, PORT_SOURCE_FD, fd)
    868 	if err != nil && err != ENOENT {
    869 		return err
    870 	}
    871 	if err == nil {
    872 		// dissociate was successful, safe to delete the cookie
    873 		fCookie := e.fds[fd]
    874 		delete(e.cookies, fCookie)
    875 	}
    876 	delete(e.fds, fd)
    877 	return err
    878 }
    879 
    880 func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
    881 	fCookie := new(fileObjCookie)
    882 	fCookie.cookie = cookie
    883 	if name != "" && stat != nil {
    884 		fCookie.fobj = new(fileObj)
    885 		bs, err := ByteSliceFromString(name)
    886 		if err != nil {
    887 			return nil, err
    888 		}
    889 		fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
    890 		s := stat.Sys().(*syscall.Stat_t)
    891 		fCookie.fobj.Atim.Sec = s.Atim.Sec
    892 		fCookie.fobj.Atim.Nsec = s.Atim.Nsec
    893 		fCookie.fobj.Mtim.Sec = s.Mtim.Sec
    894 		fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
    895 		fCookie.fobj.Ctim.Sec = s.Ctim.Sec
    896 		fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
    897 	}
    898 	return fCookie, nil
    899 }
    900 
    901 // GetOne wraps port_get(3c) and returns a single PortEvent.
    902 func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
    903 	pe := new(portEvent)
    904 	_, err := port_get(e.port, pe, t)
    905 	if err != nil {
    906 		return nil, err
    907 	}
    908 	p := new(PortEvent)
    909 	e.mu.Lock()
    910 	defer e.mu.Unlock()
    911 	err = e.peIntToExt(pe, p)
    912 	if err != nil {
    913 		return nil, err
    914 	}
    915 	return p, nil
    916 }
    917 
    918 // peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
    919 // NOTE: Always call this function while holding the e.mu mutex
    920 func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
    921 	if e.cookies == nil {
    922 		return fmt.Errorf("this EventPort is already closed")
    923 	}
    924 	peExt.Events = peInt.Events
    925 	peExt.Source = peInt.Source
    926 	fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
    927 	_, found := e.cookies[fCookie]
    928 
    929 	if !found {
    930 		panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
    931 	}
    932 	peExt.Cookie = fCookie.cookie
    933 	delete(e.cookies, fCookie)
    934 
    935 	switch peInt.Source {
    936 	case PORT_SOURCE_FD:
    937 		peExt.Fd = uintptr(peInt.Object)
    938 		// Only remove the fds entry if it exists and this cookie matches
    939 		if fobj, ok := e.fds[peExt.Fd]; ok {
    940 			if fobj == fCookie {
    941 				delete(e.fds, peExt.Fd)
    942 			}
    943 		}
    944 	case PORT_SOURCE_FILE:
    945 		peExt.fobj = fCookie.fobj
    946 		peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
    947 		// Only remove the paths entry if it exists and this cookie matches
    948 		if fobj, ok := e.paths[peExt.Path]; ok {
    949 			if fobj == fCookie {
    950 				delete(e.paths, peExt.Path)
    951 			}
    952 		}
    953 	}
    954 	return nil
    955 }
    956 
    957 // Pending wraps port_getn(3c) and returns how many events are pending.
    958 func (e *EventPort) Pending() (int, error) {
    959 	var n uint32 = 0
    960 	_, err := port_getn(e.port, nil, 0, &n, nil)
    961 	return int(n), err
    962 }
    963 
    964 // Get wraps port_getn(3c) and fills a slice of PortEvent.
    965 // It will block until either min events have been received
    966 // or the timeout has been exceeded. It will return how many
    967 // events were actually received along with any error information.
    968 func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error) {
    969 	if min == 0 {
    970 		return 0, fmt.Errorf("need to request at least one event or use Pending() instead")
    971 	}
    972 	if len(s) < min {
    973 		return 0, fmt.Errorf("len(s) (%d) is less than min events requested (%d)", len(s), min)
    974 	}
    975 	got := uint32(min)
    976 	max := uint32(len(s))
    977 	var err error
    978 	ps := make([]portEvent, max)
    979 	_, err = port_getn(e.port, &ps[0], max, &got, timeout)
    980 	// got will be trustworthy with ETIME, but not any other error.
    981 	if err != nil && err != ETIME {
    982 		return 0, err
    983 	}
    984 	e.mu.Lock()
    985 	defer e.mu.Unlock()
    986 	valid := 0
    987 	for i := 0; i < int(got); i++ {
    988 		err2 := e.peIntToExt(&ps[i], &s[i])
    989 		if err2 != nil {
    990 			if valid == 0 && err == nil {
    991 				// If err2 is the only error and there are no valid events
    992 				// to return, return it to the caller.
    993 				err = err2
    994 			}
    995 			break
    996 		}
    997 		valid = i + 1
    998 	}
    999 	return valid, err
   1000 }
   1001 
   1002 //sys	putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
   1003 
   1004 func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
   1005 	var clp, datap *strbuf
   1006 	if len(cl) > 0 {
   1007 		clp = &strbuf{
   1008 			Len: int32(len(cl)),
   1009 			Buf: (*int8)(unsafe.Pointer(&cl[0])),
   1010 		}
   1011 	}
   1012 	if len(data) > 0 {
   1013 		datap = &strbuf{
   1014 			Len: int32(len(data)),
   1015 			Buf: (*int8)(unsafe.Pointer(&data[0])),
   1016 		}
   1017 	}
   1018 	return putmsg(fd, clp, datap, flags)
   1019 }
   1020 
   1021 //sys	getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
   1022 
   1023 func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
   1024 	var clp, datap *strbuf
   1025 	if len(cl) > 0 {
   1026 		clp = &strbuf{
   1027 			Maxlen: int32(len(cl)),
   1028 			Buf:    (*int8)(unsafe.Pointer(&cl[0])),
   1029 		}
   1030 	}
   1031 	if len(data) > 0 {
   1032 		datap = &strbuf{
   1033 			Maxlen: int32(len(data)),
   1034 			Buf:    (*int8)(unsafe.Pointer(&data[0])),
   1035 		}
   1036 	}
   1037 
   1038 	if err = getmsg(fd, clp, datap, &flags); err != nil {
   1039 		return nil, nil, 0, err
   1040 	}
   1041 
   1042 	if len(cl) > 0 {
   1043 		retCl = cl[:clp.Len]
   1044 	}
   1045 	if len(data) > 0 {
   1046 		retData = data[:datap.Len]
   1047 	}
   1048 	return retCl, retData, flags, nil
   1049 }
   1050 
   1051 func IoctlSetIntRetInt(fd int, req int, arg int) (int, error) {
   1052 	return ioctlRet(fd, req, uintptr(arg))
   1053 }
   1054 
   1055 func IoctlSetString(fd int, req int, val string) error {
   1056 	bs := make([]byte, len(val)+1)
   1057 	copy(bs[:len(bs)-1], val)
   1058 	err := ioctlPtr(fd, req, unsafe.Pointer(&bs[0]))
   1059 	runtime.KeepAlive(&bs[0])
   1060 	return err
   1061 }
   1062 
   1063 // Lifreq Helpers
   1064 
   1065 func (l *Lifreq) SetName(name string) error {
   1066 	if len(name) >= len(l.Name) {
   1067 		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
   1068 	}
   1069 	for i := range name {
   1070 		l.Name[i] = int8(name[i])
   1071 	}
   1072 	return nil
   1073 }
   1074 
   1075 func (l *Lifreq) SetLifruInt(d int) {
   1076 	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
   1077 }
   1078 
   1079 func (l *Lifreq) GetLifruInt() int {
   1080 	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
   1081 }
   1082 
   1083 func (l *Lifreq) SetLifruUint(d uint) {
   1084 	*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
   1085 }
   1086 
   1087 func (l *Lifreq) GetLifruUint() uint {
   1088 	return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
   1089 }
   1090 
   1091 func IoctlLifreq(fd int, req int, l *Lifreq) error {
   1092 	return ioctlPtr(fd, req, unsafe.Pointer(l))
   1093 }
   1094 
   1095 // Strioctl Helpers
   1096 
   1097 func (s *Strioctl) SetInt(i int) {
   1098 	s.Len = int32(unsafe.Sizeof(i))
   1099 	s.Dp = (*int8)(unsafe.Pointer(&i))
   1100 }
   1101 
   1102 func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
   1103 	return ioctlPtrRet(fd, req, unsafe.Pointer(s))
   1104 }
   1105 
   1106 // Ucred Helpers
   1107 // See ucred(3c) and getpeerucred(3c)
   1108 
   1109 //sys	getpeerucred(fd uintptr, ucred *uintptr) (err error)
   1110 //sys	ucredFree(ucred uintptr) = ucred_free
   1111 //sys	ucredGet(pid int) (ucred uintptr, err error) = ucred_get
   1112 //sys	ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid
   1113 //sys	ucredGetegid(ucred uintptr) (gid int) = ucred_getegid
   1114 //sys	ucredGetruid(ucred uintptr) (uid int) = ucred_getruid
   1115 //sys	ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid
   1116 //sys	ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid
   1117 //sys	ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid
   1118 //sys	ucredGetpid(ucred uintptr) (pid int) = ucred_getpid
   1119 
   1120 // Ucred is an opaque struct that holds user credentials.
   1121 type Ucred struct {
   1122 	ucred uintptr
   1123 }
   1124 
   1125 // We need to ensure that ucredFree is called on the underlying ucred
   1126 // when the Ucred is garbage collected.
   1127 func ucredFinalizer(u *Ucred) {
   1128 	ucredFree(u.ucred)
   1129 }
   1130 
   1131 func GetPeerUcred(fd uintptr) (*Ucred, error) {
   1132 	var ucred uintptr
   1133 	err := getpeerucred(fd, &ucred)
   1134 	if err != nil {
   1135 		return nil, err
   1136 	}
   1137 	result := &Ucred{
   1138 		ucred: ucred,
   1139 	}
   1140 	// set the finalizer on the result so that the ucred will be freed
   1141 	runtime.SetFinalizer(result, ucredFinalizer)
   1142 	return result, nil
   1143 }
   1144 
   1145 func UcredGet(pid int) (*Ucred, error) {
   1146 	ucred, err := ucredGet(pid)
   1147 	if err != nil {
   1148 		return nil, err
   1149 	}
   1150 	result := &Ucred{
   1151 		ucred: ucred,
   1152 	}
   1153 	// set the finalizer on the result so that the ucred will be freed
   1154 	runtime.SetFinalizer(result, ucredFinalizer)
   1155 	return result, nil
   1156 }
   1157 
   1158 func (u *Ucred) Geteuid() int {
   1159 	defer runtime.KeepAlive(u)
   1160 	return ucredGeteuid(u.ucred)
   1161 }
   1162 
   1163 func (u *Ucred) Getruid() int {
   1164 	defer runtime.KeepAlive(u)
   1165 	return ucredGetruid(u.ucred)
   1166 }
   1167 
   1168 func (u *Ucred) Getsuid() int {
   1169 	defer runtime.KeepAlive(u)
   1170 	return ucredGetsuid(u.ucred)
   1171 }
   1172 
   1173 func (u *Ucred) Getegid() int {
   1174 	defer runtime.KeepAlive(u)
   1175 	return ucredGetegid(u.ucred)
   1176 }
   1177 
   1178 func (u *Ucred) Getrgid() int {
   1179 	defer runtime.KeepAlive(u)
   1180 	return ucredGetrgid(u.ucred)
   1181 }
   1182 
   1183 func (u *Ucred) Getsgid() int {
   1184 	defer runtime.KeepAlive(u)
   1185 	return ucredGetsgid(u.ucred)
   1186 }
   1187 
   1188 func (u *Ucred) Getpid() int {
   1189 	defer runtime.KeepAlive(u)
   1190 	return ucredGetpid(u.ucred)
   1191 }