emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 1a8d311 2/2: Fix non-blocking GnuTLS with slow conn


From: Paul Eggert
Subject: [Emacs-diffs] master 1a8d311 2/2: Fix non-blocking GnuTLS with slow connection
Date: Wed, 3 Aug 2016 08:55:53 +0000 (UTC)

branch: master
commit 1a8d31123698ccf6f165e49fcfe16631d07a7aea
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Fix non-blocking GnuTLS with slow connection
    
    Although the problem is reported for OS X (Bug#23982), it seems to
    be possible on other POSIXish platforms.
    * src/gnutls.c (emacs_gnutls_nonblock_errno) [!WINDOWSNT]:
    New function.
    (emacs_gnutls_handshake) [!WINDOWSNT]:
    Use it as the errno function, if non-blocking.
    (Fgnutls_boot): Use GNUTLS_NONBLOCK if non-blocking.
---
 src/gnutls.c |   31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/gnutls.c b/src/gnutls.c
index 681e298..e3e9311 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -411,6 +411,31 @@ gnutls_try_handshake (struct Lisp_Process *proc)
   return ret;
 }
 
+#ifndef WINDOWSNT
+static int
+emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr)
+{
+  int err = errno;
+
+  switch (err)
+    {
+# ifdef _AIX
+      /* This is taken from the GnuTLS system_errno function circa 2016;
+        see <http://savannah.gnu.org/support/?107464>.  */
+    case 0:
+      errno = EAGAIN;
+      /* Fall through.  */
+# endif
+    case EINPROGRESS:
+    case ENOTCONN:
+      return EAGAIN;
+
+    default:
+      return err;
+    }
+}
+#endif
+
 static int
 emacs_gnutls_handshake (struct Lisp_Process *proc)
 {
@@ -437,6 +462,9 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
       gnutls_transport_set_ptr2 (state,
                                 (void *) (intptr_t) proc->infd,
                                 (void *) (intptr_t) proc->outfd);
+      if (proc->is_non_blocking_client)
+       gnutls_transport_set_errno_function (state,
+                                            emacs_gnutls_nonblock_errno);
 #endif
 
       proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
@@ -1574,7 +1602,8 @@ one trustfile (usually a CA bundle).  */)
   /* Call gnutls_init here: */
 
   GNUTLS_LOG (1, max_log_level, "gnutls_init");
-  ret = gnutls_init (&state, GNUTLS_CLIENT);
+  int nonblock = XPROCESS (proc)->is_non_blocking_client ? GNUTLS_NONBLOCK : 0;
+  ret = gnutls_init (&state, GNUTLS_CLIENT | nonblock);
   XPROCESS (proc)->gnutls_state = state;
   if (ret < GNUTLS_E_SUCCESS)
     return gnutls_make_error (ret);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]