Mercurial > vim
diff src/channel.c @ 8210:b717dae2f26d v7.4.1398
commit https://github.com/vim/vim/commit/4e221c99e85ed40c98892068a01270b9e7492d98
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Feb 23 13:20:22 2016 +0100
patch 7.4.1398
Problem: The close-cb option is not implemented yet.
Solution: Implemente close-cb. (Yasuhiro Matsumoto)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 23 Feb 2016 13:30:07 +0100 |
parents | 08d251a1c178 |
children | 3456e2ebebd4 |
line wrap: on
line diff
--- a/src/channel.c +++ b/src/channel.c @@ -485,7 +485,11 @@ static char *e_cannot_connect = N_("E902 * Returns NULL for failure. */ channel_T * -channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) +channel_open( + char *hostname, + int port_in, + int waittime, + void (*nb_close_cb)(void)) { int sd = -1; struct sockaddr_in server; @@ -711,7 +715,7 @@ channel_open(char *hostname, int port_in } channel->CH_SOCK_FD = (sock_T)sd; - channel->ch_close_cb = close_cb; + channel->ch_nb_close_cb = nb_close_cb; #ifdef FEAT_GUI channel_gui_register(channel); @@ -790,6 +794,15 @@ channel_set_options(channel_T *channel, else *cbp = NULL; } + if (opt->jo_set & JO_CLOSE_CALLBACK) + { + cbp = &channel->ch_close_cb; + vim_free(*cbp); + if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL) + *cbp = vim_strsave(opt->jo_close_cb); + else + *cbp = NULL; + } } /* @@ -1255,7 +1268,7 @@ may_invoke_callback(channel_T *channel, ch_mode_T ch_mode = channel->ch_part[part].ch_mode; char_u *callback = NULL; - if (channel->ch_close_cb != NULL) + if (channel->ch_nb_close_cb != NULL) /* this channel is handled elsewhere (netbeans) */ return FALSE; @@ -1477,7 +1490,28 @@ channel_close(channel_T *channel) } #endif - channel->ch_close_cb = NULL; + if (channel->ch_close_cb != NULL) + { + typval_T argv[1]; + typval_T rettv; + int dummy; + + /* invoke the close callback; increment the refcount to avoid it + * being freed halfway */ + argv[0].v_type = VAR_CHANNEL; + argv[0].vval.v_channel = channel; + ++channel->ch_refcount; + call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb), + &rettv, 1, argv, 0L, 0L, &dummy, TRUE, NULL); + clear_tv(&rettv); + --channel->ch_refcount; + + /* the callback is only called once */ + vim_free(channel->ch_close_cb); + channel->ch_close_cb = NULL; + } + + channel->ch_nb_close_cb = NULL; channel_clear(channel); } @@ -1539,6 +1573,8 @@ channel_clear(channel_T *channel) #endif vim_free(channel->ch_callback); channel->ch_callback = NULL; + vim_free(channel->ch_close_cb); + channel->ch_close_cb = NULL; } #if defined(EXITFREE) || defined(PROTO) @@ -1732,8 +1768,8 @@ channel_read(channel_T *channel, int par * keep stdin and stderr open? Probably not, assume the other side * has died. */ channel_close(channel); - if (channel->ch_close_cb != NULL) - (*channel->ch_close_cb)(); + if (channel->ch_nb_close_cb != NULL) + (*channel->ch_nb_close_cb)(); if (len < 0) {