// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Linux system calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates system call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.

package syscall

import 

func rawSyscallNoError(, , ,  uintptr) (,  uintptr)

/*
 * Wrapped
 */

func ( string,  uint32) ( error) {
	return Faccessat(_AT_FDCWD, , , 0)
}

func ( string,  uint32) ( error) {
	return Fchmodat(_AT_FDCWD, , , 0)
}

func ( string,  int,  int) ( error) {
	return Fchownat(_AT_FDCWD, , , , 0)
}

func ( string,  uint32) ( int,  error) {
	return Open(, O_CREAT|O_WRONLY|O_TRUNC, )
}

func isGroupMember( int) bool {
	,  := Getgroups()
	if  != nil {
		return false
	}

	for ,  := range  {
		if  ==  {
			return true
		}
	}
	return false
}

//sys	faccessat(dirfd int, path string, mode uint32) (err error)

func ( int,  string,  uint32,  int) ( error) {
	if  & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
		return EINVAL
	}

	// The Linux kernel faccessat system call does not take any flags.
	// The glibc faccessat implements the flags itself; see
	// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
	// Because people naturally expect syscall.Faccessat to act
	// like C faccessat, we do the same.

	if  == 0 {
		return faccessat(, , )
	}

	var  Stat_t
	if  := fstatat(, , &, &_AT_SYMLINK_NOFOLLOW);  != nil {
		return 
	}

	 &= 7
	if  == 0 {
		return nil
	}

	var  int
	if &_AT_EACCESS != 0 {
		 = Geteuid()
	} else {
		 = Getuid()
	}

	if  == 0 {
		if &1 == 0 {
			// Root can read and write any file.
			return nil
		}
		if .Mode&0111 != 0 {
			// Root can execute any file that anybody can execute.
			return nil
		}
		return EACCES
	}

	var  uint32
	if uint32() == .Uid {
		 = (.Mode >> 6) & 7
	} else {
		var  int
		if &_AT_EACCESS != 0 {
			 = Getegid()
		} else {
			 = Getgid()
		}

		if uint32() == .Gid || isGroupMember() {
			 = (.Mode >> 3) & 7
		} else {
			 = .Mode & 7
		}
	}

	if & ==  {
		return nil
	}

	return EACCES
}

//sys	fchmodat(dirfd int, path string, mode uint32) (err error)

func ( int,  string,  uint32,  int) ( error) {
	// Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
	// and check the flags. Otherwise the mode would be applied to the symlink
	// destination which is not what the user expects.
	if &^_AT_SYMLINK_NOFOLLOW != 0 {
		return EINVAL
	} else if &_AT_SYMLINK_NOFOLLOW != 0 {
		return EOPNOTSUPP
	}
	return fchmodat(, , )
}

//sys	linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)

func ( string,  string) ( error) {
	return linkat(_AT_FDCWD, , _AT_FDCWD, , 0)
}

func ( string,  uint32) ( error) {
	return Mkdirat(_AT_FDCWD, , )
}

func ( string,  uint32,  int) ( error) {
	return Mknodat(_AT_FDCWD, , , )
}

func ( string,  int,  uint32) ( int,  error) {
	return openat(_AT_FDCWD, , |O_LARGEFILE, )
}

//sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)

func ( int,  string,  int,  uint32) ( int,  error) {
	return openat(, , |O_LARGEFILE, )
}

//sys	readlinkat(dirfd int, path string, buf []byte) (n int, err error)

func ( string,  []byte) ( int,  error) {
	return readlinkat(_AT_FDCWD, , )
}

func ( string,  string) ( error) {
	return Renameat(_AT_FDCWD, , _AT_FDCWD, )
}

func ( string) error {
	return unlinkat(_AT_FDCWD, , _AT_REMOVEDIR)
}

//sys	symlinkat(oldpath string, newdirfd int, newpath string) (err error)

func ( string,  string) ( error) {
	return symlinkat(, _AT_FDCWD, )
}

