summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/sys/unix/syscall_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/sys/unix/syscall_linux.go')
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux.go310
1 files changed, 270 insertions, 40 deletions
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 9908030cb..776040233 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -12,6 +12,8 @@
package unix
import (
+ "encoding/binary"
+ "net"
"syscall"
"unsafe"
)
@@ -55,17 +57,26 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
+// 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)))
+}
+
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
-func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
+func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
-func IoctlSetTermios(fd int, req uint, value *Termios) error {
+func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
@@ -489,6 +500,47 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
}
+// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets
+// using the RFCOMM protocol.
+//
+// Server example:
+//
+// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
+// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{
+// Channel: 1,
+// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00
+// })
+// _ = Listen(fd, 1)
+// nfd, sa, _ := Accept(fd)
+// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd)
+// Read(nfd, buf)
+//
+// Client example:
+//
+// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
+// _ = Connect(fd, &SockaddrRFCOMM{
+// Channel: 1,
+// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11
+// })
+// Write(fd, []byte(`hello`))
+type SockaddrRFCOMM struct {
+ // Addr represents a bluetooth address, byte ordering is little-endian.
+ Addr [6]uint8
+
+ // Channel is a designated bluetooth channel, only 1-30 are available for use.
+ // Since Linux 2.6.7 and further zero value is the first available channel.
+ Channel uint8
+
+ raw RawSockaddrRFCOMM
+}
+
+func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_BLUETOOTH
+ sa.raw.Channel = sa.Channel
+ sa.raw.Bdaddr = sa.Addr
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
+}
+
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
// The RxID and TxID fields are used for transport protocol addressing in
// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
@@ -651,7 +703,70 @@ func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
+type SockaddrXDP struct {
+ Flags uint16
+ Ifindex uint32
+ QueueID uint32
+ SharedUmemFD uint32
+ raw RawSockaddrXDP
+}
+
+func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_XDP
+ sa.raw.Flags = sa.Flags
+ sa.raw.Ifindex = sa.Ifindex
+ sa.raw.Queue_id = sa.QueueID
+ sa.raw.Shared_umem_fd = sa.SharedUmemFD
+
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
+}
+
+// This constant mirrors the #define of PX_PROTO_OE in
+// linux/if_pppox.h. We're defining this by hand here instead of
+// autogenerating through mkerrors.sh because including
+// linux/if_pppox.h causes some declaration conflicts with other
+// includes (linux/if_pppox.h includes linux/in.h, which conflicts
+// with netinet/in.h). Given that we only need a single zero constant
+// out of that file, it's cleaner to just define it by hand here.
+const px_proto_oe = 0
+
+type SockaddrPPPoE struct {
+ SID uint16
+ Remote net.HardwareAddr
+ Dev string
+ raw RawSockaddrPPPoX
+}
+
+func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if len(sa.Remote) != 6 {
+ return nil, 0, EINVAL
+ }
+ if len(sa.Dev) > IFNAMSIZ-1 {
+ return nil, 0, EINVAL
+ }
+
+ *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
+ // This next field is in host-endian byte order. We can't use the
+ // same unsafe pointer cast as above, because this value is not
+ // 32-bit aligned and some architectures don't allow unaligned
+ // access.
+ //
+ // However, the value of px_proto_oe is 0, so we can use
+ // encoding/binary helpers to write the bytes without worrying
+ // about the ordering.
+ binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
+ // This field is deliberately big-endian, unlike the previous
+ // one. The kernel expects SID to be in network byte order.
+ binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
+ copy(sa.raw[8:14], sa.Remote)
+ for i := 14; i < 14+IFNAMSIZ; i++ {
+ sa.raw[i] = 0
+ }
+ copy(sa.raw[14:], sa.Dev)
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
+}
+
+func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_NETLINK:
pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
@@ -728,6 +843,55 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
Port: pp.Port,
}
return sa, nil
+ case AF_BLUETOOTH:
+ proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
+ if err != nil {
+ return nil, err
+ }
+ // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections
+ switch proto {
+ case BTPROTO_L2CAP:
+ pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
+ sa := &SockaddrL2{
+ PSM: pp.Psm,
+ CID: pp.Cid,
+ Addr: pp.Bdaddr,
+ AddrType: pp.Bdaddr_type,
+ }
+ return sa, nil
+ case BTPROTO_RFCOMM:
+ pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
+ sa := &SockaddrRFCOMM{
+ Channel: pp.Channel,
+ Addr: pp.Bdaddr,
+ }
+ return sa, nil
+ }
+ case AF_XDP:
+ pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))
+ sa := &SockaddrXDP{
+ Flags: pp.Flags,
+ Ifindex: pp.Ifindex,
+ QueueID: pp.Queue_id,
+ SharedUmemFD: pp.Shared_umem_fd,
+ }
+ return sa, nil
+ case AF_PPPOX:
+ pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
+ if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
+ return nil, EINVAL
+ }
+ sa := &SockaddrPPPoE{
+ SID: binary.BigEndian.Uint16(pp[6:8]),
+ Remote: net.HardwareAddr(pp[8:14]),
+ }
+ for i := 14; i < 14+IFNAMSIZ; i++ {
+ if pp[i] == 0 {
+ sa.Dev = string(pp[14:i])
+ break
+ }
+ }
+ return sa, nil
}
return nil, EAFNOSUPPORT
}
@@ -739,7 +903,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
if err != nil {
return
}
- sa, err = anyToSockaddr(&rsa)
+ sa, err = anyToSockaddr(fd, &rsa)
if err != nil {
Close(nfd)
nfd = 0
@@ -757,7 +921,7 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small")
}
- sa, err = anyToSockaddr(&rsa)
+ sa, err = anyToSockaddr(fd, &rsa)
if err != nil {
Close(nfd)
nfd = 0
@@ -771,7 +935,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
if err = getsockname(fd, &rsa, &len); err != nil {
return
}
- return anyToSockaddr(&rsa)
+ return anyToSockaddr(fd, &rsa)
}
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
@@ -960,7 +1124,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
- from, err = anyToSockaddr(&rsa)
+ from, err = anyToSockaddr(fd, &rsa)
}
return
}
@@ -1030,7 +1194,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro
// The ptrace syscall differs from glibc's ptrace.
// Peeks returns the word in *data, not as the return value.
- var buf [sizeofPtr]byte
+ var buf [SizeofPtr]byte
// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
// access (PEEKUSER warns that it might), but if we don't
@@ -1038,12 +1202,12 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro
// boundary and not get the bytes leading up to the page
// boundary.
n := 0
- if addr%sizeofPtr != 0 {
- err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
+ if addr%SizeofPtr != 0 {
+ err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return 0, err
}
- n += copy(out, buf[addr%sizeofPtr:])
+ n += copy(out, buf[addr%SizeofPtr:])
out = out[n:]
}
@@ -1081,15 +1245,15 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c
// Leading edge.
n := 0
- if addr%sizeofPtr != 0 {
- var buf [sizeofPtr]byte
- err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
+ if addr%SizeofPtr != 0 {
+ var buf [SizeofPtr]byte
+ err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return 0, err
}
- n += copy(buf[addr%sizeofPtr:], data)
+ n += copy(buf[addr%SizeofPtr:], data)
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
- err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
+ err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
if err != nil {
return 0, err
}
@@ -1097,19 +1261,19 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c
}
// Interior.
- for len(data) > sizeofPtr {
+ for len(data) > SizeofPtr {
word := *((*uintptr)(unsafe.Pointer(&data[0])))
err = ptrace(pokeReq, pid, addr+uintptr(n), word)
if err != nil {
return n, err
}
- n += sizeofPtr
- data = data[sizeofPtr:]
+ n += SizeofPtr
+ data = data[SizeofPtr:]
}
// Trailing edge.
if len(data) > 0 {
- var buf [sizeofPtr]byte
+ var buf [SizeofPtr]byte
err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return n, err
@@ -1196,6 +1360,13 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
return mount(source, target, fstype, flags, datap)
}
+func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+ if raceenabled {
+ raceReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ return sendfile(outfd, infd, offset, count)
+}
+
// Sendto
// Recvfrom
// Socketpair
@@ -1208,9 +1379,11 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//sys Adjtimex(buf *Timex) (state int, 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 Close(fd int) (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)
//sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate1(flag int) (fd int, err error)
@@ -1223,7 +1396,12 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//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)
+//sys Flistxattr(fd int, dest []byte) (sz int, err error)
//sys Flock(fd int, how int) (err error)
+//sys Fremovexattr(fd int, attr string) (err error)
+//sys Fsetxattr(fd int, attr string, dest []byte, flags 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)
@@ -1241,6 +1419,7 @@ func Getpgrp() (pid int) {
//sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettid() (tid int)
//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
+//sys InitModule(moduleImage []byte, params string) (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)
@@ -1251,6 +1430,7 @@ func Getpgrp() (pid int) {
//sys Llistxattr(path string, dest []byte) (sz int, err error)
//sys Lremovexattr(path string, attr string) (err error)
//sys Lsetxattr(path string, attr string, data []byte, flags int) (err error)
+//sys MemfdCreate(name string, flags int) (fd 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)
@@ -1262,6 +1442,7 @@ func Getpgrp() (pid int) {
//sys read(fd int, p []byte) (n int, err error)
//sys Removexattr(path string, attr string) (err error)
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
+//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
//sys Setdomainname(p []byte) (err error)
//sys Sethostname(p []byte) (err error)
@@ -1329,15 +1510,12 @@ func Munmap(b []byte) (err error) {
// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
// using the specified flags.
func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
- n, _, errno := Syscall6(
- SYS_VMSPLICE,
- uintptr(fd),
- uintptr(unsafe.Pointer(&iovs[0])),
- uintptr(len(iovs)),
- uintptr(flags),
- 0,
- 0,
- )
+ var p unsafe.Pointer
+ if len(iovs) > 0 {
+ p = unsafe.Pointer(&iovs[0])
+ }
+
+ n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
if errno != 0 {
return 0, syscall.Errno(errno)
}
@@ -1350,10 +1528,70 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
return EINVAL
- } else if flags&(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
- return EOPNOTSUPP
}
- return faccessat(dirfd, path, mode)
+
+ // 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 flags == 0 {
+ return faccessat(dirfd, path, mode)
+ }
+
+ var st Stat_t
+ if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
+ return err
+ }
+
+ mode &= 7
+ if mode == 0 {
+ return nil
+ }
+
+ var uid int
+ if flags&AT_EACCESS != 0 {
+ uid = Geteuid()
+ } else {
+ uid = Getuid()
+ }
+
+ if uid == 0 {
+ if mode&1 == 0 {
+ // Root can read and write any file.
+ return nil
+ }
+ if st.Mode&0111 != 0 {
+ // Root can execute any file that anybody can execute.
+ return nil
+ }
+ return EACCES
+ }
+
+ var fmode uint32
+ if uint32(uid) == st.Uid {
+ fmode = (st.Mode >> 6) & 7
+ } else {
+ var gid int
+ if flags&AT_EACCESS != 0 {
+ gid = Getegid()
+ } else {
+ gid = Getgid()
+ }
+
+ if uint32(gid) == st.Gid {
+ fmode = (st.Mode >> 3) & 7
+ } else {
+ fmode = st.Mode & 7
+ }
+ }
+
+ if fmode&mode == mode {
+ return nil
+ }
+
+ return EACCES
}
/*
@@ -1365,21 +1603,14 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// Brk
// Capget
// Capset
-// ClockGetres
// ClockNanosleep
// ClockSettime
// Clone
-// CreateModule
-// DeleteModule
// EpollCtlOld
// EpollPwait
// EpollWaitOld
// Execve
-// Fgetxattr
-// Flistxattr
// Fork
-// Fremovexattr
-// Fsetxattr
// Futex
// GetKernelSyms
// GetMempolicy
@@ -1418,7 +1649,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// Pselect6
// Ptrace
// Putpmsg
-// QueryModule
// Quotactl
// Readahead
// Readv