summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-08-25 09:32:25 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-08-25 09:32:25 +0800
commitfce991c7ba4a2ebed2658352b6bd4e677773c493 (patch)
tree288c91c9cabeb7907ee0f3a008e83aca7c58cd18
parent0e040b10e38aee0c0136732f74a3e8bd988b50e5 (diff)
downloadpttbbs-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
-rw-r--r--common/sys/net.c41
-rw-r--r--include/cmsys.h1
2 files changed, 41 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;
diff --git a/include/cmsys.h b/include/cmsys.h
index ae7f6347..4574f74b 100644
--- a/include/cmsys.h
+++ b/include/cmsys.h
@@ -78,6 +78,7 @@ extern uint32_t ipstr2int(const char *ip);
extern int tobind (const char *addr);
extern int tobindex (const char *addr, int qlen, int (*setsock)(int), int do_listen);
extern int toconnect(const char *addr);
+extern int toconnectex(const char *addr, int timeout);
extern int toread (int fd, void *buf, int len);
extern int towrite (int fd, const void *buf, int len);
extern int send_remote_fd(int tunnel, int fd);