0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 7.4.1524

Problem:    Channel test fails on BSD.
Solution:   Break out of the loop when connect() succeeds. (Ozaki Kiichi)
This commit is contained in:
Bram Moolenaar
2016-03-08 22:33:07 +01:00
parent 0622732b32
commit 045a284a83
2 changed files with 69 additions and 59 deletions

View File

@@ -587,7 +587,6 @@ channel_open(
u_long val = 1; u_long val = 1;
#else #else
int port = port_in; int port = port_in;
struct timeval start_tv;
#endif #endif
channel_T *channel; channel_T *channel;
int ret; int ret;
@@ -629,6 +628,10 @@ channel_open(
*/ */
while (TRUE) while (TRUE)
{ {
#ifndef WIN32
long elapsed_msec = 0;
#endif
if (sd >= 0) if (sd >= 0)
sock_close(sd); sock_close(sd);
sd = socket(AF_INET, SOCK_STREAM, 0); sd = socket(AF_INET, SOCK_STREAM, 0);
@@ -664,15 +667,17 @@ channel_open(
ch_logsn(channel, "Connecting to %s port %d", hostname, port); ch_logsn(channel, "Connecting to %s port %d", hostname, port);
ret = connect(sd, (struct sockaddr *)&server, sizeof(server)); ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
if (ret == 0)
/* The connection could be established. */
break;
SOCK_ERRNO; SOCK_ERRNO;
if (ret < 0) if (waittime < 0 || (errno != EWOULDBLOCK
{
if (errno != EWOULDBLOCK
&& errno != ECONNREFUSED && errno != ECONNREFUSED
#ifdef EINPROGRESS #ifdef EINPROGRESS
&& errno != EINPROGRESS && errno != EINPROGRESS
#endif #endif
) ))
{ {
ch_errorn(channel, ch_errorn(channel,
"channel_open: Connect failed with errno %d", errno); "channel_open: Connect failed with errno %d", errno);
@@ -681,11 +686,12 @@ channel_open(
channel_free(channel); channel_free(channel);
return NULL; return NULL;
} }
}
/* If we don't block and connect() failed then try using select() to /* If connect() didn't finish then try using select() to wait for the
* wait for the connection to be made. */ * connection to be made. */
if (waittime >= 0 && ret < 0) #ifndef WIN32
if (errno != ECONNREFUSED)
#endif
{ {
struct timeval tv; struct timeval tv;
fd_set rfds; fd_set rfds;
@@ -693,6 +699,8 @@ channel_open(
#ifndef WIN32 #ifndef WIN32
int so_error = 0; int so_error = 0;
socklen_t so_error_len = sizeof(so_error); socklen_t so_error_len = sizeof(so_error);
struct timeval start_tv;
struct timeval end_tv;
#endif #endif
FD_ZERO(&rfds); FD_ZERO(&rfds);
@@ -723,14 +731,15 @@ channel_open(
#ifdef WIN32 #ifdef WIN32
/* On Win32: select() is expected to work and wait for up to the /* On Win32: select() is expected to work and wait for up to the
* waittime for the socket to be open. */ * waittime for the socket to be open. */
if (!FD_ISSET(sd, &wfds) || ret == 0) if (FD_ISSET(sd, &wfds))
break;
#else #else
/* On Linux-like systems: See socket(7) for the behavior /* On Linux-like systems: See socket(7) for the behavior
* After putting the socket in non-blocking mode, connect() will * After putting the socket in non-blocking mode, connect() will
* return EINPROGRESS, select() will not wait (as if writing is * return EINPROGRESS, select() will not wait (as if writing is
* possible), need to use getsockopt() to check if the socket is * possible), need to use getsockopt() to check if the socket is
* actually able to connect. * 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. */ * are set. Use getsockopt() to find out what kind of failure. */
if (FD_ISSET(sd, &rfds) || FD_ISSET(sd, &wfds)) if (FD_ISSET(sd, &rfds) || FD_ISSET(sd, &wfds))
{ {
@@ -754,16 +763,17 @@ channel_open(
} }
} }
if (!FD_ISSET(sd, &wfds) || so_error != 0) if (FD_ISSET(sd, &wfds) && so_error == 0)
#endif /* Did not detect an error, connection is established. */
{ break;
#ifndef WIN32
struct timeval end_tv;
long elapsed_msec;
gettimeofday(&end_tv, NULL); gettimeofday(&end_tv, NULL);
elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000 elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000; + (end_tv.tv_usec - start_tv.tv_usec) / 1000;
#endif
}
#ifndef WIN32
if (waittime > 1 && elapsed_msec < waittime) if (waittime > 1 && elapsed_msec < waittime)
{ {
/* The port isn't ready but we also didn't get an error. /* The port isn't ready but we also didn't get an error.
@@ -785,6 +795,7 @@ channel_open(
/* we were interrupted, behave as if timed out */ /* we were interrupted, behave as if timed out */
} }
#endif #endif
/* We timed out. */ /* We timed out. */
ch_error(channel, "Connection timed out"); ch_error(channel, "Connection timed out");
sock_close(sd); sock_close(sd);
@@ -793,9 +804,6 @@ channel_open(
} }
ch_log(channel, "Connection made"); ch_log(channel, "Connection made");
break;
}
}
if (waittime >= 0) if (waittime >= 0)
{ {

View File

@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1524,
/**/ /**/
1523, 1523,
/**/ /**/