equal
deleted
inserted
replaced
6 |
6 |
7 // Socket control messages |
7 // Socket control messages |
8 |
8 |
9 package unix |
9 package unix |
10 |
10 |
11 import "unsafe" |
11 import ( |
12 |
12 "unsafe" |
13 // Round the length of a raw sockaddr up to align it properly. |
13 ) |
14 func cmsgAlignOf(salen int) int { |
|
15 salign := sizeofPtr |
|
16 // NOTE: It seems like 64-bit Darwin, DragonFly BSD and |
|
17 // Solaris kernels still require 32-bit aligned access to |
|
18 // network subsystem. |
|
19 if darwin64Bit || dragonfly64Bit || solaris64Bit { |
|
20 salign = 4 |
|
21 } |
|
22 return (salen + salign - 1) & ^(salign - 1) |
|
23 } |
|
24 |
14 |
25 // CmsgLen returns the value to store in the Len field of the Cmsghdr |
15 // CmsgLen returns the value to store in the Len field of the Cmsghdr |
26 // structure, taking into account any necessary alignment. |
16 // structure, taking into account any necessary alignment. |
27 func CmsgLen(datalen int) int { |
17 func CmsgLen(datalen int) int { |
28 return cmsgAlignOf(SizeofCmsghdr) + datalen |
18 return cmsgAlignOf(SizeofCmsghdr) + datalen |
32 // payload of the passed data length occupies. |
22 // payload of the passed data length occupies. |
33 func CmsgSpace(datalen int) int { |
23 func CmsgSpace(datalen int) int { |
34 return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) |
24 return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) |
35 } |
25 } |
36 |
26 |
37 func cmsgData(h *Cmsghdr) unsafe.Pointer { |
27 func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer { |
38 return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr))) |
28 return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset) |
39 } |
29 } |
40 |
30 |
41 // SocketControlMessage represents a socket control message. |
31 // SocketControlMessage represents a socket control message. |
42 type SocketControlMessage struct { |
32 type SocketControlMessage struct { |
43 Header Cmsghdr |
33 Header Cmsghdr |
76 b := make([]byte, CmsgSpace(datalen)) |
66 b := make([]byte, CmsgSpace(datalen)) |
77 h := (*Cmsghdr)(unsafe.Pointer(&b[0])) |
67 h := (*Cmsghdr)(unsafe.Pointer(&b[0])) |
78 h.Level = SOL_SOCKET |
68 h.Level = SOL_SOCKET |
79 h.Type = SCM_RIGHTS |
69 h.Type = SCM_RIGHTS |
80 h.SetLen(CmsgLen(datalen)) |
70 h.SetLen(CmsgLen(datalen)) |
81 data := cmsgData(h) |
71 for i, fd := range fds { |
82 for _, fd := range fds { |
72 *(*int32)(h.data(4 * uintptr(i))) = int32(fd) |
83 *(*int32)(data) = int32(fd) |
|
84 data = unsafe.Pointer(uintptr(data) + 4) |
|
85 } |
73 } |
86 return b |
74 return b |
87 } |
75 } |
88 |
76 |
89 // ParseUnixRights decodes a socket control message that contains an |
77 // ParseUnixRights decodes a socket control message that contains an |