2828# define ECONNREFUSED WSAECONNREFUSED
2929# undef EWOULDBLOCK
3030# define EWOULDBLOCK WSAEWOULDBLOCK
31+ # undef EINPROGRESS
32+ # define EINPROGRESS WSAEINPROGRESS
3133# ifdef EINTR
3234# undef EINTR
3335# endif
@@ -317,20 +319,47 @@ add_channel(void)
317319 * Called when the refcount of a channel is zero.
318320 * Return TRUE if "channel" has a callback and the associated job wasn't
319321 * killed.
320- * If the job was killed the channel is not expected to work anymore.
321- * If there is no callback then nobody can get readahead.
322322 */
323323 static int
324324channel_still_useful (channel_T * channel )
325325{
326+ int has_sock_msg ;
327+ #ifdef CHANNEL_PIPES
328+ int has_out_msg ;
329+ int has_err_msg ;
330+ #endif
331+
332+ /* If the job was killed the channel is not expected to work anymore. */
326333 if (channel -> ch_job_killed && channel -> ch_job == NULL )
327334 return FALSE;
328- return channel -> ch_callback != NULL
335+
336+ /* If there is a close callback it may still need to be invoked. */
337+ if (channel -> ch_close_cb != NULL )
338+ return TRUE;
339+
340+ /* If there is no callback then nobody can get readahead. If the fd is
341+ * closed and there is no readahead then the callback won't be called. */
342+ has_sock_msg = channel -> ch_part [PART_SOCK ].ch_fd != INVALID_FD
343+ || channel -> ch_part [PART_SOCK ].ch_head .rq_next != NULL
344+ || channel -> ch_part [PART_SOCK ].ch_json_head .jq_next != NULL ;
345+ #ifdef CHANNEL_PIPES
346+ has_out_msg = channel -> ch_part [PART_OUT ].ch_fd != INVALID_FD
347+ || channel -> ch_part [PART_OUT ].ch_head .rq_next != NULL
348+ || channel -> ch_part [PART_OUT ].ch_json_head .jq_next != NULL ;
349+ has_err_msg = channel -> ch_part [PART_ERR ].ch_fd != INVALID_FD
350+ || channel -> ch_part [PART_ERR ].ch_head .rq_next != NULL
351+ || channel -> ch_part [PART_ERR ].ch_json_head .jq_next != NULL ;
352+ #endif
353+ return (channel -> ch_callback != NULL && (has_sock_msg
329354#ifdef CHANNEL_PIPES
330- || channel -> ch_part [PART_OUT ].ch_callback != NULL
331- || channel -> ch_part [PART_ERR ].ch_callback != NULL
355+ || has_out_msg || has_err_msg
332356#endif
333- || channel -> ch_close_cb != NULL ;
357+ ))
358+ #ifdef CHANNEL_PIPES
359+ || (channel -> ch_part [PART_OUT ].ch_callback != NULL && has_out_msg )
360+ || (channel -> ch_part [PART_ERR ].ch_callback != NULL && has_err_msg )
361+ #endif
362+ ;
334363}
335364
336365/*
@@ -569,8 +598,6 @@ channel_open(
569598#else
570599 int port = port_in ;
571600 struct timeval start_tv ;
572- int so_error ;
573- socklen_t so_error_len = sizeof (so_error );
574601#endif
575602 channel_T * channel ;
576603 int ret ;
@@ -652,7 +679,6 @@ channel_open(
652679 {
653680 if (errno != EWOULDBLOCK
654681 && errno != ECONNREFUSED
655-
656682#ifdef EINPROGRESS
657683 && errno != EINPROGRESS
658684#endif
@@ -672,14 +698,15 @@ channel_open(
672698 if (waittime >= 0 && ret < 0 )
673699 {
674700 struct timeval tv ;
701+ fd_set rfds ;
675702 fd_set wfds ;
676- #if defined(__APPLE__ ) && __APPLE__ == 1
677- # define PASS_RFDS
678- fd_set rfds ;
703+ #ifndef WIN32
704+ int so_error = 0 ;
705+ socklen_t so_error_len = sizeof (so_error );
706+ #endif
679707
680708 FD_ZERO (& rfds );
681709 FD_SET (sd , & rfds );
682- #endif
683710 FD_ZERO (& wfds );
684711 FD_SET (sd , & wfds );
685712
@@ -690,13 +717,7 @@ channel_open(
690717#endif
691718 ch_logn (channel ,
692719 "Waiting for connection (waittime %d msec)..." , waittime );
693- ret = select ((int )sd + 1 ,
694- #ifdef PASS_RFDS
695- & rfds ,
696- #else
697- NULL ,
698- #endif
699- & wfds , NULL , & tv );
720+ ret = select ((int )sd + 1 , & rfds , & wfds , NULL , & tv );
700721
701722 if (ret < 0 )
702723 {
@@ -708,29 +729,42 @@ channel_open(
708729 channel_free (channel );
709730 return NULL ;
710731 }
711- #ifdef PASS_RFDS
712- if (ret == 0 && FD_ISSET (sd , & rfds ) && FD_ISSET (sd , & wfds ))
713- {
714- /* For OS X, this implies error. See tcp(4). */
715- ch_error (channel , "channel_open: Connect failed" );
716- EMSG (_ (e_cannot_connect ));
717- sock_close (sd );
718- channel_free (channel );
719- return NULL ;
720- }
721- #endif
732+
722733#ifdef WIN32
723- /* On Win32 select() is expected to work and wait for up to the
734+ /* On Win32: select() is expected to work and wait for up to the
724735 * waittime for the socket to be open. */
725736 if (!FD_ISSET (sd , & wfds ) || ret == 0 )
726737#else
727- /* See socket(7) for the behavior on Linux-like systems:
738+ /* On Linux-like systems: See socket(7) for the behavior
728739 * After putting the socket in non-blocking mode, connect() will
729740 * return EINPROGRESS, select() will not wait (as if writing is
730741 * possible), need to use getsockopt() to check if the socket is
731- * actually open. */
732- getsockopt (sd , SOL_SOCKET , SO_ERROR , & so_error , & so_error_len );
733- if (!FD_ISSET (sd , & wfds ) || ret == 0 || so_error != 0 )
742+ * actually connect.
743+ * We detect an failure to connect when both read and write fds
744+ * are set. Use getsockopt() to find out what kind of failure. */
745+ if (FD_ISSET (sd , & rfds ) && FD_ISSET (sd , & wfds ))
746+ {
747+ ret = getsockopt (sd ,
748+ SOL_SOCKET , SO_ERROR , & so_error , & so_error_len );
749+ if (ret < 0 || (so_error != 0
750+ && so_error != EWOULDBLOCK
751+ && so_error != ECONNREFUSED
752+ # ifdef EINPROGRESS
753+ && so_error != EINPROGRESS
754+ # endif
755+ ))
756+ {
757+ ch_errorn (channel ,
758+ "channel_open: Connect failed with errno %d" ,
759+ so_error );
760+ PERROR (_ (e_cannot_connect ));
761+ sock_close (sd );
762+ channel_free (channel );
763+ return NULL ;
764+ }
765+ }
766+
767+ if (!FD_ISSET (sd , & wfds ) || so_error != 0 )
734768#endif
735769 {
736770#ifndef WIN32
@@ -1515,7 +1549,7 @@ may_invoke_callback(channel_T *channel, int part)
15151549 {
15161550 if (item -> cq_seq_nr == seq_nr )
15171551 {
1518- ch_logs (channel , "Invoking one-time callback '%s' " ,
1552+ ch_logs (channel , "Invoking one-time callback %s " ,
15191553 (char * )item -> cq_callback );
15201554 /* Remove the item from the list first, if the callback
15211555 * invokes ch_close() the list will be cleared. */
@@ -1576,7 +1610,7 @@ may_invoke_callback(channel_T *channel, int part)
15761610 if (callback != NULL )
15771611 {
15781612 /* invoke the channel callback */
1579- ch_log (channel , "Invoking channel callback" );
1613+ ch_logs (channel , "Invoking channel callback %s" , ( char * ) callback );
15801614 invoke_callback (channel , callback , argv );
15811615 }
15821616 }
@@ -1776,7 +1810,6 @@ channel_free_all(void)
17761810
17771811/* Sent when the channel is found closed when reading. */
17781812#define DETACH_MSG_RAW "DETACH\n"
1779- #define DETACH_MSG_JSON "\"DETACH\"\n"
17801813
17811814/* Buffer size for reading incoming messages. */
17821815#define MAXMSGSIZE 4096
@@ -1872,7 +1905,6 @@ channel_read(channel_T *channel, int part, char *func)
18721905 int readlen = 0 ;
18731906 sock_T fd ;
18741907 int use_socket = FALSE;
1875- char * msg ;
18761908
18771909 fd = channel -> ch_part [part ].ch_fd ;
18781910 if (fd == INVALID_FD )
@@ -1927,11 +1959,12 @@ channel_read(channel_T *channel, int part, char *func)
19271959 * -> ui_breakcheck
19281960 * -> gui event loop or select loop
19291961 * -> channel_read()
1962+ * Don't send "DETACH" for a JS or JSON channel.
19301963 */
1931- msg = channel -> ch_part [part ].ch_mode == MODE_RAW
1932- || channel -> ch_part [part ].ch_mode == MODE_NL
1933- ? DETACH_MSG_RAW : DETACH_MSG_JSON ;
1934- channel_save ( channel , part , ( char_u * ) msg , ( int )STRLEN (msg ));
1964+ if ( channel -> ch_part [part ].ch_mode == MODE_RAW
1965+ || channel -> ch_part [part ].ch_mode == MODE_NL )
1966+ channel_save ( channel , part , ( char_u * ) DETACH_MSG_RAW ,
1967+ ( int )STRLEN (DETACH_MSG_RAW ));
19351968
19361969 /* TODO: When reading from stdout is not possible, should we try to
19371970 * keep stdin and stderr open? Probably not, assume the other side
0 commit comments