return -1;
}
- if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- sdb_close(s);
- return -1;
- }
+ int connect_timeout = 1;
+ if(connect_nonb(s, (struct sockaddr *) &addr, sizeof(addr), connect_timeout) < 0) {
+ sdb_close(s);
+ return -1;
+ }
return s;
}
+int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen, int nsec)
+{
+ int flags, n, error;
+ socklen_t len;
+ fd_set rset, wset;
+ struct timeval tval;
+
+ flags = fcntl(sockfd, F_GETFL, 0);
+ fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+ error = 0;
+ if ((n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
+ if (errno != EINPROGRESS)
+ return (-1);
+
+ /* Do whatever we want while the connect is taking place. */
+
+ if (n == 0)
+ goto done;
+ /* connect completed immediately */
+
+ FD_ZERO(&rset);
+ FD_SET(sockfd, &rset);
+ wset = rset;
+ tval.tv_sec = nsec;
+ tval.tv_usec = 0;
+ if ((n = select(sockfd + 1, &rset, &wset, NULL, nsec ? &tval : NULL))
+ == 0) {
+ sdb_close(sockfd); /* timeout */
+ errno = ETIMEDOUT;
+ return (-1);
+ }
+ if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+ len = sizeof(error);
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+ return (-1); /* Solaris pending error */
+ } else
+ D("select error: sockfd not set\n");
+
+ done: fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
+
+ if (error) {
+ sdb_close(sockfd); /* just in case */
+ errno = error;
+ return (-1);
+ }
+ return (0);
+}
+
+
+
static int _sdb_port_listen(uint32_t inet, int port, int type)
{
struct sockaddr_in addr;