func ( string) error {
	return unlinkat(_AT_FDCWD, , 0)
}

//sys	unlinkat(dirfd int, path string, flags int) (err error)

func ( int,  string) error {
	return unlinkat(, , 0)
}

func ( string,  []Timeval) ( error) {
	if len() != 2 {
		return EINVAL
	}
	return utimes(, (*[2]Timeval)(unsafe.Pointer(&[0])))
}

//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)

func ( string,  []Timespec) ( error) {
	if len() != 2 {
		return EINVAL
	}
	 = utimensat(_AT_FDCWD, , (*[2]Timespec)(unsafe.Pointer(&[0])), 0)
	if  != ENOSYS {
		return 
	}
	// If the utimensat syscall isn't available (utimensat was added to Linux
	// in 2.6.22, Released, 8 July 2007) then fall back to utimes
	var  [2]Timeval
	for  := 0;  < 2; ++ {
		[].Sec = [].Sec
		[].Usec = [].Nsec / 1000
	}
	return utimes(, (*[2]Timeval)(unsafe.Pointer(&[0])))
}

func ( int,  string,  []Timeval) ( error) {
	if len() != 2 {
		return EINVAL
	}
	return futimesat(, , (*[2]Timeval)(unsafe.Pointer(&[0])))
}

func ( int,  []Timeval) ( error) {
	// Believe it or not, this is the best we can do on Linux
	// (and is what glibc does).
	return Utimes("/proc/self/fd/"+itoa(), )
}

const ImplementsGetwd = true

//sys	Getcwd(buf []byte) (n int, err error)

func () ( string,  error) {
	var  [PathMax]byte
	,  := Getcwd([0:])
	if  != nil {
		return "", 
	}
	// Getcwd returns the number of bytes written to buf, including the NUL.
	if  < 1 ||  > len() || [-1] != 0 {
		return "", EINVAL
	}
	return string([0 : -1]), nil
}

func () ( []int,  error) {
	,  := getgroups(0, nil)
	if  != nil {
		return nil, 
	}
	if  == 0 {
		return nil, nil
	}

	// Sanity check group count. Max is 1<<16 on Linux.
	if  < 0 ||  > 1<<20 {
		return nil, EINVAL
	}

	 := make([]_Gid_t, )
	,  = getgroups(, &[0])
	if  != nil {
		return nil, 
	}
	 = make([]int, )
	for ,  := range [0:] {
		[] = int()
	}
	return
}

var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.

func ( []int) ( error) {
	 := uintptr(len())
	if  == 0 {
		if cgo_libc_setgroups == nil {
			if , ,  := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0);  != 0 {
				 = errnoErr()
			}
			return
		}
		if  := cgocaller(cgo_libc_setgroups, 0, 0);  != 0 {
			 = errnoErr(Errno())
		}
		return
	}

	 := make([]_Gid_t, len())
	for ,  := range  {
		[] = _Gid_t()
	}
	if cgo_libc_setgroups == nil {
		if , ,  := AllThreadsSyscall(_SYS_setgroups, , uintptr(unsafe.Pointer(&[0])), 0);  != 0 {
			 = errnoErr()
		}
		return
	}
	if  := cgocaller(cgo_libc_setgroups, , uintptr(unsafe.Pointer(&[0])));  != 0 {
		 = errnoErr(Errno())
	}
	return
}

type WaitStatus uint32

// Wait status is 7 bits at bottom, either 0 (exited),
// 0x7F (stopped), or a signal number that caused an exit.
// The 0x80 bit is whether there was a core dump.
// An extra number (exit code, signal causing a stop)
// is in the high bits. At least that's the idea.
// There are various irregularities. For example, the
// "continued" status is 0xFFFF, distinguishing itself
// from stopped via the core dump bit.

const (
	mask    = 0x7F
	core    = 0x80
	exited  = 0x00
	stopped = 0x7F
	shift   = 8
)

