Patch 7.4.1342
Problem:    On Mac OS/X the waittime must be > 0 for connect to work.
Solution:   Use select() in a different way. (partly by Kazunobu Kuriyama)
            Always use a waittime of 1 or more.
Files:      src/eval.c, src/channel.c, src/testdir/test_channel.vim


*** ../vim-7.4.1341/src/eval.c  2016-02-16 21:02:17.603873545 +0100
--- src/eval.c  2016-02-16 21:13:24.020861321 +0100
***************
*** 10031,10037 ****
        if ((item = dict_find(dict, (char_u *)"timeout", -1)) != NULL)
            timeout = get_tv_number(&item->di_tv);
      }
!     if (waittime < 0 || timeout < 0)
      {
        EMSG(_(e_invarg));
        return;
--- 10031,10037 ----
        if ((item = dict_find(dict, (char_u *)"timeout", -1)) != NULL)
            timeout = get_tv_number(&item->di_tv);
      }
!     if (timeout < 0)
      {
        EMSG(_(e_invarg));
        return;
*** ../vim-7.4.1341/src/channel.c       2016-02-16 21:02:17.603873545 +0100
--- src/channel.c       2016-02-16 21:55:34.934173321 +0100
***************
*** 253,259 ****
        return NULL;
  
      channel->ch_id = next_ch_id++;
!     ch_log(channel, "Opening channel\n");
  
  #ifdef CHANNEL_PIPES
      for (which = CHAN_SOCK; which <= CHAN_IN; ++which)
--- 253,259 ----
        return NULL;
  
      channel->ch_id = next_ch_id++;
!     ch_log(channel, "Created channel\n");
  
  #ifdef CHANNEL_PIPES
      for (which = CHAN_SOCK; which <= CHAN_IN; ++which)
***************
*** 458,465 ****
--- 458,469 ----
  
  #endif
  
+ static char *e_cannot_connect = N_("E902: Cannot connect to port");
+ 
  /*
   * Open a socket channel to "hostname":"port".
+  * "waittime" is the time in msec to wait for the connection.
+  * When negative wait forever.
   * Returns the channel for success.
   * Returns NULL for failure.
   */
***************
*** 492,498 ****
  
      if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
      {
!       ch_error(NULL, "in socket() in channel_open().\n");
        PERROR("E898: socket() in channel_open()");
        channel_free(channel);
        return NULL;
--- 496,502 ----
  
      if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
      {
!       ch_error(channel, "in socket() in channel_open().\n");
        PERROR("E898: socket() in channel_open()");
        channel_free(channel);
        return NULL;
***************
*** 505,511 ****
      server.sin_port = htons(port);
      if ((host = gethostbyname(hostname)) == NULL)
      {
!       ch_error(NULL, "in gethostbyname() in channel_open()\n");
        PERROR("E901: gethostbyname() in channel_open()");
        sock_close(sd);
        channel_free(channel);
--- 509,515 ----
      server.sin_port = htons(port);
      if ((host = gethostbyname(hostname)) == NULL)
      {
!       ch_error(channel, "in gethostbyname() in channel_open()\n");
        PERROR("E901: gethostbyname() in channel_open()");
        sock_close(sd);
        channel_free(channel);
***************
*** 525,531 ****
           )
        {
            SOCK_ERRNO;
!           ch_errorn(NULL, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
            sock_close(sd);
            channel_free(channel);
--- 529,535 ----
           )
        {
            SOCK_ERRNO;
!           ch_errorn(channel, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
            sock_close(sd);
            channel_free(channel);
***************
*** 534,540 ****
      }
  
      /* Try connecting to the server. */
!     ch_logsn(NULL, "Connecting to %s port %d", hostname, port);
      ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
      SOCK_ERRNO;
      if (ret < 0)
--- 538,544 ----
      }
  
      /* Try connecting to the server. */
!     ch_logsn(channel, "Connecting to %s port %d\n", hostname, port);
      ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
      SOCK_ERRNO;
      if (ret < 0)
***************
*** 545,553 ****
  #endif
                )
        {
!           ch_errorn(NULL, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
!           PERROR(_("E902: Cannot connect to port"));
            sock_close(sd);
            channel_free(channel);
            return NULL;
--- 549,557 ----
  #endif
                )
        {
!           ch_errorn(channel, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
!           PERROR(_(e_cannot_connect));
            sock_close(sd);
            channel_free(channel);
            return NULL;
***************
*** 558,586 ****
      {
        struct timeval  tv;
        fd_set          wfds;
! 
        FD_ZERO(&wfds);
        FD_SET(sd, &wfds);
        tv.tv_sec = waittime / 1000;
        tv.tv_usec = (waittime % 1000) * 1000;
!       ret = select((int)sd + 1, NULL, &wfds, NULL, &tv);
        if (ret < 0)
        {
            SOCK_ERRNO;
!           ch_errorn(NULL, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
!           PERROR(_("E902: Cannot connect to port"));
            sock_close(sd);
            channel_free(channel);
            return NULL;
        }
        if (!FD_ISSET(sd, &wfds))
        {
            /* don't give an error, we just timed out. */
            sock_close(sd);
            channel_free(channel);
            return NULL;
        }
      }
  
      if (waittime >= 0)
--- 562,623 ----
      {
        struct timeval  tv;
        fd_set          wfds;
! #if defined(__APPLE__) && __APPLE__ == 1
! # define PASS_RFDS
!       fd_set          rfds;
! 
!       FD_ZERO(&rfds);
!       FD_SET(sd, &rfds);
!       /* On Mac a zero timeout almost never works.  At least wait one
!        * millisecond. */
!       if (waittime == 0)
!           waittime = 1;
! #endif
        FD_ZERO(&wfds);
        FD_SET(sd, &wfds);
        tv.tv_sec = waittime / 1000;
        tv.tv_usec = (waittime % 1000) * 1000;
! 
!       ch_logn(channel, "Waiting for connection (timeout %d msec)...\n",
!                                                                   waittime);
!       ret = select((int)sd + 1,
! #ifdef PASS_RFDS
!               &rfds,
! #else
!               NULL,
! #endif
!               &wfds, NULL, &tv);
! 
        if (ret < 0)
        {
            SOCK_ERRNO;
!           ch_errorn(channel, "channel_open: Connect failed with errno %d\n",
                                                                       errno);
!           PERROR(_(e_cannot_connect));
            sock_close(sd);
            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\n");
+           EMSG(_(e_cannot_connect));
+           sock_close(sd);
+           channel_free(channel);
+           return NULL;
+       }
+ #endif
        if (!FD_ISSET(sd, &wfds))
        {
            /* don't give an error, we just timed out. */
+           ch_error(channel, "Connection timed out\n");
            sock_close(sd);
            channel_free(channel);
            return NULL;
        }
+       ch_log(channel, "Connection made\n");
      }
  
      if (waittime >= 0)
***************
*** 600,606 ****
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            SOCK_ERRNO;
!           ch_log(NULL, "socket() retry in channel_open()\n");
            PERROR("E900: socket() retry in channel_open()");
            channel_free(channel);
            return NULL;
--- 637,643 ----
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            SOCK_ERRNO;
!           ch_log(channel, "socket() retry in channel_open()\n");
            PERROR("E900: socket() retry in channel_open()");
            channel_free(channel);
            return NULL;
***************
*** 614,620 ****
            while (retries-- && ((errno == ECONNREFUSED)
                                                     || (errno == EINTR)))
            {
!               ch_log(NULL, "retrying...\n");
                mch_delay(3000L, TRUE);
                ui_breakcheck();
                if (got_int)
--- 651,657 ----
            while (retries-- && ((errno == ECONNREFUSED)
                                                     || (errno == EINTR)))
            {
!               ch_log(channel, "retrying...\n");
                mch_delay(3000L, TRUE);
                ui_breakcheck();
                if (got_int)
***************
*** 633,639 ****
            if (!success)
            {
                /* Get here when the server can't be found. */
!               ch_error(NULL, "Cannot connect to port after retry\n");
                PERROR(_("E899: Cannot connect to port after retry"));
                sock_close(sd);
                channel_free(channel);
--- 670,676 ----
            if (!success)
            {
                /* Get here when the server can't be found. */
!               ch_error(channel, "Cannot connect to port after retry\n");
                PERROR(_("E899: Cannot connect to port after retry"));
                sock_close(sd);
                channel_free(channel);
***************
*** 1434,1440 ****
      int                       ret;
  
      if (timeout > 0)
!       ch_logn(channel, "Waiting for %d msec\n", timeout);
  
  
  # ifdef WIN32
--- 1471,1477 ----
      int                       ret;
  
      if (timeout > 0)
!       ch_logn(channel, "Waiting for up to %d msec\n", timeout);
  
  
  # ifdef WIN32
***************
*** 1447,1453 ****
        /* reading from a pipe, not a socket */
        while (TRUE)
        {
!           if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL) && nread 
> 0)
                return OK;
            diff = deadline - GetTickCount();
            if (diff < 0)
--- 1484,1491 ----
        /* reading from a pipe, not a socket */
        while (TRUE)
        {
!           if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL)
!                                                                && nread > 0)
                return OK;
            diff = deadline - GetTickCount();
            if (diff < 0)
*** ../vim-7.4.1341/src/testdir/test_channel.vim        2016-02-16 
21:02:17.603873545 +0100
--- src/testdir/test_channel.vim        2016-02-16 21:56:56.329313942 +0100
***************
*** 28,34 ****
    finish
  endif
  
! let s:chopt = has('osx') ? {'waittime' : 1} : {}
  
  " Run "testfunc" after sarting the server and stop the server afterwards.
  func s:run_server(testfunc)
--- 28,34 ----
    finish
  endif
  
! let s:chopt = {}
  
  " Run "testfunc" after sarting the server and stop the server afterwards.
  func s:run_server(testfunc)
*** ../vim-7.4.1341/src/version.c       2016-02-16 21:02:17.607873503 +0100
--- src/version.c       2016-02-16 21:57:53.160713954 +0100
***************
*** 749,750 ****
--- 749,752 ----
  {   /* Add new patch number below this line */
+ /**/
+     1342,
  /**/

-- 
Facepalm statement #7: "Last week I almost got pregnant!"

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui