Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / syscalls / socket_bsd.go
blobeaf20f9edf0ec6d0bdd31444793503d21066eee0
1 // socket_bsd.go -- Socket handling specific to *BSD based systems.
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Low-level socket interface.
8 // Only for implementing net package.
9 // DO NOT USE DIRECTLY.
11 package syscall
13 import "unsafe"
15 type RawSockaddrInet4 struct {
16 Len uint8;
17 Family uint8;
18 Port uint16;
19 Addr [4]byte /* in_addr */;
20 Zero [8]uint8;
23 type RawSockaddrInet6 struct {
24 Len uint8;
25 Family uint8;
26 Port uint16;
27 Flowinfo uint32;
28 Addr [16]byte /* in6_addr */;
29 Scope_id uint32;
32 type RawSockaddrUnix struct {
33 Len uint8;
34 Family uint8;
35 Path [108]int8;
38 type RawSockaddr struct {
39 Len uint8;
40 Family uint8;
41 Data [14]int8;
44 func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
45 if sa.Port < 0 || sa.Port > 0xFFFF {
46 return nil, 0, EINVAL;
48 sa.raw.Len = SizeofSockaddrInet4;
49 sa.raw.Family = AF_INET;
50 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
51 p[0] = byte(sa.Port>>8);
52 p[1] = byte(sa.Port);
53 for i := 0; i < len(sa.Addr); i++ {
54 sa.raw.Addr[i] = sa.Addr[i];
56 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
59 func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
60 if sa.Port < 0 || sa.Port > 0xFFFF {
61 return nil, 0, EINVAL;
63 sa.raw.Len = SizeofSockaddrInet6;
64 sa.raw.Family = AF_INET6;
65 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
66 p[0] = byte(sa.Port>>8);
67 p[1] = byte(sa.Port);
68 for i := 0; i < len(sa.Addr); i++ {
69 sa.raw.Addr[i] = sa.Addr[i];
71 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
74 func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
75 name := sa.Name;
76 n := len(name);
77 if n >= len(sa.raw.Path) || n == 0 {
78 return nil, 0, EINVAL;
80 sa.raw.Len = byte(3 + n); // 2 for Family, Len; 1 for NUL.
81 sa.raw.Family = AF_UNIX;
82 for i := 0; i < n; i++ {
83 sa.raw.Path[i] = int8(name[i]);
85 if sa.raw.Path[0] == '@' {
86 sa.raw.Path[0] = 0;
89 // length is family, name, NUL.
90 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
93 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
94 switch rsa.Addr.Family {
95 case AF_UNIX:
96 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
97 if pp.Len < 3 || pp.Len > SizeofSockaddrUnix {
98 return nil, EINVAL
100 sa := new(SockaddrUnix)
101 n := int(pp.Len) - 3 // subtract leading Family, Len, terminating NUL.
102 for i := 0; i < n; i++ {
103 if pp.Path[i] == 0 {
104 // found early NUL; assume Len is overestimating.
105 n = i
106 break
109 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
110 sa.Name = string(bytes[0:n])
111 return sa, 0
113 case AF_INET:
114 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa));
115 sa := new(SockaddrInet4);
116 p := (*[2]byte)(unsafe.Pointer(&pp.Port));
117 sa.Port = int(p[0])<<8 + int(p[1]);
118 for i := 0; i < len(sa.Addr); i++ {
119 sa.Addr[i] = pp.Addr[i];
121 return sa, 0;
123 case AF_INET6:
124 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa));
125 sa := new(SockaddrInet6);
126 p := (*[2]byte)(unsafe.Pointer(&pp.Port));
127 sa.Port = int(p[0])<<8 + int(p[1]);
128 for i := 0; i < len(sa.Addr); i++ {
129 sa.Addr[i] = pp.Addr[i];
131 return sa, 0;
133 return nil, EAFNOSUPPORT;
136 // BindToDevice binds the socket associated with fd to device.
137 func BindToDevice(fd int, device string) (errno int) {
138 return ENOSYS