On Sat, Aug 23, 2003 at 09:54:10PM -0700, Phil Nadeau wrote:
> Hello POE,
>
> I noticed the problem that Bruno Boettcher was having with
> POE::Wheel::ReadLine and I am having a similar problem. I'm writing in
> with my observations.
>
> First, system is Linux 2.4.20, Perl is 5.8.0, POE is 0.26.
> Term::ReadKey is 1.7. I'm using libtermcap-compat, which may not be the
> same as libtermcap.
>
> The first character entered is handled normally. The second character
> entered puts the program into a loop where the wheel's 'select read' event
> is called repeatedly; however, ReadKey(-1) returns an undefined value, so
> the keys aren't actually delivered to the program. When I terminate the
> program using 'kill' from another terminal, the characters that I typed
> show up on the command line for the shell - which I guess means they were
> buffered but not consumed by a read from perl.
>
> I don't think that this is a problem with POE per se, because the test
> program show in 'perldoc Term::ReadKey' doesn't seem to work either.
I agree. This sounds like a classic case of "suffering from buffering".
Unfortunately, I develop on FreeBSD, and "it works for me" so I can't
dig into it myself.
Another problem might be in the tty itself. Setting it non-blocking
doesn't guarantee that it will respond immediately. Check the
description of VMIN and VTIME in your termios man page.
This should set VMIN and VTIME to 0, which enables non-blocking
semantics down in the tty itself. This might prevent keystrokes from
being buffered. The new version of your test program would look like
this:
> #!/usr/bin/perl
>
> use Term::ReadKey;
>
> ReadMode 5; # Turn off controls keys
my $tio = new POSIX::Termios;
$tio->getattr(fileno(STDIN)); # usually 0
$tio->setcc(VMIN, 0);
$tio->setcc(VTIME, 0);
$tio->setattr(fileno(STDIN), TCSANOW);
> while (1) {
> while (not defined ($key = ReadKey(-1))) {
> print "Foo\n";
> sleep (1);
> }
> print "Get key $key\n";
> ($key eq 'q') and last;
> }
> ReadMode 0; # Reset tty mode before exiting
Another thing to try would be setbuf() or setvbuf() on STDIN. I could
swear I saw something exporting that to Perl, but I can't find it
anywhere. Maybe I'm misremembering from C.
Anyway, let me know if that works. I'll add it to POE::Wheel::ReadLine
if it clears up the problem.
Thanks for looking into this.
--
Rocco Caputo - [EMAIL PROTECTED] - http://poe.perl.org/