diff options
Diffstat (limited to 'src/nvim/channel.c')
-rw-r--r-- | src/nvim/channel.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 7a08ba58d0..22eb31513d 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -499,48 +499,54 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, } /// @param data will be consumed -size_t channel_send(uint64_t id, char *data, size_t len, const char **error) +size_t channel_send(uint64_t id, char *data, size_t len, + bool data_owned, const char **error) { Channel *chan = find_channel(id); + size_t written = 0; if (!chan) { *error = _(e_invchan); - goto err; + goto retfree; } if (chan->streamtype == kChannelStreamStderr) { if (chan->stream.err.closed) { *error = _("Can't send data to closed stream"); - goto err; + goto retfree; } // unbuffered write - size_t written = fwrite(data, len, 1, stderr); - xfree(data); - return len * written; + written = len * fwrite(data, len, 1, stderr); + goto retfree; } if (chan->streamtype == kChannelStreamInternal && chan->term) { terminal_receive(chan->term, data, len); - return len; + written = len; + goto retfree; } Stream *in = channel_instream(chan); if (in->closed) { *error = _("Can't send data to closed stream"); - goto err; + goto retfree; } if (chan->is_rpc) { *error = _("Can't send raw data to rpc channel"); - goto err; + goto retfree; } - WBuffer *buf = wstream_new_buffer(data, len, 1, xfree); + // write can be delayed indefinitely, so always use an allocated buffer + WBuffer *buf = wstream_new_buffer(data_owned ? data : xmemdup(data, len), + len, 1, xfree); return wstream_write(in, buf) ? len : 0; -err: - xfree(data); - return 0; +retfree: + if (data_owned) { + xfree(data); + } + return written; } /// Convert binary byte array to a readfile()-style list |