~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/syscall/sockcmsg_unix.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 
9
9
package syscall
10
10
 
11
 
import (
12
 
        "unsafe"
13
 
)
 
11
import "unsafe"
14
12
 
15
 
// Round the length of a raw sockaddr up to align it propery.
 
13
// Round the length of a raw sockaddr up to align it properly.
16
14
func cmsgAlignOf(salen int) int {
17
15
        salign := sizeofPtr
18
16
        // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
20
18
        if darwinAMD64 {
21
19
                salign = 4
22
20
        }
23
 
        if salen == 0 {
24
 
                return salign
25
 
        }
26
21
        return (salen + salign - 1) & ^(salign - 1)
27
22
}
28
23
 
38
33
        return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
39
34
}
40
35
 
41
 
func cmsgData(cmsg *Cmsghdr) unsafe.Pointer {
42
 
        return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + SizeofCmsghdr)
 
36
func cmsgData(h *Cmsghdr) unsafe.Pointer {
 
37
        return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)))
43
38
}
44
39
 
 
40
// SocketControlMessage represents a socket control message.
45
41
type SocketControlMessage struct {
46
42
        Header Cmsghdr
47
43
        Data   []byte
48
44
}
49
45
 
50
 
func ParseSocketControlMessage(buf []byte) ([]SocketControlMessage, error) {
51
 
        var (
52
 
                h     *Cmsghdr
53
 
                dbuf  []byte
54
 
                e     error
55
 
                cmsgs []SocketControlMessage
56
 
        )
57
 
 
58
 
        for len(buf) >= CmsgLen(0) {
59
 
                h, dbuf, e = socketControlMessageHeaderAndData(buf)
60
 
                if e != nil {
61
 
                        break
 
46
// ParseSocketControlMessage parses b as an array of socket control
 
47
// messages.
 
48
func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
 
49
        var msgs []SocketControlMessage
 
50
        i := 0
 
51
        for i+CmsgLen(0) <= len(b) {
 
52
                h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
 
53
                if err != nil {
 
54
                        return nil, err
62
55
                }
63
 
                m := SocketControlMessage{}
64
 
                m.Header = *h
65
 
                m.Data = dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]
66
 
                cmsgs = append(cmsgs, m)
67
 
                buf = buf[cmsgAlignOf(int(h.Len)):]
 
56
                m := SocketControlMessage{Header: *h, Data: dbuf}
 
57
                msgs = append(msgs, m)
 
58
                i += cmsgAlignOf(int(h.Len))
68
59
        }
69
 
 
70
 
        return cmsgs, e
 
60
        return msgs, nil
71
61
}
72
62
 
73
 
func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
74
 
        h := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
75
 
        if h.Len < SizeofCmsghdr || int(h.Len) > len(buf) {
 
63
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
 
64
        h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
 
65
        if h.Len < SizeofCmsghdr || int(h.Len) > len(b) {
76
66
                return nil, nil, EINVAL
77
67
        }
78
 
        return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
 
68
        return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil
79
69
}
80
70
 
81
71
// UnixRights encodes a set of open file descriptors into a socket
82
72
// control message for sending to another process.
83
73
func UnixRights(fds ...int) []byte {
84
74
        datalen := len(fds) * 4
85
 
        buf := make([]byte, CmsgSpace(datalen))
86
 
        cmsg := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
87
 
        cmsg.Level = SOL_SOCKET
88
 
        cmsg.Type = SCM_RIGHTS
89
 
        cmsg.SetLen(CmsgLen(datalen))
90
 
 
91
 
        data := uintptr(cmsgData(cmsg))
 
75
        b := make([]byte, CmsgSpace(datalen))
 
76
        h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
 
77
        h.Level = SOL_SOCKET
 
78
        h.Type = SCM_RIGHTS
 
79
        h.SetLen(CmsgLen(datalen))
 
80
        data := uintptr(cmsgData(h))
92
81
        for _, fd := range fds {
93
82
                *(*int32)(unsafe.Pointer(data)) = int32(fd)
94
83
                data += 4
95
84
        }
96
 
 
97
 
        return buf
 
85
        return b
98
86
}
99
87
 
100
88
// ParseUnixRights decodes a socket control message that contains an
101
89
// integer array of open file descriptors from another process.
102
 
func ParseUnixRights(msg *SocketControlMessage) ([]int, error) {
103
 
        if msg.Header.Level != SOL_SOCKET {
104
 
                return nil, EINVAL
105
 
        }
106
 
        if msg.Header.Type != SCM_RIGHTS {
107
 
                return nil, EINVAL
108
 
        }
109
 
        fds := make([]int, len(msg.Data)>>2)
110
 
        for i, j := 0, 0; i < len(msg.Data); i += 4 {
111
 
                fds[j] = int(*(*int32)(unsafe.Pointer(&msg.Data[i])))
 
90
func ParseUnixRights(m *SocketControlMessage) ([]int, error) {
 
91
        if m.Header.Level != SOL_SOCKET {
 
92
                return nil, EINVAL
 
93
        }
 
94
        if m.Header.Type != SCM_RIGHTS {
 
95
                return nil, EINVAL
 
96
        }
 
97
        fds := make([]int, len(m.Data)>>2)
 
98
        for i, j := 0, 0; i < len(m.Data); i += 4 {
 
99
                fds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i])))
112
100
                j++
113
101
        }
114
102
        return fds, nil