LibIRCClient 1.10 Used by Probotic
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
Это архивный репозиторий. Вы можете его клонировать или просматривать файлы, но не вносить изменения или открывать задачи/запросы на слияние.

160 строки
3.0KB

  1. /*
  2. * Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
  3. *
  4. * This library is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or (at your
  7. * option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  12. * License for more details.
  13. */
  14. /*
  15. * The sockets interface was moved out to simplify going OpenSSL integration.
  16. */
  17. #if !defined (_WIN32)
  18. #include <sys/socket.h>
  19. #include <netdb.h>
  20. #include <arpa/inet.h>
  21. #include <netinet/in.h>
  22. #include <fcntl.h>
  23. #define IS_SOCKET_ERROR(a) ((a)<0)
  24. typedef int socket_t;
  25. #else
  26. #include <winsock2.h>
  27. #include <ws2tcpip.h>
  28. #include <windows.h>
  29. #define IS_SOCKET_ERROR(a) ((a)==SOCKET_ERROR)
  30. #if !defined(EWOULDBLOCK)
  31. #define EWOULDBLOCK WSAEWOULDBLOCK
  32. #endif
  33. #if !defined(EINPROGRESS)
  34. #define EINPROGRESS WSAEINPROGRESS
  35. #endif
  36. #if !defined(EINTR)
  37. #define EINTR WSAEINTR
  38. #endif
  39. #if !defined(EAGAIN)
  40. #define EAGAIN EWOULDBLOCK
  41. #endif
  42. typedef SOCKET socket_t;
  43. #endif
  44. #ifndef INADDR_NONE
  45. #define INADDR_NONE 0xFFFFFFFF
  46. #endif
  47. static int socket_error()
  48. {
  49. #if !defined (_WIN32)
  50. return errno;
  51. #else
  52. return WSAGetLastError();
  53. #endif
  54. }
  55. static int socket_create (int domain, int type, socket_t * sock)
  56. {
  57. *sock = socket (domain, type, 0);
  58. return IS_SOCKET_ERROR(*sock) ? 1 : 0;
  59. }
  60. static int socket_make_nonblocking (socket_t * sock)
  61. {
  62. #if !defined (_WIN32)
  63. return fcntl (*sock, F_SETFL, fcntl (*sock, F_GETFL,0 ) | O_NONBLOCK) != 0;
  64. #else
  65. unsigned long mode = 1;
  66. return ioctlsocket (*sock, FIONBIO, &mode) == SOCKET_ERROR;
  67. #endif
  68. }
  69. static int socket_close (socket_t * sock)
  70. {
  71. #if !defined (_WIN32)
  72. close (*sock);
  73. #else
  74. closesocket (*sock);
  75. #endif
  76. *sock = -1;
  77. return 0;
  78. }
  79. static int socket_connect (socket_t * sock, const struct sockaddr *saddr, socklen_t len)
  80. {
  81. while ( 1 )
  82. {
  83. if ( connect (*sock, saddr, len) < 0 )
  84. {
  85. if ( socket_error() == EINTR )
  86. continue;
  87. if ( socket_error() != EINPROGRESS && socket_error() != EWOULDBLOCK )
  88. return 1;
  89. }
  90. return 0;
  91. }
  92. }
  93. static int socket_accept (socket_t * sock, socket_t * newsock, struct sockaddr *saddr, socklen_t * len)
  94. {
  95. while ( IS_SOCKET_ERROR(*newsock = accept (*sock, saddr, len)) )
  96. {
  97. if ( socket_error() == EINTR )
  98. continue;
  99. return 1;
  100. }
  101. return 0;
  102. }
  103. static int socket_recv (socket_t * sock, void * buf, size_t len)
  104. {
  105. int length;
  106. while ( (length = recv (*sock, buf, len, 0)) < 0 )
  107. {
  108. int err = socket_error();
  109. if ( err != EINTR && err != EAGAIN )
  110. break;
  111. }
  112. return length;
  113. }
  114. static int socket_send (socket_t * sock, const void *buf, size_t len)
  115. {
  116. int length;
  117. while ( (length = send (*sock, buf, len, 0)) < 0 )
  118. {
  119. int err = socket_error();
  120. if ( err != EINTR && err != EAGAIN )
  121. break;
  122. }
  123. return length;
  124. }