Skip Menu |

This queue is for tickets about the TermReadKey CPAN distribution.

Report information
The Basics
Id: 56486
Status: resolved
Priority: 0/
Queue: TermReadKey

People
Owner: Nobody in particular
Requestors: chrisb [...] debian.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 2.30



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 ) ); }
On 2010-04-11 11:36:30, crispygoth wrote: Show quoted text
> 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.
To add more information: things may even fail if an older version of the resize program exists. Seen on a FreeBSD 8.0 system: $ env SHELL=/usr/local/bin/zsh /usr/local/bin/resize TERMCAP='xterm|xterm-color|X11 terminal emulator:ti@:te@:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:@7=\EOF:@8=\EOM:kI=\E[2~:kh=\EOH:kP=\E[5~:kN=\E[6~:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:Km=\E[M:li#25:co#80:am:kn#12:km:mi:ms:xn:AX:bl=^G:is=\E[\!p\E[?3;4l\E[4l\E>:rs=\E[\!p\E[?3;4l\E[4l\E>:le=^H:AL=\E[%dL:DL=\E[%dM:DC=\E[%dP:al=\E[L:dc=\E[P:dl=\E[M:UP=\E[%dA:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:ho=\E[H:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:im=\E[4h:ei=\E[4l:ks=\E[?1h\E=:ke=\E[?1l\E>:kD=\E[3~:kb=^H:sf=\n:sr=\EM:st=\EH:ct=\E[3g:sc=\E7:rc=\E8:eA=\E(B\E)0:as=\E(0:ae=\E(B:ml=\El:mu=\Em:up=\E[A:nd=\E[C:md=\E[1m:me=\E[m:mr=\E[7m:so=\E[7m:se=\E[27m:us=\E[4m:ue=\E[24m:vi=\E[?25l:ve=\E[?25h:ut:Co#8:pa#64:op=\E[39;49m:AB=\E[4%dm:AF=\E[3%dm:'; export TERMCAP; And here it stops, and the COLUMN and LINES environment variables are missing, but that's what GetTerminalSize() needs. The proposed stty solution would probably work here. Another possibility is the "tput" program, which could maybe be tried after stty as the very last fallback: $ tput co; tput li 80 24 Regards, Slaven
I've applied a similar patch to 2.31 on CPAN let me know how this goes