socket.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // -*- C++ -*-
  2. // Module: Log4CPLUS
  3. // File: socket.h
  4. // Created: 1/2010
  5. // Author: Vaclav Haisman
  6. //
  7. //
  8. // Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
  9. //
  10. // Redistribution and use in source and binary forms, with or without modifica-
  11. // tion, are permitted provided that the following conditions are met:
  12. //
  13. // 1. Redistributions of source code must retain the above copyright notice,
  14. // this list of conditions and the following disclaimer.
  15. //
  16. // 2. Redistributions in binary form must reproduce the above copyright notice,
  17. // this list of conditions and the following disclaimer in the documentation
  18. // and/or other materials provided with the distribution.
  19. //
  20. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  21. // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  24. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  25. // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  29. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. /** @file
  31. * This header contains declaration internal to log4cplus. They must never be
  32. * visible from user accesible headers or exported in DLL/shared libray.
  33. */
  34. #ifndef LOG4CPLUS_INTERNAL_SOCKET_H_
  35. #define LOG4CPLUS_INTERNAL_SOCKET_H_
  36. #include <log4cplus/config.hxx>
  37. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  38. #pragma once
  39. #endif
  40. #if ! defined (INSIDE_LOG4CPLUS)
  41. # error "This header must not be be used outside log4cplus' implementation files."
  42. #endif
  43. #if defined(_WIN32)
  44. #include <log4cplus/config/windowsh-inc.h>
  45. #endif
  46. #include <log4cplus/helpers/socket.h>
  47. #include <cerrno>
  48. #ifdef LOG4CPLUS_HAVE_ERRNO_H
  49. #include <errno.h>
  50. #endif
  51. #ifdef LOG4CPLUS_HAVE_UNISTD_H
  52. #include <unistd.h>
  53. #endif
  54. #if defined (LOG4CPLUS_HAVE_NETDB_H)
  55. #include <netdb.h>
  56. #endif
  57. namespace log4cplus {
  58. namespace helpers {
  59. #if defined(_WIN32)
  60. typedef SOCKET os_socket_type;
  61. os_socket_type const INVALID_OS_SOCKET_VALUE = INVALID_SOCKET;
  62. struct ADDRINFOT_deleter
  63. {
  64. void
  65. operator () (ADDRINFOA * ptr) const
  66. {
  67. FreeAddrInfoA(ptr);
  68. }
  69. void
  70. operator () (ADDRINFOW * ptr) const
  71. {
  72. FreeAddrInfoW(ptr);
  73. }
  74. };
  75. struct socket_closer
  76. {
  77. void
  78. operator () (SOCKET s)
  79. {
  80. if (s && s != INVALID_OS_SOCKET_VALUE)
  81. {
  82. DWORD const eno = WSAGetLastError();
  83. ::closesocket(s);
  84. WSASetLastError(eno);
  85. }
  86. }
  87. };
  88. #else
  89. typedef int os_socket_type;
  90. os_socket_type const INVALID_OS_SOCKET_VALUE = -1;
  91. struct addrinfo_deleter
  92. {
  93. void
  94. operator () (struct addrinfo * ptr) const
  95. {
  96. freeaddrinfo(ptr);
  97. }
  98. };
  99. struct socket_closer
  100. {
  101. void
  102. operator () (os_socket_type s)
  103. {
  104. if (s >= 0)
  105. {
  106. int const eno = errno;
  107. close(s);
  108. errno = eno;
  109. }
  110. }
  111. };
  112. #endif
  113. struct socket_holder
  114. {
  115. os_socket_type sock;
  116. socket_holder()
  117. : sock(INVALID_OS_SOCKET_VALUE)
  118. { }
  119. socket_holder(os_socket_type s)
  120. : sock(s)
  121. { }
  122. ~socket_holder()
  123. {
  124. socket_closer()(sock);
  125. }
  126. void
  127. reset(os_socket_type s = INVALID_OS_SOCKET_VALUE)
  128. {
  129. if (sock != INVALID_OS_SOCKET_VALUE)
  130. socket_closer()(sock);
  131. sock = s;
  132. }
  133. os_socket_type
  134. detach()
  135. {
  136. os_socket_type s = sock;
  137. sock = INVALID_OS_SOCKET_VALUE;
  138. return s;
  139. }
  140. private:
  141. socket_holder (socket_holder const &);
  142. socket_holder operator = (socket_holder const &);
  143. #if defined (LOG4CPLUS_HAVE_CXX11_SUPPORT)
  144. socket_holder (socket_holder &&);
  145. socket_holder operator = (socket_holder &&);
  146. #endif
  147. };
  148. static inline
  149. os_socket_type
  150. to_os_socket (SOCKET_TYPE const & x)
  151. {
  152. return static_cast<os_socket_type>(x);
  153. }
  154. static inline
  155. SOCKET_TYPE
  156. to_log4cplus_socket (os_socket_type const & x)
  157. {
  158. return static_cast<SOCKET_TYPE>(x);
  159. }
  160. static inline
  161. void
  162. set_last_socket_error (int err)
  163. {
  164. errno = err;
  165. }
  166. static inline
  167. int
  168. get_last_socket_error ()
  169. {
  170. return errno;
  171. }
  172. } // namespace helpers {
  173. } // namespace log4cplus {
  174. #endif // LOG4CPLUS_INTERNAL_SOCKET_H_