Commit 82ca2551 authored by ian's avatar ian
Browse files

syscall: Support socket control messages.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183745 138bc75d-0d04-0410-961f-82ee72b054a4
parent f444be4c
...@@ -1593,6 +1593,13 @@ else # !LIBGO_IS_SOLARIS ...@@ -1593,6 +1593,13 @@ else # !LIBGO_IS_SOLARIS
syscall_uname_file = go/syscall/libcall_uname.go syscall_uname_file = go/syscall/libcall_uname.go
endif endif
# GNU/Linux specific socket control messages.
if LIBGO_IS_LINUX
syscall_sockcmsg_file = go/syscall/sockcmsg_linux.go
else
syscall_sockcmsg_file =
endif
# Support for netlink sockets and messages. # Support for netlink sockets and messages.
if LIBGO_IS_LINUX if LIBGO_IS_LINUX
syscall_netlink_file = go/syscall/netlink_linux.go syscall_netlink_file = go/syscall/netlink_linux.go
...@@ -1606,8 +1613,10 @@ go_base_syscall_files = \ ...@@ -1606,8 +1613,10 @@ go_base_syscall_files = \
go/syscall/libcall_support.go \ go/syscall/libcall_support.go \
go/syscall/libcall_posix.go \ go/syscall/libcall_posix.go \
go/syscall/socket.go \ go/syscall/socket.go \
go/syscall/sockcmsg_unix.go \
go/syscall/str.go \ go/syscall/str.go \
go/syscall/syscall.go \ go/syscall/syscall.go \
$(syscall_sockcmsg_file) \
$(syscall_syscall_file) \ $(syscall_syscall_file) \
$(syscall_exec_file) \ $(syscall_exec_file) \
$(syscall_exec_os_file) \ $(syscall_exec_os_file) \
......
...@@ -1923,6 +1923,10 @@ go_unicode_utf8_files = \ ...@@ -1923,6 +1923,10 @@ go_unicode_utf8_files = \
# 32-bit Solaris 2/x86 needs _nuname, handled in libcall_solaris_386.go. # 32-bit Solaris 2/x86 needs _nuname, handled in libcall_solaris_386.go.
@LIBGO_IS_386_TRUE@@LIBGO_IS_SOLARIS_TRUE@syscall_uname_file = @LIBGO_IS_386_TRUE@@LIBGO_IS_SOLARIS_TRUE@syscall_uname_file =
@LIBGO_IS_SOLARIS_FALSE@syscall_uname_file = go/syscall/libcall_uname.go @LIBGO_IS_SOLARIS_FALSE@syscall_uname_file = go/syscall/libcall_uname.go
@LIBGO_IS_LINUX_FALSE@syscall_sockcmsg_file =
# GNU/Linux specific socket control messages.
@LIBGO_IS_LINUX_TRUE@syscall_sockcmsg_file = go/syscall/sockcmsg_linux.go
@LIBGO_IS_LINUX_FALSE@syscall_netlink_file = @LIBGO_IS_LINUX_FALSE@syscall_netlink_file =
# Support for netlink sockets and messages. # Support for netlink sockets and messages.
...@@ -1933,8 +1937,10 @@ go_base_syscall_files = \ ...@@ -1933,8 +1937,10 @@ go_base_syscall_files = \
go/syscall/libcall_support.go \ go/syscall/libcall_support.go \
go/syscall/libcall_posix.go \ go/syscall/libcall_posix.go \
go/syscall/socket.go \ go/syscall/socket.go \
go/syscall/sockcmsg_unix.go \
go/syscall/str.go \ go/syscall/str.go \
go/syscall/syscall.go \ go/syscall/syscall.go \
$(syscall_sockcmsg_file) \
$(syscall_syscall_file) \ $(syscall_syscall_file) \
$(syscall_exec_file) \ $(syscall_exec_file) \
$(syscall_exec_os_file) \ $(syscall_exec_os_file) \
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
// Round the length of a raw sockaddr up to align it propery. // Round the length of a raw sockaddr up to align it propery.
func cmsgAlignOf(salen int) int { func cmsgAlignOf(salen int) int {
salign := sizeofPtr salign := int(sizeofPtr)
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem. // aligned access to BSD subsystem.
if darwinAMD64 { if darwinAMD64 {
...@@ -39,7 +39,7 @@ func CmsgSpace(datalen int) int { ...@@ -39,7 +39,7 @@ func CmsgSpace(datalen int) int {
} }
func cmsgData(cmsg *Cmsghdr) unsafe.Pointer { func cmsgData(cmsg *Cmsghdr) unsafe.Pointer {
return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + SizeofCmsghdr) return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + uintptr(SizeofCmsghdr))
} }
type SocketControlMessage struct { type SocketControlMessage struct {
...@@ -72,7 +72,7 @@ func ParseSocketControlMessage(buf []byte) ([]SocketControlMessage, error) { ...@@ -72,7 +72,7 @@ func ParseSocketControlMessage(buf []byte) ([]SocketControlMessage, error) {
func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) { func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
h := (*Cmsghdr)(unsafe.Pointer(&buf[0])) h := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
if h.Len < SizeofCmsghdr || int(h.Len) > len(buf) { if int(h.Len) < SizeofCmsghdr || int(h.Len) > len(buf) {
return nil, nil, EINVAL return nil, nil, EINVAL
} }
return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
......
...@@ -17,12 +17,12 @@ import "unsafe" ...@@ -17,12 +17,12 @@ import "unsafe"
var SocketDisableIPv6 bool var SocketDisableIPv6 bool
type Sockaddr interface { type Sockaddr interface {
sockaddr() (ptr *RawSockaddrAny, len Socklen_t, err error) // lowercase; only we can define Sockaddrs sockaddr() (ptr *RawSockaddrAny, len Socklen_t, err error) // lowercase; only we can define Sockaddrs
} }
type RawSockaddrAny struct { type RawSockaddrAny struct {
Addr RawSockaddr Addr RawSockaddr
Pad [12]int8 Pad [12]int8
} }
const SizeofSockaddrAny = 0x1c const SizeofSockaddrAny = 0x1c
...@@ -30,7 +30,7 @@ const SizeofSockaddrAny = 0x1c ...@@ -30,7 +30,7 @@ const SizeofSockaddrAny = 0x1c
type SockaddrInet4 struct { type SockaddrInet4 struct {
Port int Port int
Addr [4]byte Addr [4]byte
raw RawSockaddrInet4 raw RawSockaddrInet4
} }
func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) { func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
...@@ -40,7 +40,7 @@ func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) { ...@@ -40,7 +40,7 @@ func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
sa.raw.Family = AF_INET sa.raw.Family = AF_INET
n := sa.raw.setLen() n := sa.raw.setLen()
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port>>8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i] sa.raw.Addr[i] = sa.Addr[i]
...@@ -49,10 +49,10 @@ func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) { ...@@ -49,10 +49,10 @@ func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
} }
type SockaddrInet6 struct { type SockaddrInet6 struct {
Port int Port int
ZoneId uint32 ZoneId uint32
Addr [16]byte Addr [16]byte
raw RawSockaddrInet6 raw RawSockaddrInet6
} }
func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) { func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
...@@ -62,7 +62,7 @@ func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) { ...@@ -62,7 +62,7 @@ func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
sa.raw.Family = AF_INET6 sa.raw.Family = AF_INET6
n := sa.raw.setLen() n := sa.raw.setLen()
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port>>8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { for i := 0; i < len(sa.Addr); i++ {
...@@ -73,7 +73,7 @@ func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) { ...@@ -73,7 +73,7 @@ func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
type SockaddrUnix struct { type SockaddrUnix struct {
Name string Name string
raw RawSockaddrUnix raw RawSockaddrUnix
} }
func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) { func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
...@@ -268,12 +268,12 @@ func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { ...@@ -268,12 +268,12 @@ func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
} }
type Linger struct { type Linger struct {
Onoff int32; Onoff int32
Linger int32; Linger int32
} }
func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l))); return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l)))
} }
func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
...@@ -405,3 +405,7 @@ func (iov *Iovec) SetLen(length int) { ...@@ -405,3 +405,7 @@ func (iov *Iovec) SetLen(length int) {
func (msghdr *Msghdr) SetControllen(length int) { func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = Msghdr_controllen_t(length) msghdr.Controllen = Msghdr_controllen_t(length)
} }
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = Cmsghdr_len_t(length)
}
...@@ -483,6 +483,43 @@ echo $msghdr | \ ...@@ -483,6 +483,43 @@ echo $msghdr | \
-e 's/msg_flags/Flags/' \ -e 's/msg_flags/Flags/' \
>> ${OUT} >> ${OUT}
# The MSG_ flags for Msghdr.
grep '^const _MSG_' gen-sysinfo.go | \
sed -e 's/^\(const \)_\(MSG_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
# The cmsghdr struct.
cmsghdr=`grep '^type _cmsghdr ' gen-sysinfo.go`
if test -n "$cmsghdr"; then
cmsghdr_len=`echo $cmsghdr | sed -n -e 's/^.*cmsg_len \([^ ]*\);.*$/\1/p'`
echo "type Cmsghdr_len_t $cmsghdr_len" >> ${OUT}
echo "$cmsghdr" | \
sed -e 's/_cmsghdr/Cmsghdr/' \
-e 's/cmsg_len *[a-zA-Z0-9_]*/Len Cmsghdr_len_t/' \
-e 's/cmsg_level/Level/' \
-e 's/cmsg_type/Type/' \
>> ${OUT}
# The size of the cmsghdr struct.
echo 'var SizeofCmsghdr = int(unsafe.Sizeof(Cmsghdr{}))' >> ${OUT}
fi
# The SCM_ flags for Cmsghdr.
grep '^const _SCM_' gen-sysinfo.go | \
sed -e 's/^\(const \)_\(SCM_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
# The ucred struct.
grep '^type _ucred ' gen-sysinfo.go | \
sed -e 's/_ucred/Ucred/' \
-e 's/pid/Pid/' \
-e 's/uid/Uid/' \
-e 's/gid/Gid/' \
>> ${OUT}
# The size of the ucred struct.
if grep 'type Ucred ' ${OUT} >/dev/null 2>&1; then
echo 'var SizeofUcred = int(unsafe.Sizeof(Ucred{}))' >> ${OUT}
fi
# The ip_mreq struct. # The ip_mreq struct.
grep '^type _ip_mreq ' gen-sysinfo.go | \ grep '^type _ip_mreq ' gen-sysinfo.go | \
sed -e 's/_ip_mreq/IPMreq/' \ sed -e 's/_ip_mreq/IPMreq/' \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment