summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2002-04-12 21:27:09 +0000
committerJeffrey Stedfast <fejj@src.gnome.org>2002-04-12 21:27:09 +0000
commitf401293d9a446ca34f087e3a5bcccc45c8575cf5 (patch)
tree5004b247e8bd6c374531d132792260c96480fe71
parent9a3185f4d4fa49b01d398f105d819f2d3ffad750 (diff)
downloadevolution-data-server-f401293d9a446ca34f087e3a5bcccc45c8575cf5.tar.gz
Backport non-blocking connect code. Hopefully this fixes the Operation In
2002-04-09 Jeffrey Stedfast <fejj@ximian.com> * camel-tcp-stream-ssl.c (stream_connect): Backport non-blocking connect code. Hopefully this fixes the Operation In Progress errors.
-rw-r--r--camel/ChangeLog6
-rw-r--r--camel/camel-tcp-stream-ssl.c81
2 files changed, 81 insertions, 6 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 0ede08f55..7aafaaef1 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,9 @@
+2002-04-09 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-tcp-stream-ssl.c (stream_connect): Backport non-blocking
+ connect code. Hopefully this fixes the Operation In Progress
+ errors.
+
2002-04-09 Not Zed <NotZed@Ximian.com>
* camel-mime-part.c (construct_from_parser): If we get multiple
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 46a8dfa6e..f5f507617 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -159,6 +159,9 @@ set_errno (int code)
{
/* FIXME: this should handle more. */
switch (code) {
+ case PR_INVALID_ARGUMENT_ERROR:
+ errno = EINVAL;
+ break;
case PR_PENDING_INTERRUPT_ERROR:
errno = EINTR;
break;
@@ -169,6 +172,27 @@ set_errno (int code)
case PR_WOULD_BLOCK_ERROR:
errno = EWOULDBLOCK;
break;
+ case PR_IN_PROGRESS_ERROR:
+ errno = EINPROGRESS;
+ break;
+ case PR_ALREADY_INITIATED_ERROR:
+ errno = EALREADY;
+ break;
+ case PR_NETWORK_UNREACHABLE_ERROR:
+ errno = EHOSTUNREACH;
+ break;
+ case PR_CONNECT_REFUSED_ERROR:
+ errno = ECONNREFUSED;
+ break;
+ case PR_CONNECT_TIMEOUT_ERROR:
+ errno = ETIMEDOUT;
+ break;
+ case PR_NOT_CONNECTED_ERROR:
+ errno = ENOTCONN;
+ break;
+ case PR_CONNECT_RESET_ERROR:
+ errno = ECONNRESET;
+ break;
case PR_IO_ERROR:
default:
errno = EIO;
@@ -479,20 +503,65 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
memset ((void *) &netaddr, 0, sizeof (PRNetAddr));
memcpy (&netaddr.inet.ip, host->h_addr, sizeof (netaddr.inet.ip));
- if (PR_InitializeNetAddr (PR_IpAddrNull, port, &netaddr) == PR_FAILURE)
+ if (PR_InitializeNetAddr (PR_IpAddrNull, port, &netaddr) == PR_FAILURE) {
+ set_errno (PR_GetError ());
return -1;
+ }
fd = PR_OpenTCPSocket (host->h_addrtype);
+ if (fd == NULL) {
+ set_errno (PR_GetError ());
+ return -1;
+ }
+
ssl_fd = SSL_ImportFD (NULL, fd);
-
+ if (ssl_fd == NULL) {
+ set_errno (PR_GetError ());
+ return -1;
+ }
+
SSL_OptionSet (ssl_fd, SSL_SECURITY, PR_TRUE);
SSL_SetURL (ssl_fd, ssl->priv->expected_host);
- if (ssl_fd == NULL || PR_Connect (ssl_fd, &netaddr, timeout) == PR_FAILURE) {
- if (ssl_fd != NULL)
- PR_Close (ssl_fd);
+ if (PR_Connect (ssl_fd, &netaddr, timeout) == PR_FAILURE) {
+ int errnosave;
- return -1;
+ set_errno (PR_GetError ());
+ if (errno == EINPROGRESS) {
+ gboolean connected = FALSE;
+ PRPollDesc poll;
+
+ do {
+ poll.fd = fd;
+ poll.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+ poll.out_flags = 0;
+
+ timeout = PR_INTERVAL_MIN;
+
+ if (PR_Poll (&poll, 1, timeout) == PR_FAILURE) {
+ set_errno (PR_GetError ());
+ goto exception;
+ }
+
+ if (PR_GetConnectStatus (&poll) == PR_FAILURE) {
+ set_errno (PR_GetError ());
+ if (errno != EINPROGRESS)
+ goto exception;
+ } else {
+ connected = TRUE;
+ }
+ } while (!connected);
+ } else {
+ exception:
+ errnosave = errno;
+ PR_Close (fd);
+ ssl->priv->sockfd = NULL;
+ errno = errnosave;
+
+ return -1;
+ }
+
+ errno = 0;
}
/*SSL_GetClientAuthDataHook (sslSocket, ssl_get_client_auth, (void *)certNickname);*/