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:
126
src/channel.c
126
src/channel.c
@@ -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,28 +667,31 @@ 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
|
||||||
{
|
&& errno != ECONNREFUSED
|
||||||
if (errno != EWOULDBLOCK
|
|
||||||
&& 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);
|
||||||
PERROR(_(e_cannot_connect));
|
PERROR(_(e_cannot_connect));
|
||||||
sock_close(sd);
|
sock_close(sd);
|
||||||
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,19 +731,20 @@ 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))
|
||||||
{
|
{
|
||||||
ret = getsockopt(sd,
|
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
|
if (ret < 0 || (so_error != 0
|
||||||
&& so_error != EWOULDBLOCK
|
&& so_error != EWOULDBLOCK
|
||||||
&& so_error != ECONNREFUSED
|
&& so_error != ECONNREFUSED
|
||||||
@@ -754,49 +763,48 @@ 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;
|
||||||
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
|
#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)
|
if (waittime >= 0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user