unix.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. #ifndef HAS_FCNTL
  105. int nonBlocking = 1;
  106. #endif
  107. struct sockaddr_in sin;
  108. if (newSocket == ENET_SOCKET_NULL)
  109. return ENET_SOCKET_NULL;
  110. if (type == ENET_SOCKET_TYPE_DATAGRAM)
  111. {
  112. #ifdef HAS_FCNTL
  113. fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
  114. #else
  115. ioctl (newSocket, FIONBIO, & nonBlocking);
  116. #endif
  117. setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
  118. }
  119. if (address == NULL)
  120. return newSocket;
  121. memset (& sin, 0, sizeof (struct sockaddr_in));
  122. sin.sin_family = AF_INET;
  123. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  124. sin.sin_addr.s_addr = address -> host;
  125. if (bind (newSocket,
  126. (struct sockaddr *) & sin,
  127. sizeof (struct sockaddr_in)) == -1 ||
  128. (type == ENET_SOCKET_TYPE_STREAM &&
  129. listen (newSocket, SOMAXCONN) == -1))
  130. {
  131. close (newSocket);
  132. return ENET_SOCKET_NULL;
  133. }
  134. return newSocket;
  135. }
  136. int
  137. enet_socket_connect (ENetSocket socket, const ENetAddress * address)
  138. {
  139. struct sockaddr_in sin;
  140. memset (& sin, 0, sizeof (struct sockaddr_in));
  141. sin.sin_family = AF_INET;
  142. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  143. sin.sin_addr.s_addr = address -> host;
  144. return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
  145. }
  146. ENetSocket
  147. enet_socket_accept (ENetSocket socket, ENetAddress * address)
  148. {
  149. int result;
  150. struct sockaddr_in sin;
  151. socklen_t sinLength = sizeof (struct sockaddr_in);
  152. result = accept (socket,
  153. address != NULL ? (struct sockaddr *) & sin : NULL,
  154. address != NULL ? & sinLength : NULL);
  155. if (result == -1)
  156. return ENET_SOCKET_NULL;
  157. if (address != NULL)
  158. {
  159. address -> host = (enet_uint32) sin.sin_addr.s_addr;
  160. address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  161. }
  162. return result;
  163. }
  164. void
  165. enet_socket_destroy (ENetSocket socket)
  166. {
  167. close (socket);
  168. }
  169. int
  170. enet_socket_send (ENetSocket socket,
  171. const ENetAddress * address,
  172. const ENetBuffer * buffers,
  173. size_t bufferCount)
  174. {
  175. struct msghdr msgHdr;
  176. struct sockaddr_in sin;
  177. int sentLength;
  178. memset (& msgHdr, 0, sizeof (struct msghdr));
  179. if (address != NULL)
  180. {
  181. sin.sin_family = AF_INET;
  182. sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  183. sin.sin_addr.s_addr = address -> host;
  184. msgHdr.msg_name = & sin;
  185. msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  186. }
  187. msgHdr.msg_iov = (struct iovec *) buffers;
  188. msgHdr.msg_iovlen = bufferCount;
  189. sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
  190. if (sentLength == -1)
  191. {
  192. if (errno == EWOULDBLOCK)
  193. return 0;
  194. return -1;
  195. }
  196. return sentLength;
  197. }
  198. int
  199. enet_socket_receive (ENetSocket socket,
  200. ENetAddress * address,
  201. ENetBuffer * buffers,
  202. size_t bufferCount)
  203. {
  204. struct msghdr msgHdr;
  205. struct sockaddr_in sin;
  206. int recvLength;
  207. memset (& msgHdr, 0, sizeof (struct msghdr));
  208. if (address != NULL)
  209. {
  210. msgHdr.msg_name = & sin;
  211. msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  212. }
  213. msgHdr.msg_iov = (struct iovec *) buffers;
  214. msgHdr.msg_iovlen = bufferCount;
  215. recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
  216. if (recvLength == -1)
  217. {
  218. if (errno == EWOULDBLOCK)
  219. return 0;
  220. return -1;
  221. }
  222. #ifdef HAS_MSGHDR_FLAGS
  223. if (msgHdr.msg_flags & MSG_TRUNC)
  224. return -1;
  225. #endif
  226. if (address != NULL)
  227. {
  228. address -> host = (enet_uint32) sin.sin_addr.s_addr;
  229. address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  230. }
  231. return recvLength;
  232. }
  233. int
  234. enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
  235. {
  236. #ifdef HAS_POLL
  237. struct pollfd pollSocket;
  238. int pollCount;
  239. pollSocket.fd = socket;
  240. pollSocket.events = 0;
  241. if (* condition & ENET_SOCKET_WAIT_SEND)
  242. pollSocket.events |= POLLOUT;
  243. if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  244. pollSocket.events |= POLLIN;
  245. pollCount = poll (& pollSocket, 1, timeout);
  246. if (pollCount < 0)
  247. return -1;
  248. * condition = ENET_SOCKET_WAIT_NONE;
  249. if (pollCount == 0)
  250. return 0;
  251. if (pollSocket.revents & POLLOUT)
  252. * condition |= ENET_SOCKET_WAIT_SEND;
  253. if (pollSocket.revents & POLLIN)
  254. * condition |= ENET_SOCKET_WAIT_RECEIVE;
  255. return 0;
  256. #else
  257. fd_set readSet, writeSet;
  258. struct timeval timeVal;
  259. int selectCount;
  260. timeVal.tv_sec = timeout / 1000;
  261. timeVal.tv_usec = (timeout % 1000) * 1000;
  262. FD_ZERO (& readSet);
  263. FD_ZERO (& writeSet);
  264. if (* condition & ENET_SOCKET_WAIT_SEND)
  265. FD_SET (socket, & writeSet);
  266. if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  267. FD_SET (socket, & readSet);
  268. selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
  269. if (selectCount < 0)
  270. return -1;
  271. * condition = ENET_SOCKET_WAIT_NONE;
  272. if (selectCount == 0)
  273. return 0;
  274. if (FD_ISSET (socket, & writeSet))
  275. * condition |= ENET_SOCKET_WAIT_SEND;
  276. if (FD_ISSET (socket, & readSet))
  277. * condition |= ENET_SOCKET_WAIT_RECEIVE;
  278. return 0;
  279. #endif
  280. }
  281. #endif