Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

non-destructive read on stdin

by jeremyh (Beadle)
on Aug 01, 2006 at 22:58 UTC ( #565101=perlquestion: print w/ replies, xml ) Need Help??
jeremyh has asked for the wisdom of the Perl Monks concerning the following question:

I'm sure there's a way to do this, but I'm having trouble coming up with it:

High-level goal - I would like to read the contents of stdin, and then put them back for another process to read.

I've been looking at saving the contents in a scalar and then closing and reopening stdin for output, writing the contents to it, then closing and reopening it for reading, but I can't get this to work.

I expect there's a way to do it with something lower level for the read (like in C), but I was hoping it could be done at the high level.

Thanks for your input..

Comment on non-destructive read on stdin
Re: non-destructive read on stdin
by ikegami (Pope) on Aug 01, 2006 at 23:03 UTC
    open "|...", IPC::Open3, IPC::Run, IPC::Run3, etc provide means of feeding input to a child process via its STDIN.


    my $stdin; while (<STDIN>) { $stdin .= $_; ... process STDIN as usual ... } open(my $child, "|child") or die("Unable to start child: $!\n"); print $child $stdin;
      Yes, I should have thought of that - thanks!
Re: non-destructive read on stdin
by rodion (Chaplain) on Aug 01, 2006 at 23:21 UTC
    I think what you're looking for is an unget_char() routine to work with a getchar() routine. (Actually unget_str(), but it's easier to explain at the character level. And it has historical precedence in C, although it's neithe ANSI nor Posix standard.)

    To make this work rolling your own, you need to pull all input from a single routine, a getchar() routine, and that routine needs to have an extra buffer that you can put characters back into, when you don't want them yet. getchar() takes bytes from that extra buffer, in order, and only when the extra buffer's empty does it go to STDIN itself.

    This is the only way to maintain the sequence of characters comming in. If you try to load them back in by stuffing them into STDIN, then you will always have a race condition where a new character typed in can get stuffed in after you took characters out, but before you put them back in. This will happen rarely and unpredictably, and possibly more often when the system is loaded. It will probably not show up in testing.

    Update: Looks like I misunderstood what the OP wanted. I should have read "process" as "OS process", which makes sense to do, but I missed it. Oh well, it was a decent answer to a different question, I think. (And thanks to betterworld for pointing out the error.)

      Every process has its own buffers for getc/ungetc. Jeremyh wants another process to read the ungotten characters, which won't be possible even if their STDIN file descriptors refer to the same pipe/socket/terminal/whatever.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://565101]
Approved by ikegami
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2014-07-30 23:01 GMT
Find Nodes?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:

    Results (241 votes), past polls