func ( WaitStatus) () bool { return &mask == exited }

func ( WaitStatus) () bool { return &mask != stopped && &mask != exited }

func ( WaitStatus) () bool { return &0xFF == stopped }

func ( WaitStatus) () bool { return  == 0xFFFF }

func ( WaitStatus) () bool { return .Signaled() && &core != 0 }

func ( WaitStatus) () int {
	if !.Exited() {
		return -1
	}
	return int(>>shift) & 0xFF
}

func ( WaitStatus) () Signal {
	if !.Signaled() {
		return -1
	}
	return Signal( & mask)
}

func ( WaitStatus) () Signal {
	if !.Stopped() {
		return -1
	}
	return Signal(>>shift) & 0xFF
}

func ( WaitStatus) () int {
	if .StopSignal() != SIGTRAP {
		return -1
	}
	return int(>>shift) >> 8
}

//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)

func ( int,  *WaitStatus,  int,  *Rusage) ( int,  error) {
	var  _C_int
	,  = wait4(, &, , )
	if  != nil {
		* = WaitStatus()
	}
	return
}

func ( string,  uint32) ( error) {
	return Mknod(, |S_IFIFO, 0)
}

func ( *SockaddrInet4) () (unsafe.Pointer, _Socklen, error) {
	if .Port < 0 || .Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_INET
	 := (*[2]byte)(unsafe.Pointer(&.raw.Port))
	[0] = byte(.Port >> 8)
	[1] = byte(.Port)
	for  := 0;  < len(.Addr); ++ {
		.raw.Addr[] = .Addr[]
	}
	return unsafe.Pointer(&.raw), SizeofSockaddrInet4, nil
}

func ( *SockaddrInet6) () (unsafe.Pointer, _Socklen, error) {
	if .Port < 0 || .Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_INET6
	 := (*[2]byte)(unsafe.Pointer(&.raw.Port))
	[0] = byte(.Port >> 8)
	[1] = byte(.Port)
	.raw.Scope_id = .ZoneId
	for  := 0;  < len(.Addr); ++ {
		.raw.Addr[] = .Addr[]
	}
	return unsafe.Pointer(&.raw), SizeofSockaddrInet6, nil
}

