changeset 111367:1d1b5e1c230b

Backport r99750 from trunk
author Chong Yidong <cyd@stupidchicken.com>
date Thu, 04 Nov 2010 15:53:28 -0400
parents 7be30ce79ffd
children 5a8705defdf9
files src/ChangeLog src/process.c
diffstat 2 files changed, 37 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Nov 04 15:47:27 2010 -0400
+++ b/src/ChangeLog	Thu Nov 04 15:53:28 2010 -0400
@@ -1,3 +1,8 @@
+2010-03-25  Helmut Eller  <eller.helmut@gmail.com>
+
+	* process.c (Fmake_network_process): Call `select' for interrupted
+	`connect' rather than creating new socket (Bug#5173).
+
 2010-11-04  Kenichi Handa  <handa@m17n.org>
 
 	* font.c (font_delete_unmatched): Check Vface_ignored_fonts.
--- a/src/process.c	Thu Nov 04 15:47:27 2010 -0400
+++ b/src/process.c	Thu Nov 04 15:53:28 2010 -0400
@@ -3573,8 +3573,6 @@
     {
       int optn, optbits;
 
-    retry_connect:
-
       s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
       if (s < 0)
 	{
@@ -3691,6 +3689,38 @@
 #endif
 #endif
 #endif
+      if (xerrno == EINTR)
+	{
+	  /* Unlike most other syscalls connect() cannot be called
+	     again.  (That would return EALREADY.)  The proper way to
+	     wait for completion is select(). */
+	  int sc;
+	  SELECT_TYPE fdset;
+	retry_select:
+	  FD_ZERO (&fdset);
+	  FD_SET (s, &fdset);
+	  QUIT;
+	  sc = select (s + 1, (SELECT_TYPE *)0, &fdset, (SELECT_TYPE *)0,
+		       (EMACS_TIME *)0);
+	  if (sc == -1)
+	    {
+	      if (errno == EINTR) 
+		goto retry_select;
+	      else 
+		report_file_error ("select failed", Qnil);
+	    }
+	  eassert (sc > 0);
+	  {
+	    int len = sizeof xerrno;
+	    eassert (FD_ISSET (s, &fdset));
+	    if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1)
+	      report_file_error ("getsockopt failed", Qnil);
+	    if (xerrno != 0)
+	      errno = xerrno, report_file_error ("error during connect", Qnil);
+	    else
+	      break;
+	  }
+	}
 
       immediate_quit = 0;
 
@@ -3698,9 +3728,6 @@
       specpdl_ptr = specpdl + count1;
       emacs_close (s);
       s = -1;
-
-      if (xerrno == EINTR)
-	goto retry_connect;
     }
 
   if (s >= 0)