3 @brief ENet Unix system specific functions
8 #include <sys/socket.h>
11 #include <arpa/inet.h>
18 #define ENET_BUILDING_LIB 1
19 #include "enet/enet.h"
34 typedef int socklen_t
;
38 #define MSG_NOSIGNAL 0
41 static enet_uint32 timeBase
= 0;
44 enet_initialize (void)
50 enet_deinitialize (void)
57 struct timeval timeVal
;
59 gettimeofday (& timeVal
, NULL
);
61 return timeVal
.tv_sec
* 1000 + timeVal
.tv_usec
/ 1000 - timeBase
;
65 enet_time_set (enet_uint32 newTimeBase
)
67 struct timeval timeVal
;
69 gettimeofday (& timeVal
, NULL
);
71 timeBase
= timeVal
.tv_sec
* 1000 + timeVal
.tv_usec
/ 1000 - newTimeBase
;
75 enet_address_set_host (ENetAddress
* address
, const char * name
)
77 struct hostent
* hostEntry
= NULL
;
78 #ifdef HAS_GETHOSTBYNAME_R
79 struct hostent hostData
;
83 #if defined(linux) || defined(__FreeBSD__)
84 gethostbyname_r (name
, & hostData
, buffer
, sizeof (buffer
), & hostEntry
, & errnum
);
86 hostEntry
= gethostbyname_r (name
, & hostData
, buffer
, sizeof (buffer
), & errnum
);
89 hostEntry
= gethostbyname (name
);
92 if (hostEntry
== NULL
||
93 hostEntry
-> h_addrtype
!= AF_INET
)
96 if (! inet_pton (AF_INET
, name
, & address
-> host
))
98 if (! inet_aton (name
, (struct in_addr
*) & address
-> host
))
104 address
-> host
= * (enet_uint32
*) hostEntry
-> h_addr_list
[0];
110 enet_address_get_host_ip (const ENetAddress
* address
, char * name
, size_t nameLength
)
113 if (inet_ntop (AF_INET
, & address
-> host
, name
, nameLength
) == NULL
)
115 char * addr
= inet_ntoa (* (struct in_addr
*) & address
-> host
);
117 strncpy (name
, addr
, nameLength
);
125 enet_address_get_host (const ENetAddress
* address
, char * name
, size_t nameLength
)
128 struct hostent
* hostEntry
= NULL
;
129 #ifdef HAS_GETHOSTBYADDR_R
130 struct hostent hostData
;
134 in
.s_addr
= address
-> host
;
136 #if defined(linux) || defined(__FreeBSD__)
137 gethostbyaddr_r ((char *) & in
, sizeof (struct in_addr
), AF_INET
, & hostData
, buffer
, sizeof (buffer
), & hostEntry
, & errnum
);
139 hostEntry
= gethostbyaddr_r ((char *) & in
, sizeof (struct in_addr
), AF_INET
, & hostData
, buffer
, sizeof (buffer
), & errnum
);
142 in
.s_addr
= address
-> host
;
144 hostEntry
= gethostbyaddr ((char *) & in
, sizeof (struct in_addr
), AF_INET
);
147 if (hostEntry
== NULL
)
148 return enet_address_get_host_ip (address
, name
, nameLength
);
150 strncpy (name
, hostEntry
-> h_name
, nameLength
);
156 enet_socket_create (ENetSocketType type
, const ENetAddress
* address
)
158 ENetSocket newSocket
= socket (PF_INET
, type
== ENET_SOCKET_TYPE_DATAGRAM
? SOCK_DGRAM
: SOCK_STREAM
, 0);
159 struct sockaddr_in sin
;
161 if (newSocket
== ENET_SOCKET_NULL
)
162 return ENET_SOCKET_NULL
;
167 memset (& sin
, 0, sizeof (struct sockaddr_in
));
169 sin
.sin_family
= AF_INET
;
170 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
171 sin
.sin_addr
.s_addr
= address
-> host
;
174 (struct sockaddr
*) & sin
,
175 sizeof (struct sockaddr_in
)) == -1 ||
176 (type
== ENET_SOCKET_TYPE_STREAM
&&
177 address
-> port
!= ENET_PORT_ANY
&&
178 listen (newSocket
, SOMAXCONN
) == -1))
182 return ENET_SOCKET_NULL
;
189 enet_socket_set_option (ENetSocket socket
, ENetSocketOption option
, int value
)
194 case ENET_SOCKOPT_NONBLOCK
:
196 result
= fcntl (socket
, F_SETFL
, O_NONBLOCK
| fcntl (socket
, F_GETFL
));
198 result
= ioctl (socket
, FIONBIO
, & value
);
202 case ENET_SOCKOPT_BROADCAST
:
203 result
= setsockopt (socket
, SOL_SOCKET
, SO_BROADCAST
, (char *) & value
, sizeof (int));
206 case ENET_SOCKOPT_RCVBUF
:
207 result
= setsockopt (socket
, SOL_SOCKET
, SO_RCVBUF
, (char *) & value
, sizeof (int));
210 case ENET_SOCKOPT_SNDBUF
:
211 result
= setsockopt (socket
, SOL_SOCKET
, SO_SNDBUF
, (char *) & value
, sizeof (int));
217 return result
== -1 ? -1 : 0;
221 enet_socket_connect (ENetSocket socket
, const ENetAddress
* address
)
223 struct sockaddr_in sin
;
225 memset (& sin
, 0, sizeof (struct sockaddr_in
));
227 sin
.sin_family
= AF_INET
;
228 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
229 sin
.sin_addr
.s_addr
= address
-> host
;
231 return connect (socket
, (struct sockaddr
*) & sin
, sizeof (struct sockaddr_in
));
235 enet_socket_accept (ENetSocket socket
, ENetAddress
* address
)
238 struct sockaddr_in sin
;
239 socklen_t sinLength
= sizeof (struct sockaddr_in
);
241 result
= accept (socket
,
242 address
!= NULL
? (struct sockaddr
*) & sin
: NULL
,
243 address
!= NULL
? & sinLength
: NULL
);
246 return ENET_SOCKET_NULL
;
250 address
-> host
= (enet_uint32
) sin
.sin_addr
.s_addr
;
251 address
-> port
= ENET_NET_TO_HOST_16 (sin
.sin_port
);
258 enet_socket_destroy (ENetSocket socket
)
264 enet_socket_send (ENetSocket socket
,
265 const ENetAddress
* address
,
266 const ENetBuffer
* buffers
,
269 struct msghdr msgHdr
;
270 struct sockaddr_in sin
;
273 memset (& msgHdr
, 0, sizeof (struct msghdr
));
277 sin
.sin_family
= AF_INET
;
278 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
279 sin
.sin_addr
.s_addr
= address
-> host
;
281 msgHdr
.msg_name
= & sin
;
282 msgHdr
.msg_namelen
= sizeof (struct sockaddr_in
);
285 msgHdr
.msg_iov
= (struct iovec
*) buffers
;
286 msgHdr
.msg_iovlen
= bufferCount
;
288 sentLength
= sendmsg (socket
, & msgHdr
, MSG_NOSIGNAL
);
290 if (sentLength
== -1)
292 if (errno
== EWOULDBLOCK
)
302 enet_socket_receive (ENetSocket socket
,
303 ENetAddress
* address
,
304 ENetBuffer
* buffers
,
307 struct msghdr msgHdr
;
308 struct sockaddr_in sin
;
311 memset (& msgHdr
, 0, sizeof (struct msghdr
));
315 msgHdr
.msg_name
= & sin
;
316 msgHdr
.msg_namelen
= sizeof (struct sockaddr_in
);
319 msgHdr
.msg_iov
= (struct iovec
*) buffers
;
320 msgHdr
.msg_iovlen
= bufferCount
;
322 recvLength
= recvmsg (socket
, & msgHdr
, MSG_NOSIGNAL
);
324 if (recvLength
== -1)
326 if (errno
== EWOULDBLOCK
)
332 #ifdef HAS_MSGHDR_FLAGS
333 if (msgHdr
.msg_flags
& MSG_TRUNC
)
339 address
-> host
= (enet_uint32
) sin
.sin_addr
.s_addr
;
340 address
-> port
= ENET_NET_TO_HOST_16 (sin
.sin_port
);
347 enet_socket_wait (ENetSocket socket
, enet_uint32
* condition
, enet_uint32 timeout
)
350 struct pollfd pollSocket
;
353 pollSocket
.fd
= socket
;
354 pollSocket
.events
= 0;
356 if (* condition
& ENET_SOCKET_WAIT_SEND
)
357 pollSocket
.events
|= POLLOUT
;
359 if (* condition
& ENET_SOCKET_WAIT_RECEIVE
)
360 pollSocket
.events
|= POLLIN
;
362 pollCount
= poll (& pollSocket
, 1, timeout
);
367 * condition
= ENET_SOCKET_WAIT_NONE
;
372 if (pollSocket
.revents
& POLLOUT
)
373 * condition
|= ENET_SOCKET_WAIT_SEND
;
375 if (pollSocket
.revents
& POLLIN
)
376 * condition
|= ENET_SOCKET_WAIT_RECEIVE
;
380 fd_set readSet
, writeSet
;
381 struct timeval timeVal
;
384 timeVal
.tv_sec
= timeout
/ 1000;
385 timeVal
.tv_usec
= (timeout
% 1000) * 1000;
388 FD_ZERO (& writeSet
);
390 if (* condition
& ENET_SOCKET_WAIT_SEND
)
391 FD_SET (socket
, & writeSet
);
393 if (* condition
& ENET_SOCKET_WAIT_RECEIVE
)
394 FD_SET (socket
, & readSet
);
396 selectCount
= select (socket
+ 1, & readSet
, & writeSet
, NULL
, & timeVal
);
401 * condition
= ENET_SOCKET_WAIT_NONE
;
403 if (selectCount
== 0)
406 if (FD_ISSET (socket
, & writeSet
))
407 * condition
|= ENET_SOCKET_WAIT_SEND
;
409 if (FD_ISSET (socket
, & readSet
))
410 * condition
|= ENET_SOCKET_WAIT_RECEIVE
;