func ( *SockaddrUnix) () (unsafe.Pointer, _Socklen, error) {
	 := .Name
	 := len()
	if  > len(.raw.Path) {
		return nil, 0, EINVAL
	}
	if  == len(.raw.Path) && [0] != '@' {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_UNIX
	for  := 0;  < ; ++ {
		.raw.Path[] = int8([])
	}
	// length is family (uint16), name, NUL.
	 := _Socklen(2)
	if  > 0 {
		 += _Socklen() + 1
	}
	if .raw.Path[0] == '@' {
		.raw.Path[0] = 0
		// Don't count trailing NUL for abstract address.
		--
	}

	return unsafe.Pointer(&.raw), , nil
}

type SockaddrLinklayer struct {
	Protocol uint16
	Ifindex  int
	Hatype   uint16
	Pkttype  uint8
	Halen    uint8
	Addr     [8]byte
	raw      RawSockaddrLinklayer
}

func ( *SockaddrLinklayer) () (unsafe.Pointer, _Socklen, error) {
	if .Ifindex < 0 || .Ifindex > 0x7fffffff {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_PACKET
	.raw.Protocol = .Protocol
	.raw.Ifindex = int32(.Ifindex)
	.raw.Hatype = .Hatype
	.raw.Pkttype = .Pkttype
	.raw.Halen = .Halen
	for  := 0;  < len(.Addr); ++ {
		.raw.Addr[] = .Addr[]
	}
	return unsafe.Pointer(&.raw), SizeofSockaddrLinklayer, nil
}

type SockaddrNetlink struct {
	Family uint16
	Pad    uint16
	Pid    uint32
	Groups uint32
	raw    RawSockaddrNetlink
}

func ( *SockaddrNetlink) () (unsafe.Pointer, _Socklen, error) {
	.raw.Family = AF_NETLINK
	.raw.Pad = .Pad
	.raw.Pid = .Pid
	.raw.Groups = .Groups
	return unsafe.Pointer(&.raw), SizeofSockaddrNetlink, nil
}

func anyToSockaddr( *RawSockaddrAny) (Sockaddr, error) {
	switch .Addr.Family {
	case AF_NETLINK:
		 := (*RawSockaddrNetlink)(unsafe.Pointer())
		 := new(SockaddrNetlink)
		.Family = .Family
		.Pad = .Pad
		.Pid = .Pid
		.Groups = .Groups
		return , nil

	case AF_PACKET:
		 := (*RawSockaddrLinklayer)(unsafe.Pointer())
		 := new(SockaddrLinklayer)
		.Protocol = .Protocol
		.Ifindex = int(.Ifindex)
		.Hatype = .Hatype
		.Pkttype = .Pkttype
		.Halen = .Halen
		for  := 0;  < len(.Addr); ++ {
			.Addr[] = .Addr[]
		}
		return , nil

	case AF_UNIX:
		 := (*RawSockaddrUnix)(unsafe.Pointer())
		 := new(SockaddrUnix)
		if .Path[0] == 0 {
			// "Abstract" Unix domain socket.
			// Rewrite leading NUL as @ for textual display.
			// (This is the standard convention.)
			// Not friendly to overwrite in place,
			// but the callers below don't care.
			.Path[0] = '@'
		}

		// Assume path ends at NUL.
		// This is not technically the Linux semantics for
		// abstract Unix domain sockets--they are supposed
		// to be uninterpreted fixed-size binary blobs--but
		// everyone uses this convention.
		 := 0
		for  < len(.Path) && .Path[] != 0 {
			++
		}
		 := (*[len(.Path)]byte)(unsafe.Pointer(&.Path[0]))[0:]
		.Name = string()
		return , nil

	case AF_INET:
		 := (*RawSockaddrInet4)(unsafe.Pointer())
		 := new(SockaddrInet4)
		 := (*[2]byte)(unsafe.Pointer(&.Port))
		.Port = int([0])<<8 + int([1])
		for  := 0;  < len(.Addr); ++ {
			.Addr[] = .Addr[]
		}
		return , nil

	case AF_INET6:
		 := (*RawSockaddrInet6)(unsafe.Pointer())
		 := new(SockaddrInet6)
		 := (*[2]byte)(unsafe.Pointer(&.Port))
		.Port = int([0])<<8 + int([1])
		.ZoneId = .Scope_id
		for  := 0;  < len(.Addr); ++ {
			.Addr[] = .Addr[]
		}
		return , nil
	}
	return nil, EAFNOSUPPORT
}

func ( int) ( int,  Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	,  = accept(, &, &)
	if  != nil {
		return
	}
	,  = anyToSockaddr(&)
	if  != nil {
		Close()
		 = 0
	}
	return
}

func ( int,  int) ( int,  Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	,  = accept4(, &, &, )
	if  != nil {
		return
	}
	if  > SizeofSockaddrAny {
		panic("RawSockaddrAny too small")
	}
	,  = anyToSockaddr(&)
	if  != nil {
		Close()
		 = 0
	}
	return
}

func ( int) ( Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if  = getsockname(, &, &);  != nil {
		return
	}
	return anyToSockaddr(&)
}

func (, ,  int) ( [4]byte,  error) {
	 := _Socklen(4)
	 = getsockopt(, , , unsafe.Pointer(&[0]), &)
	return , 
}

func (, ,  int) (*IPMreq, error) {
	var  IPMreq
	 := _Socklen(SizeofIPMreq)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPMreqn, error) {
	var  IPMreqn
	 := _Socklen(SizeofIPMreqn)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPv6Mreq, error) {
	var  IPv6Mreq
	 := _Socklen(SizeofIPv6Mreq)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPv6MTUInfo, error) {
	var  IPv6MTUInfo
	 := _Socklen(SizeofIPv6MTUInfo)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*ICMPv6Filter, error) {
	var  ICMPv6Filter
	 := _Socklen(SizeofICMPv6Filter)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*Ucred, error) {
	var  Ucred
	 := _Socklen(SizeofUcred)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int,  *IPMreqn) ( error) {
	return setsockopt(, , , unsafe.Pointer(), unsafe.Sizeof(*))
}

func ( int, ,  []byte,  int) (,  int,  int,  Sockaddr,  error) {
	var  Msghdr
	var  RawSockaddrAny
	.Name = (*byte)(unsafe.Pointer(&))
	.Namelen = uint32(SizeofSockaddrAny)
	var  Iovec
	if len() > 0 {
		.Base = &[0]
		.SetLen(len())
	}
	var  byte
	if len() > 0 {
		if len() == 0 {
			var  int
			,  = GetsockoptInt(, SOL_SOCKET, SO_TYPE)
			if  != nil {
				return
			}
			// receive at least one normal byte
			if  != SOCK_DGRAM {
				.Base = &
				.SetLen(1)
			}
		}
		.Control = &[0]
		.SetControllen(len())
	}
	.Iov = &
	.Iovlen = 1
	if ,  = recvmsg(, &, );  != nil {
		return
	}
	 = int(.Controllen)
	 = int(.Flags)
	// source address is only specified if the socket is unconnected
	if .Addr.Family != AF_UNSPEC {
		,  = anyToSockaddr(&)
	}
	return
}

func ( int, ,  []byte,  Sockaddr,  int) ( error) {
	_,  = SendmsgN(, , , , )
	return
}

func ( int, ,  []byte,  Sockaddr,  int) ( int,  error) {
	var  unsafe.Pointer
	var  _Socklen
	if  != nil {
		var  error
		, ,  = .sockaddr()
		if  != nil {
			return 0, 
		}
	}
	var  Msghdr
	.Name = (*byte)()
	.Namelen = uint32()
	var  Iovec
	if len() > 0 {
		.Base = &[0]
		.SetLen(len())
	}
	var  byte
	if len() > 0 {
		if len() == 0 {
			var  int
			,  = GetsockoptInt(, SOL_SOCKET, SO_TYPE)
			if  != nil {
				return 0, 
			}
			// send at least one normal byte
			if  != SOCK_DGRAM {
				.Base = &
				.SetLen(1)
			}
		}
		.Control = &[0]
		.SetControllen(len())
	}
	.Iov = &
	.Iovlen = 1
	if ,  = sendmsg(, &, );  != nil {
		return 0, 
	}
	if len() > 0 && len() == 0 {
		 = 0
	}
	return , nil
}

// BindToDevice binds the socket associated with fd to device.
func ( int,  string) ( error) {
	return SetsockoptString(, SOL_SOCKET, SO_BINDTODEVICE, )
}

//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)

func ptracePeek( int,  int,  uintptr,  []byte) ( int,  error) {
	// The peek requests are machine-size oriented, so we wrap it
	// to retrieve arbitrary-length data.

	// The ptrace syscall differs from glibc's ptrace.
	// Peeks returns the word in *data, not as the return value.

	var  [sizeofPtr]byte

	// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
	// access (PEEKUSER warns that it might), but if we don't
	// align our reads, we might straddle an unmapped page
	// boundary and not get the bytes leading up to the page
	// boundary.
	 := 0
	if %sizeofPtr != 0 {
		 = ptrace(, , -%sizeofPtr, uintptr(unsafe.Pointer(&[0])))
		if  != nil {
			return 0, 
		}
		 += copy(, [%sizeofPtr:])
		 = [:]
	}

	// Remainder.
	for len() > 0 {
		// We use an internal buffer to guarantee alignment.
		// It's not documented if this is necessary, but we're paranoid.
		 = ptrace(, , +uintptr(), uintptr(unsafe.Pointer(&[0])))
		if  != nil {
			return , 
		}
		 := copy(, [0:])
		 += 
		 = [:]
	}

	return , nil
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePeek(PTRACE_PEEKTEXT, , , )
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePeek(PTRACE_PEEKDATA, , , )
}

func ptracePoke( int,  int,  int,  uintptr,  []byte) ( int,  error) {
	// As for ptracePeek, we need to align our accesses to deal
	// with the possibility of straddling an invalid page.

	// Leading edge.
	 := 0
	if %sizeofPtr != 0 {
		var  [sizeofPtr]byte
		 = ptrace(, , -%sizeofPtr, uintptr(unsafe.Pointer(&[0])))
		if  != nil {
			return 0, 
		}
		 += copy([%sizeofPtr:], )
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , -%sizeofPtr, )
		if  != nil {
			return 0, 
		}
		 = [:]
	}

	// Interior.
	for len() > sizeofPtr {
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , +uintptr(), )
		if  != nil {
			return , 
		}
		 += sizeofPtr
		 = [sizeofPtr:]
	}

	// Trailing edge.
	if len() > 0 {
		var  [sizeofPtr]byte
		 = ptrace(, , +uintptr(), uintptr(unsafe.Pointer(&[0])))
		if  != nil {
			return , 
		}
		copy([0:], )
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , +uintptr(), )
		if  != nil {
			return , 
		}
		 += len()
	}

	return , nil
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, , , )
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, , , )
}

