Subject: Re: bug#22789: 25.1.50; In last master build https connections stop working

From: Lars Ingebrigtsen <[email-masked]>
Date: Sun, 28 Feb 2016 09:08:46 +1030

Alain Schneble <[email-masked]> writes:

> What I found out is that it runs into the following branch in
> wait_reading_process_output:
>
> ...
> else
> {
>   /* Preserve status of processes already terminated.  */
>   XPROCESS (proc)->tick = ++process_tick;
>   deactivate_process (proc);
>   if (XPROCESS (proc)->raw_status_new)
>     update_status (XPROCESS (proc));
>   if (EQ (XPROCESS (proc)->status, Qrun))
>     pset_status (XPROCESS (proc),
>                  list2 (Qexit, make_number (256)));
> }
>
> Here it deactivates the process, but as its status is "connect", it
> won't change it.  That's the reason why it remains in "connect" state.
>
> I guess that it enters this path because the socket is not ready yet.
> But why?  I will try to figure it out later...

I think you're on to something!

The thing starts with

	      nread = read_process_output (proc, channel);

and for un-setup TLS sockets, it'll now get back -1, and it should
ideally end up in the

	      else if (nread == -1 && errno == EAGAIN)
		;

thing, so that it tries again later.  But errno is not EAGAIN here
(usually)...

Does the following patch make things work on Windows?

diff --git a/src/gnutls.c b/src/gnutls.c
index d1b34c5..a6b1294 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -403,6 +403,9 @@ gnutls_try_handshake (struct Lisp_Process *proc)
   gnutls_session_t state = proc->gnutls_state;
   int ret;
 
+  if (proc->is_non_blocking_client)
+    proc->gnutls_p = true;
+
   do
     {
       ret = gnutls_handshake (state);
@@ -410,13 +413,13 @@ gnutls_try_handshake (struct Lisp_Process *proc)
       QUIT;
     }
   while (ret < 0 && gnutls_error_is_fatal (ret) == 0
-	 && ! proc->is_non_blocking_client);
+#if 0
+	 && ! proc->is_non_blocking_client
+#endif
+	 );
 
   proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
 
-  if (proc->is_non_blocking_client)
-    proc->gnutls_p = true;
-
   if (ret == GNUTLS_E_SUCCESS)
     {
       /* Here we're finally done.  */
@@ -541,7 +544,10 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
   gnutls_session_t state = proc->gnutls_state;
 
   if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
-    return -1;
+    {
+      errno = EAGAIN;
+      return -1;
+    }
 
   rtnval = gnutls_record_recv (state, buf, nbyte);
   if (rtnval >= 0)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no