Patch 7.4.1457
Problem:    Opening a channel with select() is not done properly.
Solution:   Also used read-fds. Use getsockopt() to check for errors. (Ozaki
            Kiichi)
Files:      src/channel.c


*** ../vim-7.4.1456/src/channel.c       2016-02-28 19:30:20.360625771 +0100
--- src/channel.c       2016-02-28 20:37:21.502571714 +0100
***************
*** 28,33 ****
--- 28,35 ----
  # define ECONNREFUSED WSAECONNREFUSED
  # undef EWOULDBLOCK
  # define EWOULDBLOCK WSAEWOULDBLOCK
+ # undef EINPROGRESS
+ # define EINPROGRESS WSAEINPROGRESS
  # ifdef EINTR
  #  undef EINTR
  # endif
***************
*** 550,557 ****
  #else
      int                       port = port_in;
      struct timeval    start_tv;
-     int                       so_error;
-     socklen_t         so_error_len = sizeof(so_error);
  #endif
      channel_T         *channel;
      int                       ret;
--- 552,557 ----
***************
*** 633,639 ****
        {
            if (errno != EWOULDBLOCK
                    && errno != ECONNREFUSED
- 
  #ifdef EINPROGRESS
                    && errno != EINPROGRESS
  #endif
--- 633,638 ----
***************
*** 653,666 ****
        if (waittime >= 0 && ret < 0)
        {
            struct timeval      tv;
            fd_set              wfds;
! #if defined(__APPLE__) && __APPLE__ == 1
! # define PASS_RFDS
!           fd_set          rfds;
  
            FD_ZERO(&rfds);
            FD_SET(sd, &rfds);
- #endif
            FD_ZERO(&wfds);
            FD_SET(sd, &wfds);
  
--- 652,664 ----
        if (waittime >= 0 && ret < 0)
        {
            struct timeval      tv;
+           fd_set              rfds;
            fd_set              wfds;
!           int                 so_error = 0;
!           socklen_t           so_error_len = sizeof(so_error);
  
            FD_ZERO(&rfds);
            FD_SET(sd, &rfds);
            FD_ZERO(&wfds);
            FD_SET(sd, &wfds);
  
***************
*** 671,683 ****
  #endif
            ch_logn(channel,
                    "Waiting for connection (waittime %d msec)...", waittime);
!           ret = select((int)sd + 1,
! #ifdef PASS_RFDS
!                   &rfds,
! #else
!                   NULL,
! #endif
!                   &wfds, NULL, &tv);
  
            if (ret < 0)
            {
--- 669,675 ----
  #endif
            ch_logn(channel,
                    "Waiting for connection (waittime %d msec)...", waittime);
!           ret = select((int)sd + 1, &rfds, &wfds, NULL, &tv);
  
            if (ret < 0)
            {
***************
*** 689,718 ****
                channel_free(channel);
                return NULL;
            }
! #ifdef PASS_RFDS
!           if (ret == 0 && FD_ISSET(sd, &rfds) && FD_ISSET(sd, &wfds))
!           {
!               /* For OS X, this implies error. See tcp(4). */
!               ch_error(channel, "channel_open: Connect failed");
!               EMSG(_(e_cannot_connect));
!               sock_close(sd);
!               channel_free(channel);
!               return NULL;
!           }
! #endif
! #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)
! #else
!           /* See socket(7) for the behavior on Linux-like systems:
             * 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 open. */
!           getsockopt(sd, SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
!           if (!FD_ISSET(sd, &wfds) || ret == 0 || so_error != 0)
  #endif
            {
  #ifndef WIN32
                struct  timeval end_tv;
--- 681,719 ----
                channel_free(channel);
                return NULL;
            }
! 
!           /* On Win32: select() is expected to work and wait for up to the
!            * waittime for the socket to be open.
!            * 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 connect.
!            * We detect an failure to connect when both 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);
!               if (ret < 0 || (so_error != 0
!                       && so_error != EWOULDBLOCK
!                       && so_error != ECONNREFUSED
! #ifdef EINPROGRESS
!                       && so_error != EINPROGRESS
  #endif
+                       ))
+               {
+                   ch_errorn(channel,
+                           "channel_open: Connect failed with errno %d",
+                           so_error);
+                   PERROR(_(e_cannot_connect));
+                   sock_close(sd);
+                   channel_free(channel);
+                   return NULL;
+               }
+           }
+ 
+           if (!FD_ISSET(sd, &wfds) || so_error != 0)
            {
  #ifndef WIN32
                struct  timeval end_tv;
*** ../vim-7.4.1456/src/version.c       2016-02-28 20:13:14.237733718 +0100
--- src/version.c       2016-02-28 20:51:15.593837802 +0100
***************
*** 745,746 ****
--- 745,748 ----
  {   /* Add new patch number below this line */
+ /**/
+     1457,
  /**/

-- 
(letter from Mark to Mike, about the film's probable certificate)
      I would like to get back to the Censor and agree to lose the shits, take
      the odd Jesus Christ out and lose Oh fuck off, but to retain 'fart in
      your general direction', 'castanets of your testicles' and 'oral sex'
      and ask him for an 'A' rating on that basis.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui