vendor/golang.org/x/sys/unix/syscall_linux.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
    10 // wrap it in our own nicer implementation.
    10 // wrap it in our own nicer implementation.
    11 
    11 
    12 package unix
    12 package unix
    13 
    13 
    14 import (
    14 import (
       
    15 	"encoding/binary"
       
    16 	"runtime"
    15 	"syscall"
    17 	"syscall"
    16 	"unsafe"
    18 	"unsafe"
    17 )
    19 )
    18 
    20 
    19 /*
    21 /*
    32 	return Fchownat(AT_FDCWD, path, uid, gid, 0)
    34 	return Fchownat(AT_FDCWD, path, uid, gid, 0)
    33 }
    35 }
    34 
    36 
    35 func Creat(path string, mode uint32) (fd int, err error) {
    37 func Creat(path string, mode uint32) (fd int, err error) {
    36 	return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
    38 	return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
       
    39 }
       
    40 
       
    41 //sys	FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
       
    42 //sys	fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error)
       
    43 
       
    44 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) {
       
    45 	if pathname == "" {
       
    46 		return fanotifyMark(fd, flags, mask, dirFd, nil)
       
    47 	}
       
    48 	p, err := BytePtrFromString(pathname)
       
    49 	if err != nil {
       
    50 		return err
       
    51 	}
       
    52 	return fanotifyMark(fd, flags, mask, dirFd, p)
    37 }
    53 }
    38 
    54 
    39 //sys	fchmodat(dirfd int, path string, mode uint32) (err error)
    55 //sys	fchmodat(dirfd int, path string, mode uint32) (err error)
    40 
    56 
    41 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
    57 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
    53 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
    69 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
    54 
    70 
    55 // ioctl itself should not be exposed directly, but additional get/set
    71 // ioctl itself should not be exposed directly, but additional get/set
    56 // functions for specific types are permissible.
    72 // functions for specific types are permissible.
    57 
    73 
    58 // IoctlSetInt performs an ioctl operation which sets an integer value
    74 // IoctlRetInt performs an ioctl operation specified by req on a device
    59 // on fd, using the specified request number.
    75 // associated with opened file descriptor fd, and returns a non-negative
    60 func IoctlSetInt(fd int, req uint, value int) error {
    76 // integer that is returned by the ioctl syscall.
    61 	return ioctl(fd, req, uintptr(value))
    77 func IoctlRetInt(fd int, req uint) (int, error) {
    62 }
    78 	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
    63 
    79 	if err != 0 {
    64 func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
    80 		return 0, err
    65 	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
    81 	}
    66 }
    82 	return int(ret), nil
    67 
    83 }
    68 func ioctlSetTermios(fd int, req uint, value *Termios) error {
    84 
    69 	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
    85 // IoctlSetPointerInt performs an ioctl operation which sets an
    70 }
    86 // integer value on fd, using the specified request number. The ioctl
    71 
    87 // argument is called with a pointer to the integer value, rather than
    72 // IoctlGetInt performs an ioctl operation which gets an integer value
    88 // passing the integer value directly.
    73 // from fd, using the specified request number.
    89 func IoctlSetPointerInt(fd int, req uint, value int) error {
    74 func IoctlGetInt(fd int, req uint) (int, error) {
    90 	v := int32(value)
    75 	var value int
    91 	return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
       
    92 }
       
    93 
       
    94 func IoctlSetRTCTime(fd int, value *RTCTime) error {
       
    95 	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
       
    96 	runtime.KeepAlive(value)
       
    97 	return err
       
    98 }
       
    99 
       
   100 func IoctlGetUint32(fd int, req uint) (uint32, error) {
       
   101 	var value uint32
    76 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   102 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
    77 	return value, err
   103 	return value, err
    78 }
   104 }
    79 
   105 
    80 func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
   106 func IoctlGetRTCTime(fd int) (*RTCTime, error) {
    81 	var value Winsize
   107 	var value RTCTime
    82 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
   108 	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
    83 	return &value, err
       
    84 }
       
    85 
       
    86 func IoctlGetTermios(fd int, req uint) (*Termios, error) {
       
    87 	var value Termios
       
    88 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
       
    89 	return &value, err
   109 	return &value, err
    90 }
   110 }
    91 
   111 
    92 //sys	Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
   112 //sys	Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
    93 
   113 
   708 	sa.raw.Shared_umem_fd = sa.SharedUmemFD
   728 	sa.raw.Shared_umem_fd = sa.SharedUmemFD
   709 
   729 
   710 	return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
   730 	return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
   711 }
   731 }
   712 
   732 
       
   733 // This constant mirrors the #define of PX_PROTO_OE in
       
   734 // linux/if_pppox.h. We're defining this by hand here instead of
       
   735 // autogenerating through mkerrors.sh because including
       
   736 // linux/if_pppox.h causes some declaration conflicts with other
       
   737 // includes (linux/if_pppox.h includes linux/in.h, which conflicts
       
   738 // with netinet/in.h). Given that we only need a single zero constant
       
   739 // out of that file, it's cleaner to just define it by hand here.
       
   740 const px_proto_oe = 0
       
   741 
       
   742 type SockaddrPPPoE struct {
       
   743 	SID    uint16
       
   744 	Remote []byte
       
   745 	Dev    string
       
   746 	raw    RawSockaddrPPPoX
       
   747 }
       
   748 
       
   749 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
       
   750 	if len(sa.Remote) != 6 {
       
   751 		return nil, 0, EINVAL
       
   752 	}
       
   753 	if len(sa.Dev) > IFNAMSIZ-1 {
       
   754 		return nil, 0, EINVAL
       
   755 	}
       
   756 
       
   757 	*(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
       
   758 	// This next field is in host-endian byte order. We can't use the
       
   759 	// same unsafe pointer cast as above, because this value is not
       
   760 	// 32-bit aligned and some architectures don't allow unaligned
       
   761 	// access.
       
   762 	//
       
   763 	// However, the value of px_proto_oe is 0, so we can use
       
   764 	// encoding/binary helpers to write the bytes without worrying
       
   765 	// about the ordering.
       
   766 	binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
       
   767 	// This field is deliberately big-endian, unlike the previous
       
   768 	// one. The kernel expects SID to be in network byte order.
       
   769 	binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
       
   770 	copy(sa.raw[8:14], sa.Remote)
       
   771 	for i := 14; i < 14+IFNAMSIZ; i++ {
       
   772 		sa.raw[i] = 0
       
   773 	}
       
   774 	copy(sa.raw[14:], sa.Dev)
       
   775 	return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
       
   776 }
       
   777 
       
   778 // SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets.
       
   779 // For more information on TIPC, see: http://tipc.sourceforge.net/.
       
   780 type SockaddrTIPC struct {
       
   781 	// Scope is the publication scopes when binding service/service range.
       
   782 	// Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE.
       
   783 	Scope int
       
   784 
       
   785 	// Addr is the type of address used to manipulate a socket. Addr must be
       
   786 	// one of:
       
   787 	//  - *TIPCSocketAddr: "id" variant in the C addr union
       
   788 	//  - *TIPCServiceRange: "nameseq" variant in the C addr union
       
   789 	//  - *TIPCServiceName: "name" variant in the C addr union
       
   790 	//
       
   791 	// If nil, EINVAL will be returned when the structure is used.
       
   792 	Addr TIPCAddr
       
   793 
       
   794 	raw RawSockaddrTIPC
       
   795 }
       
   796 
       
   797 // TIPCAddr is implemented by types that can be used as an address for
       
   798 // SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange,
       
   799 // and *TIPCServiceName.
       
   800 type TIPCAddr interface {
       
   801 	tipcAddrtype() uint8
       
   802 	tipcAddr() [12]byte
       
   803 }
       
   804 
       
   805 func (sa *TIPCSocketAddr) tipcAddr() [12]byte {
       
   806 	var out [12]byte
       
   807 	copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])
       
   808 	return out
       
   809 }
       
   810 
       
   811 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }
       
   812 
       
   813 func (sa *TIPCServiceRange) tipcAddr() [12]byte {
       
   814 	var out [12]byte
       
   815 	copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])
       
   816 	return out
       
   817 }
       
   818 
       
   819 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }
       
   820 
       
   821 func (sa *TIPCServiceName) tipcAddr() [12]byte {
       
   822 	var out [12]byte
       
   823 	copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])
       
   824 	return out
       
   825 }
       
   826 
       
   827 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }
       
   828 
       
   829 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
       
   830 	if sa.Addr == nil {
       
   831 		return nil, 0, EINVAL
       
   832 	}
       
   833 
       
   834 	sa.raw.Family = AF_TIPC
       
   835 	sa.raw.Scope = int8(sa.Scope)
       
   836 	sa.raw.Addrtype = sa.Addr.tipcAddrtype()
       
   837 	sa.raw.Addr = sa.Addr.tipcAddr()
       
   838 
       
   839 	return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
       
   840 }
       
   841 
   713 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
   842 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
   714 	switch rsa.Addr.Family {
   843 	switch rsa.Addr.Family {
   715 	case AF_NETLINK:
   844 	case AF_NETLINK:
   716 		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
   845 		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
   717 		sa := new(SockaddrNetlink)
   846 		sa := new(SockaddrNetlink)
   753 		// everyone uses this convention.
   882 		// everyone uses this convention.
   754 		n := 0
   883 		n := 0
   755 		for n < len(pp.Path) && pp.Path[n] != 0 {
   884 		for n < len(pp.Path) && pp.Path[n] != 0 {
   756 			n++
   885 			n++
   757 		}
   886 		}
   758 		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
   887 		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
   759 		sa.Name = string(bytes)
   888 		sa.Name = string(bytes)
   760 		return sa, nil
   889 		return sa, nil
   761 
   890 
   762 	case AF_INET:
   891 	case AF_INET:
   763 		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   892 		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   818 			Ifindex:      pp.Ifindex,
   947 			Ifindex:      pp.Ifindex,
   819 			QueueID:      pp.Queue_id,
   948 			QueueID:      pp.Queue_id,
   820 			SharedUmemFD: pp.Shared_umem_fd,
   949 			SharedUmemFD: pp.Shared_umem_fd,
   821 		}
   950 		}
   822 		return sa, nil
   951 		return sa, nil
       
   952 	case AF_PPPOX:
       
   953 		pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
       
   954 		if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
       
   955 			return nil, EINVAL
       
   956 		}
       
   957 		sa := &SockaddrPPPoE{
       
   958 			SID:    binary.BigEndian.Uint16(pp[6:8]),
       
   959 			Remote: pp[8:14],
       
   960 		}
       
   961 		for i := 14; i < 14+IFNAMSIZ; i++ {
       
   962 			if pp[i] == 0 {
       
   963 				sa.Dev = string(pp[14:i])
       
   964 				break
       
   965 			}
       
   966 		}
       
   967 		return sa, nil
       
   968 	case AF_TIPC:
       
   969 		pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))
       
   970 
       
   971 		sa := &SockaddrTIPC{
       
   972 			Scope: int(pp.Scope),
       
   973 		}
       
   974 
       
   975 		// Determine which union variant is present in pp.Addr by checking
       
   976 		// pp.Addrtype.
       
   977 		switch pp.Addrtype {
       
   978 		case TIPC_SERVICE_RANGE:
       
   979 			sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))
       
   980 		case TIPC_SERVICE_ADDR:
       
   981 			sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))
       
   982 		case TIPC_SOCKET_ADDR:
       
   983 			sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))
       
   984 		default:
       
   985 			return nil, EINVAL
       
   986 		}
       
   987 
       
   988 		return sa, nil
   823 	}
   989 	}
   824 	return nil, EAFNOSUPPORT
   990 	return nil, EAFNOSUPPORT
   825 }
   991 }
   826 
   992 
   827 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   993 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   903 		}
  1069 		}
   904 	}
  1070 	}
   905 	return string(buf[:vallen-1]), nil
  1071 	return string(buf[:vallen-1]), nil
   906 }
  1072 }
   907 
  1073 
       
  1074 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {
       
  1075 	var value TpacketStats
       
  1076 	vallen := _Socklen(SizeofTpacketStats)
       
  1077 	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
       
  1078 	return &value, err
       
  1079 }
       
  1080 
       
  1081 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) {
       
  1082 	var value TpacketStatsV3
       
  1083 	vallen := _Socklen(SizeofTpacketStatsV3)
       
  1084 	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
       
  1085 	return &value, err
       
  1086 }
       
  1087 
   908 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
  1088 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
   909 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
  1089 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
       
  1090 }
       
  1091 
       
  1092 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error {
       
  1093 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
       
  1094 }
       
  1095 
       
  1096 // SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a
       
  1097 // socket to filter incoming packets.  See 'man 7 socket' for usage information.
       
  1098 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {
       
  1099 	return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))
       
  1100 }
       
  1101 
       
  1102 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
       
  1103 	var p unsafe.Pointer
       
  1104 	if len(filter) > 0 {
       
  1105 		p = unsafe.Pointer(&filter[0])
       
  1106 	}
       
  1107 	return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))
       
  1108 }
       
  1109 
       
  1110 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error {
       
  1111 	return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
       
  1112 }
       
  1113 
       
  1114 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {
       
  1115 	return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
   910 }
  1116 }
   911 
  1117 
   912 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
  1118 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
   913 
  1119 
   914 // KeyctlInt calls keyctl commands in which each argument is an int.
  1120 // KeyctlInt calls keyctl commands in which each argument is an int.
  1014 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html
  1220 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html
  1015 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
  1221 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
  1016 	return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
  1222 	return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
  1017 }
  1223 }
  1018 
  1224 
       
  1225 // KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This
       
  1226 // command limits the set of keys that can be linked to the keyring, regardless
       
  1227 // of keyring permissions. The command requires the "setattr" permission.
       
  1228 //
       
  1229 // When called with an empty keyType the command locks the keyring, preventing
       
  1230 // any further keys from being linked to the keyring.
       
  1231 //
       
  1232 // The "asymmetric" keyType defines restrictions requiring key payloads to be
       
  1233 // DER encoded X.509 certificates signed by keys in another keyring. Restrictions
       
  1234 // for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted",
       
  1235 // "key_or_keyring:<key>", and "key_or_keyring:<key>:chain".
       
  1236 //
       
  1237 // As of Linux 4.12, only the "asymmetric" keyType defines type-specific
       
  1238 // restrictions.
       
  1239 //
       
  1240 // See the full documentation at:
       
  1241 // http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html
       
  1242 // http://man7.org/linux/man-pages/man2/keyctl.2.html
       
  1243 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {
       
  1244 	if keyType == "" {
       
  1245 		return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)
       
  1246 	}
       
  1247 	return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
       
  1248 }
       
  1249 
       
  1250 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
       
  1251 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
       
  1252 
  1019 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1253 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1020 	var msg Msghdr
  1254 	var msg Msghdr
  1021 	var rsa RawSockaddrAny
  1255 	var rsa RawSockaddrAny
  1022 	msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1256 	msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1023 	msg.Namelen = uint32(SizeofSockaddrAny)
  1257 	msg.Namelen = uint32(SizeofSockaddrAny)
  1120 	// to retrieve arbitrary-length data.
  1354 	// to retrieve arbitrary-length data.
  1121 
  1355 
  1122 	// The ptrace syscall differs from glibc's ptrace.
  1356 	// The ptrace syscall differs from glibc's ptrace.
  1123 	// Peeks returns the word in *data, not as the return value.
  1357 	// Peeks returns the word in *data, not as the return value.
  1124 
  1358 
  1125 	var buf [sizeofPtr]byte
  1359 	var buf [SizeofPtr]byte
  1126 
  1360 
  1127 	// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
  1361 	// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
  1128 	// access (PEEKUSER warns that it might), but if we don't
  1362 	// access (PEEKUSER warns that it might), but if we don't
  1129 	// align our reads, we might straddle an unmapped page
  1363 	// align our reads, we might straddle an unmapped page
  1130 	// boundary and not get the bytes leading up to the page
  1364 	// boundary and not get the bytes leading up to the page
  1131 	// boundary.
  1365 	// boundary.
  1132 	n := 0
  1366 	n := 0
  1133 	if addr%sizeofPtr != 0 {
  1367 	if addr%SizeofPtr != 0 {
  1134 		err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
  1368 		err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
  1135 		if err != nil {
  1369 		if err != nil {
  1136 			return 0, err
  1370 			return 0, err
  1137 		}
  1371 		}
  1138 		n += copy(out, buf[addr%sizeofPtr:])
  1372 		n += copy(out, buf[addr%SizeofPtr:])
  1139 		out = out[n:]
  1373 		out = out[n:]
  1140 	}
  1374 	}
  1141 
  1375 
  1142 	// Remainder.
  1376 	// Remainder.
  1143 	for len(out) > 0 {
  1377 	for len(out) > 0 {
  1171 	// As for ptracePeek, we need to align our accesses to deal
  1405 	// As for ptracePeek, we need to align our accesses to deal
  1172 	// with the possibility of straddling an invalid page.
  1406 	// with the possibility of straddling an invalid page.
  1173 
  1407 
  1174 	// Leading edge.
  1408 	// Leading edge.
  1175 	n := 0
  1409 	n := 0
  1176 	if addr%sizeofPtr != 0 {
  1410 	if addr%SizeofPtr != 0 {
  1177 		var buf [sizeofPtr]byte
  1411 		var buf [SizeofPtr]byte
  1178 		err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
  1412 		err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
  1179 		if err != nil {
  1413 		if err != nil {
  1180 			return 0, err
  1414 			return 0, err
  1181 		}
  1415 		}
  1182 		n += copy(buf[addr%sizeofPtr:], data)
  1416 		n += copy(buf[addr%SizeofPtr:], data)
  1183 		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
  1417 		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
  1184 		err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
  1418 		err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
  1185 		if err != nil {
  1419 		if err != nil {
  1186 			return 0, err
  1420 			return 0, err
  1187 		}
  1421 		}
  1188 		data = data[n:]
  1422 		data = data[n:]
  1189 	}
  1423 	}
  1190 
  1424 
  1191 	// Interior.
  1425 	// Interior.
  1192 	for len(data) > sizeofPtr {
  1426 	for len(data) > SizeofPtr {
  1193 		word := *((*uintptr)(unsafe.Pointer(&data[0])))
  1427 		word := *((*uintptr)(unsafe.Pointer(&data[0])))
  1194 		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
  1428 		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
  1195 		if err != nil {
  1429 		if err != nil {
  1196 			return n, err
  1430 			return n, err
  1197 		}
  1431 		}
  1198 		n += sizeofPtr
  1432 		n += SizeofPtr
  1199 		data = data[sizeofPtr:]
  1433 		data = data[SizeofPtr:]
  1200 	}
  1434 	}
  1201 
  1435 
  1202 	// Trailing edge.
  1436 	// Trailing edge.
  1203 	if len(data) > 0 {
  1437 	if len(data) > 0 {
  1204 		var buf [sizeofPtr]byte
  1438 		var buf [SizeofPtr]byte
  1205 		err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
  1439 		err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
  1206 		if err != nil {
  1440 		if err != nil {
  1207 			return n, err
  1441 			return n, err
  1208 		}
  1442 		}
  1209 		copy(buf[0:], data)
  1443 		copy(buf[0:], data)
  1257 	return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
  1491 	return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
  1258 }
  1492 }
  1259 
  1493 
  1260 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
  1494 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
  1261 
  1495 
       
  1496 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
       
  1497 
  1262 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
  1498 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
       
  1499 
       
  1500 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
  1263 
  1501 
  1264 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
  1502 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
  1265 
  1503 
  1266 //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
  1504 //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
  1267 
  1505 
  1268 func Reboot(cmd int) (err error) {
  1506 func Reboot(cmd int) (err error) {
  1269 	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
  1507 	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
  1270 }
  1508 }
  1271 
  1509 
  1272 func ReadDirent(fd int, buf []byte) (n int, err error) {
  1510 func direntIno(buf []byte) (uint64, bool) {
  1273 	return Getdents(fd, buf)
  1511 	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
       
  1512 }
       
  1513 
       
  1514 func direntReclen(buf []byte) (uint64, bool) {
       
  1515 	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
       
  1516 }
       
  1517 
       
  1518 func direntNamlen(buf []byte) (uint64, bool) {
       
  1519 	reclen, ok := direntReclen(buf)
       
  1520 	if !ok {
       
  1521 		return 0, false
       
  1522 	}
       
  1523 	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
  1274 }
  1524 }
  1275 
  1525 
  1276 //sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
  1526 //sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
  1277 
  1527 
  1278 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  1528 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  1284 	datap, err := BytePtrFromString(data)
  1534 	datap, err := BytePtrFromString(data)
  1285 	if err != nil {
  1535 	if err != nil {
  1286 		return err
  1536 		return err
  1287 	}
  1537 	}
  1288 	return mount(source, target, fstype, flags, datap)
  1538 	return mount(source, target, fstype, flags, datap)
       
  1539 }
       
  1540 
       
  1541 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
       
  1542 	if raceenabled {
       
  1543 		raceReleaseMerge(unsafe.Pointer(&ioSync))
       
  1544 	}
       
  1545 	return sendfile(outfd, infd, offset, count)
  1289 }
  1546 }
  1290 
  1547 
  1291 // Sendto
  1548 // Sendto
  1292 // Recvfrom
  1549 // Recvfrom
  1293 // Socketpair
  1550 // Socketpair
  1296  * Direct access
  1553  * Direct access
  1297  */
  1554  */
  1298 //sys	Acct(path string) (err error)
  1555 //sys	Acct(path string) (err error)
  1299 //sys	AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
  1556 //sys	AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
  1300 //sys	Adjtimex(buf *Timex) (state int, err error)
  1557 //sys	Adjtimex(buf *Timex) (state int, err error)
       
  1558 //sys	Capget(hdr *CapUserHeader, data *CapUserData) (err error)
       
  1559 //sys	Capset(hdr *CapUserHeader, data *CapUserData) (err error)
  1301 //sys	Chdir(path string) (err error)
  1560 //sys	Chdir(path string) (err error)
  1302 //sys	Chroot(path string) (err error)
  1561 //sys	Chroot(path string) (err error)
  1303 //sys	ClockGetres(clockid int32, res *Timespec) (err error)
  1562 //sys	ClockGetres(clockid int32, res *Timespec) (err error)
  1304 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
  1563 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
       
  1564 //sys	ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
  1305 //sys	Close(fd int) (err error)
  1565 //sys	Close(fd int) (err error)
  1306 //sys	CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
  1566 //sys	CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
       
  1567 //sys	DeleteModule(name string, flags int) (err error)
  1307 //sys	Dup(oldfd int) (fd int, err error)
  1568 //sys	Dup(oldfd int) (fd int, err error)
  1308 //sys	Dup3(oldfd int, newfd int, flags int) (err error)
  1569 //sys	Dup3(oldfd int, newfd int, flags int) (err error)
  1309 //sysnb	EpollCreate1(flag int) (fd int, err error)
  1570 //sysnb	EpollCreate1(flag int) (fd int, err error)
  1310 //sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
  1571 //sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
  1311 //sys	Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
  1572 //sys	Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
  1312 //sys	Exit(code int) = SYS_EXIT_GROUP
  1573 //sys	Exit(code int) = SYS_EXIT_GROUP
  1313 //sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
  1574 //sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
  1314 //sys	Fchdir(fd int) (err error)
  1575 //sys	Fchdir(fd int) (err error)
  1315 //sys	Fchmod(fd int, mode uint32) (err error)
  1576 //sys	Fchmod(fd int, mode uint32) (err error)
  1316 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
  1577 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
  1317 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
       
  1318 //sys	Fdatasync(fd int) (err error)
  1578 //sys	Fdatasync(fd int) (err error)
  1319 //sys	Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
  1579 //sys	Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
       
  1580 //sys	FinitModule(fd int, params string, flags int) (err error)
  1320 //sys	Flistxattr(fd int, dest []byte) (sz int, err error)
  1581 //sys	Flistxattr(fd int, dest []byte) (sz int, err error)
  1321 //sys	Flock(fd int, how int) (err error)
  1582 //sys	Flock(fd int, how int) (err error)
  1322 //sys	Fremovexattr(fd int, attr string) (err error)
  1583 //sys	Fremovexattr(fd int, attr string) (err error)
  1323 //sys	Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
  1584 //sys	Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
  1324 //sys	Fsync(fd int) (err error)
  1585 //sys	Fsync(fd int) (err error)
  1336 //sys	Getrandom(buf []byte, flags int) (n int, err error)
  1597 //sys	Getrandom(buf []byte, flags int) (n int, err error)
  1337 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
  1598 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
  1338 //sysnb	Getsid(pid int) (sid int, err error)
  1599 //sysnb	Getsid(pid int) (sid int, err error)
  1339 //sysnb	Gettid() (tid int)
  1600 //sysnb	Gettid() (tid int)
  1340 //sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
  1601 //sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
       
  1602 //sys	InitModule(moduleImage []byte, params string) (err error)
  1341 //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
  1603 //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
  1342 //sysnb	InotifyInit1(flags int) (fd int, err error)
  1604 //sysnb	InotifyInit1(flags int) (fd int, err error)
  1343 //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
  1605 //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
  1344 //sysnb	Kill(pid int, sig syscall.Signal) (err error)
  1606 //sysnb	Kill(pid int, sig syscall.Signal) (err error)
  1345 //sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
  1607 //sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
  1357 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
  1619 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
  1358 //sys   Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
  1620 //sys   Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
  1359 //sys	Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
  1621 //sys	Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
  1360 //sys	read(fd int, p []byte) (n int, err error)
  1622 //sys	read(fd int, p []byte) (n int, err error)
  1361 //sys	Removexattr(path string, attr string) (err error)
  1623 //sys	Removexattr(path string, attr string) (err error)
  1362 //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
       
  1363 //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
  1624 //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
  1364 //sys	RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
  1625 //sys	RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
  1365 //sys	Setdomainname(p []byte) (err error)
  1626 //sys	Setdomainname(p []byte) (err error)
  1366 //sys	Sethostname(p []byte) (err error)
  1627 //sys	Sethostname(p []byte) (err error)
  1367 //sysnb	Setpgid(pid int, pgid int) (err error)
  1628 //sysnb	Setpgid(pid int, pgid int) (err error)
  1368 //sysnb	Setsid() (pid int, err error)
  1629 //sysnb	Setsid() (pid int, err error)
  1369 //sysnb	Settimeofday(tv *Timeval) (err error)
  1630 //sysnb	Settimeofday(tv *Timeval) (err error)
  1370 //sys	Setns(fd int, nstype int) (err error)
  1631 //sys	Setns(fd int, nstype int) (err error)
  1371 
  1632 
       
  1633 // PrctlRetInt performs a prctl operation specified by option and further
       
  1634 // optional arguments arg2 through arg5 depending on option. It returns a
       
  1635 // non-negative integer that is returned by the prctl syscall.
       
  1636 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
       
  1637 	ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
       
  1638 	if err != 0 {
       
  1639 		return 0, err
       
  1640 	}
       
  1641 	return int(ret), nil
       
  1642 }
       
  1643 
  1372 // issue 1435.
  1644 // issue 1435.
  1373 // On linux Setuid and Setgid only affects the current thread, not the process.
  1645 // On linux Setuid and Setgid only affects the current thread, not the process.
  1374 // This does not match what most callers expect so we must return an error
  1646 // This does not match what most callers expect so we must return an error
  1375 // here rather than letting the caller think that the call succeeded.
  1647 // here rather than letting the caller think that the call succeeded.
  1376 
  1648 
  1380 
  1652 
  1381 func Setgid(uid int) (err error) {
  1653 func Setgid(uid int) (err error) {
  1382 	return EOPNOTSUPP
  1654 	return EOPNOTSUPP
  1383 }
  1655 }
  1384 
  1656 
       
  1657 // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
       
  1658 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability.
       
  1659 // If the call fails due to other reasons, current fsgid will be returned.
       
  1660 func SetfsgidRetGid(gid int) (int, error) {
       
  1661 	return setfsgid(gid)
       
  1662 }
       
  1663 
       
  1664 // SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set.
       
  1665 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability
       
  1666 // If the call fails due to other reasons, current fsuid will be returned.
       
  1667 func SetfsuidRetUid(uid int) (int, error) {
       
  1668 	return setfsuid(uid)
       
  1669 }
       
  1670 
       
  1671 func Setfsgid(gid int) error {
       
  1672 	_, err := setfsgid(gid)
       
  1673 	return err
       
  1674 }
       
  1675 
       
  1676 func Setfsuid(uid int) error {
       
  1677 	_, err := setfsuid(uid)
       
  1678 	return err
       
  1679 }
       
  1680 
       
  1681 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
       
  1682 	return signalfd(fd, sigmask, _C__NSIG/8, flags)
       
  1683 }
       
  1684 
  1385 //sys	Setpriority(which int, who int, prio int) (err error)
  1685 //sys	Setpriority(which int, who int, prio int) (err error)
  1386 //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
  1686 //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
       
  1687 //sys	signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4
  1387 //sys	Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
  1688 //sys	Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
  1388 //sys	Sync()
  1689 //sys	Sync()
  1389 //sys	Syncfs(fd int) (err error)
  1690 //sys	Syncfs(fd int) (err error)
  1390 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
  1691 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
  1391 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
  1692 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
  1397 //sys	Unshare(flags int) (err error)
  1698 //sys	Unshare(flags int) (err error)
  1398 //sys	write(fd int, p []byte) (n int, err error)
  1699 //sys	write(fd int, p []byte) (n int, err error)
  1399 //sys	exitThread(code int) (err error) = SYS_EXIT
  1700 //sys	exitThread(code int) (err error) = SYS_EXIT
  1400 //sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
  1701 //sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
  1401 //sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
  1702 //sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
       
  1703 //sys	readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
       
  1704 //sys	writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
       
  1705 //sys	preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
       
  1706 //sys	pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
       
  1707 //sys	preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
       
  1708 //sys	pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
       
  1709 
       
  1710 func bytes2iovec(bs [][]byte) []Iovec {
       
  1711 	iovecs := make([]Iovec, len(bs))
       
  1712 	for i, b := range bs {
       
  1713 		iovecs[i].SetLen(len(b))
       
  1714 		if len(b) > 0 {
       
  1715 			iovecs[i].Base = &b[0]
       
  1716 		} else {
       
  1717 			iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
       
  1718 		}
       
  1719 	}
       
  1720 	return iovecs
       
  1721 }
       
  1722 
       
  1723 // offs2lohi splits offs into its lower and upper unsigned long. On 64-bit
       
  1724 // systems, hi will always be 0. On 32-bit systems, offs will be split in half.
       
  1725 // preadv/pwritev chose this calling convention so they don't need to add a
       
  1726 // padding-register for alignment on ARM.
       
  1727 func offs2lohi(offs int64) (lo, hi uintptr) {
       
  1728 	return uintptr(offs), uintptr(uint64(offs) >> SizeofLong)
       
  1729 }
       
  1730 
       
  1731 func Readv(fd int, iovs [][]byte) (n int, err error) {
       
  1732 	iovecs := bytes2iovec(iovs)
       
  1733 	n, err = readv(fd, iovecs)
       
  1734 	readvRacedetect(iovecs, n, err)
       
  1735 	return n, err
       
  1736 }
       
  1737 
       
  1738 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
       
  1739 	iovecs := bytes2iovec(iovs)
       
  1740 	lo, hi := offs2lohi(offset)
       
  1741 	n, err = preadv(fd, iovecs, lo, hi)
       
  1742 	readvRacedetect(iovecs, n, err)
       
  1743 	return n, err
       
  1744 }
       
  1745 
       
  1746 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
       
  1747 	iovecs := bytes2iovec(iovs)
       
  1748 	lo, hi := offs2lohi(offset)
       
  1749 	n, err = preadv2(fd, iovecs, lo, hi, flags)
       
  1750 	readvRacedetect(iovecs, n, err)
       
  1751 	return n, err
       
  1752 }
       
  1753 
       
  1754 func readvRacedetect(iovecs []Iovec, n int, err error) {
       
  1755 	if !raceenabled {
       
  1756 		return
       
  1757 	}
       
  1758 	for i := 0; n > 0 && i < len(iovecs); i++ {
       
  1759 		m := int(iovecs[i].Len)
       
  1760 		if m > n {
       
  1761 			m = n
       
  1762 		}
       
  1763 		n -= m
       
  1764 		if m > 0 {
       
  1765 			raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
       
  1766 		}
       
  1767 	}
       
  1768 	if err == nil {
       
  1769 		raceAcquire(unsafe.Pointer(&ioSync))
       
  1770 	}
       
  1771 }
       
  1772 
       
  1773 func Writev(fd int, iovs [][]byte) (n int, err error) {
       
  1774 	iovecs := bytes2iovec(iovs)
       
  1775 	if raceenabled {
       
  1776 		raceReleaseMerge(unsafe.Pointer(&ioSync))
       
  1777 	}
       
  1778 	n, err = writev(fd, iovecs)
       
  1779 	writevRacedetect(iovecs, n)
       
  1780 	return n, err
       
  1781 }
       
  1782 
       
  1783 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
       
  1784 	iovecs := bytes2iovec(iovs)
       
  1785 	if raceenabled {
       
  1786 		raceReleaseMerge(unsafe.Pointer(&ioSync))
       
  1787 	}
       
  1788 	lo, hi := offs2lohi(offset)
       
  1789 	n, err = pwritev(fd, iovecs, lo, hi)
       
  1790 	writevRacedetect(iovecs, n)
       
  1791 	return n, err
       
  1792 }
       
  1793 
       
  1794 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
       
  1795 	iovecs := bytes2iovec(iovs)
       
  1796 	if raceenabled {
       
  1797 		raceReleaseMerge(unsafe.Pointer(&ioSync))
       
  1798 	}
       
  1799 	lo, hi := offs2lohi(offset)
       
  1800 	n, err = pwritev2(fd, iovecs, lo, hi, flags)
       
  1801 	writevRacedetect(iovecs, n)
       
  1802 	return n, err
       
  1803 }
       
  1804 
       
  1805 func writevRacedetect(iovecs []Iovec, n int) {
       
  1806 	if !raceenabled {
       
  1807 		return
       
  1808 	}
       
  1809 	for i := 0; n > 0 && i < len(iovecs); i++ {
       
  1810 		m := int(iovecs[i].Len)
       
  1811 		if m > n {
       
  1812 			m = n
       
  1813 		}
       
  1814 		n -= m
       
  1815 		if m > 0 {
       
  1816 			raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
       
  1817 		}
       
  1818 	}
       
  1819 }
  1402 
  1820 
  1403 // mmap varies by architecture; see syscall_linux_*.go.
  1821 // mmap varies by architecture; see syscall_linux_*.go.
  1404 //sys	munmap(addr uintptr, length uintptr) (err error)
  1822 //sys	munmap(addr uintptr, length uintptr) (err error)
  1405 
  1823 
  1406 var mapper = &mmapper{
  1824 var mapper = &mmapper{
  1426 //sys	Munlockall() (err error)
  1844 //sys	Munlockall() (err error)
  1427 
  1845 
  1428 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
  1846 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
  1429 // using the specified flags.
  1847 // using the specified flags.
  1430 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
  1848 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
  1431 	n, _, errno := Syscall6(
  1849 	var p unsafe.Pointer
  1432 		SYS_VMSPLICE,
  1850 	if len(iovs) > 0 {
  1433 		uintptr(fd),
  1851 		p = unsafe.Pointer(&iovs[0])
  1434 		uintptr(unsafe.Pointer(&iovs[0])),
  1852 	}
  1435 		uintptr(len(iovs)),
  1853 
  1436 		uintptr(flags),
  1854 	n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
  1437 		0,
       
  1438 		0,
       
  1439 	)
       
  1440 	if errno != 0 {
  1855 	if errno != 0 {
  1441 		return 0, syscall.Errno(errno)
  1856 		return 0, syscall.Errno(errno)
  1442 	}
  1857 	}
  1443 
  1858 
  1444 	return int(n), nil
  1859 	return int(n), nil
  1513 	}
  1928 	}
  1514 
  1929 
  1515 	return EACCES
  1930 	return EACCES
  1516 }
  1931 }
  1517 
  1932 
       
  1933 //sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
       
  1934 //sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
       
  1935 
       
  1936 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We
       
  1937 // originally tried to generate it via unix/linux/types.go with "type
       
  1938 // fileHandle C.struct_file_handle" but that generated empty structs
       
  1939 // for mips64 and mips64le. Instead, hard code it for now (it's the
       
  1940 // same everywhere else) until the mips64 generator issue is fixed.
       
  1941 type fileHandle struct {
       
  1942 	Bytes uint32
       
  1943 	Type  int32
       
  1944 }
       
  1945 
       
  1946 // FileHandle represents the C struct file_handle used by
       
  1947 // name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see
       
  1948 // OpenByHandleAt).
       
  1949 type FileHandle struct {
       
  1950 	*fileHandle
       
  1951 }
       
  1952 
       
  1953 // NewFileHandle constructs a FileHandle.
       
  1954 func NewFileHandle(handleType int32, handle []byte) FileHandle {
       
  1955 	const hdrSize = unsafe.Sizeof(fileHandle{})
       
  1956 	buf := make([]byte, hdrSize+uintptr(len(handle)))
       
  1957 	copy(buf[hdrSize:], handle)
       
  1958 	fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
       
  1959 	fh.Type = handleType
       
  1960 	fh.Bytes = uint32(len(handle))
       
  1961 	return FileHandle{fh}
       
  1962 }
       
  1963 
       
  1964 func (fh *FileHandle) Size() int   { return int(fh.fileHandle.Bytes) }
       
  1965 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }
       
  1966 func (fh *FileHandle) Bytes() []byte {
       
  1967 	n := fh.Size()
       
  1968 	if n == 0 {
       
  1969 		return nil
       
  1970 	}
       
  1971 	return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
       
  1972 }
       
  1973 
       
  1974 // NameToHandleAt wraps the name_to_handle_at system call; it obtains
       
  1975 // a handle for a path name.
       
  1976 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {
       
  1977 	var mid _C_int
       
  1978 	// Try first with a small buffer, assuming the handle will
       
  1979 	// only be 32 bytes.
       
  1980 	size := uint32(32 + unsafe.Sizeof(fileHandle{}))
       
  1981 	didResize := false
       
  1982 	for {
       
  1983 		buf := make([]byte, size)
       
  1984 		fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
       
  1985 		fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))
       
  1986 		err = nameToHandleAt(dirfd, path, fh, &mid, flags)
       
  1987 		if err == EOVERFLOW {
       
  1988 			if didResize {
       
  1989 				// We shouldn't need to resize more than once
       
  1990 				return
       
  1991 			}
       
  1992 			didResize = true
       
  1993 			size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))
       
  1994 			continue
       
  1995 		}
       
  1996 		if err != nil {
       
  1997 			return
       
  1998 		}
       
  1999 		return FileHandle{fh}, int(mid), nil
       
  2000 	}
       
  2001 }
       
  2002 
       
  2003 // OpenByHandleAt wraps the open_by_handle_at system call; it opens a
       
  2004 // file via a handle as previously returned by NameToHandleAt.
       
  2005 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {
       
  2006 	return openByHandleAt(mountFD, handle.fileHandle, flags)
       
  2007 }
       
  2008 
       
  2009 // Klogset wraps the sys_syslog system call; it sets console_loglevel to
       
  2010 // the value specified by arg and passes a dummy pointer to bufp.
       
  2011 func Klogset(typ int, arg int) (err error) {
       
  2012 	var p unsafe.Pointer
       
  2013 	_, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
       
  2014 	if errno != 0 {
       
  2015 		return errnoErr(errno)
       
  2016 	}
       
  2017 	return nil
       
  2018 }
       
  2019 
  1518 /*
  2020 /*
  1519  * Unimplemented
  2021  * Unimplemented
  1520  */
  2022  */
  1521 // AfsSyscall
  2023 // AfsSyscall
  1522 // Alarm
  2024 // Alarm
  1523 // ArchPrctl
  2025 // ArchPrctl
  1524 // Brk
  2026 // Brk
  1525 // Capget
       
  1526 // Capset
       
  1527 // ClockNanosleep
  2027 // ClockNanosleep
  1528 // ClockSettime
  2028 // ClockSettime
  1529 // Clone
  2029 // Clone
  1530 // CreateModule
       
  1531 // DeleteModule
       
  1532 // EpollCtlOld
  2030 // EpollCtlOld
  1533 // EpollPwait
  2031 // EpollPwait
  1534 // EpollWaitOld
  2032 // EpollWaitOld
  1535 // Execve
  2033 // Execve
  1536 // Fork
  2034 // Fork
  1570 // Nfsservctl
  2068 // Nfsservctl
  1571 // Personality
  2069 // Personality
  1572 // Pselect6
  2070 // Pselect6
  1573 // Ptrace
  2071 // Ptrace
  1574 // Putpmsg
  2072 // Putpmsg
  1575 // QueryModule
       
  1576 // Quotactl
  2073 // Quotactl
  1577 // Readahead
  2074 // Readahead
  1578 // Readv
  2075 // Readv
  1579 // RemapFilePages
  2076 // RemapFilePages
  1580 // RestartSyscall
  2077 // RestartSyscall
  1604 // Shmat
  2101 // Shmat
  1605 // Shmctl
  2102 // Shmctl
  1606 // Shmdt
  2103 // Shmdt
  1607 // Shmget
  2104 // Shmget
  1608 // Sigaltstack
  2105 // Sigaltstack
  1609 // Signalfd
       
  1610 // Swapoff
  2106 // Swapoff
  1611 // Swapon
  2107 // Swapon
  1612 // Sysfs
  2108 // Sysfs
  1613 // TimerCreate
  2109 // TimerCreate
  1614 // TimerDelete
  2110 // TimerDelete