OpenTTD
os_abstraction.h
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
16 #ifndef NETWORK_CORE_OS_ABSTRACTION_H
17 #define NETWORK_CORE_OS_ABSTRACTION_H
18 
19 /* Include standard stuff per OS */
20 
21 #ifdef ENABLE_NETWORK
22 
23 /* Windows stuff */
24 #if defined(_WIN32)
25 #include <errno.h>
26 #include <winsock2.h>
27 #include <ws2tcpip.h>
28 #include <windows.h>
29 
30 #define GET_LAST_ERROR() WSAGetLastError()
31 #undef EWOULDBLOCK
32 #define EWOULDBLOCK WSAEWOULDBLOCK
33 /* Windows has some different names for some types */
34 typedef unsigned long in_addr_t;
35 
36 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
37  /* Windows has some different names for some types */
38  typedef SSIZE_T ssize_t;
39  typedef int socklen_t;
40 # define IPPROTO_IPV6 41
41 #endif /* !(__MINGW32__ && __CYGWIN__) */
42 #endif /* _WIN32 */
43 
44 /* UNIX stuff */
45 #if defined(UNIX) && !defined(__OS2__)
46 # if defined(OPENBSD) || defined(__NetBSD__)
47 # define AI_ADDRCONFIG 0
48 # endif
49 # define SOCKET int
50 # define INVALID_SOCKET -1
51 # if !defined(__MORPHOS__) && !defined(__AMIGA__)
52 # define ioctlsocket ioctl
53 # if !defined(BEOS_NET_SERVER)
54 # define closesocket close
55 # endif
56 # define GET_LAST_ERROR() (errno)
57 # endif
58 /* Need this for FIONREAD on solaris */
59 # define BSD_COMP
60 
61 /* Includes needed for UNIX-like systems */
62 # include <unistd.h>
63 # include <sys/ioctl.h>
64 # if defined(__BEOS__) && defined(BEOS_NET_SERVER)
65 # include <be/net/socket.h>
66 # include <be/kernel/OS.h> /* snooze() */
67 # include <be/net/netdb.h>
68  typedef unsigned long in_addr_t;
69 # define INADDR_NONE INADDR_BROADCAST
70 # else
71 # include <sys/socket.h>
72 # include <netinet/in.h>
73 # include <netinet/tcp.h>
74 # include <arpa/inet.h>
75 # include <net/if.h>
76 /* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
77 # if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__INNOTEK_LIBC__) \
78  && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
79 /* If for any reason ifaddrs.h does not exist on your system, comment out
80  * the following two lines and an alternative way will be used to fetch
81  * the list of IPs from the system. */
82 # include <ifaddrs.h>
83 # define HAVE_GETIFADDRS
84 # endif
85 # if !defined(INADDR_NONE)
86 # define INADDR_NONE 0xffffffff
87 # endif
88 # if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
89  /* needed on Zeta */
90 # include <sys/sockio.h>
91 # endif
92 # endif /* BEOS_NET_SERVER */
93 
94 # if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
95  typedef uint32_t in_addr_t;
96 # endif
97 
98 # include <errno.h>
99 # include <sys/time.h>
100 # include <netdb.h>
101 #endif /* UNIX */
102 
103 #ifdef __BEOS__
104  typedef int socklen_t;
105 #endif
106 
107 #ifdef __HAIKU__
108  #define IPV6_V6ONLY 27
109 #endif
110 
111 /* OS/2 stuff */
112 #if defined(__OS2__)
113 # define SOCKET int
114 # define INVALID_SOCKET -1
115 # define ioctlsocket ioctl
116 # define closesocket close
117 # define GET_LAST_ERROR() (sock_errno())
118 
119 /* Includes needed for OS/2 systems */
120 # include <types.h>
121 # include <unistd.h>
122 # include <sys/ioctl.h>
123 # include <sys/socket.h>
124 # include <netinet/in.h>
125 # include <netinet/tcp.h>
126 # include <arpa/inet.h>
127 # include <net/if.h>
128 # include <errno.h>
129 # include <sys/time.h>
130 # include <netdb.h>
131 # include <nerrno.h>
132 # define INADDR_NONE 0xffffffff
133 # include "../../3rdparty/os2/getaddrinfo.h"
134 # include "../../3rdparty/os2/getnameinfo.h"
135 
136 #define IPV6_V6ONLY 27
137 
138 /*
139  * IPv6 address
140  */
141 struct in6_addr {
142  union {
143  uint8_t __u6_addr8[16];
144  uint16_t __u6_addr16[8];
145  uint32_t __u6_addr32[4];
146  } __u6_addr; /* 128-bit IP6 address */
147 };
148 
149 #define s6_addr __u6_addr.__u6_addr8
150 
151 struct sockaddr_in6 {
152  uint8_t sin6_len; /* length of this struct */
153  sa_family_t sin6_family; /* AF_INET6 */
154  in_port_t sin6_port; /* Transport layer port # */
155  uint32_t sin6_flowinfo; /* IP6 flow information */
156  struct in6_addr sin6_addr; /* IP6 address */
157  uint32_t sin6_scope_id; /* scope zone index */
158 };
159 
160 typedef int socklen_t;
161 #if !defined(__INNOTEK_LIBC__)
162 typedef unsigned long in_addr_t;
163 #endif /* __INNOTEK_LIBC__ */
164 
165 #endif /* OS/2 */
166 
167 /* MorphOS and Amiga stuff */
168 #if defined(__MORPHOS__) || defined(__AMIGA__)
169 # include <exec/types.h>
170 # include <proto/exec.h> /* required for Open/CloseLibrary() */
171  /* MorphOS defines his network functions with UBYTE arrays while we
172  * use char arrays. This gives tons of unneeded warnings */
173 # define UBYTE char
174 # if defined(__MORPHOS__)
175 # include <sys/filio.h> /* FIO* defines */
176 # include <sys/sockio.h> /* SIO* defines */
177 # include <netinet/in.h>
178 # else /* __AMIGA__ */
179 # include <proto/socket.h>
180 # endif
181 
182 /* Make the names compatible */
183 # define closesocket(s) CloseSocket(s)
184 # define GET_LAST_ERROR() Errno()
185 # define ioctlsocket(s, request, status) IoctlSocket((LONG)s, (ULONG)request, (char*)status)
186 # define ioctl ioctlsocket
187 
188  typedef unsigned int in_addr_t;
189  typedef long socklen_t;
190  extern struct Library *SocketBase;
191 
192 # ifdef __AMIGA__
193  /* for usleep() implementation */
194  extern struct Device *TimerBase;
195  extern struct MsgPort *TimerPort;
196  extern struct timerequest *TimerRequest;
197 # endif
198 #endif /* __MORPHOS__ || __AMIGA__ */
199 
205 static inline bool SetNonBlocking(SOCKET d)
206 {
207 #ifdef _WIN32
208  u_long nonblocking = 1;
209 #else
210  int nonblocking = 1;
211 #endif
212 #if (defined(__BEOS__) && defined(BEOS_NET_SERVER))
213  return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
214 #else
215  return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
216 #endif
217 }
218 
224 static inline bool SetNoDelay(SOCKET d)
225 {
226  /* XXX should this be done at all? */
227 #if !defined(BEOS_NET_SERVER) /* not implemented on BeOS net_server */
228  int b = 1;
229  /* The (const char*) cast is needed for windows */
230  return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
231 #else
232  return true;
233 #endif
234 }
235 
236 /* Make sure these structures have the size we expect them to be */
237 assert_compile(sizeof(in_addr) == 4);
238 assert_compile(sizeof(in6_addr) == 16);
239 
240 #endif /* ENABLE_NETWORK */
241 
242 #endif /* NETWORK_CORE_OS_ABSTRACTION_H */
static bool SetNonBlocking(SOCKET d)
Try to set the socket into non-blocking mode.
assert_compile(sizeof(in_addr)==4)
IPv4 addresses should be 4 bytes.
static bool SetNoDelay(SOCKET d)
Try to set the socket to not delay sending.