#include #include #include #include #include int connect_wait ( int sockno, struct sockaddr * addr, size_t addrlen, struct timeval * timeout) { int res, opt; // get socket flags if ((opt = fcntl (sockno, F_GETFL, NULL)) < 0) { return -1; } // set socket non-blocking if (fcntl (sockno, F_SETFL, opt | O_NONBLOCK) < 0) { return -1; } // try to connect if ((res = connect (sockno, addr, addrlen)) < 0) { if (errno == EINPROGRESS) { fd_set wait_set; // make file descriptor set with socket FD_ZERO (&wait_set); FD_SET (sockno, &wait_set); // wait for socket to be writable; return after given timeout res = select (sockno + 1, NULL, &wait_set, NULL, timeout); } } // connection was successful immediately else { res = 1; } // reset socket flags if (fcntl (sockno, F_SETFL, opt) < 0) { return -1; } // an error occured in connect or select if (res < 0) { return -1; } // select timed out else if (res == 0) { errno = ETIMEDOUT; return 1; } // almost finished... else { socklen_t len = sizeof (opt); // check for errors in socket layer if (getsockopt (sockno, SOL_SOCKET, SO_ERROR, &opt, &len) < 0) { return -1; } // there was an error if (opt) { errno = opt; return -1; } } return 0; }