On Monday, September 5, 2016 at 11:30:42 AM UTC+9, mattn wrote:
> > Isn't the best solution then to have channel_wait() not return an error?
> > Or is there some way to detect the situation, perhaps by using
> > LastError().  At least it should only affect Windows, since on Unix we
> > don't want to make this exception.
> 
> I say again, This is posssible to be reproduced on Linux.

While the process alive, stdout is not filled in the buffer. But when the 
process exited, buffer should be flushed. So if we change this like below to 
debug output,

-----------------------------------
diff --git a/src/channel.c b/src/channel.c
index 10ed42e..15a3f72 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -59,6 +59,12 @@ static void channel_read(channel_T *channel, int part, char 
*func);
 /* Whether a redraw is needed for appending a line to a buffer. */
 static int channel_need_redraw = FALSE;
 
+static void debuglog(char* buf) {
+  FILE *fp = fopen("debug.log", "a");
+  fprintf(fp, "%s\n", buf);
+  fclose(fp);
+}
+
 /* Whether we are inside channel_parse_messages() or another situation where it
  * is safe to invoke callbacks. */
 static int safe_to_invoke_callback = 0;
@@ -2894,11 +2900,14 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
        while (TRUE)
        {
            int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL);
+           char buff[256];
+           sprintf(buff, "polling %ld, %d, %ld", nread, r, GetLastError());
+           debuglog(buff);
 
-           if (r && nread > 0)
-               return CW_READY;
            if (r == 0)
                return CW_ERROR;
+           if (nread > 0)
+               return CW_READY;
 
            /* perhaps write some buffer lines */
            channel_write_any_lines();
@@ -3003,6 +3012,7 @@ channel_close_on_error(channel_T *channel, char *func)
      * died.  Don't close the channel right away, it may be the wrong moment
      * to invoke callbacks. */
     channel->ch_to_be_closed = TRUE;
+    debuglog("close");
 
 #ifdef FEAT_GUI
     /* Stop listening to GUI events right away. */
@@ -3033,9 +3043,6 @@ channel_read(channel_T *channel, int part, char *func)
     sock_T             fd;
     int                        use_socket = FALSE;
 
-    /* If we detected a read error don't try reading again. */
-    if (channel->ch_to_be_closed)
-       return;
 
     fd = channel->ch_part[part].ch_fd;
     if (fd == INVALID_FD)
@@ -3045,6 +3052,14 @@ channel_read(channel_T *channel, int part, char *func)
     }
     use_socket = fd == channel->CH_SOCK_FD;
 
+    {
+      DWORD nread;
+      int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL);
+      char buff[256];
+      sprintf(buff, "let's read %ld, %d", nread, r);
+      debuglog(buff);
+    }
+
     /* Allocate a buffer to read into. */
     if (buf == NULL)
     {
-----------------------------------

The output become:

polling 0, 1, 0
polling 0, 1, 0
polling 0, 1, 0
polling 0, 1, 0
polling 0, 0, 109
close
polling 18, 1, 0
let's read 18, 1
polling 18, 1, 0

Then, I check GetLastError() to ignore ERROR_BROKEN_BUFFER that occur when 
process exited.

diff --git a/src/channel.c b/src/channel.c
index 10ed42e..c465be7 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2888,17 +2888,18 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
        DWORD   nread;
        int     sleep_time;
        DWORD   deadline = GetTickCount() + timeout;
-       int     delay = 1;
+       int     r, delay = 1;
 
        /* reading from a pipe, not a socket */
        while (TRUE)
        {
-           int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL);
+           nread = 0;
+           r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL);
 
-           if (r && nread > 0)
-               return CW_READY;
-           if (r == 0)
+           if (r == 0 && GetLastError() != ERROR_BROKEN_PIPE)
                return CW_ERROR;
+           if (nread > 0)
+               return CW_READY;
 
            /* perhaps write some buffer lines */
            channel_write_any_lines();
diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim
index 24b05be..cdf4c53 100644
--- a/src/testdir/shared.vim
+++ b/src/testdir/shared.vim
@@ -121,10 +121,10 @@ func WaitFor(expr)
   for i in range(100)
     try
       if eval(a:expr)
-       if has('reltime')
-         return float2nr(reltimefloat(reltime(start)) * 1000)
-       endif
-       return slept
+        if has('reltime')
+          return float2nr(reltimefloat(reltime(start)) * 1000)
+        endif
+        return slept
       endif
     catch
     endtry

https://gist.github.com/80bbdb9d27b62e0f37c86f8f2e112b34

-- 
-- 
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