From fce991c7ba4a2ebed2658352b6bd4e677773c493 Mon Sep 17 00:00:00 2001 From: piaip Date: Tue, 25 Aug 2009 01:32:25 +0000 Subject: * enable timeout in toconnectex. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4770 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- common/sys/net.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'common/sys') diff --git a/common/sys/net.c b/common/sys/net.c index 3e65a697..8166ed1d 100644 --- a/common/sys/net.c +++ b/common/sys/net.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,11 @@ int tobind(const char * addr) } int toconnect(const char *addr) +{ + return toconnectex(addr, -1); +} + +int toconnectex(const char *addr, int timeout) { int sock; @@ -152,12 +158,20 @@ int toconnect(const char *addr) else { char buf[64], *port; struct sockaddr_in serv_name; + int oflags = 0; if( (sock = socket(PF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); return -1; } + if (timeout > 0) + { + // set to non-block to allow timeout + oflags = fcntl(sock, F_GETFL, NULL); + fcntl(sock, F_SETFL, oflags | O_NONBLOCK); + } + strlcpy(buf, addr, sizeof(buf)); if ( (port = strchr(buf, ':')) != NULL) *port++ = '\0'; @@ -172,10 +186,35 @@ int toconnect(const char *addr) serv_name.sin_port = htons(atoi(port)); serv_name.sin_family = AF_INET; - if( connect(sock, (struct sockaddr*)&serv_name, sizeof(serv_name)) < 0 ){ + while ( connect(sock, (struct sockaddr*)&serv_name, sizeof(serv_name)) < 0 ) + { + if (errno == EINPROGRESS) + { + struct timeval tv = {0}; + fd_set myset; + + assert(timeout > 0); + tv.tv_sec = timeout; // set timeout here + FD_ZERO(&myset); + FD_SET(sock, &myset); + + if (select(sock+1, NULL, &myset, NULL, &tv) > 0) + { + // success + break; + } + } + + // various failure close(sock); return -1; } + + if (timeout > 0) + { + // restore flags + fcntl(sock, F_SETFL, oflags); + } } return sock; -- cgit v1.2.3