diff options
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/usocket.c b/src/usocket.c index 617b1ea..cf0458d 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -113,7 +113,7 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) | |||
113 | if (err > 0) { | 113 | if (err > 0) { |
114 | char dummy; | 114 | char dummy; |
115 | /* recv will set errno to the value a blocking connect would set */ | 115 | /* recv will set errno to the value a blocking connect would set */ |
116 | if (recv(sock, &dummy, 0, 0) < 0 && errno != EWOULDBLOCK) | 116 | if (recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN) |
117 | return sock_connectstrerror(errno); | 117 | return sock_connectstrerror(errno); |
118 | else | 118 | else |
119 | return NULL; | 119 | return NULL; |
@@ -179,7 +179,7 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | |||
179 | /* if result is valid, we are done */ | 179 | /* if result is valid, we are done */ |
180 | if (*pa != SOCK_INVALID) return NULL; | 180 | if (*pa != SOCK_INVALID) return NULL; |
181 | /* find out if we failed for a fatal reason */ | 181 | /* find out if we failed for a fatal reason */ |
182 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) | 182 | if (errno != EAGAIN && errno != ECONNABORTED) |
183 | return sock_acceptstrerror(errno); | 183 | return sock_acceptstrerror(errno); |
184 | /* call select to avoid busy-wait. */ | 184 | /* call select to avoid busy-wait. */ |
185 | FD_ZERO(&fds); | 185 | FD_ZERO(&fds); |
@@ -206,21 +206,23 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
206 | while (put < 0 && errno == EINTR); | 206 | while (put < 0 && errno == EINTR); |
207 | /* deal with failure */ | 207 | /* deal with failure */ |
208 | if (put <= 0) { | 208 | if (put <= 0) { |
209 | int ret; | ||
209 | fd_set fds; | 210 | fd_set fds; |
210 | /* in any case, nothing has been sent */ | 211 | /* in any case, nothing has been sent */ |
211 | *sent = 0; | 212 | *sent = 0; |
213 | /* only proceed to select if no error happened */ | ||
214 | if (errno != EAGAIN) return IO_ERROR; | ||
215 | /* optimize for the timeout = 0 case */ | ||
216 | if (timeout == 0) return IO_TIMEOUT; | ||
212 | /* here we know the connection has been closed */ | 217 | /* here we know the connection has been closed */ |
213 | if (errno == EPIPE) return IO_CLOSED; | 218 | if (errno == EPIPE) return IO_CLOSED; |
214 | /* run select to avoid busy wait */ | 219 | /* run select to avoid busy wait */ |
215 | FD_ZERO(&fds); | 220 | FD_ZERO(&fds); |
216 | FD_SET(sock, &fds); | 221 | FD_SET(sock, &fds); |
217 | if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { | 222 | ret = sock_select(sock+1, NULL, &fds, NULL, timeout); |
218 | /* here the call was interrupted. calling again might work */ | 223 | if (ret == 0) return IO_TIMEOUT; |
219 | if (errno == EINTR) return IO_RETRY; | 224 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
220 | /* here there was no data before timeout */ | 225 | else return IO_ERROR; |
221 | else return IO_TIMEOUT; | ||
222 | /* here we didn't send anything, but now we can */ | ||
223 | } else return IO_RETRY; | ||
224 | /* here we successfully sent something */ | 226 | /* here we successfully sent something */ |
225 | } else { | 227 | } else { |
226 | *sent = put; | 228 | *sent = put; |
@@ -240,15 +242,18 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
240 | do put = sendto(sock, data, count, 0, addr, addr_len); | 242 | do put = sendto(sock, data, count, 0, addr, addr_len); |
241 | while (put < 0 && errno == EINTR); | 243 | while (put < 0 && errno == EINTR); |
242 | if (put <= 0) { | 244 | if (put <= 0) { |
245 | int ret; | ||
243 | fd_set fds; | 246 | fd_set fds; |
244 | *sent = 0; | 247 | *sent = 0; |
248 | if (errno != EAGAIN) return IO_ERROR; | ||
249 | if (timeout == 0) return IO_TIMEOUT; | ||
245 | if (errno == EPIPE) return IO_CLOSED; | 250 | if (errno == EPIPE) return IO_CLOSED; |
246 | FD_ZERO(&fds); | 251 | FD_ZERO(&fds); |
247 | FD_SET(sock, &fds); | 252 | FD_SET(sock, &fds); |
248 | if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { | 253 | ret = sock_select(sock+1, NULL, &fds, NULL, timeout); |
249 | if (errno == EINTR) return IO_RETRY; | 254 | if (ret == 0) return IO_TIMEOUT; |
250 | else return IO_TIMEOUT; | 255 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
251 | } else return IO_RETRY; | 256 | else return IO_ERROR; |
252 | } else { | 257 | } else { |
253 | *sent = put; | 258 | *sent = put; |
254 | return IO_DONE; | 259 | return IO_DONE; |
@@ -270,12 +275,14 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
270 | int ret; | 275 | int ret; |
271 | *got = 0; | 276 | *got = 0; |
272 | if (taken == 0) return IO_CLOSED; | 277 | if (taken == 0) return IO_CLOSED; |
278 | if (errno != EAGAIN) return IO_ERROR; | ||
279 | if (timeout == 0) return IO_TIMEOUT; | ||
273 | FD_ZERO(&fds); | 280 | FD_ZERO(&fds); |
274 | FD_SET(sock, &fds); | 281 | FD_SET(sock, &fds); |
275 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); | 282 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); |
276 | if (ret < 0 && errno == EINTR) return IO_RETRY; | ||
277 | if (ret == 0) return IO_TIMEOUT; | 283 | if (ret == 0) return IO_TIMEOUT; |
278 | return IO_RETRY; | 284 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
285 | else return IO_ERROR; | ||
279 | } else { | 286 | } else { |
280 | *got = taken; | 287 | *got = taken; |
281 | return IO_DONE; | 288 | return IO_DONE; |
@@ -298,12 +305,14 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
298 | int ret; | 305 | int ret; |
299 | *got = 0; | 306 | *got = 0; |
300 | if (taken == 0) return IO_CLOSED; | 307 | if (taken == 0) return IO_CLOSED; |
308 | if (errno != EAGAIN) return IO_ERROR; | ||
309 | if (timeout == 0) return IO_TIMEOUT; | ||
301 | FD_ZERO(&fds); | 310 | FD_ZERO(&fds); |
302 | FD_SET(sock, &fds); | 311 | FD_SET(sock, &fds); |
303 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); | 312 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); |
304 | if (ret < 0 && errno == EINTR) return IO_RETRY; | ||
305 | if (ret == 0) return IO_TIMEOUT; | 313 | if (ret == 0) return IO_TIMEOUT; |
306 | return IO_RETRY; | 314 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
315 | else return IO_ERROR; | ||
307 | } else { | 316 | } else { |
308 | *got = taken; | 317 | *got = taken; |
309 | return IO_DONE; | 318 | return IO_DONE; |
@@ -363,7 +372,7 @@ static const char *sock_createstrerror(int err) | |||
363 | static const char *sock_acceptstrerror(int err) | 372 | static const char *sock_acceptstrerror(int err) |
364 | { | 373 | { |
365 | switch (err) { | 374 | switch (err) { |
366 | case EWOULDBLOCK: return io_strerror(IO_RETRY); | 375 | case EAGAIN: return io_strerror(IO_RETRY); |
367 | case EBADF: return "invalid descriptor"; | 376 | case EBADF: return "invalid descriptor"; |
368 | case ENOBUFS: case ENOMEM: return "insuffucient buffer space"; | 377 | case ENOBUFS: case ENOMEM: return "insuffucient buffer space"; |
369 | case ENOTSOCK: return "descriptor not a socket"; | 378 | case ENOTSOCK: return "descriptor not a socket"; |