diff options
Diffstat (limited to 'src/socket.cpp')
| -rw-r--r-- | src/socket.cpp | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/socket.cpp b/src/socket.cpp index dd19d39..3e4f3c7 100644 --- a/src/socket.cpp +++ b/src/socket.cpp | |||
| @@ -115,6 +115,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
| 115 | close(); | 115 | close(); |
| 116 | throw ExceptionBase("Connection timeout.\n"); | 116 | throw ExceptionBase("Connection timeout.\n"); |
| 117 | } | 117 | } |
| 118 | read( NULL, 0 ); // See if we can get any errors out of the way early. | ||
| 118 | } | 119 | } |
| 119 | } | 120 | } |
| 120 | 121 | ||
| @@ -129,6 +130,7 @@ void Bu::Socket::close() | |||
| 129 | #ifndef WIN32 | 130 | #ifndef WIN32 |
| 130 | fsync( nSocket ); | 131 | fsync( nSocket ); |
| 131 | #endif | 132 | #endif |
| 133 | shutdown( nSocket, SHUT_RDWR ); | ||
| 132 | ::close( nSocket ); | 134 | ::close( nSocket ); |
| 133 | } | 135 | } |
| 134 | bActive = false; | 136 | bActive = false; |
| @@ -136,25 +138,36 @@ void Bu::Socket::close() | |||
| 136 | 138 | ||
| 137 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) | 139 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) |
| 138 | { | 140 | { |
| 139 | #ifdef WIN32 | 141 | fd_set rfds; |
| 140 | int nRead = TEMP_FAILURE_RETRY( | 142 | FD_ZERO(&rfds); |
| 141 | bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); | 143 | FD_SET(nSocket, &rfds); |
| 142 | #else | 144 | struct timeval tv = {0, 0}; |
| 143 | int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); | 145 | if( bu_select( nSocket+1, &rfds, NULL, NULL, &tv ) < 0 ) |
| 144 | #endif | 146 | throw SocketException( SocketException::cRead, strerror(errno) ); |
| 145 | if( nRead < 0 ) | 147 | if( FD_ISSET( nSocket, &rfds ) ) |
| 146 | { | 148 | { |
| 149 | int nRead = TEMP_FAILURE_RETRY( | ||
| 150 | bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); | ||
| 151 | if( nRead == 0 ) | ||
| 152 | { | ||
| 153 | bActive = false; | ||
| 154 | throw SocketException( SocketException::cClosed, "Socket closed."); | ||
| 155 | } | ||
| 156 | if( nRead < 0 ) | ||
| 157 | { | ||
| 147 | #ifdef WIN32 | 158 | #ifdef WIN32 |
| 148 | int iWSAError = bu_WSAGetLastError(); | 159 | int iWSAError = bu_WSAGetLastError(); |
| 149 | if( iWSAError == WSAEWOULDBLOCK ) | 160 | if( iWSAError == WSAEWOULDBLOCK ) |
| 150 | return 0; | 161 | return 0; |
| 151 | #else | 162 | #else |
| 152 | if( errno == EAGAIN ) | 163 | if( errno == EAGAIN ) |
| 153 | return 0; | 164 | return 0; |
| 154 | throw SocketException( SocketException::cRead, strerror(errno) ); | 165 | throw SocketException( SocketException::cRead, strerror(errno) ); |
| 155 | #endif | 166 | #endif |
| 167 | } | ||
| 168 | return nRead; | ||
| 156 | } | 169 | } |
| 157 | return nRead; | 170 | return 0; |
| 158 | } | 171 | } |
| 159 | 172 | ||
| 160 | size_t Bu::Socket::read( void *pBuf, size_t nBytes, | 173 | size_t Bu::Socket::read( void *pBuf, size_t nBytes, |
| @@ -203,12 +216,12 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, | |||
| 203 | 216 | ||
| 204 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) | 217 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) |
| 205 | { | 218 | { |
| 206 | #ifdef WIN32 | 219 | //#ifdef WIN32 |
| 207 | int nWrote = TEMP_FAILURE_RETRY( | 220 | int nWrote = TEMP_FAILURE_RETRY( |
| 208 | bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); | 221 | bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); |
| 209 | #else | 222 | //#else |
| 210 | int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); | 223 | // int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); |
| 211 | #endif | 224 | //#endif |
| 212 | if( nWrote < 0 ) | 225 | if( nWrote < 0 ) |
| 213 | { | 226 | { |
| 214 | #ifdef WIN32 | 227 | #ifdef WIN32 |
