]> granicus.if.org Git - vim/commitdiff
patch 7.4.1524 v7.4.1524
authorBram Moolenaar <Bram@vim.org>
Tue, 8 Mar 2016 21:33:07 +0000 (22:33 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 8 Mar 2016 21:33:07 +0000 (22:33 +0100)
Problem:    Channel test fails on BSD.
Solution:   Break out of the loop when connect() succeeds. (Ozaki Kiichi)

src/channel.c
src/version.c

index 3856dabbc72ae8d268675af07d502536b77f18c6..4eedb03eb32024d2e088d2612f51aa2a3e13484f 100644 (file)
@@ -587,7 +587,6 @@ channel_open(
     u_long             val = 1;
 #else
     int                        port = port_in;
-    struct timeval     start_tv;
 #endif
     channel_T          *channel;
     int                        ret;
@@ -629,6 +628,10 @@ channel_open(
      */
     while (TRUE)
     {
+#ifndef WIN32
+       long elapsed_msec = 0;
+#endif
+
        if (sd >= 0)
            sock_close(sd);
        sd = socket(AF_INET, SOCK_STREAM, 0);
@@ -664,28 +667,31 @@ channel_open(
        ch_logsn(channel, "Connecting to %s port %d", hostname, port);
        ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
 
+       if (ret == 0)
+           /* The connection could be established. */
+           break;
+
        SOCK_ERRNO;
-       if (ret < 0)
-       {
-           if (errno != EWOULDBLOCK
-                   && errno != ECONNREFUSED
+       if (waittime < 0 || (errno != EWOULDBLOCK
+               && errno != ECONNREFUSED
 #ifdef EINPROGRESS
-                   && errno != EINPROGRESS
+               && errno != EINPROGRESS
 #endif
-                   )
-           {
-               ch_errorn(channel,
-                       "channel_open: Connect failed with errno %d", errno);
-               PERROR(_(e_cannot_connect));
-               sock_close(sd);
-               channel_free(channel);
-               return NULL;
-           }
+               ))
+       {
+           ch_errorn(channel,
+                        "channel_open: Connect failed with errno %d", errno);
+           PERROR(_(e_cannot_connect));
+           sock_close(sd);
+           channel_free(channel);
+           return NULL;
        }
 
-       /* If we don't block and connect() failed then try using select() to
-        * wait for the connection to be made. */
-       if (waittime >= 0 && ret < 0)
+       /* If connect() didn't finish then try using select() to wait for the
+        * connection to be made. */
+#ifndef WIN32
+       if (errno != ECONNREFUSED)
+#endif
        {
            struct timeval      tv;
            fd_set              rfds;
@@ -693,6 +699,8 @@ channel_open(
 #ifndef WIN32
            int                 so_error = 0;
            socklen_t           so_error_len = sizeof(so_error);
+           struct timeval      start_tv;
+           struct timeval      end_tv;
 #endif
 
            FD_ZERO(&rfds);
@@ -723,19 +731,20 @@ channel_open(
 #ifdef WIN32
            /* On Win32: select() is expected to work and wait for up to the
             * waittime for the socket to be open. */
-           if (!FD_ISSET(sd, &wfds) || ret == 0)
+           if (FD_ISSET(sd, &wfds))
+               break;
 #else
            /* On Linux-like systems: See socket(7) for the behavior
             * After putting the socket in non-blocking mode, connect() will
             * return EINPROGRESS, select() will not wait (as if writing is
             * possible), need to use getsockopt() to check if the socket is
             * actually able to connect.
-            * We detect an failure to connect when either read and write fds
+            * We detect a failure to connect when either read and write fds
             * are set.  Use getsockopt() to find out what kind of failure. */
            if (FD_ISSET(sd, &rfds) || FD_ISSET(sd, &wfds))
            {
                ret = getsockopt(sd,
-                           SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
+                             SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
                if (ret < 0 || (so_error != 0
                        && so_error != EWOULDBLOCK
                        && so_error != ECONNREFUSED
@@ -754,49 +763,48 @@ channel_open(
                }
            }
 
-           if (!FD_ISSET(sd, &wfds) || so_error != 0)
-#endif
-           {
-#ifndef WIN32
-               struct  timeval end_tv;
-               long    elapsed_msec;
+           if (FD_ISSET(sd, &wfds) && so_error == 0)
+               /* Did not detect an error, connection is established. */
+               break;
 
-               gettimeofday(&end_tv, NULL);
-               elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000
-                                + (end_tv.tv_usec - start_tv.tv_usec) / 1000;
-               if (waittime > 1 && elapsed_msec < waittime)
-               {
-                   /* The port isn't ready but we also didn't get an error.
-                    * This happens when the server didn't open the socket
-                    * yet.  Wait a bit and try again. */
-                   mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE);
-                   ui_breakcheck();
-                   if (!got_int)
-                   {
-                       /* reduce the waittime by the elapsed time and the 50
-                        * msec delay (or a bit more) */
-                       waittime -= elapsed_msec;
-                       if (waittime > 50)
-                           waittime -= 50;
-                       else
-                           waittime = 1;
-                       continue;
-                   }
-                   /* we were interrupted, behave as if timed out */
-               }
+           gettimeofday(&end_tv, NULL);
+           elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000
+                            + (end_tv.tv_usec - start_tv.tv_usec) / 1000;
 #endif
-               /* We timed out. */
-               ch_error(channel, "Connection timed out");
-               sock_close(sd);
-               channel_free(channel);
-               return NULL;
-           }
+       }
 
-           ch_log(channel, "Connection made");
-           break;
+#ifndef WIN32
+       if (waittime > 1 && elapsed_msec < waittime)
+       {
+           /* The port isn't ready but we also didn't get an error.
+            * This happens when the server didn't open the socket
+            * yet.  Wait a bit and try again. */
+           mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE);
+           ui_breakcheck();
+           if (!got_int)
+           {
+               /* reduce the waittime by the elapsed time and the 50
+                * msec delay (or a bit more) */
+               waittime -= elapsed_msec;
+               if (waittime > 50)
+                   waittime -= 50;
+               else
+                   waittime = 1;
+               continue;
+           }
+           /* we were interrupted, behave as if timed out */
        }
+#endif
+
+       /* We timed out. */
+       ch_error(channel, "Connection timed out");
+       sock_close(sd);
+       channel_free(channel);
+       return NULL;
     }
 
+    ch_log(channel, "Connection made");
+
     if (waittime >= 0)
     {
 #ifdef _WIN32
index dffa9f0fd10c3eeed665affcc2712fa71c88552d..a760c76059c02aace311bfec5f3902a38eafa374 100644 (file)
@@ -743,6 +743,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1524,
 /**/
     1523,
 /**/