@@ -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
0 commit comments