syscall_linux.mx 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  // Linux system calls.
   6  // This file is compiled as ordinary Go code,
   7  // but it is also input to mksyscall,
   8  // which parses the //sys lines and generates system call stubs.
   9  // Note that sometimes we use a lowercase //sys name and
  10  // wrap it in our own nicer implementation.
  11  
  12  package syscall
  13  
  14  import (
  15  	"internal/itoa"
  16  	runtimesyscall "internal/runtime/syscall"
  17  	"runtime"
  18  	"slices"
  19  	"unsafe"
  20  )
  21  
  22  // Pull in entersyscall/exitsyscall for Syscall/Syscall6.
  23  //
  24  // Note that this can't be a push linkname because the runtime already has a
  25  // nameless linkname to export to assembly here and in x/sys. Additionally,
  26  // entersyscall fetches the caller PC and SP and thus can't have a wrapper
  27  // inbetween.
  28  
  29  //go:linkname runtime_entersyscall runtime.entersyscall
  30  func runtime_entersyscall()
  31  
  32  //go:linkname runtime_exitsyscall runtime.exitsyscall
  33  func runtime_exitsyscall()
  34  
  35  // N.B. For the Syscall functions below:
  36  //
  37  // //go:uintptrkeepalive because the uintptr argument may be converted pointers
  38  // that need to be kept alive in the caller.
  39  //
  40  // //go:nosplit because stack copying does not account for uintptrkeepalive, so
  41  // the stack must not grow. Stack copying cannot blindly assume that all
  42  // uintptr arguments are pointers, because some values may look like pointers,
  43  // but not really be pointers, and adjusting their value would break the call.
  44  //
  45  // //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is
  46  // called after fork, or from a signal handler.
  47  //
  48  // //go:linkname to ensure ABI wrappers are generated for external callers
  49  // (notably x/sys/unix assembly).
  50  
  51  //go:uintptrkeepalive
  52  //go:nosplit
  53  //go:norace
  54  //go:linkname RawSyscall
  55  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
  56  	return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
  57  }
  58  
  59  //go:uintptrkeepalive
  60  //go:nosplit
  61  //go:norace
  62  //go:linkname RawSyscall6
  63  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
  64  	var errno uintptr
  65  	r1, r2, errno = runtimesyscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
  66  	err = Errno(errno)
  67  	return
  68  }
  69  
  70  //go:uintptrkeepalive
  71  //go:nosplit
  72  //go:linkname Syscall
  73  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
  74  	runtime_entersyscall()
  75  	// N.B. Calling RawSyscall here is unsafe with atomic coverage
  76  	// instrumentation and race mode.
  77  	//
  78  	// Coverage instrumentation will add a sync/atomic call to RawSyscall.
  79  	// Race mode will add race instrumentation to sync/atomic. Race
  80  	// instrumentation requires a P, which we no longer have.
  81  	//
  82  	// RawSyscall6 is fine because it is implemented in assembly and thus
  83  	// has no coverage instrumentation.
  84  	//
  85  	// This is typically not a problem in the runtime because cmd/go avoids
  86  	// adding coverage instrumentation to the runtime in race mode.
  87  	r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
  88  	runtime_exitsyscall()
  89  	return
  90  }
  91  
  92  //go:uintptrkeepalive
  93  //go:nosplit
  94  //go:linkname Syscall6
  95  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
  96  	runtime_entersyscall()
  97  	r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
  98  	runtime_exitsyscall()
  99  	return
 100  }
 101  
 102  func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
 103  func rawVforkSyscall(trap, a1, a2, a3 uintptr) (r1 uintptr, err Errno)
 104  
 105  /*
 106   * Wrapped
 107   */
 108  
 109  func Access(path string, mode uint32) (err error) {
 110  	return Faccessat(_AT_FDCWD, path, mode, 0)
 111  }
 112  
 113  func Chmod(path string, mode uint32) (err error) {
 114  	return Fchmodat(_AT_FDCWD, path, mode, 0)
 115  }
 116  
 117  func Chown(path string, uid int, gid int) (err error) {
 118  	return Fchownat(_AT_FDCWD, path, uid, gid, 0)
 119  }
 120  
 121  func Creat(path string, mode uint32) (fd int, err error) {
 122  	return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
 123  }
 124  
 125  func EpollCreate(size int) (fd int, err error) {
 126  	if size <= 0 {
 127  		return -1, EINVAL
 128  	}
 129  	return EpollCreate1(0)
 130  }
 131  
 132  func isGroupMember(gid int) bool {
 133  	groups, err := Getgroups()
 134  	if err != nil {
 135  		return false
 136  	}
 137  
 138  	return slices.Contains(groups, gid)
 139  }
 140  
 141  func isCapDacOverrideSet() bool {
 142  	const _CAP_DAC_OVERRIDE = 1
 143  	var c caps
 144  	c.hdr.version = _LINUX_CAPABILITY_VERSION_3
 145  
 146  	_, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
 147  
 148  	return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
 149  }
 150  
 151  //sys	faccessat(dirfd int, path string, mode uint32) (err error)
 152  //sys	faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2
 153  
 154  func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
 155  	if flags == 0 {
 156  		return faccessat(dirfd, path, mode)
 157  	}
 158  
 159  	// Attempt to use the newer faccessat2, which supports flags directly,
 160  	// falling back if it doesn't exist.
 161  	//
 162  	// Don't attempt on Android, which does not allow faccessat2 through
 163  	// its seccomp policy [1] on any version of Android as of 2022-12-20.
 164  	//
 165  	// [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
 166  	if runtime.GOOS != "android" {
 167  		if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
 168  			return err
 169  		}
 170  	}
 171  
 172  	// The Linux kernel faccessat system call does not take any flags.
 173  	// The glibc faccessat implements the flags itself; see
 174  	// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
 175  	// Because people naturally expect syscall.Faccessat to act
 176  	// like C faccessat, we do the same.
 177  
 178  	if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
 179  		return EINVAL
 180  	}
 181  
 182  	var st Stat_t
 183  	if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
 184  		return err
 185  	}
 186  
 187  	mode &= 7
 188  	if mode == 0 {
 189  		return nil
 190  	}
 191  
 192  	// Fallback to checking permission bits.
 193  	var uid int
 194  	if flags&_AT_EACCESS != 0 {
 195  		uid = Geteuid()
 196  		if uid != 0 && isCapDacOverrideSet() {
 197  			// If CAP_DAC_OVERRIDE is set, file access check is
 198  			// done by the kernel in the same way as for root
 199  			// (see generic_permission() in the Linux sources).
 200  			uid = 0
 201  		}
 202  	} else {
 203  		uid = Getuid()
 204  	}
 205  
 206  	if uid == 0 {
 207  		if mode&1 == 0 {
 208  			// Root can read and write any file.
 209  			return nil
 210  		}
 211  		if st.Mode&0111 != 0 {
 212  			// Root can execute any file that anybody can execute.
 213  			return nil
 214  		}
 215  		return EACCES
 216  	}
 217  
 218  	var fmode uint32
 219  	if uint32(uid) == st.Uid {
 220  		fmode = (st.Mode >> 6) & 7
 221  	} else {
 222  		var gid int
 223  		if flags&_AT_EACCESS != 0 {
 224  			gid = Getegid()
 225  		} else {
 226  			gid = Getgid()
 227  		}
 228  
 229  		if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
 230  			fmode = (st.Mode >> 3) & 7
 231  		} else {
 232  			fmode = st.Mode & 7
 233  		}
 234  	}
 235  
 236  	if fmode&mode == mode {
 237  		return nil
 238  	}
 239  
 240  	return EACCES
 241  }
 242  
 243  //sys	fchmodat(dirfd int, path string, mode uint32) (err error)
 244  //sys	fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_fchmodat2
 245  
 246  func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
 247  	// Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
 248  	// Try fchmodat2 if flags are specified.
 249  	if flags != 0 {
 250  		err := fchmodat2(dirfd, path, mode, flags)
 251  		if err == ENOSYS {
 252  			// fchmodat2 isn't available. If the flags are known to be valid,
 253  			// return EOPNOTSUPP to indicate that fchmodat doesn't support them.
 254  			if flags&^(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
 255  				return EINVAL
 256  			} else if flags&(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
 257  				return EOPNOTSUPP
 258  			}
 259  		}
 260  		return err
 261  	}
 262  	return fchmodat(dirfd, path, mode)
 263  }
 264  
 265  //sys	linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
 266  
 267  func Link(oldpath string, newpath string) (err error) {
 268  	return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
 269  }
 270  
 271  func Mkdir(path string, mode uint32) (err error) {
 272  	return Mkdirat(_AT_FDCWD, path, mode)
 273  }
 274  
 275  func Mknod(path string, mode uint32, dev int) (err error) {
 276  	return Mknodat(_AT_FDCWD, path, mode, dev)
 277  }
 278  
 279  func Open(path string, mode int, perm uint32) (fd int, err error) {
 280  	return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
 281  }
 282  
 283  //sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 284  
 285  func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
 286  	return openat(dirfd, path, flags|O_LARGEFILE, mode)
 287  }
 288  
 289  func Pipe(p []int) error {
 290  	return Pipe2(p, 0)
 291  }
 292  
 293  //sysnb pipe2(p *[2]_C_int, flags int) (err error)
 294  
 295  func Pipe2(p []int, flags int) error {
 296  	if len(p) != 2 {
 297  		return EINVAL
 298  	}
 299  	var pp [2]_C_int
 300  	err := pipe2(&pp, flags)
 301  	if err == nil {
 302  		p[0] = int(pp[0])
 303  		p[1] = int(pp[1])
 304  	}
 305  	return err
 306  }
 307  
 308  //sys	readlinkat(dirfd int, path string, buf []byte) (n int, err error)
 309  
 310  func Readlink(path string, buf []byte) (n int, err error) {
 311  	return readlinkat(_AT_FDCWD, path, buf)
 312  }
 313  
 314  func Rename(oldpath string, newpath string) (err error) {
 315  	return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
 316  }
 317  
 318  func Rmdir(path string) error {
 319  	return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
 320  }
 321  
 322  //sys	symlinkat(oldpath string, newdirfd int, newpath string) (err error)
 323  
 324  func Symlink(oldpath string, newpath string) (err error) {
 325  	return symlinkat(oldpath, _AT_FDCWD, newpath)
 326  }
 327  
 328  func Unlink(path string) error {
 329  	return unlinkat(_AT_FDCWD, path, 0)
 330  }
 331  
 332  //sys	unlinkat(dirfd int, path string, flags int) (err error)
 333  
 334  func Unlinkat(dirfd int, path string) error {
 335  	return unlinkat(dirfd, path, 0)
 336  }
 337  
 338  func Utimes(path string, tv []Timeval) (err error) {
 339  	if len(tv) != 2 {
 340  		return EINVAL
 341  	}
 342  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 343  }
 344  
 345  //sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
 346  
 347  func UtimesNano(path string, ts []Timespec) (err error) {
 348  	if len(ts) != 2 {
 349  		return EINVAL
 350  	}
 351  	return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
 352  }
 353  
 354  func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
 355  	if len(tv) != 2 {
 356  		return EINVAL
 357  	}
 358  	return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 359  }
 360  
 361  func Futimes(fd int, tv []Timeval) (err error) {
 362  	// Believe it or not, this is the best we can do on Linux
 363  	// (and is what glibc does).
 364  	return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
 365  }
 366  
 367  const ImplementsGetwd = true
 368  
 369  //sys	Getcwd(buf []byte) (n int, err error)
 370  
 371  func Getwd() (wd string, err error) {
 372  	var buf [PathMax]byte
 373  	n, err := Getcwd(buf[0:])
 374  	if err != nil {
 375  		return "", err
 376  	}
 377  	// Getcwd returns the number of bytes written to buf, including the NUL.
 378  	if n < 1 || n > len(buf) || buf[n-1] != 0 {
 379  		return "", EINVAL
 380  	}
 381  	// In some cases, Linux can return a path that starts with the
 382  	// "(unreachable)" prefix, which can potentially be a valid relative
 383  	// path. To work around that, return ENOENT if path is not absolute.
 384  	if buf[0] != '/' {
 385  		return "", ENOENT
 386  	}
 387  
 388  	return string(buf[0 : n-1]), nil
 389  }
 390  
 391  func Getgroups() (gids []int, err error) {
 392  	n, err := getgroups(0, nil)
 393  	if err != nil {
 394  		return nil, err
 395  	}
 396  	if n == 0 {
 397  		return nil, nil
 398  	}
 399  
 400  	// Sanity check group count. Max is 1<<16 on Linux.
 401  	if n < 0 || n > 1<<20 {
 402  		return nil, EINVAL
 403  	}
 404  
 405  	a := make([]_Gid_t, n)
 406  	n, err = getgroups(n, &a[0])
 407  	if err != nil {
 408  		return nil, err
 409  	}
 410  	gids = make([]int, n)
 411  	for i, v := range a[0:n] {
 412  		gids[i] = int(v)
 413  	}
 414  	return
 415  }
 416  
 417  var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.
 418  
 419  func Setgroups(gids []int) (err error) {
 420  	n := uintptr(len(gids))
 421  	if n == 0 {
 422  		if cgo_libc_setgroups == nil {
 423  			if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
 424  				err = errnoErr(e1)
 425  			}
 426  			return
 427  		}
 428  		if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
 429  			err = errnoErr(Errno(ret))
 430  		}
 431  		return
 432  	}
 433  
 434  	a := make([]_Gid_t, len(gids))
 435  	for i, v := range gids {
 436  		a[i] = _Gid_t(v)
 437  	}
 438  	if cgo_libc_setgroups == nil {
 439  		if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
 440  			err = errnoErr(e1)
 441  		}
 442  		return
 443  	}
 444  	if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
 445  		err = errnoErr(Errno(ret))
 446  	}
 447  	return
 448  }
 449  
 450  type WaitStatus uint32
 451  
 452  // Wait status is 7 bits at bottom, either 0 (exited),
 453  // 0x7F (stopped), or a signal number that caused an exit.
 454  // The 0x80 bit is whether there was a core dump.
 455  // An extra number (exit code, signal causing a stop)
 456  // is in the high bits. At least that's the idea.
 457  // There are various irregularities. For example, the
 458  // "continued" status is 0xFFFF, distinguishing itself
 459  // from stopped via the core dump bit.
 460  
 461  const (
 462  	mask    = 0x7F
 463  	core    = 0x80
 464  	exited  = 0x00
 465  	stopped = 0x7F
 466  	shift   = 8
 467  )
 468  
 469  func (w WaitStatus) Exited() bool { return w&mask == exited }
 470  
 471  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
 472  
 473  func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
 474  
 475  func (w WaitStatus) Continued() bool { return w == 0xFFFF }
 476  
 477  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
 478  
 479  func (w WaitStatus) ExitStatus() int {
 480  	if !w.Exited() {
 481  		return -1
 482  	}
 483  	return int(w>>shift) & 0xFF
 484  }
 485  
 486  func (w WaitStatus) Signal() Signal {
 487  	if !w.Signaled() {
 488  		return -1
 489  	}
 490  	return Signal(w & mask)
 491  }
 492  
 493  func (w WaitStatus) StopSignal() Signal {
 494  	if !w.Stopped() {
 495  		return -1
 496  	}
 497  	return Signal(w>>shift) & 0xFF
 498  }
 499  
 500  func (w WaitStatus) TrapCause() int {
 501  	if w.StopSignal() != SIGTRAP {
 502  		return -1
 503  	}
 504  	return int(w>>shift) >> 8
 505  }
 506  
 507  //sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
 508  
 509  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
 510  	var status _C_int
 511  	wpid, err = wait4(pid, &status, options, rusage)
 512  	if wstatus != nil {
 513  		*wstatus = WaitStatus(status)
 514  	}
 515  	return
 516  }
 517  
 518  func Mkfifo(path string, mode uint32) (err error) {
 519  	return Mknod(path, mode|S_IFIFO, 0)
 520  }
 521  
 522  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 523  	if sa.Port < 0 || sa.Port > 0xFFFF {
 524  		return nil, 0, EINVAL
 525  	}
 526  	sa.raw.Family = AF_INET
 527  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 528  	p[0] = byte(sa.Port >> 8)
 529  	p[1] = byte(sa.Port)
 530  	sa.raw.Addr = sa.Addr
 531  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
 532  }
 533  
 534  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
 535  	if sa.Port < 0 || sa.Port > 0xFFFF {
 536  		return nil, 0, EINVAL
 537  	}
 538  	sa.raw.Family = AF_INET6
 539  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 540  	p[0] = byte(sa.Port >> 8)
 541  	p[1] = byte(sa.Port)
 542  	sa.raw.Scope_id = sa.ZoneId
 543  	sa.raw.Addr = sa.Addr
 544  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
 545  }
 546  
 547  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
 548  	name := sa.Name
 549  	n := len(name)
 550  	if n > len(sa.raw.Path) {
 551  		return nil, 0, EINVAL
 552  	}
 553  	// Abstract addresses start with NUL.
 554  	// '@' is also a valid way to specify abstract addresses.
 555  	isAbstract := n > 0 && (name[0] == '@' || name[0] == '\x00')
 556  
 557  	// Non-abstract named addresses are NUL terminated.
 558  	// The length can't use the full capacity as we need to add NUL.
 559  	if n == len(sa.raw.Path) && !isAbstract {
 560  		return nil, 0, EINVAL
 561  	}
 562  	sa.raw.Family = AF_UNIX
 563  	for i := 0; i < n; i++ {
 564  		sa.raw.Path[i] = int8(name[i])
 565  	}
 566  	// Length is family + name (+ NUL if non-abstract).
 567  	// Family is of type uint16 (2 bytes).
 568  	sl := _Socklen(2 + n)
 569  	if isAbstract {
 570  		// Abstract addresses are not NUL terminated.
 571  		// We rewrite '@' prefix to NUL here.
 572  		sa.raw.Path[0] = 0
 573  	} else if n > 0 {
 574  		// Add NUL for non-abstract named addresses.
 575  		sl++
 576  	}
 577  
 578  	return unsafe.Pointer(&sa.raw), sl, nil
 579  }
 580  
 581  type SockaddrLinklayer struct {
 582  	Protocol uint16
 583  	Ifindex  int
 584  	Hatype   uint16
 585  	Pkttype  uint8
 586  	Halen    uint8
 587  	Addr     [8]byte
 588  	raw      RawSockaddrLinklayer
 589  }
 590  
 591  func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
 592  	if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
 593  		return nil, 0, EINVAL
 594  	}
 595  	sa.raw.Family = AF_PACKET
 596  	sa.raw.Protocol = sa.Protocol
 597  	sa.raw.Ifindex = int32(sa.Ifindex)
 598  	sa.raw.Hatype = sa.Hatype
 599  	sa.raw.Pkttype = sa.Pkttype
 600  	sa.raw.Halen = sa.Halen
 601  	sa.raw.Addr = sa.Addr
 602  	return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
 603  }
 604  
 605  type SockaddrNetlink struct {
 606  	Family uint16
 607  	Pad    uint16
 608  	Pid    uint32
 609  	Groups uint32
 610  	raw    RawSockaddrNetlink
 611  }
 612  
 613  func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
 614  	sa.raw.Family = AF_NETLINK
 615  	sa.raw.Pad = sa.Pad
 616  	sa.raw.Pid = sa.Pid
 617  	sa.raw.Groups = sa.Groups
 618  	return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
 619  }
 620  
 621  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
 622  	switch rsa.Addr.Family {
 623  	case AF_NETLINK:
 624  		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
 625  		sa := new(SockaddrNetlink)
 626  		sa.Family = pp.Family
 627  		sa.Pad = pp.Pad
 628  		sa.Pid = pp.Pid
 629  		sa.Groups = pp.Groups
 630  		return sa, nil
 631  
 632  	case AF_PACKET:
 633  		pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
 634  		sa := new(SockaddrLinklayer)
 635  		sa.Protocol = pp.Protocol
 636  		sa.Ifindex = int(pp.Ifindex)
 637  		sa.Hatype = pp.Hatype
 638  		sa.Pkttype = pp.Pkttype
 639  		sa.Halen = pp.Halen
 640  		sa.Addr = pp.Addr
 641  		return sa, nil
 642  
 643  	case AF_UNIX:
 644  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
 645  		sa := new(SockaddrUnix)
 646  		if pp.Path[0] == 0 {
 647  			// "Abstract" Unix domain socket.
 648  			// Rewrite leading NUL as @ for textual display.
 649  			// (This is the standard convention.)
 650  			// Not friendly to overwrite in place,
 651  			// but the callers below don't care.
 652  			pp.Path[0] = '@'
 653  		}
 654  
 655  		// Assume path ends at NUL.
 656  		// This is not technically the Linux semantics for
 657  		// abstract Unix domain sockets--they are supposed
 658  		// to be uninterpreted fixed-size binary blobs--but
 659  		// everyone uses this convention.
 660  		n := 0
 661  		for n < len(pp.Path) && pp.Path[n] != 0 {
 662  			n++
 663  		}
 664  		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
 665  		return sa, nil
 666  
 667  	case AF_INET:
 668  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
 669  		sa := new(SockaddrInet4)
 670  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 671  		sa.Port = int(p[0])<<8 + int(p[1])
 672  		sa.Addr = pp.Addr
 673  		return sa, nil
 674  
 675  	case AF_INET6:
 676  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
 677  		sa := new(SockaddrInet6)
 678  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 679  		sa.Port = int(p[0])<<8 + int(p[1])
 680  		sa.ZoneId = pp.Scope_id
 681  		sa.Addr = pp.Addr
 682  		return sa, nil
 683  	}
 684  	return nil, EAFNOSUPPORT
 685  }
 686  
 687  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
 688  	return Accept4(fd, 0)
 689  }
 690  
 691  func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
 692  	var rsa RawSockaddrAny
 693  	var len _Socklen = SizeofSockaddrAny
 694  	nfd, err = accept4(fd, &rsa, &len, flags)
 695  	if err != nil {
 696  		return
 697  	}
 698  	if len > SizeofSockaddrAny {
 699  		panic("RawSockaddrAny too small")
 700  	}
 701  	sa, err = anyToSockaddr(&rsa)
 702  	if err != nil {
 703  		Close(nfd)
 704  		nfd = 0
 705  	}
 706  	return
 707  }
 708  
 709  func Getsockname(fd int) (sa Sockaddr, err error) {
 710  	var rsa RawSockaddrAny
 711  	var len _Socklen = SizeofSockaddrAny
 712  	if err = getsockname(fd, &rsa, &len); err != nil {
 713  		return
 714  	}
 715  	return anyToSockaddr(&rsa)
 716  }
 717  
 718  func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
 719  	vallen := _Socklen(4)
 720  	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
 721  	return value, err
 722  }
 723  
 724  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
 725  	var value IPMreq
 726  	vallen := _Socklen(SizeofIPMreq)
 727  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 728  	return &value, err
 729  }
 730  
 731  func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
 732  	var value IPMreqn
 733  	vallen := _Socklen(SizeofIPMreqn)
 734  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 735  	return &value, err
 736  }
 737  
 738  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
 739  	var value IPv6Mreq
 740  	vallen := _Socklen(SizeofIPv6Mreq)
 741  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 742  	return &value, err
 743  }
 744  
 745  func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
 746  	var value IPv6MTUInfo
 747  	vallen := _Socklen(SizeofIPv6MTUInfo)
 748  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 749  	return &value, err
 750  }
 751  
 752  func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
 753  	var value ICMPv6Filter
 754  	vallen := _Socklen(SizeofICMPv6Filter)
 755  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 756  	return &value, err
 757  }
 758  
 759  func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
 760  	var value Ucred
 761  	vallen := _Socklen(SizeofUcred)
 762  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
 763  	return &value, err
 764  }
 765  
 766  func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
 767  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
 768  }
 769  
 770  func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
 771  	var msg Msghdr
 772  	msg.Name = (*byte)(unsafe.Pointer(rsa))
 773  	msg.Namelen = uint32(SizeofSockaddrAny)
 774  	var iov Iovec
 775  	if len(p) > 0 {
 776  		iov.Base = &p[0]
 777  		iov.SetLen(len(p))
 778  	}
 779  	var dummy byte
 780  	if len(oob) > 0 {
 781  		if len(p) == 0 {
 782  			var sockType int
 783  			sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
 784  			if err != nil {
 785  				return
 786  			}
 787  			// receive at least one normal byte
 788  			if sockType != SOCK_DGRAM {
 789  				iov.Base = &dummy
 790  				iov.SetLen(1)
 791  			}
 792  		}
 793  		msg.Control = &oob[0]
 794  		msg.SetControllen(len(oob))
 795  	}
 796  	msg.Iov = &iov
 797  	msg.Iovlen = 1
 798  	if n, err = recvmsg(fd, &msg, flags); err != nil {
 799  		return
 800  	}
 801  	oobn = int(msg.Controllen)
 802  	recvflags = int(msg.Flags)
 803  	return
 804  }
 805  
 806  func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 807  	var msg Msghdr
 808  	msg.Name = (*byte)(ptr)
 809  	msg.Namelen = uint32(salen)
 810  	var iov Iovec
 811  	if len(p) > 0 {
 812  		iov.Base = &p[0]
 813  		iov.SetLen(len(p))
 814  	}
 815  	var dummy byte
 816  	if len(oob) > 0 {
 817  		if len(p) == 0 {
 818  			var sockType int
 819  			sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
 820  			if err != nil {
 821  				return 0, err
 822  			}
 823  			// send at least one normal byte
 824  			if sockType != SOCK_DGRAM {
 825  				iov.Base = &dummy
 826  				iov.SetLen(1)
 827  			}
 828  		}
 829  		msg.Control = &oob[0]
 830  		msg.SetControllen(len(oob))
 831  	}
 832  	msg.Iov = &iov
 833  	msg.Iovlen = 1
 834  	if n, err = sendmsg(fd, &msg, flags); err != nil {
 835  		return 0, err
 836  	}
 837  	if len(oob) > 0 && len(p) == 0 {
 838  		n = 0
 839  	}
 840  	return n, nil
 841  }
 842  
 843  // BindToDevice binds the socket associated with fd to device.
 844  func BindToDevice(fd int, device string) (err error) {
 845  	return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
 846  }
 847  
 848  //sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
 849  //sys	ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE
 850  
 851  func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
 852  	// The peek requests are machine-size oriented, so we wrap it
 853  	// to retrieve arbitrary-length data.
 854  
 855  	// The ptrace syscall differs from glibc's ptrace.
 856  	// Peeks returns the word in *data, not as the return value.
 857  
 858  	var buf [sizeofPtr]byte
 859  
 860  	// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
 861  	// access (PEEKUSER warns that it might), but if we don't
 862  	// align our reads, we might straddle an unmapped page
 863  	// boundary and not get the bytes leading up to the page
 864  	// boundary.
 865  	n := 0
 866  	if addr%sizeofPtr != 0 {
 867  		err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
 868  		if err != nil {
 869  			return 0, err
 870  		}
 871  		n += copy(out, buf[addr%sizeofPtr:])
 872  		out = out[n:]
 873  	}
 874  
 875  	// Remainder.
 876  	for len(out) > 0 {
 877  		// We use an internal buffer to guarantee alignment.
 878  		// It's not documented if this is necessary, but we're paranoid.
 879  		err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
 880  		if err != nil {
 881  			return n, err
 882  		}
 883  		copied := copy(out, buf[0:])
 884  		n += copied
 885  		out = out[copied:]
 886  	}
 887  
 888  	return n, nil
 889  }
 890  
 891  func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
 892  	return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
 893  }
 894  
 895  func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
 896  	return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
 897  }
 898  
 899  func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
 900  	// As for ptracePeek, we need to align our accesses to deal
 901  	// with the possibility of straddling an invalid page.
 902  
 903  	// Leading edge.
 904  	n := 0
 905  	if addr%sizeofPtr != 0 {
 906  		var buf [sizeofPtr]byte
 907  		err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
 908  		if err != nil {
 909  			return 0, err
 910  		}
 911  		n += copy(buf[addr%sizeofPtr:], data)
 912  		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
 913  		err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
 914  		if err != nil {
 915  			return 0, err
 916  		}
 917  		data = data[n:]
 918  	}
 919  
 920  	// Interior.
 921  	for len(data) > sizeofPtr {
 922  		word := *((*uintptr)(unsafe.Pointer(&data[0])))
 923  		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
 924  		if err != nil {
 925  			return n, err
 926  		}
 927  		n += sizeofPtr
 928  		data = data[sizeofPtr:]
 929  	}
 930  
 931  	// Trailing edge.
 932  	if len(data) > 0 {
 933  		var buf [sizeofPtr]byte
 934  		err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
 935  		if err != nil {
 936  			return n, err
 937  		}
 938  		copy(buf[0:], data)
 939  		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
 940  		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
 941  		if err != nil {
 942  			return n, err
 943  		}
 944  		n += len(data)
 945  	}
 946  
 947  	return n, nil
 948  }
 949  
 950  func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
 951  	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
 952  }
 953  
 954  func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
 955  	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
 956  }
 957  
 958  const (
 959  	_NT_PRSTATUS = 1
 960  )
 961  
 962  func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
 963  	var iov Iovec
 964  	iov.Base = (*byte)(unsafe.Pointer(regsout))
 965  	iov.SetLen(int(unsafe.Sizeof(*regsout)))
 966  	return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
 967  }
 968  
 969  func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
 970  	var iov Iovec
 971  	iov.Base = (*byte)(unsafe.Pointer(regs))
 972  	iov.SetLen(int(unsafe.Sizeof(*regs)))
 973  	return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
 974  }
 975  
 976  func PtraceSetOptions(pid int, options int) (err error) {
 977  	return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
 978  }
 979  
 980  func PtraceGetEventMsg(pid int) (msg uint, err error) {
 981  	var data _C_long
 982  	err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
 983  	msg = uint(data)
 984  	return
 985  }
 986  
 987  func PtraceCont(pid int, signal int) (err error) {
 988  	return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
 989  }
 990  
 991  func PtraceSyscall(pid int, signal int) (err error) {
 992  	return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
 993  }
 994  
 995  func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
 996  
 997  func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
 998  
 999  func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1000  
