]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: Fix FD passing on OpenBSD
authorMatthew Dempsky <mdempsky@google.com>
Wed, 27 Feb 2013 04:19:23 +0000 (15:19 +1100)
committerDave Cheney <dave@cheney.net>
Wed, 27 Feb 2013 04:19:23 +0000 (15:19 +1100)
Fixes #3349.

R=bradfitz, dave, minux.ma
CC=golang-dev
https://golang.org/cl/7383056

src/pkg/syscall/passfd_test.go
src/pkg/syscall/sockcmsg_unix.go

index 71a4a495f0cd4dc73961b440a0cc37fe88f52a8a..a0e590950755fc8f3b7866ddf42b394c87c8629f 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux darwin freebsd netbsd
+// +build linux darwin freebsd netbsd openbsd
 
 package syscall_test
 
@@ -149,3 +149,49 @@ func passFDChild() {
                return
        }
 }
+
+// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
+// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
+func TestUnixRightsRoundtrip(t *testing.T) {
+       testCases := [...][][]int{
+               {{42}},
+               {{1, 2}},
+               {{3, 4, 5}},
+               {{}},
+               {{1, 2}, {3, 4, 5}, {}, {7}},
+       }
+       for _, testCase := range testCases {
+               b := []byte{}
+               var n int
+               for _, fds := range testCase {
+                       // Last assignment to n wins
+                       n = len(b) + syscall.CmsgLen(4*len(fds))
+                       b = append(b, syscall.UnixRights(fds...)...)
+               }
+               // Truncate b
+               b = b[:n]
+
+               scms, err := syscall.ParseSocketControlMessage(b)
+               if err != nil {
+                       t.Fatalf("ParseSocketControlMessage: %v", err)
+               }
+               if len(scms) != len(testCase) {
+                       t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
+               }
+               for i, scm := range scms {
+                       gotFds, err := syscall.ParseUnixRights(&scm)
+                       if err != nil {
+                               t.Fatalf("ParseUnixRights: %v", err)
+                       }
+                       wantFds := testCase[i]
+                       if len(gotFds) != len(wantFds) {
+                               t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
+                       }
+                       for j, fd := range gotFds {
+                               if fd != wantFds[j] {
+                                       t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
+                               }
+                       }
+               }
+       }
+}
index 3af3068fd93c471f79daf91869db42bc499c8c33..bc7cf2098f9d13b50f48bb601a1e99a6d5782a33 100644 (file)
@@ -10,7 +10,7 @@ package syscall
 
 import "unsafe"
 
-// Round the length of a raw sockaddr up to align it propery.
+// Round the length of a raw sockaddr up to align it properly.
 func cmsgAlignOf(salen int) int {
        salign := sizeofPtr
        // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
@@ -18,9 +18,6 @@ func cmsgAlignOf(salen int) int {
        if darwinAMD64 {
                salign = 4
        }
-       if salen == 0 {
-               return salign
-       }
        return (salen + salign - 1) & ^(salign - 1)
 }
 
@@ -50,14 +47,15 @@ type SocketControlMessage struct {
 // messages.
 func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
        var msgs []SocketControlMessage
-       for len(b) >= CmsgLen(0) {
-               h, dbuf, err := socketControlMessageHeaderAndData(b)
+       i := 0
+       for i+CmsgLen(0) <= len(b) {
+               h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
                if err != nil {
                        return nil, err
                }
-               m := SocketControlMessage{Header: *h, Data: dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]}
+               m := SocketControlMessage{Header: *h, Data: dbuf}
                msgs = append(msgs, m)
-               b = b[cmsgAlignOf(int(h.Len)):]
+               i += cmsgAlignOf(int(h.Len))
        }
        return msgs, nil
 }
@@ -67,7 +65,7 @@ func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
        if h.Len < SizeofCmsghdr || int(h.Len) > len(b) {
                return nil, nil, EINVAL
        }
-       return h, b[cmsgAlignOf(SizeofCmsghdr):], nil
+       return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil
 }
 
 // UnixRights encodes a set of open file descriptors into a socket