From: Lars Ingebrigtsen <larsi@gnus.org>
Date: Sun, 22 Jul 2018 11:39:10 +0000 (+0200)
Subject: Make async :family 'local failures fail correctly again
X-Git-Tag: emacs-26.1.90~215
X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=18588bc;p=emacs.git

Make async :family 'local failures fail correctly again

* src/fileio.c (get_file_errno_data): Refactor out into its own
function so that we can reuse the error handling from an async
context (bug#31901).

* src/process.c (connect_network_socket): When an async :family
'local client fails (with a file error, for instance), mark the
process as failed.

(cherry picked from commit 92ba34d89ac4f5b5bbb818e1c39a3cc12a405790)
---

diff --git a/src/fileio.c b/src/fileio.c
index 9dbe3ad788e..e2be7fe2c69 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -195,8 +195,8 @@ check_writable (const char *filename, int amode)
    list before reporting it; this saves report_file_errno's caller the
    trouble of preserving errno before calling list1.  */
 
-void
-report_file_errno (char const *string, Lisp_Object name, int errorno)
+Lisp_Object
+get_file_errno_data (char const *string, Lisp_Object name, int errorno)
 {
   Lisp_Object data = CONSP (name) || NILP (name) ? name : list1 (name);
   char *str = emacs_strerror (errorno);
@@ -206,10 +206,18 @@ report_file_errno (char const *string, Lisp_Object name, int errorno)
   Lisp_Object errdata = Fcons (errstring, data);
 
   if (errorno == EEXIST)
-    xsignal (Qfile_already_exists, errdata);
+    return Fcons (Qfile_already_exists, errdata);
   else
-    xsignal (errorno == ENOENT ? Qfile_missing : Qfile_error,
-	     Fcons (build_string (string), errdata));
+    return Fcons (errorno == ENOENT ? Qfile_missing : Qfile_error,
+		  Fcons (build_string (string), errdata));
+}
+
+void
+report_file_errno (char const *string, Lisp_Object name, int errorno)
+{
+  Lisp_Object data = get_file_errno_data (string, name, errorno);
+
+  xsignal (Fcar (data), Fcdr (data));
 }
 
 /* Signal a file-access failure that set errno.  STRING describes the
diff --git a/src/lisp.h b/src/lisp.h
index b2449cb87d3..05d1cd8201a 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4031,6 +4031,7 @@ extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
 extern void close_file_unwind (int);
 extern void fclose_unwind (void *);
 extern void restore_point_unwind (Lisp_Object);
+extern Lisp_Object get_file_errno_data (const char *, Lisp_Object, int);
 extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
 extern _Noreturn void report_file_error (const char *, Lisp_Object);
 extern _Noreturn void report_file_notify_error (const char *, Lisp_Object);
diff --git a/src/process.c b/src/process.c
index 8629f834e79..676f38446e4 100644
--- a/src/process.c
+++ b/src/process.c
@@ -3578,17 +3578,23 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
 
   if (s < 0)
     {
+      const char *err = (p->is_server
+			 ? "make server process failed"
+			 : "make client process failed");
+
       /* If non-blocking got this far - and failed - assume non-blocking is
 	 not supported after all.  This is probably a wrong assumption, but
 	 the normal blocking calls to open-network-stream handles this error
 	 better.  */
       if (p->is_non_blocking_client)
-	return;
+	{
+	  Lisp_Object data = get_file_errno_data (err, contact, xerrno);
+
+	  pset_status (p, list2 (Fcar (data), Fcdr (data)));
+	  return;
+	}
 
-      report_file_errno ((p->is_server
-			  ? "make server process failed"
-			  : "make client process failed"),
-			 contact, xerrno);
+      report_file_errno (err, contact, xerrno);
     }
 
   inch = s;