summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-08 22:33:07 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-08 22:33:07 +0100
commit045a284a83c2a85113de233d5233eae34724a4b6 (patch)
tree729c27ab1ae94dd317bb732d5f2fb899c12d7a49
parent0622732b32ff4a883e4f490a1b38ada539da8ba2 (diff)
patch 7.4.1524v7.4.1524
Problem: Channel test fails on BSD. Solution: Break out of the loop when connect() succeeds. (Ozaki Kiichi)
-rw-r--r--src/channel.c124
-rw-r--r--src/version.c2
2 files changed, 68 insertions, 58 deletions
diff --git a/src/channel.c b/src/channel.c
index 3856dabbc7..4eedb03eb3 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -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
diff --git a/src/version.c b/src/version.c
index dffa9f0fd1..a760c76059 100644
--- a/src/version.c
+++ b/src/version.c
@@ -744,6 +744,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1524,
+/**/
1523,
/**/
1522,