aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2012-11-20 08:00:44 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2012-11-20 08:00:44 +0000
commit00005461fdb385879610569ea0e9e55434df245c (patch)
tree17b6eb8eaa8b0c4b13dce204296c64c190dbe453
parent7c3096ef716062c33d654db32972cee7e954c75a (diff)
enabled connection timeout setting on Windows.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@3188 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog5
-rw-r--r--libsylph/socket.c65
2 files changed, 67 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ccb4d547..bb7dfe31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-11-20
+
+ * libsylph/socket.c: sock_connect_with_timeout(): enabled timeout
+ setting on Windows.
+
2012-10-30
* version 3.3.0
diff --git a/libsylph/socket.c b/libsylph/socket.c
index 482d29a7..6da0b6f8 100644
--- a/libsylph/socket.c
+++ b/libsylph/socket.c
@@ -670,13 +670,72 @@ static gint sock_connect_with_timeout(gint sock,
{
gint ret;
-#ifdef G_OS_UNIX
+#ifdef G_OS_WIN32
+ WSAEVENT hevent;
+ gint err;
+ DWORD dwret;
+ WSANETWORKEVENTS events;
+
+ errno = 0;
+
+ hevent = WSACreateEvent();
+ if (hevent == WSA_INVALID_EVENT)
+ return -1;
+
+ ret = WSAEventSelect(sock, hevent, FD_CONNECT);
+ if (ret == SOCKET_ERROR) {
+ g_warning("sock_connect_with_timeout: WSAEventSelect");
+ WSACloseEvent(hevent);
+ return -1;
+ }
+
+ ret = connect(sock, serv_addr, addrlen);
+
+ if (ret == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ if (err != WSAEWOULDBLOCK) {
+ g_warning("sock_connect_with_timeout: connect (%d)", err);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ dwret = WSAWaitForMultipleEvents(1, &hevent, FALSE, timeout_secs * 1000, FALSE);
+ if (dwret == WSA_WAIT_TIMEOUT) {
+ g_warning("sock_connect_with_timeout: timeout");
+ errno = WSAETIMEDOUT;
+ ret = -1;
+ goto end;
+ } else if (dwret != WSA_WAIT_EVENT_0) {
+ g_warning("sock_connect_with_timeout: WSAWaitForMultipleEvents (%d)", dwret);
+ ret = -1;
+ goto end;
+ }
+
+ ret = WSAEnumNetworkEvents(sock, hevent, &events);
+ if (ret == SOCKET_ERROR) {
+ g_warning("sock_connect_with_timeout: WSAEnumNetworkEvents (%d)", ret);
+ ret = -1;
+ goto end;
+ }
+
+ if ((events.lNetworkEvents & FD_CONNECT) &&
+ events.iErrorCode[FD_CONNECT_BIT] == 0) {
+ ret = 0;
+ errno = 0;
+ } else
+ ret = -1;
+
+end:
+ WSAEventSelect(sock, NULL, 0);
+ WSACloseEvent(hevent);
+
+ set_nonblocking_mode(sock, FALSE);
+#else
set_nonblocking_mode(sock, TRUE);
-#endif
ret = connect(sock, serv_addr, addrlen);
-#ifdef G_OS_UNIX
if (ret < 0) {
if (EINPROGRESS == errno) {
fd_set fds;