diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/formula.h | 3 | ||||
-rw-r--r-- | src/linux_compatibility.h | 2 | ||||
-rw-r--r-- | src/socket.cpp | 49 | ||||
-rw-r--r-- | src/tests/socketbreak.cpp | 27 |
4 files changed, 62 insertions, 19 deletions
diff --git a/src/formula.h b/src/formula.h index c57c4bb..c88e409 100644 --- a/src/formula.h +++ b/src/formula.h | |||
@@ -44,8 +44,9 @@ namespace Bu | |||
44 | { | 44 | { |
45 | } | 45 | } |
46 | 46 | ||
47 | prec run( const char *sFormula ) | 47 | prec run( const Bu::FString &sFormulaSrc ) |
48 | { | 48 | { |
49 | const char *sFormula = sFormulaSrc.getStr(); | ||
49 | for(;;) | 50 | for(;;) |
50 | { | 51 | { |
51 | uint8_t tNum = nextToken( &sFormula ); | 52 | uint8_t tNum = nextToken( &sFormula ); |
diff --git a/src/linux_compatibility.h b/src/linux_compatibility.h index 67016a7..6d3d85e 100644 --- a/src/linux_compatibility.h +++ b/src/linux_compatibility.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define bu_bind bind | 15 | #define bu_bind bind |
16 | #define bu_listen listen | 16 | #define bu_listen listen |
17 | #define bu_accept accept | 17 | #define bu_accept accept |
18 | #define bu_send send | ||
19 | #define bu_recv recv | ||
18 | 20 | ||
19 | #define bu_gai_strerror gai_strerror | 21 | #define bu_gai_strerror gai_strerror |
20 | 22 | ||
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 |
diff --git a/src/tests/socketbreak.cpp b/src/tests/socketbreak.cpp new file mode 100644 index 0000000..82069de --- /dev/null +++ b/src/tests/socketbreak.cpp | |||
@@ -0,0 +1,27 @@ | |||
1 | #include "bu/serversocket.h" | ||
2 | #include "bu/socket.h" | ||
3 | |||
4 | int main() | ||
5 | { | ||
6 | Bu::ServerSocket sSrv( 9987 ); | ||
7 | |||
8 | Bu::Socket sSend("localhost", 9987 ); | ||
9 | |||
10 | Bu::Socket sRecv( sSrv.accept() ); | ||
11 | |||
12 | printf("Connected sockets.\n"); | ||
13 | |||
14 | sleep( 1 ); | ||
15 | printf("Closing sRecv.\n"); | ||
16 | sRecv.close(); | ||
17 | sleep( 1 ); | ||
18 | |||
19 | char buf[3]; | ||
20 | printf("About to write.\n"); | ||
21 | printf("write: %d\n", sSend.write("hi", 2 ) ); | ||
22 | printf("About to read.\n"); | ||
23 | printf("read: %d\n", sSend.read( buf, 2 ) ); | ||
24 | |||
25 | return 0; | ||
26 | } | ||
27 | |||