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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui