@@ -485,7 +485,11 @@ static char *e_cannot_connect = N_("E902: Cannot connect to port");
485485 * Returns NULL for failure.
486486 */
487487 channel_T *
488- channel_open (char * hostname , int port_in , int waittime , void (* close_cb )(void ))
488+ channel_open (
489+ char * hostname ,
490+ int port_in ,
491+ int waittime ,
492+ void (* nb_close_cb )(void ))
489493{
490494 int sd = -1 ;
491495 struct sockaddr_in server ;
@@ -711,7 +715,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
711715 }
712716
713717 channel -> CH_SOCK_FD = (sock_T )sd ;
714- channel -> ch_close_cb = close_cb ;
718+ channel -> ch_nb_close_cb = nb_close_cb ;
715719
716720#ifdef FEAT_GUI
717721 channel_gui_register (channel );
@@ -790,6 +794,15 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
790794 else
791795 * cbp = NULL ;
792796 }
797+ if (opt -> jo_set & JO_CLOSE_CALLBACK )
798+ {
799+ cbp = & channel -> ch_close_cb ;
800+ vim_free (* cbp );
801+ if (opt -> jo_close_cb != NULL && * opt -> jo_close_cb != NUL )
802+ * cbp = vim_strsave (opt -> jo_close_cb );
803+ else
804+ * cbp = NULL ;
805+ }
793806}
794807
795808/*
@@ -1255,7 +1268,7 @@ may_invoke_callback(channel_T *channel, int part)
12551268 ch_mode_T ch_mode = channel -> ch_part [part ].ch_mode ;
12561269 char_u * callback = NULL ;
12571270
1258- if (channel -> ch_close_cb != NULL )
1271+ if (channel -> ch_nb_close_cb != NULL )
12591272 /* this channel is handled elsewhere (netbeans) */
12601273 return FALSE;
12611274
@@ -1477,7 +1490,28 @@ channel_close(channel_T *channel)
14771490 }
14781491#endif
14791492
1480- channel -> ch_close_cb = NULL ;
1493+ if (channel -> ch_close_cb != NULL )
1494+ {
1495+ typval_T argv [1 ];
1496+ typval_T rettv ;
1497+ int dummy ;
1498+
1499+ /* invoke the close callback; increment the refcount to avoid it
1500+ * being freed halfway */
1501+ argv [0 ].v_type = VAR_CHANNEL ;
1502+ argv [0 ].vval .v_channel = channel ;
1503+ ++ channel -> ch_refcount ;
1504+ call_func (channel -> ch_close_cb , (int )STRLEN (channel -> ch_close_cb ),
1505+ & rettv , 1 , argv , 0L , 0L , & dummy , TRUE, NULL );
1506+ clear_tv (& rettv );
1507+ -- channel -> ch_refcount ;
1508+
1509+ /* the callback is only called once */
1510+ vim_free (channel -> ch_close_cb );
1511+ channel -> ch_close_cb = NULL ;
1512+ }
1513+
1514+ channel -> ch_nb_close_cb = NULL ;
14811515 channel_clear (channel );
14821516}
14831517
@@ -1539,6 +1573,8 @@ channel_clear(channel_T *channel)
15391573#endif
15401574 vim_free (channel -> ch_callback );
15411575 channel -> ch_callback = NULL ;
1576+ vim_free (channel -> ch_close_cb );
1577+ channel -> ch_close_cb = NULL ;
15421578}
15431579
15441580#if defined(EXITFREE ) || defined(PROTO )
@@ -1732,8 +1768,8 @@ channel_read(channel_T *channel, int part, char *func)
17321768 * keep stdin and stderr open? Probably not, assume the other side
17331769 * has died. */
17341770 channel_close (channel );
1735- if (channel -> ch_close_cb != NULL )
1736- (* channel -> ch_close_cb )();
1771+ if (channel -> ch_nb_close_cb != NULL )
1772+ (* channel -> ch_nb_close_cb )();
17371773
17381774 if (len < 0 )
17391775 {
0 commit comments