]> git.eshelyaron.com Git - emacs.git/commitdiff
Backport 2010-03-25T08:48:52Z!mituharu@math.s.chiba-u.ac.jp from trunk
authorHelmut Eller <eller.helmut@gmail.com>
Thu, 4 Nov 2010 19:53:28 +0000 (15:53 -0400)
committerChong Yidong <cyd@stupidchicken.com>
Thu, 4 Nov 2010 19:53:28 +0000 (15:53 -0400)
src/ChangeLog
src/process.c

index 077385d6f6c2f55acfebb62fc58bea8a8b84a0b2..f3bbfe05dac032cc3de2a433c470eed202a5bad5 100644 (file)
@@ -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.
index 567300e2f64bcfb169069e641c1cd844eaa40c0c..77490adaa79052f96984800a8284cb0ddecfeeb7 100644 (file)
@@ -3573,8 +3573,6 @@ usage: (make-network-process &rest ARGS)  */)
     {
       int optn, optbits;
 
-    retry_connect:
-
       s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
       if (s < 0)
        {
@@ -3691,6 +3689,38 @@ usage: (make-network-process &rest ARGS)  */)
 #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 @@ usage: (make-network-process &rest ARGS)  */)
       specpdl_ptr = specpdl + count1;
       emacs_close (s);
       s = -1;
-
-      if (xerrno == EINTR)
-       goto retry_connect;
     }
 
   if (s >= 0)