To: vim_dev@googlegroups.com Subject: Patch 7.4.1506 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1506 Problem: Job cannot read from a file. Solution: Implement reading from a file for Unix. Files: src/eval.c, src/os_unix.c, src/os_win32.c, src/testdir/test_channel.vim *** ../vim-7.4.1505/src/eval.c 2016-03-06 21:33:58.286366293 +0100 --- src/eval.c 2016-03-06 22:51:31.277006261 +0100 *************** *** 15118,15123 **** --- 15118,15124 ---- garray_T ga; #endif jobopt_T opt; + int part; rettv->v_type = VAR_JOB; job = job_alloc(); *************** *** 15135,15140 **** --- 15136,15152 ---- + JO_STOPONEXIT + JO_EXIT_CB + JO_OUT_IO) == FAIL) return; + /* Check that when io is "file" that there is a file name. */ + for (part = PART_OUT; part <= PART_IN; ++part) + if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT))) + && opt.jo_io[part] == JIO_FILE + && (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT))) + || *opt.jo_io_name[part] == NUL)) + { + EMSG(_("E920: -io file requires -name to be set")); + return; + } + if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER) { buf_T *buf; *** ../vim-7.4.1505/src/os_unix.c 2016-03-05 22:05:22.575744309 +0100 --- src/os_unix.c 2016-03-06 22:50:48.829456508 +0100 *************** *** 5045,5050 **** --- 5045,5051 ---- int fd_out[2]; /* for stdout */ int fd_err[2]; /* for stderr */ channel_T *channel = NULL; + int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; /* default is to fail */ *************** *** 5055,5062 **** /* TODO: without the channel feature connect the child to /dev/null? */ /* Open pipes for stdin, stdout, stderr. */ ! if (pipe(fd_in) < 0 || pipe(fd_out) < 0 ! || (!use_out_for_err && pipe(fd_err) < 0)) goto failed; channel = add_channel(); --- 5056,5077 ---- /* TODO: without the channel feature connect the child to /dev/null? */ /* Open pipes for stdin, stdout, stderr. */ ! if (use_file_for_in) ! { ! char_u *fname = options->jo_io_name[PART_IN]; ! ! fd_in[0] = mch_open((char *)fname, O_RDONLY, 0); ! if (fd_in[0] < 0) ! { ! EMSG2(_(e_notopen), fname); ! goto failed; ! } ! } ! 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(); *************** *** 5088,5094 **** /* TODO: re-enable this when pipes connect without a channel */ # ifdef FEAT_CHANNEL /* set up stdin for the child */ ! close(fd_in[1]); close(0); ignored = dup(fd_in[0]); close(fd_in[0]); --- 5103,5110 ---- /* TODO: re-enable this when pipes connect without a channel */ # ifdef FEAT_CHANNEL /* set up stdin for the child */ ! if (!use_file_for_in) ! close(fd_in[1]); close(0); ignored = dup(fd_in[0]); close(fd_in[0]); *************** *** 5130,5141 **** # ifdef FEAT_CHANNEL /* child stdin, stdout and stderr */ ! close(fd_in[0]); close(fd_out[1]); if (!use_out_for_err) close(fd_err[1]); ! channel_set_pipes(channel, 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); --- 5146,5160 ---- # ifdef FEAT_CHANNEL /* 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); *************** *** 5151,5157 **** if (fd_in[0] >= 0) { close(fd_in[0]); ! close(fd_in[1]); } if (fd_out[0] >= 0) { --- 5170,5177 ---- if (fd_in[0] >= 0) { close(fd_in[0]); ! if (!use_file_for_in) ! close(fd_in[1]); } if (fd_out[0] >= 0) { *** ../vim-7.4.1505/src/os_win32.c 2016-03-03 22:51:36.137809664 +0100 --- src/os_win32.c 2016-03-06 22:56:34.445784395 +0100 *************** *** 5000,5005 **** --- 5000,5006 ---- HANDLE jo; # ifdef FEAT_CHANNEL channel_T *channel; + int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; HANDLE ifd[2]; HANDLE ofd[2]; *************** *** 5035,5047 **** saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; ! if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) ! || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0) ! || !CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) ! || !pSetHandleInformation(ofd[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]; --- 5036,5060 ---- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; ! if (use_file_for_in) ! { ! char_u *fname = options->jo_io_name[PART_IN]; ! ! // TODO ! EMSG2(_(e_notopen), fname); ! goto failed; ! } ! else if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) ! || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) ! goto failed; ! ! if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) ! || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) ! goto failed; ! ! if (!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]; *** ../vim-7.4.1505/src/testdir/test_channel.vim 2016-03-06 21:35:53.545137298 +0100 --- src/testdir/test_channel.vim 2016-03-06 23:06:12.895589935 +0100 *************** *** 524,529 **** --- 524,554 ---- endtry endfunc + func Test_nl_read_file() + if !has('job') + return + endif + " TODO: make this work for MS-Windows. + if !has('unix') + return + endif + call ch_log('Test_nl_read_file()') + call writefile(['echo something', 'echoerr wrong', 'double this'], 'Xinput') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'in-io': 'file', 'in-name': 'Xinput'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call assert_equal("something", ch_readraw(handle)) + call assert_equal("wrong", ch_readraw(handle, {'part': 'err'})) + call assert_equal("this", ch_readraw(handle)) + call assert_equal("AND this", ch_readraw(handle)) + finally + call job_stop(job) + call delete('Xinput') + endtry + endfunc + func Test_pipe_to_buffer() if !has('job') return *************** *** 556,562 **** if !has('job') return endif - call ch_logfile('channellog', 'w') call ch_log('Test_pipe_from_buffer()') sp pipe-input --- 581,586 ---- *************** *** 574,580 **** finally call job_stop(job) endtry - call ch_logfile('') endfunc func Test_pipe_to_nameless_buffer() --- 598,603 ---- *** ../vim-7.4.1505/src/version.c 2016-03-06 21:50:28.631838525 +0100 --- src/version.c 2016-03-06 22:57:34.529140609 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1506, /**/ -- I used to be indecisive, now I'm not sure. /// 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 ///