changeset 8384:764dba33605c v7.4.1484

commit https://github.com/vim/vim/commit/c25558bff4ed10d2642e6f5c016701641c494916 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 3 21:02:23 2016 +0100 patch 7.4.1484 Problem: Channel "err-io" value "out" is not supported. Solution: Connect stderr to stdout if wanted.
author Christian Brabandt <cb@256bit.org>
date Thu, 03 Mar 2016 21:15:05 +0100
parents 7aa65c2cc0f5
children 4ee533cc650f
files src/os_unix.c src/os_win32.c src/testdir/test_channel.vim src/testdir/test_channel_pipe.py src/version.c
diffstat 5 files changed, 60 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5045,6 +5045,7 @@ mch_start_job(char **argv, job_T *job, j
     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, j
     /* 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, j
 	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, j
     /* 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
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -5000,6 +5000,7 @@ mch_start_job(char *cmd, job_T *job, job
     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, job
        || !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, job
 # 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);
 
--- 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
--- 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()
--- 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,