unix.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /**
  2. @file unix.c
  3. @brief ENet Unix system specific functions
  4. */
  5. #ifndef WIN32
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/time.h>
  10. #include <netdb.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. #include <time.h>
  15. #define ENET_BUILDING_LIB 1
  16. #include "enet/enet.h"
  17. #ifdef HAS_FCNTL
  18. #include <fcntl.h>
  19. #endif
  20. #ifdef HAS_POLL
  21. #include <sys/poll.h>
  22. #endif
  23. #ifndef HAS_SOCKLEN_T
  24. typedef int socklen_t;
  25. #endif
  26. #ifndef MSG_NOSIGNAL
  27. #define MSG_NOSIGNAL 0
  28. #endif
  29. static enet_uint32 timeBase = 0;
  30. int
  31. enet_initialize (void)
  32. {
  33. return 0;
  34. }
  35. void
  36. enet_deinitialize (void)
  37. {
  38. }
  39. enet_uint32
  40. enet_time_get (void)
  41. {
  42. struct timeval timeVal;
  43. gettimeofday (& timeVal, NULL);
  44. return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
  45. }
  46. void
  47. enet_time_set (enet_uint32 newTimeBase)
  48. {
  49. struct timeval timeVal;
  50. gettimeofday (& timeVal, NULL);
  51. timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
  52. }
  53. int
  54. enet_address_set_host (ENetAddress * address, const char * name)
  55. {
  56. struct hostent * hostEntry = NULL;
  57. #ifdef HAS_GETHOSTBYNAME_R
  58. struct hostent hostData;
  59. char buffer [2048];
  60. int errnum;
  61. #ifdef linux
  62. gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
  63. #else
  64. hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
  65. #endif
  66. #else
  67. hostEntry = gethostbyname (name);
  68. #endif
  69. if (hostEntry == NULL ||
  70. hostEntry -> h_addrtype != AF_INET)
  71. return -1;
  72. address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
  73. return 0;
  74. }
  75. int
  76. enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
  77. {
  78. struct in_addr in;
  79. struct hostent * hostEntry = NULL;
  80. #ifdef HAS_GETHOSTBYADDR_R
  81. struct hostent hostData;
  82. char buffer [2048];
  83. int errnum;
  84. in.s_addr = address -> host;
  85. #ifdef linux
  86. gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
  87. #else
  88. hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
  89. #endif
  90. #else
  91. in.s_addr = address -> host;
  92. hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
  93. #endif
  94. if (hostEntry == NULL)
  95. return -1;
  96. strncpy (name, hostEntry -> h_name, nameLength);
  97. return 0;
  98. }
  99. ENetSocket
  100. enet_socket_create (ENetSocketType type, const ENetAddress * address)
  101. {
  102. ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
  103. int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
  104. allowBroadcasting = 1;
  105. #ifndef HAS_FCNTL
  106. int nonBlocking = 1;
  107. #endif
  108. struct sockaddr_in sin;
  109. if (newSocket == ENET_SOCKET_NULL)
  110. return ENET_SOCKET_NULL;
  111. if (type == ENET_SOCKET_TYPE_DATAGRAM)
  112. {
  113. #ifdef HAS_FCNTL
  114. fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
  115. #else
  116. ioctl (newSocket, FIONBIO, & nonBlocking);
  117. #endif
  118. setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
  119. setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int));
  120. }
  121. if (address == NULL)
  122. return newSocket;
  123. memset (& sin, 0, sizeof (struct sockaddr_in));
  124. sin.sin_family = AF_INET;
  125. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  126. sin.sin_addr.s_addr = address -> host;
  127. if (bind (newSocket,
  128. (struct sockaddr *) & sin,
  129. sizeof (struct sockaddr_in)) == -1 ||
  130. (type == ENET_SOCKET_TYPE_STREAM &&
  131. listen (newSocket, SOMAXCONN) == -1))
  132. {
  133. close (newSocket);
  134. return ENET_SOCKET_NULL;
  135. }
  136. return newSocket;
  137. }
  138. int
  139. enet_socket_connect (ENetSocket socket, const ENetAddress * address)
  140. {
  141. struct sockaddr_in sin;
  142. memset (& sin, 0, sizeof (struct sockaddr_in));
  143. sin.sin_family = AF_INET;
  144. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  145. sin.sin_addr.s_addr = address -> host;
  146. return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
  147. }
  148. ENetSocket
  149. enet_socket_accept (ENetSocket socket, ENetAddress * address)
  150. {
  151. int result;
  152. struct sockaddr_in sin;
  153. socklen_t sinLength = sizeof (struct sockaddr_in);
  154. result = accept (socket,
  155. address != NULL ? (struct sockaddr *) & sin : NULL,
  156. address != NULL ? & sinLength : NULL);
  157. if (result == -1)
  158. return ENET_SOCKET_NULL;
  159. if (address != NULL)
  160. {
  161. address -> host = (enet_uint32) sin.sin_addr.s_addr;
  162. address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  163. }
  164. return result;
  165. }
  166. void
  167. enet_socket_destroy (ENetSocket socket)
  168. {
  169. close (socket);
  170. }
  171. int
  172. enet_socket_send (ENetSocket socket,
  173. const ENetAddress * address,
  174. const ENetBuffer * buffers,
  175. size_t bufferCount)
  176. {
  177. struct msghdr msgHdr;
  178. struct sockaddr_in sin;
  179. int sentLength;
  180. memset (& msgHdr, 0, sizeof (struct msghdr));
  181. if (address != NULL)
  182. {
  183. sin.sin_family = AF_INET;
  184. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  185. sin.sin_addr.s_addr = address -> host;
  186. msgHdr.msg_name = & sin;
  187. msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  188. }
  189. msgHdr.msg_iov = (struct iovec *) buffers;
  190. msgHdr.msg_iovlen = bufferCount;
  191. sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
  192. if (sentLength == -1)
  193. {
  194. if (errno == EWOULDBLOCK)
  195. return 0;
  196. return -1;
  197. }
  198. return sentLength;
  199. }
  200. int
  201. enet_socket_receive (ENetSocket socket,
  202. ENetAddress * address,
  203. ENetBuffer * buffers,
  204. size_t bufferCount)
  205. {
  206. struct msghdr msgHdr;
  207. struct sockaddr_in sin;
  208. int recvLength;
  209. memset (& msgHdr, 0, sizeof (struct msghdr));
  210. if (address != NULL)
  211. {
  212. msgHdr.msg_name = & sin;
  213. msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  214. }
  215. msgHdr.msg_iov = (struct iovec *) buffers;
  216. msgHdr.msg_iovlen = bufferCount;
  217. recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
  218. if (recvLength == -1)
  219. {
  220. if (errno == EWOULDBLOCK)
  221. return 0;
  222. return -1;
  223. }
  224. #ifdef HAS_MSGHDR_FLAGS
  225. if (msgHdr.msg_flags & MSG_TRUNC)
  226. return -1;
  227. #endif
  228. if (address != NULL)
  229. {
  230. address -> host = (enet_uint32) sin.sin_addr.s_addr;
  231. address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  232. }
  233. return recvLength;
  234. }
  235. int
  236. enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
  237. {
  238. #ifdef HAS_POLL
  239. struct pollfd pollSocket;
  240. int pollCount;
  241. pollSocket.fd = socket;
  242. pollSocket.events = 0;
  243. if (* condition & ENET_SOCKET_WAIT_SEND)
  244. pollSocket.events |= POLLOUT;
  245. if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  246. pollSocket.events |= POLLIN;
  247. pollCount = poll (& pollSocket, 1, timeout);
  248. if (pollCount < 0)
  249. return -1;
  250. * condition = ENET_SOCKET_WAIT_NONE;
  251. if (pollCount == 0)
  252. return 0;
  253. if (pollSocket.revents & POLLOUT)
  254. * condition |= ENET_SOCKET_WAIT_SEND;
  255. if (pollSocket.revents & POLLIN)
  256. * condition |= ENET_SOCKET_WAIT_RECEIVE;
  257. return 0;
  258. #else
  259. fd_set readSet, writeSet;
  260. struct timeval timeVal;
  261. int selectCount;
  262. timeVal.tv_sec = timeout / 1000;
  263. timeVal.tv_usec = (timeout % 1000) * 1000;
  264. FD_ZERO (& readSet);
  265. FD_ZERO (& writeSet);
  266. if (* condition & ENET_SOCKET_WAIT_SEND)
  267. FD_SET (socket, & writeSet);
  268. if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  269. FD_SET (socket, & readSet);
  270. selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
  271. if (selectCount < 0)
  272. return -1;
  273. * condition = ENET_SOCKET_WAIT_NONE;
  274. if (selectCount == 0)
  275. return 0;
  276. if (FD_ISSET (socket, & writeSet))
  277. * condition |= ENET_SOCKET_WAIT_SEND;
  278. if (FD_ISSET (socket, & readSet))
  279. * condition |= ENET_SOCKET_WAIT_RECEIVE;
  280. return 0;
  281. #endif
  282. }
  283. #endif