Skip to content

Commit 045a284

Browse files
committed
patch 7.4.1524
Problem: Channel test fails on BSD. Solution: Break out of the loop when connect() succeeds. (Ozaki Kiichi)
1 parent 0622732 commit 045a284

2 files changed

Lines changed: 68 additions & 58 deletions

File tree

src/channel.c

Lines changed: 66 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,6 @@ channel_open(
587587
u_long val = 1;
588588
#else
589589
int port = port_in;
590-
struct timeval start_tv;
591590
#endif
592591
channel_T *channel;
593592
int ret;
@@ -629,6 +628,10 @@ channel_open(
629628
*/
630629
while (TRUE)
631630
{
631+
#ifndef WIN32
632+
long elapsed_msec = 0;
633+
#endif
634+
632635
if (sd >= 0)
633636
sock_close(sd);
634637
sd = socket(AF_INET, SOCK_STREAM, 0);
@@ -664,35 +667,40 @@ channel_open(
664667
ch_logsn(channel, "Connecting to %s port %d", hostname, port);
665668
ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
666669

670+
if (ret == 0)
671+
/* The connection could be established. */
672+
break;
673+
667674
SOCK_ERRNO;
668-
if (ret < 0)
669-
{
670-
if (errno != EWOULDBLOCK
671-
&& errno != ECONNREFUSED
675+
if (waittime < 0 || (errno != EWOULDBLOCK
676+
&& errno != ECONNREFUSED
672677
#ifdef EINPROGRESS
673-
&& errno != EINPROGRESS
678+
&& errno != EINPROGRESS
674679
#endif
675-
)
676-
{
677-
ch_errorn(channel,
678-
"channel_open: Connect failed with errno %d", errno);
679-
PERROR(_(e_cannot_connect));
680-
sock_close(sd);
681-
channel_free(channel);
682-
return NULL;
683-
}
680+
))
681+
{
682+
ch_errorn(channel,
683+
"channel_open: Connect failed with errno %d", errno);
684+
PERROR(_(e_cannot_connect));
685+
sock_close(sd);
686+
channel_free(channel);
687+
return NULL;
684688
}
685689

686-
/* If we don't block and connect() failed then try using select() to
687-
* wait for the connection to be made. */
688-
if (waittime >= 0 && ret < 0)
690+
/* If connect() didn't finish then try using select() to wait for the
691+
* connection to be made. */
692+
#ifndef WIN32
693+
if (errno != ECONNREFUSED)
694+
#endif
689695
{
690696
struct timeval tv;
691697
fd_set rfds;
692698
fd_set wfds;
693699
#ifndef WIN32
694700
int so_error = 0;
695701
socklen_t so_error_len = sizeof(so_error);
702+
struct timeval start_tv;
703+
struct timeval end_tv;
696704
#endif
697705

698706
FD_ZERO(&rfds);
@@ -723,19 +731,20 @@ channel_open(
723731
#ifdef WIN32
724732
/* On Win32: select() is expected to work and wait for up to the
725733
* waittime for the socket to be open. */
726-
if (!FD_ISSET(sd, &wfds) || ret == 0)
734+
if (FD_ISSET(sd, &wfds))
735+
break;
727736
#else
728737
/* On Linux-like systems: See socket(7) for the behavior
729738
* After putting the socket in non-blocking mode, connect() will
730739
* return EINPROGRESS, select() will not wait (as if writing is
731740
* possible), need to use getsockopt() to check if the socket is
732741
* actually able to connect.
733-
* We detect an failure to connect when either read and write fds
742+
* We detect a failure to connect when either read and write fds
734743
* are set. Use getsockopt() to find out what kind of failure. */
735744
if (FD_ISSET(sd, &rfds) || FD_ISSET(sd, &wfds))
736745
{
737746
ret = getsockopt(sd,
738-
SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
747+
SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
739748
if (ret < 0 || (so_error != 0
740749
&& so_error != EWOULDBLOCK
741750
&& so_error != ECONNREFUSED
@@ -754,49 +763,48 @@ channel_open(
754763
}
755764
}
756765

757-
if (!FD_ISSET(sd, &wfds) || so_error != 0)
758-
#endif
759-
{
760-
#ifndef WIN32
761-
struct timeval end_tv;
762-
long elapsed_msec;
766+
if (FD_ISSET(sd, &wfds) && so_error == 0)
767+
/* Did not detect an error, connection is established. */
768+
break;
763769

764-
gettimeofday(&end_tv, NULL);
765-
elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000
766-
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
767-
if (waittime > 1 && elapsed_msec < waittime)
768-
{
769-
/* The port isn't ready but we also didn't get an error.
770-
* This happens when the server didn't open the socket
771-
* yet. Wait a bit and try again. */
772-
mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE);
773-
ui_breakcheck();
774-
if (!got_int)
775-
{
776-
/* reduce the waittime by the elapsed time and the 50
777-
* msec delay (or a bit more) */
778-
waittime -= elapsed_msec;
779-
if (waittime > 50)
780-
waittime -= 50;
781-
else
782-
waittime = 1;
783-
continue;
784-
}
785-
/* we were interrupted, behave as if timed out */
786-
}
770+
gettimeofday(&end_tv, NULL);
771+
elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000
772+
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
787773
#endif
788-
/* We timed out. */
789-
ch_error(channel, "Connection timed out");
790-
sock_close(sd);
791-
channel_free(channel);
792-
return NULL;
793-
}
774+
}
794775

795-
ch_log(channel, "Connection made");
796-
break;
776+
#ifndef WIN32
777+
if (waittime > 1 && elapsed_msec < waittime)
778+
{
779+
/* The port isn't ready but we also didn't get an error.
780+
* This happens when the server didn't open the socket
781+
* yet. Wait a bit and try again. */
782+
mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE);
783+
ui_breakcheck();
784+
if (!got_int)
785+
{
786+
/* reduce the waittime by the elapsed time and the 50
787+
* msec delay (or a bit more) */
788+
waittime -= elapsed_msec;
789+
if (waittime > 50)
790+
waittime -= 50;
791+
else
792+
waittime = 1;
793+
continue;
794+
}
795+
/* we were interrupted, behave as if timed out */
797796
}
797+
#endif
798+
799+
/* We timed out. */
800+
ch_error(channel, "Connection timed out");
801+
sock_close(sd);
802+
channel_free(channel);
803+
return NULL;
798804
}
799805

806+
ch_log(channel, "Connection made");
807+
800808
if (waittime >= 0)
801809
{
802810
#ifdef _WIN32

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,8 @@ static char *(features[]) =
743743

744744
static int included_patches[] =
745745
{ /* Add new patch number below this line */
746+
/**/
747+
1524,
746748
/**/
747749
1523,
748750
/**/

0 commit comments

Comments
 (0)