log4cplus
2.0.0
|
00001 // -*- C++ -*- 00002 // Module: Log4CPLUS 00003 // File: socket.h 00004 // Created: 1/2010 00005 // Author: Vaclav Haisman 00006 // 00007 // 00008 // Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved. 00009 // 00010 // Redistribution and use in source and binary forms, with or without modifica- 00011 // tion, are permitted provided that the following conditions are met: 00012 // 00013 // 1. Redistributions of source code must retain the above copyright notice, 00014 // this list of conditions and the following disclaimer. 00015 // 00016 // 2. Redistributions in binary form must reproduce the above copyright notice, 00017 // this list of conditions and the following disclaimer in the documentation 00018 // and/or other materials provided with the distribution. 00019 // 00020 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00021 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00022 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00023 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00024 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00025 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00026 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00029 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00037 #ifndef LOG4CPLUS_INTERNAL_SOCKET_H_ 00038 #define LOG4CPLUS_INTERNAL_SOCKET_H_ 00039 00040 #include <log4cplus/config.hxx> 00041 00042 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00043 #pragma once 00044 #endif 00045 00046 #if ! defined (INSIDE_LOG4CPLUS) 00047 # error "This header must not be be used outside log4cplus' implementation files." 00048 #endif 00049 00050 #if defined(_WIN32) 00051 #include <log4cplus/config/windowsh-inc.h> 00052 #endif 00053 #include <log4cplus/helpers/socket.h> 00054 00055 #include <cerrno> 00056 #ifdef LOG4CPLUS_HAVE_ERRNO_H 00057 #include <errno.h> 00058 #endif 00059 00060 #ifdef LOG4CPLUS_HAVE_UNISTD_H 00061 #include <unistd.h> 00062 #endif 00063 00064 #if defined (LOG4CPLUS_HAVE_NETDB_H) 00065 #include <netdb.h> 00066 #endif 00067 00068 00069 namespace log4cplus { 00070 00071 namespace helpers { 00072 00073 #if defined(_WIN32) 00074 typedef SOCKET os_socket_type; 00075 os_socket_type const INVALID_OS_SOCKET_VALUE = INVALID_SOCKET; 00076 00077 struct ADDRINFOT_deleter 00078 { 00079 void 00080 operator () (ADDRINFOA * ptr) const 00081 { 00082 FreeAddrInfoA(ptr); 00083 } 00084 00085 void 00086 operator () (ADDRINFOW * ptr) const 00087 { 00088 FreeAddrInfoW(ptr); 00089 } 00090 }; 00091 00092 00093 struct socket_closer 00094 { 00095 void 00096 operator () (SOCKET s) 00097 { 00098 if (s && s != INVALID_OS_SOCKET_VALUE) 00099 { 00100 DWORD const eno = WSAGetLastError(); 00101 ::closesocket(s); 00102 WSASetLastError(eno); 00103 } 00104 } 00105 }; 00106 00107 00108 #else 00109 typedef int os_socket_type; 00110 os_socket_type const INVALID_OS_SOCKET_VALUE = -1; 00111 00112 00113 struct addrinfo_deleter 00114 { 00115 void 00116 operator () (struct addrinfo * ptr) const 00117 { 00118 freeaddrinfo(ptr); 00119 } 00120 }; 00121 00122 00123 struct socket_closer 00124 { 00125 void 00126 operator () (os_socket_type s) 00127 { 00128 if (s >= 0) 00129 { 00130 int const eno = errno; 00131 close(s); 00132 errno = eno; 00133 } 00134 } 00135 }; 00136 00137 #endif 00138 00139 00140 struct socket_holder 00141 { 00142 os_socket_type sock; 00143 00144 socket_holder() 00145 : sock(INVALID_OS_SOCKET_VALUE) 00146 { } 00147 00148 socket_holder(os_socket_type s) 00149 : sock(s) 00150 { } 00151 00152 ~socket_holder() 00153 { 00154 socket_closer()(sock); 00155 } 00156 00157 void 00158 reset(os_socket_type s = INVALID_OS_SOCKET_VALUE) 00159 { 00160 if (sock != INVALID_OS_SOCKET_VALUE) 00161 socket_closer()(sock); 00162 00163 sock = s; 00164 } 00165 00166 os_socket_type 00167 detach() 00168 { 00169 os_socket_type s = sock; 00170 sock = INVALID_OS_SOCKET_VALUE; 00171 return s; 00172 } 00173 00174 socket_holder(socket_holder &&) = delete; 00175 socket_holder(socket_holder const &) = delete; 00176 00177 socket_holder operator = (socket_holder &&) = delete; 00178 socket_holder operator = (socket_holder const &) = delete; 00179 }; 00180 00181 00182 static inline 00183 os_socket_type 00184 to_os_socket (SOCKET_TYPE const & x) 00185 { 00186 return static_cast<os_socket_type>(x); 00187 } 00188 00189 00190 static inline 00191 SOCKET_TYPE 00192 to_log4cplus_socket (os_socket_type const & x) 00193 { 00194 return static_cast<SOCKET_TYPE>(x); 00195 } 00196 00197 00198 static inline 00199 void 00200 set_last_socket_error (int err) 00201 { 00202 errno = err; 00203 } 00204 00205 00206 static inline 00207 int 00208 get_last_socket_error () 00209 { 00210 return errno; 00211 } 00212 00213 00214 } // namespace helpers { 00215 00216 } // namespace log4cplus { 00217 00218 00219 #endif // LOG4CPLUS_INTERNAL_SOCKET_H_