aboutsummaryrefslogtreecommitdiff
path: root/src/usocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usocket.c')
-rw-r--r--src/usocket.c26
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)
25static int sock_waitfd(int fd, int sw, p_tm tm) { 25int 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
47static int sock_waitfd(int fd, int sw, p_tm tm) { 47int 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\*-------------------------------------------------------------------------*/
178int 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) {
321int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { 329int 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
327int sock_gethostbyname(const char *addr, struct hostent **hp) { 337int 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/*-------------------------------------------------------------------------*\