aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-08-12 14:57:47 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-08-28 14:17:58 -0300
commit801ed0e0a3489af98ca2823ee70332bcad968cba (patch)
tree3e930aad29c1f9edb42badcf37adb430f6d08290 /src
parentb744073fae555ca362bcd40e47c7ce3849206e50 (diff)
downloadrneovim-801ed0e0a3489af98ca2823ee70332bcad968cba.tar.gz
rneovim-801ed0e0a3489af98ca2823ee70332bcad968cba.tar.bz2
rneovim-801ed0e0a3489af98ca2823ee70332bcad968cba.zip
wstream: Implement wstream_set_file
It's analogous to rstream_set_file but only supports pipes(Support for regular files may be added later). This function was added to support creating API channels via stdout.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/os/wstream.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/src/nvim/os/wstream.c b/src/nvim/os/wstream.c
index 194bf757e4..44463c7c88 100644
--- a/src/nvim/os/wstream.c
+++ b/src/nvim/os/wstream.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <uv.h>
@@ -20,7 +21,7 @@ struct wstream {
size_t maxmem;
// Number of pending requests
size_t pending_reqs;
- bool freed;
+ bool freed, free_handle;
// (optional) Write callback and data
wstream_cb cb;
void *data;
@@ -60,6 +61,7 @@ WStream * wstream_new(size_t maxmem)
rv->curmem = 0;
rv->pending_reqs = 0;
rv->freed = false;
+ rv->free_handle = false;
rv->cb = NULL;
return rv;
@@ -68,9 +70,13 @@ WStream * wstream_new(size_t maxmem)
/// Frees all memory allocated for a WStream instance
///
/// @param wstream The `WStream` instance
-void wstream_free(WStream *wstream)
-{
+void wstream_free(WStream *wstream) {
if (!wstream->pending_reqs) {
+ handle_set_wstream((uv_handle_t *)wstream->stream, NULL);
+ if (wstream->free_handle) {
+ uv_close((uv_handle_t *)wstream->stream, close_cb);
+ }
+
free(wstream);
} else {
wstream->freed = true;
@@ -87,6 +93,24 @@ void wstream_set_stream(WStream *wstream, uv_stream_t *stream)
wstream->stream = stream;
}
+/// Sets the underlying file descriptor that will be written to. Only pipes
+/// are supported for now.
+///
+/// @param wstream The `WStream` instance
+/// @param file The file descriptor
+void wstream_set_file(WStream *wstream, uv_file file)
+{
+ uv_handle_type type = uv_guess_handle(file);
+
+ assert(type == UV_NAMED_PIPE || type == UV_TTY);
+ wstream->stream = xmalloc(sizeof(uv_pipe_t));
+ uv_pipe_init(uv_default_loop(), (uv_pipe_t *)wstream->stream, 0);
+ uv_pipe_open((uv_pipe_t *)wstream->stream, file);
+ wstream->stream->data = NULL;
+ handle_set_wstream((uv_handle_t *)wstream->stream, wstream);
+ wstream->free_handle = true;
+}
+
/// Sets a callback that will be called on completion of a write request,
/// indicating failure/success.
///
@@ -211,3 +235,16 @@ static void release_wbuffer(WBuffer *buffer)
free(buffer);
}
}
+
+static void close_cb(uv_handle_t *handle)
+{
+ WStream *wstream = handle_get_wstream(handle);
+
+ if (wstream) {
+ free(wstream);
+ }
+
+ free(handle->data);
+ free(handle);
+}
+