vendor/golang.org/x/sys/unix/sockcmsg_unix.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
     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