a7a4d28abcd976cf6622e3b1d6e9fe7f0299fcfc
[mesa.git] / src / gallium / auxiliary / util / u_network.c
1
2 #include "pipe/p_compiler.h"
3 #include "util/u_network.h"
4 #include "util/u_debug.h"
5
6 #include <stdio.h>
7 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
8 # include <winsock2.h>
9 # include <windows.h>
10 # include <ws2tcpip.h>
11 #elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \
12 defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
13 # include <sys/socket.h>
14 # include <netinet/in.h>
15 # include <unistd.h>
16 # include <fcntl.h>
17 # include <netdb.h>
18 #else
19 # warning "No socket implementation"
20 #endif
21
22 boolean
23 u_socket_init()
24 {
25 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
26 WORD wVersionRequested;
27 WSADATA wsaData;
28 int err;
29
30 /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
31 wVersionRequested = MAKEWORD(1, 1);
32
33 err = WSAStartup(wVersionRequested, &wsaData);
34 if (err != 0) {
35 debug_printf("WSAStartup failed with error: %d\n", err);
36 return FALSE;
37 }
38 return TRUE;
39 #elif defined(PIPE_HAVE_SOCKETS)
40 return TRUE;
41 #else
42 return FALSE;
43 #endif
44 }
45
46 void
47 u_socket_stop()
48 {
49 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
50 WSACleanup();
51 #endif
52 }
53
54 void
55 u_socket_close(int s)
56 {
57 if (s < 0)
58 return;
59
60 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
61 || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
62 shutdown(s, SHUT_RDWR);
63 close(s);
64 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
65 shutdown(s, SD_BOTH);
66 closesocket(s);
67 #else
68 assert(0);
69 #endif
70 }
71
72 int u_socket_accept(int s)
73 {
74 #if defined(PIPE_HAVE_SOCKETS)
75 return accept(s, NULL, NULL);
76 #else
77 return -1;
78 #endif
79 }
80
81 int
82 u_socket_send(int s, void *data, size_t size)
83 {
84 #if defined(PIPE_HAVE_SOCKETS)
85 return send(s, data, size, 0);
86 #else
87 return -1;
88 #endif
89 }
90
91 int
92 u_socket_peek(int s, void *data, size_t size)
93 {
94 #if defined(PIPE_HAVE_SOCKETS)
95 return recv(s, data, size, MSG_PEEK);
96 #else
97 return -1;
98 #endif
99 }
100
101 int
102 u_socket_recv(int s, void *data, size_t size)
103 {
104 #if defined(PIPE_HAVE_SOCKETS)
105 return recv(s, data, size, 0);
106 #else
107 return -1;
108 #endif
109 }
110
111 int
112 u_socket_connect(const char *hostname, uint16_t port)
113 {
114 #if defined(PIPE_HAVE_SOCKETS)
115 int s, r;
116 struct addrinfo hints, *addr;
117 char portString[20];
118
119 memset(&hints, 0, sizeof hints);
120 hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
121 hints.ai_socktype = SOCK_STREAM;
122
123 snprintf(portString, sizeof(portString), "%d", port);
124
125 r = getaddrinfo(hostname, portString, NULL, &addr);
126 if (r != 0) {
127 return -1;
128 }
129
130 s = socket(addr->ai_family, SOCK_STREAM, IPPROTO_TCP);
131 if (s < 0) {
132 freeaddrinfo(addr);
133 return -1;
134 }
135
136 if (connect(s, addr->ai_addr, (int) addr->ai_addrlen)) {
137 u_socket_close(s);
138 freeaddrinfo(addr);
139 return -1;
140 }
141
142 freeaddrinfo(addr);
143
144 return s;
145 #else
146 assert(0);
147 return -1;
148 #endif
149 }
150
151 int
152 u_socket_listen_on_port(uint16_t portnum)
153 {
154 #if defined(PIPE_HAVE_SOCKETS)
155 int s;
156 struct sockaddr_in sa;
157 memset(&sa, 0, sizeof(struct sockaddr_in));
158
159 sa.sin_family = AF_INET;
160 sa.sin_port = htons(portnum);
161
162 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
163 if (s < 0)
164 return -1;
165
166 if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
167 u_socket_close(s);
168 return -1;
169 }
170
171 listen(s, 0);
172
173 return s;
174 #else
175 assert(0);
176 return -1;
177 #endif
178 }
179
180 void
181 u_socket_block(int s, boolean block)
182 {
183 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
184 || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
185 int old = fcntl(s, F_GETFL, 0);
186 if (old == -1)
187 return;
188
189 /* TODO obey block */
190 if (block)
191 fcntl(s, F_SETFL, old & ~O_NONBLOCK);
192 else
193 fcntl(s, F_SETFL, old | O_NONBLOCK);
194 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
195 u_long iMode = block ? 0 : 1;
196 ioctlsocket(s, FIONBIO, &iMode);
197 #else
198 assert(0);
199 #endif
200 }