Skip Menu |

This queue is for tickets about the Term-Screen CPAN distribution.

Report information
The Basics
Id: 56866
Status: resolved
Priority: 0/
Queue: Term-Screen

People
Owner: Nobody in particular
Requestors: ruittenb [...] cpan.org
Cc: ruittenb [...] users.sourceforge.net
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.01
  • 1.02
  • 1.03
Fixed in: (no value)



CC: ruittenb [...] users.sourceforge.net
Subject: input is not received when it is available
The problem can be reproduced with the attached program (reproduce.pl). Run the program and press several function keys (e.g. F2/F3/F4/F5) in quick succession. The application does not receive notification of all of these keypresses: e.g. notification may stop when F2 and F3 have been received. Only when another key is pressed (e.g. 'e') then will the keys F4/F5/e arrive at the application. The problem seems to be caused by the fact that the getc() function does internal buffering, so that the select() call does not notice that there is input ready to be processed. This seems to be a problem that occurs on all Unices. The problem can be solved by using sysread() instead of getc(). I have attached a patch.
Subject: Term-Screen-1.03.diff
--- Screen-1.03.pm 2010-04-23 19:51:20.000000000 +0200 +++ Screen-1.03-sysread.pm 2010-04-23 19:52:38.000000000 +0200 @@ -6,7 +6,7 @@ use vars qw($VERSION); -$VERSION = '1.03'; +$VERSION = '1.03-sysread'; =head1 NAME @@ -441,11 +441,11 @@ sub getch { my $this = shift; - my ( $c, $fn_flag ) = ( '', 0 ); + my ( $c, $nc, $fn_flag ) = ( '', '', 0 ); my $partial_fn_str = ''; if ( $this->{IN} ) { $c = chop( $this->{IN} ); } - else { $c = getc(STDIN); } + else { sysread( STDIN, $c, 1 ); } $partial_fn_str = $c; while ( exists( $this->{KEYS}{$partial_fn_str} ) ) @@ -460,7 +460,11 @@ else # wait for another key to see if were in FN yet { if ( $this->{IN} ) { $partial_fn_str .= chop( $this->{IN} ); } - else { $partial_fn_str .= getc(); } + else + { + sysread(STDIN, $nc, 1); + $partial_fn_str .= $nc; + } } } if ($fn_flag) # seemed like a fn key @@ -552,8 +556,9 @@ sub flush_input { my $this = shift; + my $discard; $this->{IN} = ''; - while ( $this->key_pressed() ) { getc(); } + while ( $this->key_pressed() ) { sysread(STDIN, $discard, 1); } return $this; }
Subject: reproduce.pl
#!/usr/bin/env perl use Term::Screen; $term = new Term::Screen(); $delay = 1; $term->clrscr(); until ($key eq 'q') { print "Waiting for input."; until (length($term->{IN}) || $term->key_pressed($delay)) { # poll background jobs etc. print "."; } $key = $term->getch(); print "\r\nReceived: $key. Hold on while I do stuff...\r\n"; sleep 1; }