Subject: | GetTerminalSize fails when STDOUT is not a tty and 'resize' is not available |
If STDOUT has been redirected so that it is not the current tty, and the
"resize" program is unavailable, GetTerminalSize fails:
perl -MTerm::ReadKey -e 'print GetTerminalSize' | tee /dev/null
Unable to get Terminal Size. The TIOCGWINSZ ioctl didn't work. The
COLUMNS and LINES environment variables didn't work. The resize program
didn't work. at /usr/lib/perl5/Term/ReadKey.pm line 362.
This could be fixed by attempting TIOCGWINSZ on STDIN and/or STDERR, as
well as STDOUT. I can't imagine that it's uncommon for STDOUT to be
redirected with output going to STDERR that needs to know the terminal
size.
Or another option would be to attempt to use the 'size' option of the
'stty' program. I believe this option may be a GNU extension to stty, so
would only work for GNU-based systems, but it might be worth adding to
the methods GetTerminalSize attempts. I've attached a patch that adds it
as a possibility. It makes the above test script work.
Subject: | readkey-stty.patch |
Index: ReadKey.pm
===================================================================
--- ReadKey.pm (revision 55948)
+++ ReadKey.pm (working copy)
@@ -359,6 +359,27 @@
if ( @results < 4 )
{
+ my ($prog) = "stty size";
+
+ my ($stty) = scalar(`$prog 2>/dev/null`);
+ if (
+ defined $stty
+ and ( $stty =~ /(\d+) (\d+)/ )
+ )
+ {
+ $results[0] = $2;
+ $results[1] = $1;
+ @results[ 2, 3 ] = ( 0, 0 );
+ }
+ else
+ {
+ @results = ();
+ }
+ push( @fail, "stty program" );
+ }
+
+ if ( @results < 4 )
+ {
die "Unable to get Terminal Size."
. join( "", map( " The $_ didn't work.", @fail ) );
}