Patchwork libgo patch committed: Support socket control messages

login
register
mail settings
Submitter Ian Taylor
Date Jan. 30, 2012, 11:57 p.m.
Message ID <mcrbopkkakn.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/138670/
State New
Headers show

Comments

Ian Taylor - Jan. 30, 2012, 11:57 p.m.
This patch to libgo adds support for socket control messages.  The
source code was already there, but wasn't being built because mksysinfo
didn't generate the necessary type information.  This patch fixes that.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r e7bd4eb1ed7e libgo/Makefile.am
--- a/libgo/Makefile.am	Fri Jan 27 14:36:52 2012 -0800
+++ b/libgo/Makefile.am	Mon Jan 30 15:50:31 2012 -0800
@@ -1593,6 +1593,13 @@ 
 syscall_uname_file = go/syscall/libcall_uname.go
 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.
 if LIBGO_IS_LINUX
 syscall_netlink_file = go/syscall/netlink_linux.go
@@ -1606,8 +1613,10 @@ 
 	go/syscall/libcall_support.go \
 	go/syscall/libcall_posix.go \
 	go/syscall/socket.go \
+	go/syscall/sockcmsg_unix.go \
 	go/syscall/str.go \
 	go/syscall/syscall.go \
+	$(syscall_sockcmsg_file) \
 	$(syscall_syscall_file) \
 	$(syscall_exec_file) \
 	$(syscall_exec_os_file) \
diff -r e7bd4eb1ed7e libgo/go/syscall/sockcmsg_unix.go
--- a/libgo/go/syscall/sockcmsg_unix.go	Fri Jan 27 14:36:52 2012 -0800
+++ b/libgo/go/syscall/sockcmsg_unix.go	Mon Jan 30 15:50:31 2012 -0800
@@ -14,7 +14,7 @@ 
 
 // Round the length of a raw sockaddr up to align it propery.
 func cmsgAlignOf(salen int) int {
-	salign := sizeofPtr
+	salign := int(sizeofPtr)
 	// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
 	// aligned access to BSD subsystem.
 	if darwinAMD64 {
@@ -39,7 +39,7 @@ 
 }
 
 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 {
@@ -72,7 +72,7 @@ 
 
 func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
 	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 h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
diff -r e7bd4eb1ed7e libgo/go/syscall/socket.go
--- a/libgo/go/syscall/socket.go	Fri Jan 27 14:36:52 2012 -0800
+++ b/libgo/go/syscall/socket.go	Mon Jan 30 15:50:31 2012 -0800
@@ -17,12 +17,12 @@ 
 var SocketDisableIPv6 bool
 
 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 {
 	Addr RawSockaddr
-	Pad [12]int8
+	Pad  [12]int8
 }
 
 const SizeofSockaddrAny = 0x1c
@@ -30,7 +30,7 @@ 
 type SockaddrInet4 struct {
 	Port int
 	Addr [4]byte
-	raw RawSockaddrInet4
+	raw  RawSockaddrInet4
 }
 
 func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
@@ -40,7 +40,7 @@ 
 	sa.raw.Family = AF_INET
 	n := sa.raw.setLen()
 	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)
 	for i := 0; i < len(sa.Addr); i++ {
 		sa.raw.Addr[i] = sa.Addr[i]
@@ -49,10 +49,10 @@ 
 }
 
 type SockaddrInet6 struct {
-	Port int
+	Port   int
 	ZoneId uint32
-	Addr [16]byte
-	raw RawSockaddrInet6
+	Addr   [16]byte
+	raw    RawSockaddrInet6
 }
 
 func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
@@ -62,7 +62,7 @@ 
 	sa.raw.Family = AF_INET6
 	n := sa.raw.setLen()
 	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)
 	sa.raw.Scope_id = sa.ZoneId
 	for i := 0; i < len(sa.Addr); i++ {
@@ -73,7 +73,7 @@ 
 
 type SockaddrUnix struct {
 	Name string
-	raw RawSockaddrUnix
+	raw  RawSockaddrUnix
 }
 
 func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
@@ -268,12 +268,12 @@ 
 }
 
 type Linger struct {
-	Onoff int32;
-	Linger int32;
+	Onoff  int32
+	Linger int32
 }
 
 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) {
@@ -405,3 +405,7 @@ 
 func (msghdr *Msghdr) SetControllen(length int) {
 	msghdr.Controllen = Msghdr_controllen_t(length)
 }
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = Cmsghdr_len_t(length)
+}
diff -r e7bd4eb1ed7e libgo/mksysinfo.sh
--- a/libgo/mksysinfo.sh	Fri Jan 27 14:36:52 2012 -0800
+++ b/libgo/mksysinfo.sh	Mon Jan 30 15:50:31 2012 -0800
@@ -483,6 +483,43 @@ 
       -e 's/msg_flags/Flags/' \
     >> ${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.
 grep '^type _ip_mreq ' gen-sysinfo.go | \
     sed -e 's/_ip_mreq/IPMreq/' \