To: vim_dev@googlegroups.com Subject: Patch 7.4.1514 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1514 Problem: Channel output to file not implemented yet. Solution: Implement it for Unix. Files: src/os_unix.c, src/testdir/test_channel.vim, src/testdir/test_channel_pipe.py *** ../vim-7.4.1513/src/os_unix.c 2016-03-06 23:06:20.667506759 +0100 --- src/os_unix.c 2016-03-08 15:14:33.125440438 +0100 *************** *** 5046,5058 **** --- 5046,5063 ---- int fd_err[2]; /* for stderr */ channel_T *channel = NULL; int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; + int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; + int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; /* default is to fail */ job->jv_status = JOB_FAILED; fd_in[0] = -1; + fd_in[1] = -1; fd_out[0] = -1; + fd_out[1] = -1; fd_err[0] = -1; + fd_err[1] = -1; /* TODO: without the channel feature connect the child to /dev/null? */ /* Open pipes for stdin, stdout, stderr. */ *************** *** 5069,5077 **** } else if (pipe(fd_in) < 0) goto failed; ! if (pipe(fd_out) < 0) goto failed; ! if (!use_out_for_err && pipe(fd_err) < 0) goto failed; channel = add_channel(); --- 5074,5106 ---- } else if (pipe(fd_in) < 0) goto failed; ! ! if (use_file_for_out) ! { ! char_u *fname = options->jo_io_name[PART_OUT]; ! ! fd_out[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); ! if (fd_out[1] < 0) ! { ! EMSG2(_(e_notopen), fname); ! goto failed; ! } ! } ! else if (pipe(fd_out) < 0) goto failed; ! ! if (use_file_for_err) ! { ! char_u *fname = options->jo_io_name[PART_ERR]; ! ! fd_err[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); ! if (fd_err[1] < 0) ! { ! EMSG2(_(e_notopen), fname); ! goto failed; ! } ! } ! else if (!use_out_for_err && pipe(fd_err) < 0) goto failed; channel = add_channel(); *************** *** 5117,5130 **** } 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]); --- 5146,5161 ---- } else { ! if (!use_file_for_err) ! close(fd_err[0]); close(2); ignored = dup(fd_err[1]); close(fd_err[1]); } /* set up stdout for the child */ ! if (!use_file_for_out) ! close(fd_out[0]); close(1); ignored = dup(fd_out[1]); close(fd_out[1]); *************** *** 5148,5160 **** /* child stdin, stdout and stderr */ if (!use_file_for_in) close(fd_in[0]); ! close(fd_out[1]); ! if (!use_out_for_err) close(fd_err[1]); channel_set_pipes(channel, use_file_for_in ? INVALID_FD : fd_in[1], ! fd_out[0], ! use_out_for_err ? INVALID_FD : fd_err[0]); channel_set_job(channel, job, options); # ifdef FEAT_GUI channel_gui_register(channel); --- 5179,5193 ---- /* child stdin, stdout and stderr */ if (!use_file_for_in) close(fd_in[0]); ! if (!use_file_for_out) ! close(fd_out[1]); ! if (!use_out_for_err && !use_file_for_err) close(fd_err[1]); channel_set_pipes(channel, use_file_for_in ? INVALID_FD : fd_in[1], ! use_file_for_out ? INVALID_FD : fd_out[0], ! use_out_for_err || use_file_for_err ! ? INVALID_FD : fd_err[0]); channel_set_job(channel, job, options); # ifdef FEAT_GUI channel_gui_register(channel); *************** *** 5168,5188 **** if (channel != NULL) channel_free(channel); if (fd_in[0] >= 0) - { close(fd_in[0]); ! if (!use_file_for_in) ! close(fd_in[1]); ! } if (fd_out[0] >= 0) - { close(fd_out[0]); close(fd_out[1]); - } if (fd_err[0] >= 0) - { close(fd_err[0]); close(fd_err[1]); - } # endif } --- 5201,5217 ---- if (channel != NULL) channel_free(channel); if (fd_in[0] >= 0) close(fd_in[0]); ! if (fd_in[1] >= 0) ! close(fd_in[1]); if (fd_out[0] >= 0) close(fd_out[0]); + if (fd_out[1] >= 0) close(fd_out[1]); if (fd_err[0] >= 0) close(fd_err[0]); + if (fd_err[1] >= 0) close(fd_err[1]); # endif } *** ../vim-7.4.1513/src/testdir/test_channel.vim 2016-03-08 13:48:42.999473488 +0100 --- src/testdir/test_channel.vim 2016-03-08 15:28:42.676529201 +0100 *************** *** 555,560 **** --- 555,651 ---- endtry endfunc + func Test_nl_write_out_file() + if !has('job') + return + endif + " TODO: make this work for MS-Windows + if !has('unix') + return + endif + call ch_log('Test_nl_write_out_file()') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'out-io': 'file', 'out-name': 'Xoutput'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call ch_sendraw(handle, "echo line one\n") + call ch_sendraw(handle, "echo line two\n") + call ch_sendraw(handle, "double this\n") + for i in range(50) + sleep 10m + if len(readfile('Xoutput')) > 2 + break + endif + endfor + call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput')) + finally + call job_stop(job) + call delete('Xoutput') + endtry + endfunc + + func Test_nl_write_err_file() + if !has('job') + return + endif + " TODO: make this work for MS-Windows + if !has('unix') + return + endif + call ch_log('Test_nl_write_err_file()') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'err-io': 'file', 'err-name': 'Xoutput'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call ch_sendraw(handle, "echoerr line one\n") + call ch_sendraw(handle, "echoerr line two\n") + call ch_sendraw(handle, "doubleerr this\n") + for i in range(50) + sleep 10m + if len(readfile('Xoutput')) > 2 + break + endif + endfor + call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput')) + finally + call job_stop(job) + call delete('Xoutput') + endtry + endfunc + + func Test_nl_write_both_file() + if !has('job') + return + endif + " TODO: make this work for MS-Windows + if !has('unix') + return + endif + call ch_log('Test_nl_write_both_file()') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'out-io': 'file', 'out-name': 'Xoutput', 'err-io': 'out'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call ch_sendraw(handle, "echoerr line one\n") + call ch_sendraw(handle, "echo line two\n") + call ch_sendraw(handle, "double this\n") + call ch_sendraw(handle, "doubleerr that\n") + for i in range(50) + sleep 10m + if len(readfile('Xoutput')) > 5 + break + endif + endfor + call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput')) + finally + call job_stop(job) + call delete('Xoutput') + endtry + endfunc + func Test_pipe_to_buffer() if !has('job') return *** ../vim-7.4.1513/src/testdir/test_channel_pipe.py 2016-03-03 21:02:19.631252561 +0100 --- src/testdir/test_channel_pipe.py 2016-03-08 15:26:13.242086174 +0100 *************** *** 21,30 **** 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() --- 21,33 ---- if typed.startswith("echo "): print(typed[5:-1]) sys.stdout.flush() ! if typed.startswith("double "): print(typed[7:-1] + "\nAND " + typed[7:-1]) sys.stdout.flush() + if typed.startswith("echoerr "): + print(typed[8:-1], file=sys.stderr) + sys.stderr.flush() + if typed.startswith("doubleerr "): + print(typed[10:-1] + "\nAND " + typed[10:-1], file=sys.stderr) + sys.stderr.flush() *** ../vim-7.4.1513/src/version.c 2016-03-08 14:44:28.196510619 +0100 --- src/version.c 2016-03-08 15:16:58.467907734 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1514, /**/ -- hundred-and-one symptoms of being an internet addict: 9. All your daydreaming is preoccupied with getting a faster connection to the net: 28.8...ISDN...cable modem...T1...T3. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///