func ( int,  *PtraceRegs) ( error) {
	return ptrace(PTRACE_GETREGS, , 0, uintptr(unsafe.Pointer()))
}

func ( int,  *PtraceRegs) ( error) {
	return ptrace(PTRACE_SETREGS, , 0, uintptr(unsafe.Pointer()))
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_SETOPTIONS, , 0, uintptr())
}

func ( int) ( uint,  error) {
	var  _C_long
	 = ptrace(PTRACE_GETEVENTMSG, , 0, uintptr(unsafe.Pointer(&)))
	 = uint()
	return
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_CONT, , 0, uintptr())
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_SYSCALL, , 0, uintptr())
}

func ( int) ( error) { return ptrace(PTRACE_SINGLESTEP, , 0, 0) }

func ( int) ( error) { return ptrace(PTRACE_ATTACH, , 0, 0) }

func ( int) ( error) { return ptrace(PTRACE_DETACH, , 0, 0) }

//sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)

func ( int) ( error) {
	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, , "")
}

func ( int,  []byte) ( int,  error) {
	return Getdents(, )
}

func direntIno( []byte) (uint64, bool) {
	return readInt(, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}

func direntReclen( []byte) (uint64, bool) {
	return readInt(, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}

func direntNamlen( []byte) (uint64, bool) {
	,  := direntReclen()
	if ! {
		return 0, false
	}
	return  - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}

//sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)

func ( string,  string,  string,  uintptr,  string) ( error) {
	// Certain file systems get rather angry and EINVAL if you give
	// them an empty string of data, rather than NULL.
	if  == "" {
		return mount(, , , , nil)
	}
	,  := BytePtrFromString()
	if  != nil {
		return 
	}
	return mount(, , , , )
}

// Sendto
// Recvfrom
// Socketpair

/*
 * Direct access
 */
//sys	Acct(path string) (err error)
//sys	Adjtimex(buf *Timex) (state int, err error)
//sys	Chdir(path string) (err error)
//sys	Chroot(path string) (err error)
//sys	Close(fd int) (err error)
//sys	Dup(oldfd int) (fd int, err error)
//sys	Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb	EpollCreate1(flag int) (fd int, err error)
//sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//sys	Fchdir(fd int) (err error)
//sys	Fchmod(fd int, mode uint32) (err error)
//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
//sys	Fdatasync(fd int) (err error)
//sys	Flock(fd int, how int) (err error)
//sys	Fsync(fd int) (err error)
//sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb	Getpgid(pid int) (pgid int, err error)

func () ( int) {
	, _ = Getpgid(0)
	return
}

//sysnb	Getpid() (pid int)
//sysnb	Getppid() (ppid int)
//sys	Getpriority(which int, who int) (prio int, err error)
//sysnb	Getrusage(who int, rusage *Rusage) (err error)
//sysnb	Gettid() (tid int)
//sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
//sysnb	InotifyInit1(flags int) (fd int, err error)
//sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
//sysnb	Kill(pid int, sig Signal) (err error)
//sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
//sys	Listxattr(path string, dest []byte) (sz int, err error)
//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys	read(fd int, p []byte) (n int, err error)
//sys	Removexattr(path string, attr string) (err error)
//sys	Setdomainname(p []byte) (err error)
//sys	Sethostname(p []byte) (err error)
//sysnb	Setpgid(pid int, pgid int) (err error)
//sysnb	Setsid() (pid int, err error)
//sysnb	Settimeofday(tv *Timeval) (err error)

// allThreadsCaller holds the input and output state for performing a
// allThreadsSyscall that needs to synchronize all OS thread state. Linux
// generally does not always support this natively, so we have to
// manipulate the runtime to fix things up.
type allThreadsCaller struct {
	// arguments
	trap, a1, a2, a3, a4, a5, a6 uintptr

	// return values (only set by 0th invocation)
	r1, r2 uintptr

	// err is the error code
	err Errno
}

// doSyscall is a callback for executing a syscall on the current m
// (OS thread).
//go:nosplit
//go:norace
func ( *allThreadsCaller) ( bool) bool {
	, ,  := RawSyscall(.trap, .a1, .a2, .a3)
	if  {
		.r1 = 
		.r2 = 
		.err = 
	} else if .r1 !=  || (archHonorsR2 && .r2 != ) || .err !=  {
		print("trap:", .trap, ", a123=[", .a1, ",", .a2, ",", .a3, "]\n")
		print("results: got {r1=", , ",r2=", , ",err=", , "}, want {r1=", .r1, ",r2=", .r2, ",r3=", .err, "}\n")
		panic("AllThreadsSyscall results differ between threads; runtime corrupted")
	}
	return  == 0
}

// doSyscall6 is a callback for executing a syscall6 on the current m
// (OS thread).
//go:nosplit
//go:norace
func ( *allThreadsCaller) ( bool) bool {
	, ,  := RawSyscall6(.trap, .a1, .a2, .a3, .a4, .a5, .a6)
	if  {
		.r1 = 
		.r2 = 
		.err = 
	} else if .r1 !=  || (archHonorsR2 && .r2 != ) || .err !=  {
		print("trap:", .trap, ", a123456=[", .a1, ",", .a2, ",", .a3, ",", .a4, ",", .a5, ",", .a6, "]\n")
		print("results: got {r1=", , ",r2=", , ",err=", , "}, want {r1=", .r1, ",r2=", .r2, ",r3=", .err, "}\n")
		panic("AllThreadsSyscall6 results differ between threads; runtime corrupted")
	}
	return  == 0
}

// Provided by runtime.syscall_runtime_doAllThreadsSyscall which
// serializes the world and invokes the fn on each OS thread (what the
// runtime refers to as m's). Once this function returns, all threads
// are in sync.
func runtime_doAllThreadsSyscall( func(bool) bool)

// AllThreadsSyscall performs a syscall on each OS thread of the Go
// runtime. It first invokes the syscall on one thread. Should that
// invocation fail, it returns immediately with the error status.
// Otherwise, it invokes the syscall on all of the remaining threads
// in parallel. It will terminate the program if it observes any
// invoked syscall's return value differs from that of the first
// invocation.
//
// AllThreadsSyscall is intended for emulating simultaneous
// process-wide state changes that require consistently modifying
// per-thread state of the Go runtime.
//
// AllThreadsSyscall is unaware of any threads that are launched
// explicitly by cgo linked code, so the function always returns
// ENOTSUP in binaries that use cgo.
//go:uintptrescapes
func (, , ,  uintptr) (,  uintptr,  Errno) {
	if cgo_libc_setegid != nil {
		return minus1, minus1, ENOTSUP
	}
	 := &allThreadsCaller{
		trap: ,
		a1:   ,
		a2:   ,
		a3:   ,
	}
	runtime_doAllThreadsSyscall(.doSyscall)
	 = .r1
	 = .r2
	 = .err
	return
}

// AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six
// arguments.
//go:uintptrescapes
func (, , , , , ,  uintptr) (,  uintptr,  Errno) {
	if cgo_libc_setegid != nil {
		return minus1, minus1, ENOTSUP
	}
	 := &allThreadsCaller{
		trap: ,
		a1:   ,
		a2:   ,
		a3:   ,
		a4:   ,
		a5:   ,
		a6:   ,
	}
	runtime_doAllThreadsSyscall(.doSyscall6)
	 = .r1
	 = .r2
	 = .err
	return
}

// linked by runtime.cgocall.go
//go:uintptrescapes
func cgocaller(unsafe.Pointer, ...uintptr) uintptr

var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.

const minus1 = ^uintptr(0)

func ( int) ( error) {
	if cgo_libc_setegid == nil {
		if , ,  := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(), minus1);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setegid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_seteuid == nil {
		if , ,  := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(), minus1);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_seteuid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_setgid == nil {
		if , ,  := AllThreadsSyscall(sys_SETGID, uintptr(), 0, 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setgid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.

func (,  int) ( error) {
	if cgo_libc_setregid == nil {
		if , ,  := AllThreadsSyscall(sys_SETREGID, uintptr(), uintptr(), 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setregid, uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.

func (, ,  int) ( error) {
	if cgo_libc_setresgid == nil {
		if , ,  := AllThreadsSyscall(sys_SETRESGID, uintptr(), uintptr(), uintptr());  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setresgid, uintptr(), uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.

func (, ,  int) ( error) {
	if cgo_libc_setresuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETRESUID, uintptr(), uintptr(), uintptr());  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setresuid, uintptr(), uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.

func (,  int) ( error) {
	if cgo_libc_setreuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETREUID, uintptr(), uintptr(), 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setreuid, uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_setuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETUID, uintptr(), 0, 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setuid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

//sys	Setpriority(which int, who int, prio int) (err error)
//sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
//sys	Sync()
//sysnb	Sysinfo(info *Sysinfo_t) (err error)
//sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
//sysnb	Times(tms *Tms) (ticks uintptr, err error)
//sysnb	Umask(mask int) (oldmask int)
//sysnb	Uname(buf *Utsname) (err error)
//sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
//sys	Unshare(flags int) (err error)
//sys	write(fd int, p []byte) (n int, err error)
//sys	exitThread(code int) (err error) = SYS_EXIT
//sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
//sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE

// mmap varies by architecture; see syscall_linux_*.go.
//sys	munmap(addr uintptr, length uintptr) (err error)

var mapper = &mmapper{
	active: make(map[*byte][]byte),
	mmap:   mmap,
	munmap: munmap,
}

func ( int,  int64,  int,  int,  int) ( []byte,  error) {
	return mapper.Mmap(, , , , )
}

func ( []byte) ( error) {
	return mapper.Munmap()
}

//sys	Madvise(b []byte, advice int) (err error)
//sys	Mprotect(b []byte, prot int) (err error)
//sys	Mlock(b []byte) (err error)
//sys	Munlock(b []byte) (err error)
//sys	Mlockall(flags int) (err error)
//sys	Munlockall() (err error)