To: vim_dev@googlegroups.com Subject: Patch 8.0.1381 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1381 Problem: ch_readraw() waits for NL if channel mode is NL. Solution: Pass a "raw" flag to channel_read_block(). (Yasuhiro Matsumoto) Files: src/channel.c, src/proto/channel.pro, src/testdir/test_channel.vim, src/testdir/test_channel_pipe.py *** ../vim-8.0.1380/src/channel.c 2017-11-11 15:53:56.520172366 +0100 --- src/channel.c 2017-12-09 19:12:37.719850375 +0100 *************** *** 3313,3323 **** /* * Read from RAW or NL "channel"/"part". Blocks until there is something to * read or the timeout expires. * Returns what was read in allocated memory. * Returns NULL in case of error or timeout. */ ! char_u * ! channel_read_block(channel_T *channel, ch_part_T part, int timeout) { char_u *buf; char_u *msg; --- 3313,3324 ---- /* * Read from RAW or NL "channel"/"part". Blocks until there is something to * read or the timeout expires. + * When "raw" is TRUE don't block waiting on a NL. * Returns what was read in allocated memory. * Returns NULL in case of error or timeout. */ ! static char_u * ! channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw) { char_u *buf; char_u *msg; *************** *** 3327,3333 **** readq_T *node; ch_log(channel, "Blocking %s read, timeout: %d msec", ! mode == MODE_RAW ? "RAW" : "NL", timeout); while (TRUE) { --- 3328,3334 ---- readq_T *node; ch_log(channel, "Blocking %s read, timeout: %d msec", ! mode == MODE_RAW ? "RAW" : "NL", timeout); while (TRUE) { *************** *** 3340,3345 **** --- 3341,3350 ---- break; if (channel_collapse(channel, part, mode == MODE_NL) == OK) continue; + /* If not blocking or nothing more is coming then return what we + * have. */ + if (raw || fd == INVALID_FD) + break; } /* Wait for up to the channel timeout. */ *************** *** 3366,3376 **** nl = channel_first_nl(node); /* Convert NUL to NL, the internal representation. */ ! for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) if (*p == NUL) *p = NL; ! if (nl + 1 == buf + node->rq_buflen) { /* get the whole buffer */ msg = channel_get(channel, part); --- 3371,3386 ---- nl = channel_first_nl(node); /* Convert NUL to NL, the internal representation. */ ! for (p = buf; (nl == NULL || p < nl) && p < buf + node->rq_buflen; ++p) if (*p == NUL) *p = NL; ! if (nl == NULL) ! { ! /* must be a closed channel with missing NL */ ! msg = channel_get(channel, part); ! } ! else if (nl + 1 == buf + node->rq_buflen) { /* get the whole buffer */ msg = channel_get(channel, part); *************** *** 3513,3519 **** timeout = opt.jo_timeout; if (raw || mode == MODE_RAW || mode == MODE_NL) ! rettv->vval.v_string = channel_read_block(channel, part, timeout); else { if (opt.jo_set & JO_ID) --- 3523,3530 ---- timeout = opt.jo_timeout; if (raw || mode == MODE_RAW || mode == MODE_NL) ! rettv->vval.v_string = channel_read_block(channel, part, ! timeout, raw); else { if (opt.jo_set & JO_ID) *************** *** 3955,3961 **** timeout = opt.jo_timeout; else timeout = channel_get_timeout(channel, part_read); ! rettv->vval.v_string = channel_read_block(channel, part_read, timeout); } free_job_options(&opt); } --- 3966,3973 ---- timeout = opt.jo_timeout; else timeout = channel_get_timeout(channel, part_read); ! rettv->vval.v_string = channel_read_block(channel, part_read, ! timeout, TRUE); } free_job_options(&opt); } *** ../vim-8.0.1380/src/proto/channel.pro 2017-10-01 16:21:25.297497445 +0200 --- src/proto/channel.pro 2017-12-09 18:04:45.873580843 +0100 *************** *** 31,37 **** void channel_close_in(channel_T *channel); void channel_clear(channel_T *channel); void channel_free_all(void); - char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout); void common_channel_read(typval_T *argvars, typval_T *rettv, int raw); channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp); void channel_handle_events(int only_keep_open); --- 31,36 ---- *** ../vim-8.0.1380/src/testdir/test_channel.vim 2017-12-02 16:38:07.690850293 +0100 --- src/testdir/test_channel.vim 2017-12-09 19:04:38.134562495 +0100 *************** *** 515,521 **** call assert_equal("AND this", ch_readraw(handle)) call ch_sendraw(handle, "split this line\n") ! call assert_equal("this linethis linethis line", ch_readraw(handle)) let reply = ch_evalraw(handle, "quit\n") call assert_equal("Goodbye!", reply) --- 515,521 ---- call assert_equal("AND this", ch_readraw(handle)) call ch_sendraw(handle, "split this line\n") ! call assert_equal("this linethis linethis line", ch_read(handle)) let reply = ch_evalraw(handle, "quit\n") call assert_equal("Goodbye!", reply) *************** *** 1263,1268 **** --- 1263,1293 ---- finally call job_stop(job) delfunc CloseHandler + endtry + endfunc + + " Use channel in NL mode but received text does not end in NL. + func Test_read_in_close_cb_incomplete() + if !has('job') + return + endif + call ch_log('Test_read_in_close_cb_incomplete()') + + let g:Ch_received = '' + func! CloseHandler(chan) + while ch_status(a:chan, {'part': 'out'}) == 'buffered' + let g:Ch_received .= ch_read(a:chan) + endwhile + endfunc + let job = job_start(s:python . " test_channel_pipe.py incomplete", + \ {'close_cb': 'CloseHandler'}) + call assert_equal("run", job_status(job)) + try + call WaitFor('g:Ch_received != ""') + call assert_equal('incomplete', g:Ch_received) + finally + call job_stop(job) + delfunc CloseHandler endtry endfunc *** ../vim-8.0.1380/src/testdir/test_channel_pipe.py 2017-02-06 21:56:05.000335406 +0100 --- src/testdir/test_channel_pipe.py 2017-12-09 18:22:43.311629847 +0100 *************** *** 14,19 **** --- 14,23 ---- if sys.argv[1].startswith("err"): print(sys.argv[1], file=sys.stderr) sys.stderr.flush() + elif sys.argv[1].startswith("incomplete"): + print(sys.argv[1], end='') + sys.stdout.flush() + sys.exit(0) else: print(sys.argv[1]) sys.stdout.flush() *** ../vim-8.0.1380/src/version.c 2017-12-09 17:49:19.810736642 +0100 --- src/version.c 2017-12-09 18:06:08.701119430 +0100 *************** *** 773,774 **** --- 773,776 ---- { /* Add new patch number below this line */ + /**/ + 1381, /**/ -- You can't have everything. Where would you put it? -- Steven Wright /// 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 ///