syscall_solaris.go raw

   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  // Lifreq Helpers
1056  
1057  func (l *Lifreq) SetName(name string) error {
1058  	if len(name) >= len(l.Name) {
1059  		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
1060  	}
1061  	for i := range name {
1062  		l.Name[i] = int8(name[i])
1063  	}
1064  	return nil
1065  }
1066  
1067  func (l *Lifreq) SetLifruInt(d int) {
1068  	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
1069  }
1070  
1071  func (l *Lifreq) GetLifruInt() int {
1072  	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
1073  }
1074  
1075  func (l *Lifreq) SetLifruUint(d uint) {
1076  	*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
1077  }
1078  
1079  func (l *Lifreq) GetLifruUint() uint {
1080  	return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
1081  }
1082  
1083  func IoctlLifreq(fd int, req int, l *Lifreq) error {
1084  	return ioctlPtr(fd, req, unsafe.Pointer(l))
1085  }
1086  
1087  // Strioctl Helpers
1088  
1089  func (s *Strioctl) SetInt(i int) {
1090  	s.Len = int32(unsafe.Sizeof(i))
1091  	s.Dp = (*int8)(unsafe.Pointer(&i))
1092  }
1093  
1094  func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
1095  	return ioctlPtrRet(fd, req, unsafe.Pointer(s))
1096  }
1097  
1098  // Ucred Helpers
1099  // See ucred(3c) and getpeerucred(3c)
1100  
1101  //sys	getpeerucred(fd uintptr, ucred *uintptr) (err error)
1102  //sys	ucredFree(ucred uintptr) = ucred_free
1103  //sys	ucredGet(pid int) (ucred uintptr, err error) = ucred_get
1104  //sys	ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid
1105  //sys	ucredGetegid(ucred uintptr) (gid int) = ucred_getegid
1106  //sys	ucredGetruid(ucred uintptr) (uid int) = ucred_getruid
1107  //sys	ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid
1108  //sys	ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid
1109  //sys	ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid
1110  //sys	ucredGetpid(ucred uintptr) (pid int) = ucred_getpid
1111  
1112  // Ucred is an opaque struct that holds user credentials.
1113  type Ucred struct {
1114  	ucred uintptr
1115  }
1116  
1117  // We need to ensure that ucredFree is called on the underlying ucred
1118  // when the Ucred is garbage collected.
1119  func ucredFinalizer(u *Ucred) {
1120  	ucredFree(u.ucred)
1121  }
1122  
1123  func GetPeerUcred(fd uintptr) (*Ucred, error) {
1124  	var ucred uintptr
1125  	err := getpeerucred(fd, &ucred)
1126  	if err != nil {
1127  		return nil, err
1128  	}
1129  	result := &Ucred{
1130  		ucred: ucred,
1131  	}
1132  	// set the finalizer on the result so that the ucred will be freed
1133  	runtime.SetFinalizer(result, ucredFinalizer)
1134  	return result, nil
1135  }
1136  
1137  func UcredGet(pid int) (*Ucred, error) {
1138  	ucred, err := ucredGet(pid)
1139  	if err != nil {
1140  		return nil, err
1141  	}
1142  	result := &Ucred{
1143  		ucred: ucred,
1144  	}
1145  	// set the finalizer on the result so that the ucred will be freed
1146  	runtime.SetFinalizer(result, ucredFinalizer)
1147  	return result, nil
1148  }
1149  
1150  func (u *Ucred) Geteuid() int {
1151  	defer runtime.KeepAlive(u)
1152  	return ucredGeteuid(u.ucred)
1153  }
1154  
1155  func (u *Ucred) Getruid() int {
1156  	defer runtime.KeepAlive(u)
1157  	return ucredGetruid(u.ucred)
1158  }
1159  
1160  func (u *Ucred) Getsuid() int {
1161  	defer runtime.KeepAlive(u)
1162  	return ucredGetsuid(u.ucred)
1163  }
1164  
1165  func (u *Ucred) Getegid() int {
1166  	defer runtime.KeepAlive(u)
1167  	return ucredGetegid(u.ucred)
1168  }
1169  
1170  func (u *Ucred) Getrgid() int {
1171  	defer runtime.KeepAlive(u)
1172  	return ucredGetrgid(u.ucred)
1173  }
1174  
1175  func (u *Ucred) Getsgid() int {
1176  	defer runtime.KeepAlive(u)
1177  	return ucredGetsgid(u.ucred)
1178  }
1179  
1180  func (u *Ucred) Getpid() int {
1181  	defer runtime.KeepAlive(u)
1182  	return ucredGetpid(u.ucred)
1183  }
1184