aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/channel.c')
-rw-r--r--src/nvim/channel.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 7a08ba58d0..60af11e94b 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -162,6 +162,7 @@ void channel_init(void)
/// Channel is allocated with refcount 1, which should be decreased
/// when the underlying stream closes.
Channel *channel_alloc(ChannelStreamType type)
+ FUNC_ATTR_NONNULL_RET
{
Channel *chan = xcalloc(1, sizeof(*chan));
if (type == kChannelStreamStdio) {
@@ -499,48 +500,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