http://qs321.pair.com?node_id=219891

Eradicatore has asked for the wisdom of the Perl Monks concerning the following question:

I'm tryinig to use Open3() to open up a seperate process on windows, and then read characters one at a time with ReadKey (or getc) from the OUTPUT stream from the open3() call. The problem I have is that sometimes the seperate process will just sit there waiting for the user to enter "y" or "n". At this point, my loop that is getting chars one at a time hangs, and it doesn't seem to even get any of the chars from that last line where the seperate program was waiting for input. I've been hunting around but I don't seem to be able to tie this all together myself.

I've tried setting ReadMode of the OUTPUT stream to 5 or 4, but in windows using activestate perl 5.6.0 it sends back this error:

GetConsoleMode failed, LastError=|6| at D:/Perl/site/lib/Term/ReadKey.pm line 245.

If anyone has any suggestions, I would really appreciate it. Thanks!

Justin Eltoft

"If at all god's gaze upon us falls, its with a mischievous grin, look at him" -- Dave Matthews

  • Comment on nonblocking char reads from OUTPUT stream from open3

Replies are listed 'Best First'.
Re: nonblocking char reads from OUTPUT stream from open3
by pg (Canon) on Dec 14, 2002 at 20:53 UTC
    There is a common mechanism for all descriptors, to check whether a descriptor is ready for reading/writing, please check out IO::Select.

    The main point is to call can_read or can_write before you really go reading/writing. This way, you even don't need to bother blocking/non-blocking mode. More important, you gain a better control.

    On the other hand, I attached a simple sample to show pipe:
    parn.pl: use strict; use warnings; $| ++; print "Entering parn.pl...\n"; my $chld; open($chld, "perl -w chld.pl|") || die "failed to open child process\n +"; my @ready; while (1) { my $from_chld = <$chld>; print $from_chld * 2, "\n"; } chld.pl: use strict; use warnings; $| ++; while (<>) { if ($_ < 100) { print "$_"; } }
    Update: for getc, although it returns one char a time, but unfortunately, this only happens after return is hit. An alternative way is presented in perlfunc under getc.
Re: nonblocking char reads from OUTPUT stream from open3
by dakkar (Hermit) on Dec 14, 2002 at 21:35 UTC

    ReadKey supposes that the filehandle refers to a terminal (TTY), not to a pipe (which is what Open3 gives you).

    The error you reported means (more or less): what you gave me is not a terminal, can't do anything with it.

    Try setting autoflush(1) on the filehandle.

    -- 
            dakkar - Mobilis in mobile
    
      Thanks for the reply. I think I already set this. You say autoflush on the filehandle, but I'm not sure that is exactly what you meant. I don't think you can set autoflush on a specific filehandle can you? I just set $| to 1.

      Anyway, this still wasn't solving the problem. I started out actually with getc(), because I figured that with autoflush on, there would be no way I wouldn't get all the chars up to the point where this seperate process typed out the line (without a carriage return) with the wait for a "y" or "n". But for some reason, just on that one line, the getc() stopped working it seemed.

      Justin

        You can set autoflush on a single handle:

        use IO::Handle; autoflush FH 1; # first way FH->autoflush(1); # OO-ish way

        But anyway, that's not what you need (I just tried). I just don't know how to do it... sorry

        -- 
                dakkar - Mobilis in mobile