socket: Make connecting sockets non-blocking
diff --git a/common/socket.c b/common/socket.c
index 777b23e..7111749 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -161,11 +161,37 @@
strncpy(name.sun_path, filename, sizeof(name.sun_path));
name.sun_path[sizeof(name.sun_path) - 1] = 0;
- if (connect(sfd, (struct sockaddr*)&name, sizeof(name)) < 0) {
+ int flags = fcntl(sfd, F_GETFL, 0);
+ fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
+
+ do {
+ if (connect(sfd, (struct sockaddr*)&name, sizeof(name)) != -1) {
+ break;
+ }
+ if (errno == EINPROGRESS) {
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(sfd, &fds);
+
+ struct timeval timeout;
+ timeout.tv_sec = CONNECT_TIMEOUT / 1000;
+ timeout.tv_usec = (CONNECT_TIMEOUT - (timeout.tv_sec * 1000)) * 1000;
+ if (select(sfd + 1, NULL, &fds, NULL, &timeout) == 1) {
+ int so_error;
+ socklen_t len = sizeof(so_error);
+ getsockopt(sfd, SOL_SOCKET, SO_ERROR, (void*)&so_error, &len);
+ if (so_error == 0) {
+ break;
+ }
+ }
+ }
socket_close(sfd);
+ sfd = -1;
+ } while (0);
+
+ if (sfd < 0) {
if (verbose >= 2)
- fprintf(stderr, "%s: connect: %s\n", __func__,
- strerror(errno));
+ fprintf(stderr, "%s: connect: %s\n", __func__, strerror(errno));
return -1;
}
@@ -286,7 +312,8 @@
#ifdef WIN32
ioctlsocket(sfd, FIONBIO, &l_yes);
#else
- fcntl(sfd, F_SETFL, O_NONBLOCK);
+ flags = fcntl(sfd, F_GETFL, 0);
+ fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
#endif
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
@@ -325,13 +352,6 @@
return -1;
}
-#ifdef WIN32
- ioctlsocket(sfd, FIONBIO, &l_no);
-#else
- flags = fcntl(sfd, F_GETFL, 0);
- fcntl(sfd, F_SETFL, flags & (~O_NONBLOCK));
-#endif
-
#ifdef SO_NOSIGPIPE
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");