Santiago Alejandro Aguero wrote:

> While I was trying to write some vim code for testing a (async)
> functionality for Neomake plugin, I've noticed the following scenario:
> 
> 
> - Having the following shell script (with errors):
> 
> #!/bin/sh
> 
> a='$var'
> 
> foo(
> 
> 
> - And the next vim test code:
> 
> function! StartJob()
>     let g:job = job_start(['/bin/sh', 'errors.sh'], {
>         \ 'callback': 'HandlerCallback',
>         \ 'close_cb': 'HandlerClose',
>         \ 'exit_cb': 'HandlerExit'
>         \ })
> endfunction
> 
> function! HandlerCallback(channel, line) abort
>     call Debug('[Callback] channel: ' . a:channel . ', line: ' . a:line . ', 
> channelStatus: ' . ch_status(a:channel))
> endfunction
> 
> function! HandlerClose(channel) abort
>     call Debug('[Close] channel: ' . a:channel . ', channelStatus: ' . 
> ch_status(a:channel))
> endfunction
> 
> function! HandlerExit(job, status) abort
>     call Debug('[Exit] job: ' . a:job . ', status: ' . a:status . ', 
> jobStatus: ' . job_status(a:job))
> endfunction
> 
> function! Debug(msg) abort
>     call writefile([a:msg], 'output.log', 'a')
> endfunction
> 
> command! -bar RunJob call StartJob()
> 
> 
> - Then the following thing happens:
> 
>   - RunJob # Works OK, both HandlerCallback (with data) and HandlerClose are 
> called
> 
>   - RunJob | sleep 50m # Does not work, only HandlerClose and HandlerExit are 
> being called (no buffered data)
> 
> 
> The reason I need the sleep is that I want to check every 50m for the 
> job_status in order to continue with some test assertions.
> 
> Also, I've noticed that this does not happen with other commands... Is there 
> something special about /bin/sh?

I did a bit of debugging and found that reading from the pipe fails if
the process has exited.  Vim does try to read, but gets zero bytes.
This is in fd_read() in channel_read() (on Unix fd_read() is a read()
system call).

The manual page for pipe(7) confirm this:

       If all file descriptors referring to the write end of a pipe have
       been closed, then an attempt to read(2) from the pipe will see end-
       of-file (read(2) will return 0).

There is no mention about what happens to the buffered output.  I guess
it's discarded when the write end of the pipe is closed.

I cannot think of a way to read from the pipe when the other end has
exited.  Thus the only workaround is to have the command wait a bit
before exiting.

-- 
ARTHUR:  I did say sorry about the `old woman,' but from the behind you
         looked--
DENNIS:  What I object to is you automatically treat me like an inferior!
ARTHUR:  Well, I AM king...
                                  The Quest for the Holy Grail (Monty Python)

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