diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-08-25 09:32:25 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-08-25 09:32:25 +0800 |
commit | fce991c7ba4a2ebed2658352b6bd4e677773c493 (patch) | |
tree | 288c91c9cabeb7907ee0f3a008e83aca7c58cd18 /common/sys | |
parent | 0e040b10e38aee0c0136732f74a3e8bd988b50e5 (diff) | |
download | pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar.gz pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar.bz2 pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar.lz pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar.xz pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.tar.zst pttbbs-fce991c7ba4a2ebed2658352b6bd4e677773c493.zip |
* enable timeout in toconnectex.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4770 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'common/sys')
-rw-r--r-- | common/sys/net.c | 41 |
1 files changed, 40 insertions, 1 deletions
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 <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> +#include <fcntl.h> #include <ctype.h> #include <assert.h> #include <errno.h> @@ -129,6 +130,11 @@ int tobind(const char * addr) int toconnect(const char *addr) { + return toconnectex(addr, -1); +} + +int toconnectex(const char *addr, int timeout) +{ int sock; assert(addr && *addr); @@ -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; |