OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [syscall/] [sockcmsg_unix.go] - Blame information for rev 858

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// +build darwin freebsd linux netbsd openbsd
6
 
7
// Socket control messages
8
 
9
package syscall
10
 
11
import (
12
        "unsafe"
13
)
14
 
15
// Round the length of a raw sockaddr up to align it propery.
16
func cmsgAlignOf(salen int) int {
17
        salign := int(sizeofPtr)
18
        // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
19
        // aligned access to BSD subsystem.
20
        if darwinAMD64 {
21
                salign = 4
22
        }
23
        if salen == 0 {
24
                return salign
25
        }
26
        return (salen + salign - 1) & ^(salign - 1)
27
}
28
 
29
// CmsgLen returns the value to store in the Len field of the Cmsghdr
30
// structure, taking into account any necessary alignment.
31
func CmsgLen(datalen int) int {
32
        return cmsgAlignOf(SizeofCmsghdr) + datalen
33
}
34
 
35
// CmsgSpace returns the number of bytes an ancillary element with
36
// payload of the passed data length occupies.
37
func CmsgSpace(datalen int) int {
38
        return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
39
}
40
 
41
func cmsgData(cmsg *Cmsghdr) unsafe.Pointer {
42
        return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + uintptr(SizeofCmsghdr))
43
}
44
 
45
type SocketControlMessage struct {
46
        Header Cmsghdr
47
        Data   []byte
48
}
49
 
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
62
                }
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)):]
68
        }
69
 
70
        return cmsgs, e
71
}
72
 
73
func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
74
        h := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
75
        if int(h.Len) < SizeofCmsghdr || int(h.Len) > len(buf) {
76
                return nil, nil, EINVAL
77
        }
78
        return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
79
}
80
 
81
// UnixRights encodes a set of open file descriptors into a socket
82
// control message for sending to another process.
83
func UnixRights(fds ...int) []byte {
84
        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))
92
        for _, fd := range fds {
93
                *(*int32)(unsafe.Pointer(data)) = int32(fd)
94
                data += 4
95
        }
96
 
97
        return buf
98
}
99
 
100
// ParseUnixRights decodes a socket control message that contains an
101
// 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])))
112
                j++
113
        }
114
        return fds, nil
115
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.