home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / enet / unix.c < prev    next >
Encoding:
C/C++ Source or Header  |  2007-06-01  |  9.4 KB  |  405 lines

  1. /** 
  2.  @file  unix.c
  3.  @brief ENet Unix system specific functions
  4. */
  5. #ifndef WIN32
  6.  
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/time.h>
  11. #include <arpa/inet.h>
  12. #include <netdb.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <errno.h>
  16. #include <time.h>
  17.  
  18. #define ENET_BUILDING_LIB 1
  19. #include "enet/enet.h"
  20.  
  21. #ifdef HAS_FCNTL
  22. #include <fcntl.h>
  23. #endif
  24.  
  25. #ifdef __APPLE__
  26. #undef HAS_POLL
  27. #endif
  28.  
  29. #ifdef HAS_POLL
  30. #include <sys/poll.h>
  31. #endif
  32.  
  33. #ifndef HAS_SOCKLEN_T
  34. typedef int socklen_t;
  35. #endif
  36.  
  37. #ifndef MSG_NOSIGNAL
  38. #define MSG_NOSIGNAL 0
  39. #endif
  40.  
  41. static enet_uint32 timeBase = 0;
  42.  
  43. int
  44. enet_initialize (void)
  45. {
  46.     return 0;
  47. }
  48.  
  49. void
  50. enet_deinitialize (void)
  51. {
  52. }
  53.  
  54. enet_uint32
  55. enet_time_get (void)
  56. {
  57.     struct timeval timeVal;
  58.  
  59.     gettimeofday (& timeVal, NULL);
  60.  
  61.     return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
  62. }
  63.  
  64. void
  65. enet_time_set (enet_uint32 newTimeBase)
  66. {
  67.     struct timeval timeVal;
  68.  
  69.     gettimeofday (& timeVal, NULL);
  70.     
  71.     timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
  72. }
  73.  
  74. int
  75. enet_address_set_host (ENetAddress * address, const char * name)
  76. {
  77.     struct hostent * hostEntry = NULL;
  78. #ifdef HAS_GETHOSTBYNAME_R
  79.     struct hostent hostData;
  80.     char buffer [2048];
  81.     int errnum;
  82.  
  83. #if defined(linux) || defined(__FreeBSD__)
  84.     gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
  85. #else
  86.     hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
  87. #endif
  88. #else
  89.     hostEntry = gethostbyname (name);
  90. #endif
  91.  
  92.     if (hostEntry == NULL ||
  93.         hostEntry -> h_addrtype != AF_INET)
  94.     {
  95. #ifdef HAS_INET_PTON
  96.         if (! inet_pton (AF_INET, name, & address -> host))
  97. #else
  98.         if (! inet_aton (name, (struct in_addr *) & address -> host))
  99. #endif
  100.             return -1;
  101.         return 0;
  102.     }
  103.  
  104.     address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
  105.  
  106.     return 0;
  107. }
  108.  
  109. int
  110. enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
  111. {
  112. #ifdef HAS_INET_NTOP
  113.     if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
  114. #else
  115.     char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
  116.     if (addr != NULL)
  117.         strncpy (name, addr, nameLength);
  118.     else
  119. #endif
  120.         return -1;
  121.     return 0;
  122. }
  123.  
  124. int
  125. enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
  126. {
  127.     struct in_addr in;
  128.     struct hostent * hostEntry = NULL;
  129. #ifdef HAS_GETHOSTBYADDR_R
  130.     struct hostent hostData;
  131.     char buffer [2048];
  132.     int errnum;
  133.  
  134.     in.s_addr = address -> host;
  135.  
  136. #if defined(linux) || defined(__FreeBSD__)
  137.     gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
  138. #else
  139.     hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
  140. #endif
  141. #else
  142.     in.s_addr = address -> host;
  143.  
  144.     hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
  145. #endif
  146.  
  147.     if (hostEntry == NULL)
  148.       return enet_address_get_host_ip (address, name, nameLength);
  149.  
  150.     strncpy (name, hostEntry -> h_name, nameLength);
  151.  
  152.     return 0;
  153. }
  154.  
  155. ENetSocket
  156. enet_socket_create (ENetSocketType type, const ENetAddress * address)
  157. {
  158.     ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
  159.     int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
  160.         sendBufferSize = ENET_HOST_SEND_BUFFER_SIZE,
  161.         allowBroadcasting = 1;
  162. #ifndef HAS_FCNTL
  163.     int nonBlocking = 1;
  164. #endif
  165.     struct sockaddr_in sin;
  166.  
  167.     if (newSocket == ENET_SOCKET_NULL)
  168.       return ENET_SOCKET_NULL;
  169.  
  170.     if (type == ENET_SOCKET_TYPE_DATAGRAM)
  171.     {
  172. #ifdef HAS_FCNTL
  173.         fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
  174. #else
  175.         ioctl (newSocket, FIONBIO, & nonBlocking);
  176. #endif
  177.  
  178.         setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
  179.         setsockopt (newSocket, SOL_SOCKET, SO_SNDBUF, (char *) & sendBufferSize, sizeof (int));
  180.         setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int));
  181.     }
  182.     
  183.     if (address == NULL)
  184.       return newSocket;
  185.  
  186.     memset (& sin, 0, sizeof (struct sockaddr_in));
  187.  
  188.     sin.sin_family = AF_INET;
  189.     sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  190.     sin.sin_addr.s_addr = address -> host;
  191.  
  192.     if (bind (newSocket, 
  193.               (struct sockaddr *) & sin,
  194.               sizeof (struct sockaddr_in)) == -1 ||
  195.         (type == ENET_SOCKET_TYPE_STREAM &&
  196.           address -> port != ENET_PORT_ANY &&
  197.           listen (newSocket, SOMAXCONN) == -1))
  198.     {
  199.        close (newSocket);
  200.  
  201.        return ENET_SOCKET_NULL;
  202.     }
  203.  
  204.     return newSocket;
  205. }
  206.  
  207. int
  208. enet_socket_connect (ENetSocket socket, const ENetAddress * address)
  209. {
  210.     struct sockaddr_in sin;
  211.  
  212.     memset (& sin, 0, sizeof (struct sockaddr_in));
  213.  
  214.     sin.sin_family = AF_INET;
  215.     sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  216.     sin.sin_addr.s_addr = address -> host;
  217.  
  218.     return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
  219. }
  220.  
  221. ENetSocket
  222. enet_socket_accept (ENetSocket socket, ENetAddress * address)
  223. {
  224.     int result;
  225.     struct sockaddr_in sin;
  226.     socklen_t sinLength = sizeof (struct sockaddr_in);
  227.  
  228.     result = accept (socket, 
  229.                      address != NULL ? (struct sockaddr *) & sin : NULL, 
  230.                      address != NULL ? & sinLength : NULL);
  231.     
  232.     if (result == -1)
  233.       return ENET_SOCKET_NULL;
  234.  
  235.     if (address != NULL)
  236.     {
  237.         address -> host = (enet_uint32) sin.sin_addr.s_addr;
  238.         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  239.     }
  240.  
  241.     return result;
  242.     
  243. void
  244. enet_socket_destroy (ENetSocket socket)
  245. {
  246.     close (socket);
  247. }
  248.  
  249. int
  250. enet_socket_send (ENetSocket socket,
  251.                   const ENetAddress * address,
  252.                   const ENetBuffer * buffers,
  253.                   size_t bufferCount)
  254. {
  255.     struct msghdr msgHdr;
  256.     struct sockaddr_in sin;
  257.     int sentLength;
  258.  
  259.     memset (& msgHdr, 0, sizeof (struct msghdr));
  260.  
  261.     if (address != NULL)
  262.     {
  263.         sin.sin_family = AF_INET;
  264.         sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
  265.         sin.sin_addr.s_addr = address -> host;
  266.  
  267.         msgHdr.msg_name = & sin;
  268.         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  269.     }
  270.  
  271.     msgHdr.msg_iov = (struct iovec *) buffers;
  272.     msgHdr.msg_iovlen = bufferCount;
  273.  
  274.     sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
  275.     
  276.     if (sentLength == -1)
  277.     {
  278.        if (errno == EWOULDBLOCK)
  279.          return 0;
  280.  
  281.        return -1;
  282.     }
  283.  
  284.     return sentLength;
  285. }
  286.  
  287. int
  288. enet_socket_receive (ENetSocket socket,
  289.                      ENetAddress * address,
  290.                      ENetBuffer * buffers,
  291.                      size_t bufferCount)
  292. {
  293.     struct msghdr msgHdr;
  294.     struct sockaddr_in sin;
  295.     int recvLength;
  296.  
  297.     memset (& msgHdr, 0, sizeof (struct msghdr));
  298.  
  299.     if (address != NULL)
  300.     {
  301.         msgHdr.msg_name = & sin;
  302.         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
  303.     }
  304.  
  305.     msgHdr.msg_iov = (struct iovec *) buffers;
  306.     msgHdr.msg_iovlen = bufferCount;
  307.  
  308.     recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
  309.  
  310.     if (recvLength == -1)
  311.     {
  312.        if (errno == EWOULDBLOCK)
  313.          return 0;
  314.  
  315.        return -1;
  316.     }
  317.  
  318. #ifdef HAS_MSGHDR_FLAGS
  319.     if (msgHdr.msg_flags & MSG_TRUNC)
  320.       return -1;
  321. #endif
  322.  
  323.     if (address != NULL)
  324.     {
  325.         address -> host = (enet_uint32) sin.sin_addr.s_addr;
  326.         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
  327.     }
  328.  
  329.     return recvLength;
  330. }
  331.  
  332. int
  333. enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
  334. {
  335. #ifdef HAS_POLL
  336.     struct pollfd pollSocket;
  337.     int pollCount;
  338.     
  339.     pollSocket.fd = socket;
  340.     pollSocket.events = 0;
  341.  
  342.     if (* condition & ENET_SOCKET_WAIT_SEND)
  343.       pollSocket.events |= POLLOUT;
  344.  
  345.     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  346.       pollSocket.events |= POLLIN;
  347.  
  348.     pollCount = poll (& pollSocket, 1, timeout);
  349.  
  350.     if (pollCount < 0)
  351.       return -1;
  352.  
  353.     * condition = ENET_SOCKET_WAIT_NONE;
  354.  
  355.     if (pollCount == 0)
  356.       return 0;
  357.  
  358.     if (pollSocket.revents & POLLOUT)
  359.       * condition |= ENET_SOCKET_WAIT_SEND;
  360.     
  361.     if (pollSocket.revents & POLLIN)
  362.       * condition |= ENET_SOCKET_WAIT_RECEIVE;
  363.  
  364.     return 0;
  365. #else
  366.     fd_set readSet, writeSet;
  367.     struct timeval timeVal;
  368.     int selectCount;
  369.  
  370.     timeVal.tv_sec = timeout / 1000;
  371.     timeVal.tv_usec = (timeout % 1000) * 1000;
  372.  
  373.     FD_ZERO (& readSet);
  374.     FD_ZERO (& writeSet);
  375.  
  376.     if (* condition & ENET_SOCKET_WAIT_SEND)
  377.       FD_SET (socket, & writeSet);
  378.  
  379.     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
  380.       FD_SET (socket, & readSet);
  381.  
  382.     selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
  383.  
  384.     if (selectCount < 0)
  385.       return -1;
  386.  
  387.     * condition = ENET_SOCKET_WAIT_NONE;
  388.  
  389.     if (selectCount == 0)
  390.       return 0;
  391.  
  392.     if (FD_ISSET (socket, & writeSet))
  393.       * condition |= ENET_SOCKET_WAIT_SEND;
  394.  
  395.     if (FD_ISSET (socket, & readSet))
  396.       * condition |= ENET_SOCKET_WAIT_RECEIVE;
  397.  
  398.     return 0;
  399. #endif
  400. }
  401.  
  402. #endif
  403.  
  404.