emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r99750: Call `select' for interrupted


From: YAMAMOTO Mitsuharu
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r99750: Call `select' for interrupted `connect' rather than creating new socket (Bug#5173).
Date: Thu, 25 Mar 2010 17:48:52 +0900
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 99750
author: Helmut Eller <address@hidden>
committer: YAMAMOTO Mitsuharu <address@hidden>
branch nick: trunk
timestamp: Thu 2010-03-25 17:48:52 +0900
message:
  Call `select' for interrupted `connect' rather than creating new socket 
(Bug#5173).
modified:
  src/ChangeLog
  src/process.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2010-03-24 18:02:56 +0000
+++ b/src/ChangeLog     2010-03-25 08:48:52 +0000
@@ -1,3 +1,8 @@
+2010-03-25  Helmut Eller  <address@hidden>
+
+       * process.c (Fmake_network_process): Call `select' for interrupted
+       `connect' rather than creating new socket (Bug#5173).
+
 2010-03-24  Jan Djärv  <address@hidden>
 
        * frame.c (x_get_arg): Handle RES_TYPE_BOOLEAN_NUMBER (bug #5736).

=== modified file 'src/process.c'
--- a/src/process.c     2010-03-22 19:51:59 +0000
+++ b/src/process.c     2010-03-25 08:48:52 +0000
@@ -3534,8 +3534,6 @@
     {
       int optn, optbits;
 
-    retry_connect:
-
       s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
       if (s < 0)
        {
@@ -3652,6 +3650,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;
 
@@ -3659,9 +3689,6 @@
       specpdl_ptr = specpdl + count1;
       emacs_close (s);
       s = -1;
-
-      if (xerrno == EINTR)
-       goto retry_connect;
     }
 
   if (s >= 0)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]