From 09f20ca825bc53a390ce5e52483adbfaf5acb42a Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 4 Apr 2012 20:43:27 +0000 Subject: [PATCH] 2012-04-04 22:43 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * harbour/src/rtl/hbsocket.c ! fixed problems with missing error setting in select() executed for asynchronous connect() (windows builds) and overwritten error codes in connect() and accept() (all builds). Many thanks for Mindaugas for locating the problem and patch. --- harbour/ChangeLog | 7 +++++++ harbour/src/rtl/hbsocket.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b453a58847..dd348cf308 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,13 @@ The license applies to all entries newer than 2009-04-28. */ +2012-04-04 22:43 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * harbour/src/rtl/hbsocket.c + ! fixed problems with missing error setting in select() executed + for asynchronous connect() (windows builds) and overwritten error + codes in connect() and accept() (all builds). Many thanks for + Mindaugas for locating the problem and patch. + 2012-04-04 22:29 UTC+0200 Viktor Szakats (harbour syenar.net) * hbhpdf/hbhpdf.hbp * hbhpdf/hbhpdf.hbx diff --git a/harbour/src/rtl/hbsocket.c b/harbour/src/rtl/hbsocket.c index 65a4285c23..6a3e07cac5 100644 --- a/harbour/src/rtl/hbsocket.c +++ b/harbour/src/rtl/hbsocket.c @@ -1569,6 +1569,7 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) fd_set efds; #endif int iResult, iError; + socklen_t len; #if !defined( HB_HAS_SELECT_TIMER ) HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); #endif @@ -1598,7 +1599,12 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) hb_socketSetOsError( iError ); #if defined( HB_OS_WIN ) if( iResult > 0 && FD_ISSET( ( HB_SOCKET_T ) sd, pefds ) ) + { iResult = -1; + if( getsockopt( sd, SOL_SOCKET, SO_ERROR, ( char * ) &iError, &len ) != 0 ) + iError = HB_SOCK_GETERROR(); + hb_socketSetOsError( iError ); + } else #endif if( iResult == -1 && timeout > 0 && HB_SOCK_IS_EINTR( iError ) && @@ -1622,10 +1628,8 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) #if !defined( HB_OS_WIN ) if( iResult > 0 && FD_ISSET( ( HB_SOCKET_T ) sd, &wfds ) ) { - int iError; - socklen_t len = sizeof( iError ); - - if( getsockopt( sd, SOL_SOCKET, SO_ERROR, ( void * ) &iError, &len ) != 0 ) + len = sizeof( iError ); + if( getsockopt( sd, SOL_SOCKET, SO_ERROR, ( char * ) &iError, &len ) != 0 ) { iResult = -1; iError = HB_SOCK_GETERROR(); @@ -2180,7 +2184,7 @@ HB_SOCKET hb_socketAccept( HB_SOCKET sd, void ** pSockAddr, unsigned * puiLen, H HB_SOCKET newsd = HB_NO_SOCKET; HB_SOCKADDR_STORAGE st; socklen_t len = sizeof( st ); - int ret; + int ret, err; hb_vmUnlock(); ret = hb_socketSelectRD( sd, timeout ); @@ -2193,7 +2197,8 @@ HB_SOCKET hb_socketAccept( HB_SOCKET sd, void ** pSockAddr, unsigned * puiLen, H */ ret = timeout < 0 ? 0 : hb_socketSetBlockingIO( sd, HB_FALSE ); newsd = accept( sd, &st.sa, &len ); - hb_socketSetOsError( newsd != HB_NO_SOCKET ? 0 : HB_SOCK_GETERROR() ); + err = newsd != HB_NO_SOCKET ? 0 : HB_SOCK_GETERROR(); + if( ret > 0 ) hb_socketSetBlockingIO( sd, HB_TRUE ); if( pSockAddr && puiLen ) @@ -2216,6 +2221,8 @@ HB_SOCKET hb_socketAccept( HB_SOCKET sd, void ** pSockAddr, unsigned * puiLen, H */ if( newsd != HB_NO_SOCKET ) hb_socketSetBlockingIO( newsd, HB_TRUE ); + + hb_socketSetOsError( err ); } else if( ret == 0 ) hb_socketSetRawError( HB_SOCKET_ERR_TIMEOUT ); @@ -2225,7 +2232,7 @@ HB_SOCKET hb_socketAccept( HB_SOCKET sd, void ** pSockAddr, unsigned * puiLen, H int hb_socketConnect( HB_SOCKET sd, const void * pSockAddr, unsigned uiLen, HB_MAXINT timeout ) { - int ret, blk, err; + int ret, blk, err, rawerr; hb_vmUnlock(); @@ -2250,8 +2257,20 @@ int hb_socketConnect( HB_SOCKET sd, const void * pSockAddr, unsigned uiLen, HB_M ret = -1; } } + if( blk > 0 ) + { + err = hb_socketGetOsError(); + rawerr = err ? 0 : hb_socketGetError(); + hb_socketSetBlockingIO( sd, HB_TRUE ); + + if( err ) + hb_socketSetOsError( err ); + else + hb_socketSetRawError( rawerr ); + } + hb_vmLock(); return ret; }