Currently gnuplot supports the '< SHELL COMMAND' syntax. This patch extends gnuplot with a similar syntax to read data from already opened file descriptors (using the stdin case of Bash's `[n]<&digit-` syntax for moving file descriptors). I'm not entirely clear on how the surrounding code is supposed to work, so it's possible that I've missed something. The following simple tests do work:
$ seq 10 | gnuplot -p -e "plot '<&0'"
$ cat data-1 | ./src/gnuplot -p -e "plot '<&0', '<&3', '<&4'" 3<data-2 4<data-3
Add support for '<&n' file descriptor filenames
I find serious problems when testing this patch:
plot '<&' or plot '<&0'
correctly plots one set of input points (terminated by ^D) but then hangs the program, which must be killed externally.
plot '<&1'
apparently plots from stdin (why?) but clobbers the echo of input characters to the terminal so that from that point on one is typing blind.
plot '<&2'
again plots from stdin (why?). Does not clobber echo to terminal but does clobber stderr.
So at least on my test machines (linux 32-bit gcc; linux 64-bit clang; libreadline6) this is not working correctly.
Here are some additional patches fixing most of these issues. There is at least one outstanding problems using fcntl checking, where:
hangs. This is because gnuplot reads the data from file descriptor 1 (the piped in
seqoutput) and then attempts to plot to stdout. I'm not sure how to handle this case. Ideally, gnuplot would realize that FD 1 was read-only and would die when it tried to write to it. I'll look into this next.A simple solution would be to raise an error if the requested FD matched
STD*_FILENO, but that smells funny to me. I may change my mind depending on how difficult fixing the above issue turns out to be.I've attached the additional patches. Feel free to squash when applying.
Hmm, looks like this is one patch at a time. Additional new patches to come ;).
Extra motivation
Check for read-only file descriptors with '<&n'
Some meta questions:
It shouldn't be legal. That's what the read-only check is for. Your alternative way of avoiding this is requiring FDs > 2, which will work except when:
The user uses those file descriptors for something else (in which case reading data from them should be legal):
$ gnuplot -p -e "plot '<&1'" 1< <(my-program)
The user dups those file descriptors to higher values (in which case reading data from the higher values should be illegal):
$ exec 4>&1
$ gnuplot -p -e "plot '<&4'"p 4< <(my-program)
Maybe these pathalogical cases are too unlikely to be worth dealing with?
That's a good idea, and works around most of the stdin/stdout/stderr issues. We'd need a way to flag file datafiles for not-closing though.
The input redirection syntax is in POSIX. If you're not running POSIX, I dunno how you setup the file descriptors, but I don't know how you'd setup named pipes there either ;).
I worry that your case 1 (redirecting program output through gnuplot's stdin) will cause synchronization problems. Won't this result in stdin being open twice in gnuplot? Some reads will come via one stream (fp), some by a different stream. In particular I am dubious about multiplexed mouse input, which is synchronized using FD_SET/select().
It seems to me that one of the nice things about your patch is that it would provide a way to feed data to gnuplot that bypasses the need to mix commands and data in a single stream (stdin). So my inclination is to forbid opening stdin via this mechanism. Is there a standard way for the code to test whether a requested fd is really stdin?
I'm thinking that what we want is
Something like this...
Last edit: Ethan Merritt 2013-02-14
This looks good to me, especially the rewinding. Minor nits:
I'd use “Cannot use stdin, stdout, or stderr as data files” instead of “Cannot map input file to stdin/stdout/stderr”.
I'm not sure about error message capitalization. The existing source has examples of both lowercase, and sentence case. This probably doesn't really matter ;).
I'd stick with
os_errorforfdopen, so the user can see theerrnomessage (but maybeint_erroralso printserrno?).You add an unrelated “Special filenames” comment.
You add an an unrelated newline.
There is trailing whitespace after “harmless if it connects to a pipe.”
There isn't a space after
stderr,in thefprintfcall.Paths in the new doc example assume you're in the gnuplot
srcdirectory.Cleaned up version of the patch attached.
Add to CVS for 4.6 and 4.6. As per Email discussion, we may need to add a fflush() command in df_reset_after_error(). The problem is that it is not clear how to find which fd to flush at this point.