summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/os_unix.c31
-rw-r--r--src/os_win32.c14
-rw-r--r--src/testdir/test_channel.vim24
-rw-r--r--src/testdir/test_channel_pipe.py5
-rw-r--r--src/version.c2
5 files changed, 60 insertions, 16 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 934399644..8e5ac6c8f 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5045,6 +5045,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options)
int fd_err[2]; /* for stderr */
# ifdef FEAT_CHANNEL
channel_T *channel = NULL;
+ int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
#endif
/* default is to fail */
@@ -5056,7 +5057,8 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options)
/* TODO: without the channel feature connect the child to /dev/null? */
# ifdef FEAT_CHANNEL
/* Open pipes for stdin, stdout, stderr. */
- if ((pipe(fd_in) < 0) || (pipe(fd_out) < 0) ||(pipe(fd_err) < 0))
+ if (pipe(fd_in) < 0 || pipe(fd_out) < 0
+ || (!use_out_for_err && pipe(fd_err) < 0))
goto failed;
channel = add_channel();
@@ -5093,17 +5095,26 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options)
ignored = dup(fd_in[0]);
close(fd_in[0]);
+ /* set up stderr for the child */
+ if (use_out_for_err)
+ {
+ close(2);
+ ignored = dup(fd_out[1]);
+ }
+ else
+ {
+ close(fd_err[0]);
+ close(2);
+ ignored = dup(fd_err[1]);
+ close(fd_err[1]);
+ }
+
/* set up stdout for the child */
close(fd_out[0]);
close(1);
ignored = dup(fd_out[1]);
close(fd_out[1]);
- /* set up stderr for the child */
- close(fd_err[0]);
- close(2);
- ignored = dup(fd_err[1]);
- close(fd_err[1]);
# endif
/* See above for type of argv. */
@@ -5123,9 +5134,13 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options)
/* child stdin, stdout and stderr */
close(fd_in[0]);
close(fd_out[1]);
- close(fd_err[1]);
# ifdef FEAT_CHANNEL
- channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
+ if (!use_out_for_err)
+# endif
+ close(fd_err[1]);
+# ifdef FEAT_CHANNEL
+ channel_set_pipes(channel, fd_in[1], fd_out[0],
+ use_out_for_err ? INVALID_FD : fd_err[0]);
channel_set_job(channel, job);
channel_set_options(channel, options);
# ifdef FEAT_GUI
diff --git a/src/os_win32.c b/src/os_win32.c
index 28c026308..9c87346fa 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -5000,6 +5000,7 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
HANDLE jo;
# ifdef FEAT_CHANNEL
channel_T *channel;
+ int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
HANDLE ifd[2];
HANDLE ofd[2];
HANDLE efd[2];
@@ -5038,13 +5039,14 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
|| !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)
|| !CreatePipe(&ofd[0], &ofd[1], &saAttr, 0)
|| !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)
- || !CreatePipe(&efd[0], &efd[1], &saAttr, 0)
- || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))
+ || (!use_out_for_err
+ && (!CreatePipe(&efd[0], &efd[1], &saAttr, 0)
+ || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))))
goto failed;
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = ifd[0];
si.hStdOutput = ofd[1];
- si.hStdError = efd[1];
+ si.hStdError = use_out_for_err ? ofd[1] : efd[1];
# endif
if (!vim_create_process(cmd, TRUE,
@@ -5075,10 +5077,12 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
# ifdef FEAT_CHANNEL
CloseHandle(ifd[0]);
CloseHandle(ofd[1]);
- CloseHandle(efd[1]);
+ if (!use_out_for_err)
+ CloseHandle(efd[1]);
job->jv_channel = channel;
- channel_set_pipes(channel, (sock_T)ifd[1], (sock_T)ofd[0], (sock_T)efd[0]);
+ channel_set_pipes(channel, (sock_T)ifd[1], (sock_T)ofd[0],
+ use_out_for_err ? INVALID_FD : (sock_T)efd[0]);
channel_set_job(channel, job);
channel_set_options(channel, options);
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index bc43b446e..c8779344d 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -339,10 +339,8 @@ func s:raw_one_time_callback(port)
endfunc
func Test_raw_one_time_callback()
- call ch_logfile('channellog', 'w')
call ch_log('Test_raw_one_time_callback()')
call s:run_server('s:raw_one_time_callback')
- call ch_logfile('')
endfunc
"""""""""
@@ -420,6 +418,9 @@ func Test_nl_pipe()
call ch_sendraw(handle, "echo something\n")
call assert_equal("something", ch_readraw(handle))
+ call ch_sendraw(handle, "echoerr wrong\n")
+ call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
+
call ch_sendraw(handle, "double this\n")
call assert_equal("this", ch_readraw(handle))
call assert_equal("AND this", ch_readraw(handle))
@@ -431,6 +432,25 @@ func Test_nl_pipe()
endtry
endfunc
+func Test_nl_err_to_out_pipe()
+ if !has('job')
+ return
+ endif
+ call ch_log('Test_nl_err_to_out_pipe()')
+ let job = job_start(s:python . " test_channel_pipe.py", {'err-io': 'out'})
+ call assert_equal("run", job_status(job))
+ try
+ let handle = job_getchannel(job)
+ call ch_sendraw(handle, "echo something\n")
+ call assert_equal("something", ch_readraw(handle))
+
+ call ch_sendraw(handle, "echoerr wrong\n")
+ call assert_equal("wrong", ch_readraw(handle))
+ finally
+ call job_stop(job)
+ endtry
+endfunc
+
func Test_pipe_to_buffer()
if !has('job')
return
diff --git a/src/testdir/test_channel_pipe.py b/src/testdir/test_channel_pipe.py
index 5994d27ff..2097d3ebc 100644
--- a/src/testdir/test_channel_pipe.py
+++ b/src/testdir/test_channel_pipe.py
@@ -18,9 +18,12 @@ if __name__ == "__main__":
print("Goodbye!")
sys.stdout.flush()
break
- if typed.startswith("echo"):
+ if typed.startswith("echo "):
print(typed[5:-1])
sys.stdout.flush()
+ if typed.startswith("echoerr"):
+ print(typed[8:-1], file=sys.stderr)
+ sys.stderr.flush()
if typed.startswith("double"):
print(typed[7:-1] + "\nAND " + typed[7:-1])
sys.stdout.flush()
diff --git a/src/version.c b/src/version.c
index 88f298eb1..512d8561a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -744,6 +744,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1484,
+/**/
1483,
/**/
1482,