@@ -606,7 +606,6 @@ channel_open(
606606 u_long val = 1 ;
607607#else
608608 int port = port_in ;
609- struct timeval start_tv ;
610609#endif
611610 channel_T * channel ;
612611 int ret ;
@@ -648,6 +647,10 @@ channel_open(
648647 */
649648 while (TRUE)
650649 {
650+ #ifndef WIN32
651+ long elapsed_msec = 0 ;
652+ #endif
653+
651654 if (sd >= 0 )
652655 sock_close (sd );
653656 sd = socket (AF_INET , SOCK_STREAM , 0 );
@@ -683,35 +686,40 @@ channel_open(
683686 ch_logsn (channel , "Connecting to %s port %d" , hostname , port );
684687 ret = connect (sd , (struct sockaddr * )& server , sizeof (server ));
685688
689+ if (ret == 0 )
690+ /* The connection could be established. */
691+ break ;
692+
686693 SOCK_ERRNO ;
687- if (ret < 0 )
688- {
689- if (errno != EWOULDBLOCK
690- && errno != ECONNREFUSED
694+ if (waittime < 0 || (errno != EWOULDBLOCK
695+ && errno != ECONNREFUSED
691696#ifdef EINPROGRESS
692- && errno != EINPROGRESS
697+ && errno != EINPROGRESS
693698#endif
694- )
695- {
696- ch_errorn (channel ,
697- "channel_open: Connect failed with errno %d" , errno );
698- PERROR (_ (e_cannot_connect ));
699- sock_close (sd );
700- channel_free (channel );
701- return NULL ;
702- }
699+ ))
700+ {
701+ ch_errorn (channel ,
702+ "channel_open: Connect failed with errno %d" , errno );
703+ PERROR (_ (e_cannot_connect ));
704+ sock_close (sd );
705+ channel_free (channel );
706+ return NULL ;
703707 }
704708
705- /* If we don't block and connect() failed then try using select() to
706- * wait for the connection to be made. */
707- if (waittime >= 0 && ret < 0 )
709+ /* If connect() didn't finish then try using select() to wait for the
710+ * connection to be made. */
711+ #ifndef WIN32
712+ if (errno != ECONNREFUSED )
713+ #endif
708714 {
709715 struct timeval tv ;
710716 fd_set rfds ;
711717 fd_set wfds ;
712718#ifndef WIN32
713719 int so_error = 0 ;
714720 socklen_t so_error_len = sizeof (so_error );
721+ struct timeval start_tv ;
722+ struct timeval end_tv ;
715723#endif
716724
717725 FD_ZERO (& rfds );
@@ -742,19 +750,20 @@ channel_open(
742750#ifdef WIN32
743751 /* On Win32: select() is expected to work and wait for up to the
744752 * waittime for the socket to be open. */
745- if (!FD_ISSET (sd , & wfds ) || ret == 0 )
753+ if (FD_ISSET (sd , & wfds ))
754+ break ;
746755#else
747756 /* On Linux-like systems: See socket(7) for the behavior
748757 * After putting the socket in non-blocking mode, connect() will
749758 * return EINPROGRESS, select() will not wait (as if writing is
750759 * possible), need to use getsockopt() to check if the socket is
751760 * actually able to connect.
752- * We detect an failure to connect when either read and write fds
761+ * We detect a failure to connect when either read and write fds
753762 * are set. Use getsockopt() to find out what kind of failure. */
754763 if (FD_ISSET (sd , & rfds ) || FD_ISSET (sd , & wfds ))
755764 {
756765 ret = getsockopt (sd ,
757- SOL_SOCKET , SO_ERROR , & so_error , & so_error_len );
766+ SOL_SOCKET , SO_ERROR , & so_error , & so_error_len );
758767 if (ret < 0 || (so_error != 0
759768 && so_error != EWOULDBLOCK
760769 && so_error != ECONNREFUSED
@@ -773,49 +782,48 @@ channel_open(
773782 }
774783 }
775784
776- if (!FD_ISSET (sd , & wfds ) || so_error != 0 )
777- #endif
778- {
779- #ifndef WIN32
780- struct timeval end_tv ;
781- long elapsed_msec ;
785+ if (FD_ISSET (sd , & wfds ) && so_error == 0 )
786+ /* Did not detect an error, connection is established. */
787+ break ;
782788
783- gettimeofday (& end_tv , NULL );
784- elapsed_msec = (end_tv .tv_sec - start_tv .tv_sec ) * 1000
785- + (end_tv .tv_usec - start_tv .tv_usec ) / 1000 ;
786- if (waittime > 1 && elapsed_msec < waittime )
787- {
788- /* The port isn't ready but we also didn't get an error.
789- * This happens when the server didn't open the socket
790- * yet. Wait a bit and try again. */
791- mch_delay (waittime < 50 ? (long )waittime : 50L , TRUE);
792- ui_breakcheck ();
793- if (!got_int )
794- {
795- /* reduce the waittime by the elapsed time and the 50
796- * msec delay (or a bit more) */
797- waittime -= elapsed_msec ;
798- if (waittime > 50 )
799- waittime -= 50 ;
800- else
801- waittime = 1 ;
802- continue ;
803- }
804- /* we were interrupted, behave as if timed out */
805- }
789+ gettimeofday (& end_tv , NULL );
790+ elapsed_msec = (end_tv .tv_sec - start_tv .tv_sec ) * 1000
791+ + (end_tv .tv_usec - start_tv .tv_usec ) / 1000 ;
806792#endif
807- /* We timed out. */
808- ch_error (channel , "Connection timed out" );
809- sock_close (sd );
810- channel_free (channel );
811- return NULL ;
812- }
793+ }
813794
814- ch_log (channel , "Connection made" );
815- break ;
795+ #ifndef WIN32
796+ if (waittime > 1 && elapsed_msec < waittime )
797+ {
798+ /* The port isn't ready but we also didn't get an error.
799+ * This happens when the server didn't open the socket
800+ * yet. Wait a bit and try again. */
801+ mch_delay (waittime < 50 ? (long )waittime : 50L , TRUE);
802+ ui_breakcheck ();
803+ if (!got_int )
804+ {
805+ /* reduce the waittime by the elapsed time and the 50
806+ * msec delay (or a bit more) */
807+ waittime -= elapsed_msec ;
808+ if (waittime > 50 )
809+ waittime -= 50 ;
810+ else
811+ waittime = 1 ;
812+ continue ;
813+ }
814+ /* we were interrupted, behave as if timed out */
816815 }
816+ #endif
817+
818+ /* We timed out. */
819+ ch_error (channel , "Connection timed out" );
820+ sock_close (sd );
821+ channel_free (channel );
822+ return NULL ;
817823 }
818824
825+ ch_log (channel , "Connection made" );
826+
819827 if (waittime >= 0 )
820828 {
821829#ifdef _WIN32
@@ -890,7 +898,7 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options)
890898 * Find a buffer matching "name" or create a new one.
891899 */
892900 static buf_T *
893- find_buffer (char_u * name )
901+ find_buffer (char_u * name , int err )
894902{
895903 buf_T * buf = NULL ;
896904 buf_T * save_curbuf = curbuf ;
@@ -909,7 +917,8 @@ find_buffer(char_u *name)
909917 curbuf = buf ;
910918 if (curbuf -> b_ml .ml_mfp == NULL )
911919 ml_open (curbuf );
912- ml_replace (1 , (char_u * )"Reading from channel output..." , TRUE);
920+ ml_replace (1 , (char_u * )(err ? "Reading from channel error..."
921+ : "Reading from channel output..." ), TRUE);
913922 changed_bytes (1 , 0 );
914923 curbuf = save_curbuf ;
915924 }
@@ -987,10 +996,27 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
987996 if (!(opt -> jo_set & JO_OUT_MODE ))
988997 channel -> ch_part [PART_OUT ].ch_mode = MODE_NL ;
989998 channel -> ch_part [PART_OUT ].ch_buffer =
990- find_buffer (opt -> jo_io_name [PART_OUT ]);
991- ch_logs (channel , "writing to buffer '%s'" ,
999+ find_buffer (opt -> jo_io_name [PART_OUT ], FALSE );
1000+ ch_logs (channel , "writing out to buffer '%s'" ,
9921001 (char * )channel -> ch_part [PART_OUT ].ch_buffer -> b_ffname );
9931002 }
1003+
1004+ if ((opt -> jo_set & JO_ERR_IO ) && (opt -> jo_io [PART_ERR ] == JIO_BUFFER
1005+ || (opt -> jo_io [PART_ERR ] == JIO_OUT && (opt -> jo_set & JO_OUT_IO )
1006+ && opt -> jo_io [PART_OUT ] == JIO_BUFFER )))
1007+ {
1008+ /* writing err to a buffer. Default mode is NL. */
1009+ if (!(opt -> jo_set & JO_ERR_MODE ))
1010+ channel -> ch_part [PART_ERR ].ch_mode = MODE_NL ;
1011+ if (opt -> jo_io [PART_ERR ] == JIO_OUT )
1012+ channel -> ch_part [PART_ERR ].ch_buffer =
1013+ channel -> ch_part [PART_OUT ].ch_buffer ;
1014+ else
1015+ channel -> ch_part [PART_ERR ].ch_buffer =
1016+ find_buffer (opt -> jo_io_name [PART_ERR ], TRUE);
1017+ ch_logs (channel , "writing err to buffer '%s'" ,
1018+ (char * )channel -> ch_part [PART_ERR ].ch_buffer -> b_ffname );
1019+ }
9941020}
9951021
9961022/*
@@ -1024,7 +1050,7 @@ channel_set_req_callback(
10241050write_buf_line (buf_T * buf , linenr_T lnum , channel_T * channel )
10251051{
10261052 char_u * line = ml_get_buf (buf , lnum , FALSE);
1027- int len = STRLEN (line );
1053+ int len = ( int ) STRLEN (line );
10281054 char_u * p ;
10291055
10301056 /* TODO: check if channel can be written to, do not block on write */
0 commit comments