diff options
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/usocket.c b/src/usocket.c index c1ab725..3428a0c 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #define WAITFD_R POLLIN | 22 | #define WAITFD_R POLLIN |
23 | #define WAITFD_W POLLOUT | 23 | #define WAITFD_W POLLOUT |
24 | #define WAITFD_C (POLLIN|POLLOUT) | 24 | #define WAITFD_C (POLLIN|POLLOUT) |
25 | static int sock_waitfd(int fd, int sw, p_tm tm) { | 25 | int sock_waitfd(int fd, int sw, p_tm tm) { |
26 | int ret; | 26 | int ret; |
27 | struct pollfd pfd; | 27 | struct pollfd pfd; |
28 | pfd.fd = fd; | 28 | pfd.fd = fd; |
@@ -44,7 +44,7 @@ static int sock_waitfd(int fd, int sw, p_tm tm) { | |||
44 | #define WAITFD_W 2 | 44 | #define WAITFD_W 2 |
45 | #define WAITFD_C (WAITFD_R|WAITFD_W) | 45 | #define WAITFD_C (WAITFD_R|WAITFD_W) |
46 | 46 | ||
47 | static int sock_waitfd(int fd, int sw, p_tm tm) { | 47 | int sock_waitfd(int fd, int sw, p_tm tm) { |
48 | int ret; | 48 | int ret; |
49 | fd_set rfds, wfds, *rp, *wp; | 49 | fd_set rfds, wfds, *rp, *wp; |
50 | struct timeval tv, *tp; | 50 | struct timeval tv, *tp; |
@@ -166,12 +166,20 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { | |||
166 | while ((err = errno) == EINTR); | 166 | while ((err = errno) == EINTR); |
167 | /* if connection failed immediately, return error code */ | 167 | /* if connection failed immediately, return error code */ |
168 | if (err != EINPROGRESS && err != EAGAIN) return err; | 168 | if (err != EINPROGRESS && err != EAGAIN) return err; |
169 | /* zero timeout case optimization */ | ||
170 | if (tm_iszero(tm)) return IO_TIMEOUT; | ||
169 | /* wait until we have the result of the connection attempt or timeout */ | 171 | /* wait until we have the result of the connection attempt or timeout */ |
170 | if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { | 172 | return sock_connected(ps, tm); |
171 | /* finaly find out if we succeeded connecting */ | 173 | } |
174 | |||
175 | /*-------------------------------------------------------------------------*\ | ||
176 | * Checks if socket is connected, or return reason for failure | ||
177 | \*-------------------------------------------------------------------------*/ | ||
178 | int sock_connected(p_sock ps, p_tm tm) { | ||
179 | int err; | ||
180 | if ((err = sock_waitfd(*ps, WAITFD_C, tm) == IO_CLOSED)) { | ||
172 | if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; | 181 | if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; |
173 | else return errno; | 182 | else return errno; |
174 | /* timed out or some weirder error */ | ||
175 | } else return err; | 183 | } else return err; |
176 | } | 184 | } |
177 | 185 | ||
@@ -321,13 +329,17 @@ void sock_setnonblocking(p_sock ps) { | |||
321 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | 329 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { |
322 | *hp = gethostbyaddr(addr, len, AF_INET); | 330 | *hp = gethostbyaddr(addr, len, AF_INET); |
323 | if (*hp) return IO_DONE; | 331 | if (*hp) return IO_DONE; |
324 | else return h_errno; | 332 | else if (h_errno) return h_errno; |
333 | else if (errno) return errno; | ||
334 | else return IO_UNKNOWN; | ||
325 | } | 335 | } |
326 | 336 | ||
327 | int sock_gethostbyname(const char *addr, struct hostent **hp) { | 337 | int sock_gethostbyname(const char *addr, struct hostent **hp) { |
328 | *hp = gethostbyname(addr); | 338 | *hp = gethostbyname(addr); |
329 | if (*hp) return IO_DONE; | 339 | if (*hp) return IO_DONE; |
330 | else return h_errno; | 340 | else if (h_errno) return h_errno; |
341 | else if (errno) return errno; | ||
342 | else return IO_UNKNOWN; | ||
331 | } | 343 | } |
332 | 344 | ||
333 | /*-------------------------------------------------------------------------*\ | 345 | /*-------------------------------------------------------------------------*\ |