Panda3D
socket_portable.h
1 #ifndef __SOCKET_PORTABLE_H__
2 #define __SOCKET_PORTABLE_H__
3 // Lots of stuff to make network socket-based io transparent across multiple
4 // platforms
5 
6 const int ALL_OK = 0;
7 const int BASIC_ERROR = -1;
8 
9 #define SA_SIZEOF(addr) (((addr)->sa_family == AF_INET6) ? sizeof(sockaddr_in6) : sizeof(sockaddr_in))
10 
11 #if defined(CPPPARSER)
12 // Interrogate doesn't need to parse any of this.
13 
14 typedef unsigned long SOCKET;
15 
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 
19 /************************************************************************
20 * HP SOCKET LIBRARY STUFF
21 ************************************************************************/
22 #elif defined(HP_SOCK)
23 
24 #ifndef _INCLUDE_HPUX_SOURCE
25 #define _INCLUDE_HPUX_SOURCE
26 #define _INCLUDE_POSIX_SOURCE
27 #define _INCLUDE_XOPEN_SOURCE
28 #endif
29 #include <sys/socket.h>
30 #include <sys/time.h>
31 #include <netinet/in.h>
32 #include <netdb.h>
33 #include <errno.h>
34 
35 #define socket_read read
36 #define socket_write write
37 #define socket_close close
38 
39 #define DO_CONNECT(a,b,c) connect(a,b,c)
40 #define DO_SOCKET_READ(a,b,c,d) socket_read(a,b,c)
41 #define DO_SOCKET_WRITE(a,b,c,d) socket_write(a,b,c)
42 
43 #define GETERROR() errno
44 
45 
46 #define SOCKIOCTL ioctl
47 typedef unsigned long SOCKET;
48 #define BAD_SOCKET 0xffffffff
49 
50 
51 /************************************************************************
52 * WINSOCK 32 bit STUFF
53 ************************************************************************/
54 #elif defined(_WIN32)
55 #include <winsock2.h>
56 #include <Ws2tcpip.h>
57 
58 typedef u_short sa_family_t;
59 
60 inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
61  return select((int)n, readfds, writefds, exceptfds, timeout);
62 }
63 
64 inline int DO_CONNECT(const SOCKET a, const struct sockaddr *b) {
65  return connect(a, b, SA_SIZEOF(b));
66 }
67 inline int DO_SOCKET_READ(const SOCKET a, char *buf, const int size) {
68  return recv(a, buf, size, 0);
69 }
70 inline int DO_SOCKET_WRITE(const SOCKET a, const char *buff, const int len) {
71  return send(a, buff, len, 0);
72 }
73 inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char *buffer, const int buf_len, const sockaddr *addr) {
74  return sendto(a, buffer, buf_len, 0, addr, SA_SIZEOF(addr));
75 }
76 inline SOCKET DO_NEWUDP(sa_family_t family) {
77  return socket(family, SOCK_DGRAM, 0);
78 }
79 inline SOCKET DO_NEWTCP(sa_family_t family) {
80  return socket(family, SOCK_STREAM, 0);
81 }
82 inline int DO_BIND(const SOCKET a, const sockaddr *b) {
83  return ::bind(a, b, SA_SIZEOF(b));
84 }
85 inline int DO_CLOSE(const SOCKET a) {
86  return closesocket(a);
87 }
88 inline SOCKET DO_ACCEPT(SOCKET sck, sockaddr *addr) {
89  socklen_t addrlen = sizeof(sockaddr_storage);
90  return accept(sck, addr, &addrlen);
91 }
92 inline int DO_RECV_FROM(SOCKET sck, char *data, int len, sockaddr *addr) {
93  socklen_t plen = sizeof(sockaddr_storage);
94  return recvfrom(sck, data, len, 0, addr, &plen);
95 }
96 inline int DO_LISTEN(const SOCKET a, const int size) {
97  return listen(a, size);
98 }
99 
100 inline int GETERROR() {
101  return WSAGetLastError();
102 }
103 
104 inline int SOCKIOCTL(const SOCKET s, const long flags, unsigned long *val) {
105  return ioctlsocket(s, flags, val);
106 }
107 
108 inline int init_network() {
109  static struct WSAData mydata;
110  int answer = WSAStartup(0x0101, &mydata);
111  if (answer != 0) {
112  return BASIC_ERROR;
113  }
114 
115  return ALL_OK;
116 }
117 
118 inline bool do_shutdown_send(SOCKET s) {
119  return (shutdown(s, SD_SEND) == 0);
120 }
121 
122 typedef int socklen_t;
123 const long LOCAL_NONBLOCK = 1;
124 const long LOCAL_FL_SET = FIONBIO;
125 const int LOCAL_BLOCKING_ERROR = WSAEWOULDBLOCK;
126 const int LOCAL_CONNECT_BLOCKING = WSAEWOULDBLOCK;
127 const int LOCAL_NOTCONNECTED_ERROR = WSAENOTCONN;
128 const int LOCAL_TIMEOUT_ERROR = WSAETIMEDOUT;
129 const SOCKET BAD_SOCKET = (SOCKET)-1;
130 
131 /************************************************************************
132 * Solaris 2.6 and Irix 6.4 STUFF
133 ************************************************************************/
134 #elif defined(SunOS) || defined(SUNNEW) || defined(IRIX64)
135 
136 #include <sys/types.h>
137 #include <sys/time.h>
138 #include <sys/socket.h>
139 #include <sys/ioctl.h>
140 #include <sys/filio.h>
141 #include <netinet/in.h>
142 #include <netdb.h>
143 #include <errno.h>
144 #include <fcntl.h>
145 #include <signal.h>
146 #include <unistd.h>
147 #include <string.h>
148 #include <netinet/in_systm.h>
149 #include <netinet/ip.h>
150 #include <netinet/in.h>
151 #include <arpa/inet.h>
152 
153 typedef int SOCKET;
154 const SOCKET BAD_SOCKET = 0xffffffff;
155 
156 inline int DO_CONNECT(const SOCKET a, const sockaddr *b) {
157  return connect(a, b, SA_SIZEOF(b));
158 }
159 inline int DO_SOCKET_READ(const SOCKET a, char *buf, const int size) {
160  return recv(a, buf, size, 0);
161 }
162 inline int DO_SOCKET_WRITE(const SOCKET a, const char *buff, const int len) {
163  return send(a, buff, len, 0);
164 }
165 
166 inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char *buffer, const int buf_len, const sockaddr *addr) {
167  return sendto(a, buffer, buf_len, 0, addr, SA_SIZEOF(addr));
168 }
169 inline SOCKET DO_NEWUDP(sa_family_t family) {
170  return socket(family, SOCK_DGRAM, 0);
171 }
172 inline SOCKET DO_NEWTCP(sa_family_t family) {
173  return socket(family, SOCK_STREAM, 0);
174 }
175 inline int DO_BIND(const SOCKET a, const sockaddr *b) {
176  return ::bind(a, b, SA_SIZEOF(b));
177 }
178 inline int DO_CLOSE(const SOCKET a) {
179  return close(a);
180 }
181 inline int DO_ACCEPT(SOCKET sck, sockaddr *addr) {
182  socklen_t addrlen = sizeof(sockaddr_storage);
183  return accept(sck, (sockaddr *)addr, &addrlen);
184 }
185 
186 inline int DO_RECV_FROM(SOCKET sck, char *data, int len, sockaddr *addr) {
187  socklen_t plen = sizeof(sockaddr_storage);
188  return recvfrom(sck, data, len, 0, (sockaddr *)addr, &plen);
189 }
190 inline int DO_LISTEN(const SOCKET a, const int size) {
191  return listen(a, size);
192 }
193 
194 inline int GETERROR() {
195  return errno;
196 }
197 
198 inline int SOCKIOCTL(const SOCKET s, const long flags, void *val) {
199  return ioctl(s, flags, val);
200 }
201 
202 inline int init_network() {
203  return ALL_OK;
204 }
205 #ifndef INADDR_NONE
206 const INADDR_NONE = -1;
207 #endif
208 
209 const long LOCAL_NONBLOCK = 1;
210 const long LOCAL_FL_SET = FIONBIO;
211 const int LOCAL_BLOCKING_ERROR = EAGAIN;
212 const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
213 
214 /************************************************************************
215 * LINUX and FreeBSD STUFF
216 ************************************************************************/
217 
218 #elif defined(IS_LINUX) || defined(IS_OSX) || defined(IS_FREEBSD)
219 
220 #include <sys/types.h>
221 #include <sys/time.h>
222 #include <sys/socket.h>
223 #include <sys/ioctl.h>
224 #include <netinet/in.h>
225 #include <netdb.h>
226 #include <errno.h>
227 #include <fcntl.h>
228 #include <signal.h>
229 #include <unistd.h>
230 #include <stdio.h>
231 // #include <netinetin_systm.h>
232 #include <netinet/tcp.h>
233 // #include <netinetip.h>
234 #include <netinet/in.h>
235 #include <arpa/inet.h>
236 #include <unistd.h>
237 
238 typedef int SOCKET;
239 const SOCKET BAD_SOCKET = -1;
240 inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
241  return select((int)n, readfds, writefds, exceptfds, timeout);
242 }
243 
244 inline int DO_CONNECT(const SOCKET a, const sockaddr *b) {
245  return connect(a, b, SA_SIZEOF(b));
246 }
247 inline int DO_SOCKET_READ(const SOCKET a, char *buf, const int size) {
248  return (int)recv(a, buf, (size_t)size, 0);
249 }
250 inline int DO_SOCKET_WRITE(const SOCKET a, const char *buff, const int len) {
251  return (int)send(a, buff, (size_t)len, 0);
252 }
253 inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char *buffer, const int buf_len, const sockaddr *addr) {
254  return (int)sendto(a, buffer, (size_t)buf_len, 0, addr, SA_SIZEOF(addr));
255 }
256 inline SOCKET DO_NEWUDP(sa_family_t family) {
257  return socket(family, SOCK_DGRAM, 0);
258 }
259 inline SOCKET DO_NEWTCP(sa_family_t family) {
260  return socket(family, SOCK_STREAM, 0);
261 }
262 inline int DO_BIND(const SOCKET a, const sockaddr *b) {
263  return ::bind(a, b, SA_SIZEOF(b));
264 }
265 inline int DO_CLOSE(const SOCKET a) {
266  return close(a);
267 }
268 
269 inline int DO_ACCEPT(SOCKET sck, sockaddr *addr) {
270  socklen_t addrlen = sizeof(sockaddr_storage);
271  return accept(sck, (sockaddr *)addr, &addrlen);
272 }
273 
274 inline int DO_RECV_FROM(SOCKET sck, char *data, int len, sockaddr *addr) {
275  socklen_t plen = sizeof(sockaddr_storage);
276  return (int)recvfrom(sck, data, (size_t)len, 0, (sockaddr *)addr, &plen);
277 }
278 
279 
280 inline int init_network() {
281  signal(SIGPIPE, SIG_IGN); // hmm do i still need this ...
282  return ALL_OK;
283 }
284 
285 inline int DO_LISTEN(const SOCKET a, const int size) {
286  return listen(a, size);
287 }
288 
289 inline int GETERROR() {
290  return errno;
291 }
292 
293 inline int SOCKIOCTL(const SOCKET s, const long flags, void *val) {
294  return ioctl(s, (unsigned long)flags, val);
295 }
296 
297 inline bool do_shutdown_send(SOCKET s) {
298  return (shutdown(s, SHUT_WR) == 0);
299 }
300 
301 #define BSDBLOCK
302 
303 
304 const long LOCAL_NONBLOCK = 1;
305 // With BSDBLOCK defined, we don't need FIONBIO. Solaris doesn't provide it.
306 // const long LOCAL_FL_SET = FIONBIO;
307 const int LOCAL_BLOCKING_ERROR = EAGAIN;
308 const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
309 
310 #else
311 /************************************************************************
312 * NO DEFINITION => GIVE COMPILATION ERROR
313 ************************************************************************/
314 No Host Type defined !!
315 #error Fatal
316 #endif
317 
318 #endif //__SOCKET_PORTABLE_H__