On Thu, Aug 18, 2016 at 07:39:21PM -0700, Ken Takata wrote:

> > I spent a bit of time debugging.  The problem is that after the iconv()
> > call fails, vim tries to rewind the file and the lseek() fails with ESPIPE.
> > The file created by <() ends up being a character device in /dev/fd (for
> > both bash and zsh), but the seek fails anyway, probably because the
> > underlying mechanism really is a pipe.
> 
> No, it's not the expected behavior.  lseek() should not be called when opening
> <().  It might happen when failing to detect a pipe.

Indeed, that's what's happening.  Like I said, the file that open_buffer()
stats is a character device, not a FIFO, and not a pipe.  So read_fifo
never gets set to TRUE, and readfile() thinks its okay to lseek().

I was focused on readfile() when looking at this yesterday, and completely
ignored its arguments or its caller, which probably would have gotten me to
make the "character device" portion of my message a bit more prominent.

> > As the zsh manpage suggests, this really isn't expected to work:
> > 
> >     If =(...) is used instead of <(...), then the file passed as an
> >     argument will be the name of a temporary file containing the output of
> >     the list process.  This may be used instead of the < form for a program
> >     that expects to lseek (see lseek(2)) on the input file.
> > 
> >     [ ... ] In both cases [/dev/fd and FIFO implementations of <()], the
> >     shell actually supplies the information using a pipe, so that
> >     programmes that expect to lseek (see lseek(2)) on the file will not
> >     work.
> > 
> > So it seems to me that the test is broken (though I'm not sure how to fix
> > it).
> 
> The test is not broken (at least on Linux and Cygwin.)

Right.  Because on Linux,

    $ stat -L -c %F <(echo hi)
    fifo

while on Solaris,

    $ stat -L -c %F <(echo hi)
    character special file

> Please check the patch 7.4.2189 if you want to know the purpose of the test.

I can see that.  What's not clear to me is whether the test is broken
because it assumes that the <() construct will create a FIFO, or whether
the code is broken because it doesn't test for a character device.  If I
explicitly create a FIFO with mkfifo and edit that with vim, then the right
thing happens for me.

So here's a change that will allow /dev/fd paths to be read as if they were
FIFOs, and allows the existing tests to pass for me.

diff --git a/src/buffer.c b/src/buffer.c
index 4f68882..ce0bb35 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -220,6 +220,11 @@ open_buffer(
 # ifdef S_ISSOCK
                      || S_ISSOCK(perm)
 # endif
+# ifdef S_ISCHR
+                     || (S_ISCHR(perm) &&
+                        !STRNCMP(curbuf->b_ffname, "/dev/fd/", 8) &&
+                        STRLEN(curbuf->b_ffname) > 8)
+# endif
                    ))
                read_fifo = TRUE;
        if (read_fifo)

I can try to cons up a test that explicitly uses mkfifo to test fifo input,
but I'm not sure how to explicitly use a /dev/fd device.

Thanks,
Danek

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