diff --git a/Csocket.cpp b/Csocket.cpp index d751e760..73d93aa2 100644 --- a/Csocket.cpp +++ b/Csocket.cpp @@ -28,7 +28,7 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * -* $Revision: 1.63 $ +* $Revision: 1.65 $ */ #include "Csocket.h" @@ -51,6 +51,52 @@ int GetCsockClassIdx() return( g_iCsockSSLIdx ); } +#ifdef _WIN32 +static inline void set_non_blocking(int fd) +{ + u_long iOpts = 1; + ioctlsocket( fd, FIONBIO, &iOpts ); +} + +static inline void set_blocking(int fd) +{ + u_long iOpts = 0; + ioctlsocket( fd, FIONBIO, &iOpts ); +} + +static inline void set_close_on_exec(int fd) +{ + // TODO add this for windows + // see http://gcc.gnu.org/ml/java-patches/2002-q1/msg00696.html + // for infos on how to do this +} +#else +static inline void set_non_blocking(int fd) +{ + int fdflags = fcntl(fd, F_GETFL, 0); + if ( fdflags < 0 ) + return; // Ignore errors + fcntl( fd, F_SETFL, fdflags|O_NONBLOCK ); +} + +static inline void set_blocking(int fd) +{ + int fdflags = fcntl(fd, F_GETFL, 0); + if ( fdflags < 0 ) + return; // Ignore errors + fdflags &= ~O_NONBLOCK; + fcntl( fd, F_SETFL, fdflags ); +} + +static inline void set_close_on_exec(int fd) +{ + int fdflags = fcntl(fd, F_GETFD, 0); + if ( fdflags < 0 ) + return; // Ignore errors + fcntl( fd, F_SETFD, fdflags|FD_CLOEXEC); +} +#endif /* _WIN32 */ + #ifdef HAVE_LIBSSL Csock *GetCsockFromCTX( X509_STORE_CTX *pCTX ) { @@ -762,13 +808,7 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup ) } // set it none blocking -#ifdef _WIN32 - u_long iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl (m_iReadSock, F_GETFL, 0); - fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iReadSock ); m_iConnType = OUTBOUND; @@ -792,15 +832,7 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup ) if ( m_bBLOCK ) { -#ifdef _WIN32 - u_long iOpts = 0; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - // unset the flags afterwords, rather than have connect block - int fdflags = fcntl (m_iReadSock, F_GETFL, 0); - fdflags &= ~O_NONBLOCK; - fcntl( m_iReadSock, F_SETFL, fdflags ); -#endif /* _WIN32 */ + set_blocking( m_iReadSock ); } if ( m_eConState != CST_OK ) @@ -908,13 +940,7 @@ bool Csock::Listen( u_short iPort, int iMaxConns, const CS_STRING & sBindHost, u if ( !m_bBLOCK ) { // set it none blocking -#ifdef _WIN32 - u_long iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl ( m_iReadSock, F_GETFL, 0); - fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iReadSock ); } return( true ); @@ -951,16 +977,13 @@ int Csock::Accept( CS_STRING & sHost, u_short & iRPort ) if ( iSock != -1 ) { + // Make it close-on-exec + set_close_on_exec( iSock ); + if ( !m_bBLOCK ) { // make it none blocking -#ifdef _WIN32 - u_long iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl (iSock, F_GETFL, 0); - fcntl( iSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iReadSock ); } if ( !ConnectionFrom( sHost, iRPort ) ) @@ -1212,13 +1235,7 @@ bool Csock::ConnectSSL( const CS_STRING & sBindhost ) if ( m_bBLOCK ) { -#ifdef _WIN32 - u_long iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl ( m_iReadSock, F_GETFL, 0); - fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iReadSock ); } int iErr = SSL_connect( m_ssl ); @@ -1234,15 +1251,7 @@ bool Csock::ConnectSSL( const CS_STRING & sBindhost ) if ( m_bBLOCK ) { // unset the flags afterwords, rather then have connect block -#ifdef _WIN32 - u_long iOpts = 0; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl (m_iReadSock, F_GETFL, 0); - fdflags &= ~O_NONBLOCK; - fcntl( m_iReadSock, F_SETFL, fdflags ); -#endif /* _WIN32 */ - + set_blocking( m_iReadSock ); } return( bPass ); @@ -1631,7 +1640,7 @@ void Csock::PushBuff( const char *data, int len, bool bStartAtZero ) if ( data ) m_sbuffer.append( data, len ); - while( !m_bPauseRead ) + while( !m_bPauseRead && GetCloseType() == CLT_DONT ) { CS_STRING::size_type iFind = m_sbuffer.find( "\n", iStartPos ); @@ -1757,23 +1766,11 @@ void Csock::BlockIO( bool bBLOCK ) { m_bBLOCK = bBLOCK; } void Csock::NonBlockingIO() { -#ifdef _WIN32 - u_long iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - int fdflags = fcntl ( m_iReadSock, F_GETFL, 0); - fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iReadSock ); if ( m_iReadSock != m_iWriteSock ) { -#ifdef _WIN32 - iOpts = 1; - ioctlsocket( m_iReadSock, FIONBIO, &iOpts ); -#else - fdflags = fcntl ( m_iWriteSock, F_GETFL, 0); - fcntl( m_iWriteSock, F_SETFL, fdflags|O_NONBLOCK ); -#endif /* _WIN32 */ + set_non_blocking( m_iWriteSock ); } BlockIO( false ); @@ -2215,19 +2212,20 @@ int Csock::SOCKET( bool bListen ) #ifdef HAVE_IPV6 int iRet = socket( ( GetIPv6() ? PF_INET6 : PF_INET ), SOCK_STREAM, IPPROTO_TCP ); #else - // missing wrapper around ipv6 for systems missing ipv6, Uli Schlachter int iRet = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); #endif /* HAVE_IPV6 */ + if ( iRet >= 0 ) { + set_close_on_exec( iRet ); - if ( ( iRet > -1 ) && ( bListen ) ) - { - const int on = 1; + if ( bListen ) { + const int on = 1; - if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof( on ) ) != 0 ) - PERROR( "setsockopt" ); - - } else if ( iRet == -1 ) + if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof( on ) ) != 0 ) + PERROR( "setsockopt" ); + } + } else PERROR( "socket" ); return( iRet ); diff --git a/Csocket.h b/Csocket.h index ef2ba0cb..e36f1b51 100644 --- a/Csocket.h +++ b/Csocket.h @@ -28,7 +28,7 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * -* $Revision: 1.179 $ +* $Revision: 1.181 $ */ // note to compile with win32 need to link to winsock2, using gcc its -lws2_32 @@ -112,6 +112,7 @@ namespace Csocket { #endif /* _NO_CSOCKET_NS */ + /** * @class CSCharBuffer * @brief ease of use self deleting char * class