1001  //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
1002  
1003  func Reboot(cmd int) (err error) {
1004  	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1005  }
1006  
1007  func ReadDirent(fd int, buf []byte) (n int, err error) {
1008  	return Getdents(fd, buf)
1009  }
1010  
1011  func direntIno(buf []byte) (uint64, bool) {
1012  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1013  }
1014  
1015  func direntReclen(buf []byte) (uint64, bool) {
1016  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1017  }
1018  
1019  func direntNamlen(buf []byte) (uint64, bool) {
1020  	reclen, ok := direntReclen(buf)
1021  	if !ok {
1022  		return 0, false
1023  	}
1024  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1025  }
1026  
1027  //sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
1028  
1029  func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1030  	// Certain file systems get rather angry and EINVAL if you give
1031  	// them an empty string of data, rather than NULL.
1032  	if data == "" {
1033  		return mount(source, target, fstype, flags, nil)
1034  	}
1035  	datap, err := BytePtrFromString(data)
1036  	if err != nil {
1037  		return err
1038  	}
1039  	return mount(source, target, fstype, flags, datap)
1040  }
1041  
1042  // Sendto
1043  // Recvfrom
1044  // Socketpair
1045  
1046  /*
1047   * Direct access
1048   */
1049  //sys	Acct(path string) (err error)
1050  //sys	Adjtimex(buf *Timex) (state int, err error)
1051  //sys	Chdir(path string) (err error)
1052  //sys	Chroot(path string) (err error)
1053  //sys	Close(fd int) (err error)
1054  //sys	Dup(oldfd int) (fd int, err error)
1055  //sys	Dup3(oldfd int, newfd int, flags int) (err error)
1056  //sysnb	EpollCreate1(flag int) (fd int, err error)
1057  //sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
1058  //sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
1059  //sys	Fchdir(fd int) (err error)
1060  //sys	Fchmod(fd int, mode uint32) (err error)
1061  //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
1062  //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
1063  //sys	Fdatasync(fd int) (err error)
1064  //sys	Flock(fd int, how int) (err error)
1065  //sys	Fsync(fd int) (err error)
1066  //sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
1067  //sysnb	Getpgid(pid int) (pgid int, err error)
1068  
1069  func Getpgrp() (pid int) {
1070  	pid, _ = Getpgid(0)
1071  	return
1072  }
1073  
1074  //sysnb	Getpid() (pid int)
1075  //sysnb	Getppid() (ppid int)
1076  //sys	Getpriority(which int, who int) (prio int, err error)
1077  //sysnb	Getrusage(who int, rusage *Rusage) (err error)
1078  //sysnb	Gettid() (tid int)
1079  //sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
1080  //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
1081  //sysnb	InotifyInit1(flags int) (fd int, err error)
1082  //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
1083  //sysnb	Kill(pid int, sig Signal) (err error)
1084  //sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
1085  //sys	Listxattr(path string, dest []byte) (sz int, err error)
1086  //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
1087  //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
1088  //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
1089  //sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
1090  //sysnb prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
1091  //sys	read(fd int, p []byte) (n int, err error)
1092  //sys	Removexattr(path string, attr string) (err error)
1093  //sys	Setdomainname(p []byte) (err error)
1094  //sys	Sethostname(p []byte) (err error)
1095  //sysnb	Setpgid(pid int, pgid int) (err error)
1096  //sysnb	Setsid() (pid int, err error)
1097  //sysnb	Settimeofday(tv *Timeval) (err error)
1098  
1099  // Provided by runtime.syscall_runtime_doAllThreadsSyscall which stops the
1100  // world and invokes the syscall on each OS thread. Once this function returns,
1101  // all threads are in sync.
1102  //
1103  //go:uintptrescapes
1104  func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1105  
1106  // AllThreadsSyscall performs a syscall on each OS thread of the Go
1107  // runtime. It first invokes the syscall on one thread. Should that
1108  // invocation fail, it returns immediately with the error status.
1109  // Otherwise, it invokes the syscall on all of the remaining threads
1110  // in parallel. It will terminate the program if it observes any
1111  // invoked syscall's return value differs from that of the first
1112  // invocation.
1113  //
1114  // AllThreadsSyscall is intended for emulating simultaneous
1115  // process-wide state changes that require consistently modifying
1116  // per-thread state of the Go runtime.
1117  //
1118  // AllThreadsSyscall is unaware of any threads that are launched
1119  // explicitly by cgo linked code, so the function always returns
1120  // [ENOTSUP] in binaries that use cgo.
1121  //
1122  //go:uintptrescapes
1123  func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1124  	if cgo_libc_setegid != nil {
1125  		return minus1, minus1, ENOTSUP
1126  	}
1127  	r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1128  	return r1, r2, Errno(errno)
1129  }
1130  
1131  // AllThreadsSyscall6 is like [AllThreadsSyscall], but extended to six
1132  // arguments.
1133  //
1134  //go:uintptrescapes
1135  func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1136  	if cgo_libc_setegid != nil {
1137  		return minus1, minus1, ENOTSUP
1138  	}
1139  	r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1140  	return r1, r2, Errno(errno)
1141  }
1142  
1143  // linked by runtime.cgocall.go
1144  //
1145  //go:uintptrescapes
1146  func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1147  
1148  var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.
1149  
1150  const minus1 = ^uintptr(0)
1151  
1152  func Setegid(egid int) (err error) {
1153  	if cgo_libc_setegid == nil {
1154  		if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1155  			err = errnoErr(e1)
1156  		}
1157  	} else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1158  		err = errnoErr(Errno(ret))
1159  	}
1160  	return
1161  }
1162  
1163  var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.
1164  
1165  func Seteuid(euid int) (err error) {
1166  	if cgo_libc_seteuid == nil {
1167  		if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1168  			err = errnoErr(e1)
1169  		}
1170  	} else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1171  		err = errnoErr(Errno(ret))
1172  	}
1173  	return
1174  }
1175  
1176  var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.
1177  
1178  func Setgid(gid int) (err error) {
1179  	if cgo_libc_setgid == nil {
1180  		if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1181  			err = errnoErr(e1)
1182  		}
1183  	} else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1184  		err = errnoErr(Errno(ret))
1185  	}
1186  	return
1187  }
1188  
1189  var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.
1190  
1191  func Setregid(rgid, egid int) (err error) {
1192  	if cgo_libc_setregid == nil {
1193  		if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1194  			err = errnoErr(e1)
1195  		}
1196  	} else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1197  		err = errnoErr(Errno(ret))
1198  	}
1199  	return
1200  }
1201  
1202  var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.
1203  
1204  func Setresgid(rgid, egid, sgid int) (err error) {
1205  	if cgo_libc_setresgid == nil {
1206  		if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1207  			err = errnoErr(e1)
1208  		}
1209  	} else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1210  		err = errnoErr(Errno(ret))
1211  	}
1212  	return
1213  }
1214  
1215  var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.
1216  
1217  func Setresuid(ruid, euid, suid int) (err error) {
1218  	if cgo_libc_setresuid == nil {
1219  		if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1220  			err = errnoErr(e1)
1221  		}
1222  	} else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1223  		err = errnoErr(Errno(ret))
1224  	}
1225  	return
1226  }
1227  
1228  var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.
1229  
1230  func Setreuid(ruid, euid int) (err error) {
1231  	if cgo_libc_setreuid == nil {
1232  		if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1233  			err = errnoErr(e1)
1234  		}
1235  	} else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1236  		err = errnoErr(Errno(ret))
1237  	}
1238  	return
1239  }
1240  
1241  var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.
1242  
1243  func Setuid(uid int) (err error) {
1244  	if cgo_libc_setuid == nil {
1245  		if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1246  			err = errnoErr(e1)
1247  		}
1248  	} else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1249  		err = errnoErr(Errno(ret))
1250  	}
1251  	return
1252  }
1253  
1254  //sys	Setpriority(which int, who int, prio int) (err error)
1255  //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
1256  //sys	Sync()
1257  //sysnb	Sysinfo(info *Sysinfo_t) (err error)
1258  //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
1259  //sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
1260  //sysnb	Times(tms *Tms) (ticks uintptr, err error)
1261  //sysnb	Umask(mask int) (oldmask int)
1262  //sysnb	Uname(buf *Utsname) (err error)
1263  //sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
1264  //sys	Unshare(flags int) (err error)
1265  //sys	write(fd int, p []byte) (n int, err error)
1266  //sys	exitThread(code int) (err error) = SYS_EXIT
1267  //sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
1268  
1269  // mmap varies by architecture; see syscall_linux_*.go.
1270  //sys	munmap(addr uintptr, length uintptr) (err error)
1271  
1272  var mapper = &mmapper{
1273  	active: make(map[*byte][]byte),
1274  	mmap:   mmap,
1275  	munmap: munmap,
1276  }
1277  
1278  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1279  	return mapper.Mmap(fd, offset, length, prot, flags)
1280  }
1281  
1282  func Munmap(b []byte) (err error) {
1283  	return mapper.Munmap(b)
1284  }
1285  
1286  //sys	Madvise(b []byte, advice int) (err error)
1287  //sys	Mprotect(b []byte, prot int) (err error)
1288  //sys	Mlock(b []byte) (err error)
1289  //sys	Munlock(b []byte) (err error)
1290  //sys	Mlockall(flags int) (err error)
1291  //sys	Munlockall() (err error)
1292  
1293  func Getrlimit(resource int, rlim *Rlimit) (err error) {
1294  	// prlimit1 is the same as prlimit when newlimit == nil
1295  	return prlimit1(0, resource, nil, rlim)
1296  }
1297  
1298  // setrlimit sets a resource limit.
1299  // The Setrlimit function is in rlimit.go, and calls this one.
1300  func setrlimit(resource int, rlim *Rlimit) (err error) {
1301  	return prlimit1(0, resource, rlim, nil)
1302  }
1303  
1304  // prlimit changes a resource limit. We use a single definition so that
1305  // we can tell StartProcess to not restore the original NOFILE limit.
1306  //
1307  // golang.org/x/sys linknames prlimit.
1308  // Do not remove or change the type signature.
1309  //
1310  //go:linkname prlimit
1311  func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1312  	err = prlimit1(pid, resource, newlimit, old)
1313  	if err == nil && newlimit != nil && resource == RLIMIT_NOFILE && (pid == 0 || pid == Getpid()) {
1314  		origRlimitNofile.Store(nil)
1315  	}
1316  	return err
1317  }
1318