gRPC migration update
Change-Id: Icdd1a824948fa994cd36bd121c962f5ecf74e3cf
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index b2c2d9b..41b91fd 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -70,44 +70,7 @@
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
-
-// IoctlRetInt performs an ioctl operation specified by req on a device
-// associated with opened file descriptor fd, and returns a non-negative
-// integer that is returned by the ioctl syscall.
-func IoctlRetInt(fd int, req uint) (int, error) {
- ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
- if err != 0 {
- return 0, err
- }
- return int(ret), nil
-}
-
-// IoctlSetPointerInt performs an ioctl operation which sets an
-// integer value on fd, using the specified request number. The ioctl
-// argument is called with a pointer to the integer value, rather than
-// passing the integer value directly.
-func IoctlSetPointerInt(fd int, req uint, value int) error {
- v := int32(value)
- return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
-}
-
-func IoctlSetRTCTime(fd int, value *RTCTime) error {
- err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
- runtime.KeepAlive(value)
- return err
-}
-
-func IoctlGetUint32(fd int, req uint) (uint32, error) {
- var value uint32
- err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
- return value, err
-}
-
-func IoctlGetRTCTime(fd int) (*RTCTime, error) {
- var value RTCTime
- err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
- return &value, err
-}
+// These are defined in ioctl.go and ioctl_linux.go.
//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
@@ -133,6 +96,12 @@
return openat(dirfd, path, flags|O_LARGEFILE, mode)
}
+//sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error)
+
+func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
+ return openat2(dirfd, path, how, SizeofOpenHow)
+}
+
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
@@ -591,6 +560,36 @@
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
}
+// SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939
+// protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information
+// on the purposes of the fields, check the official linux kernel documentation
+// available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst
+type SockaddrCANJ1939 struct {
+ Ifindex int
+ Name uint64
+ PGN uint32
+ Addr uint8
+ raw RawSockaddrCAN
+}
+
+func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_CAN
+ sa.raw.Ifindex = int32(sa.Ifindex)
+ n := (*[8]byte)(unsafe.Pointer(&sa.Name))
+ for i := 0; i < 8; i++ {
+ sa.raw.Addr[i] = n[i]
+ }
+ p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
+ for i := 0; i < 4; i++ {
+ sa.raw.Addr[i+8] = p[i]
+ }
+ sa.raw.Addr[12] = sa.Addr
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
+}
+
// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.
// SockaddrALG enables userspace access to the Linux kernel's cryptography
// subsystem. The Type and Name fields specify which type of hash or cipher
@@ -698,16 +697,19 @@
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
+ // - VMADDR_CID_LOCAL: refers to local communication (loopback).
// - VMADDR_CID_HOST: refers to other processes on the host.
- CID uint32
- Port uint32
- raw RawSockaddrVM
+ CID uint32
+ Port uint32
+ Flags uint8
+ raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
+ sa.raw.Flags = sa.Flags
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
@@ -839,6 +841,113 @@
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
}
+// SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets.
+type SockaddrL2TPIP struct {
+ Addr [4]byte
+ ConnId uint32
+ raw RawSockaddrL2TPIP
+}
+
+func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_INET
+ sa.raw.Conn_id = sa.ConnId
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.raw.Addr[i] = sa.Addr[i]
+ }
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
+}
+
+// SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets.
+type SockaddrL2TPIP6 struct {
+ Addr [16]byte
+ ZoneId uint32
+ ConnId uint32
+ raw RawSockaddrL2TPIP6
+}
+
+func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_INET6
+ sa.raw.Conn_id = sa.ConnId
+ sa.raw.Scope_id = sa.ZoneId
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.raw.Addr[i] = sa.Addr[i]
+ }
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
+}
+
+// SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets.
+type SockaddrIUCV struct {
+ UserID string
+ Name string
+ raw RawSockaddrIUCV
+}
+
+func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_IUCV
+ // These are EBCDIC encoded by the kernel, but we still need to pad them
+ // with blanks. Initializing with blanks allows the caller to feed in either
+ // a padded or an unpadded string.
+ for i := 0; i < 8; i++ {
+ sa.raw.Nodeid[i] = ' '
+ sa.raw.User_id[i] = ' '
+ sa.raw.Name[i] = ' '
+ }
+ if len(sa.UserID) > 8 || len(sa.Name) > 8 {
+ return nil, 0, EINVAL
+ }
+ for i, b := range []byte(sa.UserID[:]) {
+ sa.raw.User_id[i] = int8(b)
+ }
+ for i, b := range []byte(sa.Name[:]) {
+ sa.raw.Name[i] = int8(b)
+ }
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
+}
+
+type SockaddrNFC struct {
+ DeviceIdx uint32
+ TargetIdx uint32
+ NFCProtocol uint32
+ raw RawSockaddrNFC
+}
+
+func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Sa_family = AF_NFC
+ sa.raw.Dev_idx = sa.DeviceIdx
+ sa.raw.Target_idx = sa.TargetIdx
+ sa.raw.Nfc_protocol = sa.NFCProtocol
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
+}
+
+type SockaddrNFCLLCP struct {
+ DeviceIdx uint32
+ TargetIdx uint32
+ NFCProtocol uint32
+ DestinationSAP uint8
+ SourceSAP uint8
+ ServiceName string
+ raw RawSockaddrNFCLLCP
+}
+
+func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Sa_family = AF_NFC
+ sa.raw.Dev_idx = sa.DeviceIdx
+ sa.raw.Target_idx = sa.TargetIdx
+ sa.raw.Nfc_protocol = sa.NFCProtocol
+ sa.raw.Dsap = sa.DestinationSAP
+ sa.raw.Ssap = sa.SourceSAP
+ if len(sa.ServiceName) > len(sa.raw.Service_name) {
+ return nil, 0, EINVAL
+ }
+ copy(sa.raw.Service_name[:], sa.ServiceName)
+ sa.raw.SetServiceNameLen(len(sa.ServiceName))
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
+}
+
+var socketProtocol = func(fd int) (int, error) {
+ return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
+}
+
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_NETLINK:
@@ -884,40 +993,74 @@
for n < len(pp.Path) && pp.Path[n] != 0 {
n++
}
- bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
+ bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
sa.Name = string(bytes)
return sa, nil
case AF_INET:
- pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet4)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- for i := 0; i < len(sa.Addr); i++ {
- sa.Addr[i] = pp.Addr[i]
+ proto, err := socketProtocol(fd)
+ if err != nil {
+ return nil, err
}
- return sa, nil
+
+ switch proto {
+ case IPPROTO_L2TP:
+ pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
+ sa := new(SockaddrL2TPIP)
+ sa.ConnId = pp.Conn_id
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.Addr[i] = pp.Addr[i]
+ }
+ return sa, nil
+ default:
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet4)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.Addr[i] = pp.Addr[i]
+ }
+ return sa, nil
+ }
case AF_INET6:
- pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet6)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.ZoneId = pp.Scope_id
- for i := 0; i < len(sa.Addr); i++ {
- sa.Addr[i] = pp.Addr[i]
+ proto, err := socketProtocol(fd)
+ if err != nil {
+ return nil, err
}
- return sa, nil
+
+ switch proto {
+ case IPPROTO_L2TP:
+ pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))
+ sa := new(SockaddrL2TPIP6)
+ sa.ConnId = pp.Conn_id
+ sa.ZoneId = pp.Scope_id
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.Addr[i] = pp.Addr[i]
+ }
+ return sa, nil
+ default:
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet6)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.ZoneId = pp.Scope_id
+ for i := 0; i < len(sa.Addr); i++ {
+ sa.Addr[i] = pp.Addr[i]
+ }
+ return sa, nil
+ }
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
- CID: pp.Cid,
- Port: pp.Port,
+ CID: pp.Cid,
+ Port: pp.Port,
+ Flags: pp.Flags,
}
return sa, nil
case AF_BLUETOOTH:
- proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
+ proto, err := socketProtocol(fd)
if err != nil {
return nil, err
}
@@ -986,6 +1129,92 @@
}
return sa, nil
+ case AF_IUCV:
+ pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))
+
+ var user [8]byte
+ var name [8]byte
+
+ for i := 0; i < 8; i++ {
+ user[i] = byte(pp.User_id[i])
+ name[i] = byte(pp.Name[i])
+ }
+
+ sa := &SockaddrIUCV{
+ UserID: string(user[:]),
+ Name: string(name[:]),
+ }
+ return sa, nil
+
+ case AF_CAN:
+ proto, err := socketProtocol(fd)
+ if err != nil {
+ return nil, err
+ }
+
+ pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
+
+ switch proto {
+ case CAN_J1939:
+ sa := &SockaddrCANJ1939{
+ Ifindex: int(pp.Ifindex),
+ }
+ name := (*[8]byte)(unsafe.Pointer(&sa.Name))
+ for i := 0; i < 8; i++ {
+ name[i] = pp.Addr[i]
+ }
+ pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
+ for i := 0; i < 4; i++ {
+ pgn[i] = pp.Addr[i+8]
+ }
+ addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
+ addr[0] = pp.Addr[12]
+ return sa, nil
+ default:
+ sa := &SockaddrCAN{
+ Ifindex: int(pp.Ifindex),
+ }
+ rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
+ for i := 0; i < 4; i++ {
+ rx[i] = pp.Addr[i]
+ }
+ tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
+ for i := 0; i < 4; i++ {
+ tx[i] = pp.Addr[i+4]
+ }
+ return sa, nil
+ }
+ case AF_NFC:
+ proto, err := socketProtocol(fd)
+ if err != nil {
+ return nil, err
+ }
+ switch proto {
+ case NFC_SOCKPROTO_RAW:
+ pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
+ sa := &SockaddrNFC{
+ DeviceIdx: pp.Dev_idx,
+ TargetIdx: pp.Target_idx,
+ NFCProtocol: pp.Nfc_protocol,
+ }
+ return sa, nil
+ case NFC_SOCKPROTO_LLCP:
+ pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
+ if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
+ return nil, EINVAL
+ }
+ sa := &SockaddrNFCLLCP{
+ DeviceIdx: pp.Dev_idx,
+ TargetIdx: pp.Target_idx,
+ NFCProtocol: pp.Nfc_protocol,
+ DestinationSAP: pp.Dsap,
+ SourceSAP: pp.Ssap,
+ ServiceName: string(pp.Service_name[:pp.Service_name_len]),
+ }
+ return sa, nil
+ default:
+ return nil, EINVAL
+ }
}
return nil, EAFNOSUPPORT
}
@@ -993,7 +1222,11 @@
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
- nfd, err = accept(fd, &rsa, &len)
+ // Try accept4 first for Android, then try accept for kernel older than 2.6.28
+ nfd, err = accept4(fd, &rsa, &len, 0)
+ if err == ENOSYS {
+ nfd, err = accept(fd, &rsa, &len)
+ }
if err != nil {
return
}
@@ -1247,8 +1480,8 @@
return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
}
-//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
-//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
+//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
+//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var msg Msghdr
@@ -1493,8 +1726,12 @@
func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
+func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
+
func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
+func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
+
func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
@@ -1551,17 +1788,27 @@
//sys Acct(path string) (err error)
//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
//sys Adjtimex(buf *Timex) (state int, err error)
-//sys Capget(hdr *CapUserHeader, data *CapUserData) (err error)
-//sys Capset(hdr *CapUserHeader, data *CapUserData) (err error)
+//sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error)
+//sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error)
//sys Chdir(path string) (err error)
//sys Chroot(path string) (err error)
//sys ClockGetres(clockid int32, res *Timespec) (err error)
//sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
//sys Close(fd int) (err error)
+//sys CloseRange(first uint, last uint, flags uint) (err error)
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys DeleteModule(name string, flags int) (err error)
//sys Dup(oldfd int) (fd int, err error)
+
+func Dup2(oldfd, newfd int) error {
+ // Android O and newer blocks dup2; riscv and arm64 don't implement dup2.
+ if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
+ return Dup3(oldfd, newfd, 0)
+ }
+ return dup2(oldfd, newfd)
+}
+
//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)
@@ -1571,7 +1818,6 @@
//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 Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
//sys FinitModule(fd int, params string, flags int) (err error)
@@ -1613,8 +1859,8 @@
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, 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 Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
+//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
+//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
//sys read(fd int, p []byte) (n int, err error)
//sys Removexattr(path string, attr string) (err error)
@@ -1627,6 +1873,17 @@
//sysnb Settimeofday(tv *Timeval) (err error)
//sys Setns(fd int, nstype int) (err error)
+// PrctlRetInt performs a prctl operation specified by option and further
+// optional arguments arg2 through arg5 depending on option. It returns a
+// non-negative integer that is returned by the prctl syscall.
+func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
+ ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
+ if err != 0 {
+ return 0, err
+ }
+ return int(ret), nil
+}
+
// issue 1435.
// On linux Setuid and Setgid only affects the current thread, not the process.
// This does not match what most callers expect so we must return an error
@@ -1640,6 +1897,30 @@
return EOPNOTSUPP
}
+// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
+// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability.
+// If the call fails due to other reasons, current fsgid will be returned.
+func SetfsgidRetGid(gid int) (int, error) {
+ return setfsgid(gid)
+}
+
+// SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set.
+// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability
+// If the call fails due to other reasons, current fsuid will be returned.
+func SetfsuidRetUid(uid int) (int, error) {
+ return setfsuid(uid)
+}
+
+func Setfsgid(gid int) error {
+ _, err := setfsgid(gid)
+ return err
+}
+
+func Setfsuid(uid int) error {
+ _, err := setfsuid(uid)
+ return err
+}
+
func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
return signalfd(fd, sigmask, _C__NSIG/8, flags)
}
@@ -1652,6 +1933,9 @@
//sys Syncfs(fd int) (err error)
//sysnb Sysinfo(info *Sysinfo_t) (err error)
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
+//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error)
+//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
+//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
//sysnb Times(tms *Tms) (ticks uintptr, err error)
//sysnb Umask(mask int) (oldmask int)
@@ -1662,6 +1946,123 @@
//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
+//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
+//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
+//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
+//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
+//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
+//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
+
+func bytes2iovec(bs [][]byte) []Iovec {
+ iovecs := make([]Iovec, len(bs))
+ for i, b := range bs {
+ iovecs[i].SetLen(len(b))
+ if len(b) > 0 {
+ iovecs[i].Base = &b[0]
+ } else {
+ iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
+ }
+ }
+ return iovecs
+}
+
+// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit
+// systems, hi will always be 0. On 32-bit systems, offs will be split in half.
+// preadv/pwritev chose this calling convention so they don't need to add a
+// padding-register for alignment on ARM.
+func offs2lohi(offs int64) (lo, hi uintptr) {
+ return uintptr(offs), uintptr(uint64(offs) >> SizeofLong)
+}
+
+func Readv(fd int, iovs [][]byte) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ n, err = readv(fd, iovecs)
+ readvRacedetect(iovecs, n, err)
+ return n, err
+}
+
+func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ lo, hi := offs2lohi(offset)
+ n, err = preadv(fd, iovecs, lo, hi)
+ readvRacedetect(iovecs, n, err)
+ return n, err
+}
+
+func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ lo, hi := offs2lohi(offset)
+ n, err = preadv2(fd, iovecs, lo, hi, flags)
+ readvRacedetect(iovecs, n, err)
+ return n, err
+}
+
+func readvRacedetect(iovecs []Iovec, n int, err error) {
+ if !raceenabled {
+ return
+ }
+ for i := 0; n > 0 && i < len(iovecs); i++ {
+ m := int(iovecs[i].Len)
+ if m > n {
+ m = n
+ }
+ n -= m
+ if m > 0 {
+ raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
+ }
+ }
+ if err == nil {
+ raceAcquire(unsafe.Pointer(&ioSync))
+ }
+}
+
+func Writev(fd int, iovs [][]byte) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ if raceenabled {
+ raceReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ n, err = writev(fd, iovecs)
+ writevRacedetect(iovecs, n)
+ return n, err
+}
+
+func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ if raceenabled {
+ raceReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ lo, hi := offs2lohi(offset)
+ n, err = pwritev(fd, iovecs, lo, hi)
+ writevRacedetect(iovecs, n)
+ return n, err
+}
+
+func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
+ iovecs := bytes2iovec(iovs)
+ if raceenabled {
+ raceReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ lo, hi := offs2lohi(offset)
+ n, err = pwritev2(fd, iovecs, lo, hi, flags)
+ writevRacedetect(iovecs, n)
+ return n, err
+}
+
+func writevRacedetect(iovecs []Iovec, n int) {
+ if !raceenabled {
+ return
+ }
+ for i := 0; n > 0 && i < len(iovecs); i++ {
+ m := int(iovecs[i].Len)
+ if m > n {
+ m = n
+ }
+ n -= m
+ if m > 0 {
+ raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
+ }
+ }
+}
// mmap varies by architecture; see syscall_linux_*.go.
//sys munmap(addr uintptr, length uintptr) (err error)
@@ -1704,11 +2105,30 @@
return int(n), nil
}
+func isGroupMember(gid int) bool {
+ groups, err := Getgroups()
+ if err != nil {
+ return false
+ }
+
+ for _, g := range groups {
+ if g == gid {
+ return true
+ }
+ }
+ return false
+}
+
//sys faccessat(dirfd int, path string, mode uint32) (err error)
+//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error)
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
- if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
- return EINVAL
+ if flags == 0 {
+ return faccessat(dirfd, path, mode)
+ }
+
+ if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
+ return err
}
// The Linux kernel faccessat system call does not take any flags.
@@ -1717,8 +2137,8 @@
// Because people naturally expect syscall.Faccessat to act
// like C faccessat, we do the same.
- if flags == 0 {
- return faccessat(dirfd, path, mode)
+ if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
+ return EINVAL
}
var st Stat_t
@@ -1761,7 +2181,7 @@
gid = Getgid()
}
- if uint32(gid) == st.Gid {
+ if uint32(gid) == st.Gid || isGroupMember(gid) {
fmode = (st.Mode >> 3) & 7
} else {
fmode = st.Mode & 7
@@ -1775,8 +2195,8 @@
return EACCES
}
-//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
-//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
+//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
+//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
// fileHandle is the argument to nameToHandleAt and openByHandleAt. We
// originally tried to generate it via unix/linux/types.go with "type
@@ -1851,6 +2271,29 @@
return openByHandleAt(mountFD, handle.fileHandle, flags)
}
+// Klogset wraps the sys_syslog system call; it sets console_loglevel to
+// the value specified by arg and passes a dummy pointer to bufp.
+func Klogset(typ int, arg int) (err error) {
+ var p unsafe.Pointer
+ _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
+ if errno != 0 {
+ return errnoErr(errno)
+ }
+ return nil
+}
+
+// RemoteIovec is Iovec with the pointer replaced with an integer.
+// It is used for ProcessVMReadv and ProcessVMWritev, where the pointer
+// refers to a location in a different process' address space, which
+// would confuse the Go garbage collector.
+type RemoteIovec struct {
+ Base uintptr
+ Len int
+}
+
+//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV
+//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV
+
/*
* Unimplemented
*/
@@ -1945,7 +2388,6 @@
// TimerGetoverrun
// TimerGettime
// TimerSettime
-// Timerfd
// Tkill (obsolete)
// Tuxcall
// Umount2