aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/channel.c
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2021-06-14 11:56:43 -0600
committerJames McCoy <jamessan@jamessan.com>2021-08-26 21:56:45 -0400
commit915dda3f96b3619769bc93dab19841138fcb7eaf (patch)
treed9b5f6c41262406d252f22cd8db88353fbdd6d16 /src/nvim/channel.c
parentb6b12ea7c3f2a5ac18d92efc5e4ef814971dfdef (diff)
downloadrneovim-915dda3f96b3619769bc93dab19841138fcb7eaf.tar.gz
rneovim-915dda3f96b3619769bc93dab19841138fcb7eaf.tar.bz2
rneovim-915dda3f96b3619769bc93dab19841138fcb7eaf.zip
feat(job): add parameter to close stdin
Some programs behave differently when they detect that stdin is being piped. This can be problematic when these programs are used with the job control API where stdin is attached, but not typically used. It is possible to run the job using a PTY which circumvents this problem, but that includes a lot of overhead when simply closing the stdin pipe would suffice. To enable this behavior, add a new parameter to the jobstart options dict called "stdin" with two valid values: "pipe" (the default) implements the existing behavior of opening a channel for stdin and "null" which disconnects stdin (or, if you prefer, connects it to /dev/null). This is extensible so that other modes can be added in the future.
Diffstat (limited to 'src/nvim/channel.c')
-rw-r--r--src/nvim/channel.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 60af11e94b..ffa4d12d11 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -289,6 +289,9 @@ static void close_cb(Stream *stream, void *data)
/// `on_stdout` is ignored
/// @param[in] detach True if the job should not be killed when nvim exits,
/// ignored if `pty` is true
+/// @param[in] stdin Stdin mode. Either kChannelStdinPipe to open a channel
+/// for stdin or kChannelStdinNull to leave stdin
+/// disconnected.
/// @param[in] cwd Initial working directory for the job. Nvim's working
/// directory if `cwd` is NULL
/// @param[in] pty_width Width of the pty, ignored if `pty` is false
@@ -302,7 +305,7 @@ static void close_cb(Stream *stream, void *data)
Channel *channel_job_start(char **argv, CallbackReader on_stdout,
CallbackReader on_stderr, Callback on_exit,
bool pty, bool rpc, bool overlapped, bool detach,
- const char *cwd,
+ ChannelStdinMode stdin, const char *cwd,
uint16_t pty_width, uint16_t pty_height,
dict_T *env, varnumber_T *status_out)
{
@@ -345,7 +348,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
proc->overlapped = overlapped;
char *cmd = xstrdup(proc->argv[0]);
- bool has_out, has_err;
+ bool has_in, has_out, has_err;
if (proc->type == kProcessTypePty) {
has_out = true;
has_err = false;
@@ -353,7 +356,17 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
has_out = rpc || callback_reader_set(chan->on_data);
has_err = callback_reader_set(chan->on_stderr);
}
- int status = process_spawn(proc, true, has_out, has_err);
+
+ switch (stdin) {
+ case kChannelStdinPipe:
+ has_in = true;
+ break;
+ case kChannelStdinNull:
+ has_in = false;
+ break;
+ }
+
+ int status = process_spawn(proc, has_in, has_out, has_err);
if (status) {
EMSG3(_(e_jobspawn), os_strerror(status), cmd);
xfree(cmd);
@@ -369,7 +382,9 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
tv_dict_free(proc->env);
}
- wstream_init(&proc->in, 0);
+ if (has_in) {
+ wstream_init(&proc->in, 0);
+ }
if (has_out) {
rstream_init(&proc->out, 0);
}