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.