diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2012-11-20 08:00:44 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2012-11-20 08:00:44 +0000 |
commit | 00005461fdb385879610569ea0e9e55434df245c (patch) | |
tree | 17b6eb8eaa8b0c4b13dce204296c64c190dbe453 | |
parent | 7c3096ef716062c33d654db32972cee7e954c75a (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-- | ChangeLog | 5 | ||||
-rw-r--r-- | libsylph/socket.c | 65 |
2 files changed, 67 insertions, 3 deletions
@@ -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; |