sock: socket should be non-blocking

Event loop handles asynchronous connections.
This commit is contained in:
Dmitry Podgorny
2015-10-11 05:20:31 +03:00
parent 63946ff7ef
commit 8339fd0420

View File

@@ -69,7 +69,7 @@ static int _in_progress(int error)
#ifdef _WIN32 #ifdef _WIN32
return (error == WSAEWOULDBLOCK || error == WSAEINPROGRESS); return (error == WSAEWOULDBLOCK || error == WSAEINPROGRESS);
#else #else
return (errno == EINPROGRESS); return (error == EINPROGRESS);
#endif #endif
} }
@@ -80,8 +80,6 @@ sock_t sock_connect(const char * const host, const unsigned int port)
struct addrinfo *res, *ainfo, hints; struct addrinfo *res, *ainfo, hints;
int err; int err;
sock = -1;
snprintf(service, 6, "%u", port); snprintf(service, 6, "%u", port);
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
@@ -101,18 +99,19 @@ sock_t sock_connect(const char * const host, const unsigned int port)
if (sock < 0) if (sock < 0)
continue; continue;
err = sock_set_nonblocking(sock);
if (err == 0) {
err = connect(sock, ainfo->ai_addr, ainfo->ai_addrlen); err = connect(sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (err < 0) { if (err == 0 || _in_progress(sock_error()))
close(sock);
continue;
}
/* Connection has been established. */
break; break;
} }
freeaddrinfo(res);
return ainfo == NULL ? -1 : sock; close(sock);
}
freeaddrinfo(res);
sock = ainfo == NULL ? -1 : sock;
return sock;
} }
int sock_close(const sock_t sock) int sock_close(const sock_t sock)
@@ -130,7 +129,13 @@ int sock_set_blocking(const sock_t sock)
u_long block = 0; u_long block = 0;
return ioctlsocket(sock, FIONBIO, &block); return ioctlsocket(sock, FIONBIO, &block);
#else #else
return fcntl(sock, F_SETFL, 0); int rc;
rc = fcntl(sock, F_GETFL, NULL);
if (rc >= 0) {
rc = fcntl(sock, F_SETFL, rc & (~O_NONBLOCK));
}
return rc;
#endif #endif
} }
@@ -140,7 +145,13 @@ int sock_set_nonblocking(const sock_t sock)
u_long nonblock = 1; u_long nonblock = 1;
return ioctlsocket(sock, FIONBIO, &nonblock); return ioctlsocket(sock, FIONBIO, &nonblock);
#else #else
return fcntl(sock, F_SETFL, O_NONBLOCK); int rc;
rc = fcntl(sock, F_GETFL, NULL);
if (rc >= 0) {
rc = fcntl(sock, F_SETFL, rc | O_NONBLOCK);
}
return rc;
#endif #endif
} }
@@ -167,11 +178,11 @@ int sock_is_recoverable(const int error)
int sock_connect_error(const sock_t sock) int sock_connect_error(const sock_t sock)
{ {
struct sockaddr sa; struct sockaddr sa;
unsigned len; socklen_t len;
char temp; char temp;
memset(&sa, 0, sizeof(sa));
sa.sa_family = AF_UNSPEC; sa.sa_family = AF_UNSPEC;
len = sizeof(sa); len = sizeof(sa);
/* we don't actually care about the peer name, we're just checking if /* we don't actually care about the peer name, we're just checking if