From 8c69cab078d4c51d5c8f76f2aacb7bb8dd46dd7f Mon Sep 17 00:00:00 2001 From: Jun Hao Date: Thu, 14 Jul 2016 21:47:24 +0800 Subject: [PATCH] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async connection * src/gnutls.c: (emacs_gnutls_non_blocking_errno): treat errno EINPROGRESS and ENOTCONN as EAGAIN (emacs_gnutls_handshake): set errno function to it when async connection (Fgnutls_boot): set state with GNUTLS_NONBLOCK flag when async connection --- src/gnutls.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/gnutls.c b/src/gnutls.c index 7f05ac4..449a971 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -35,6 +35,10 @@ along with GNU Emacs. If not, see . */ static bool emacs_gnutls_handle_error (gnutls_session_t, int); +#ifndef WINDOWSNT +static int emacs_gnutls_non_blocking_errno(gnutls_transport_ptr_t ptr); +#endif + static bool gnutls_global_initialized; static void gnutls_log_function (int, const char *); @@ -383,6 +387,21 @@ gnutls_log_function2 (int level, const char *string, const char *extra) message ("gnutls.c: [%d] %s %s", level, string, extra); } +#ifndef WINDOWSNT +static int +emacs_gnutls_non_blocking_errno(gnutls_transport_ptr_t ptr) +{ + switch (errno) + { + case EINPROGRESS: + case ENOTCONN: + return EAGAIN; + default: + return errno; + } +} +#endif + int gnutls_try_handshake (struct Lisp_Process *proc) { @@ -460,6 +479,11 @@ 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) + /* for non blocking connection + treat EINPROGRESS and ENOTCONN as EAGAIN */ + gnutls_transport_set_errno_function(state, + emacs_gnutls_non_blocking_errno); #endif proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; @@ -1596,8 +1620,16 @@ one trustfile (usually a CA bundle). */) /* Call gnutls_init here: */ - GNUTLS_LOG (1, max_log_level, "gnutls_init"); - ret = gnutls_init (&state, GNUTLS_CLIENT); + if (XPROCESS (proc)->is_non_blocking_client) + { + GNUTLS_LOG (1, max_log_level, "gnutls_init with nonblocking"); + ret = gnutls_init(&state, GNUTLS_CLIENT|GNUTLS_NONBLOCK); + } + else + { + GNUTLS_LOG (1, max_log_level, "gnutls_init"); + ret = gnutls_init (&state, GNUTLS_CLIENT); + } XPROCESS (proc)->gnutls_state = state; if (ret < GNUTLS_E_SUCCESS) return gnutls_make_error (ret); -- 2.8.0