Fantastic -- thanks, that's exactly what I needed. BTW, I think the $2 should have been a $1. It works for me on both Linux and FreeBSD. The following is what I ended up with.
# Normally returns the number of columns on the output tty.
# Return 0 if output isn't a tty.
# Returns undef if it's unable to find the width.
sub tty_columns {
return 0 unless -t STDOUT;
my $result;
# The following works on linux, but seems to fail on freebsd.
# It works properly if the user resizes the terminal window while th
+e program is running.
if (eval "require 'sys/ioctl.ph'") {
eval {
# All of the dies on the next few lines will be caught by the ev
+al{}.
die unless defined &TIOCGWINSZ;
open(TTY, "+</dev/tty") or die;
die unless ioctl(TTY, &TIOCGWINSZ, $winsize='');
my ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
$result = $col;
}
}
return $result if defined $result;
# A less efficient fallback, should work on anything unixy.
chomp(my @lines = `stty -a`);
my ($rows, $columns);
for (@lines) {
$rows = $1 if /rows (\d+);/; # linux
$rows = $1 if /(\d+) rows;/; # FreeBSD
$columns = $1 if /columns (\d+);/; # linux
$columns = $1 if /(\d+) columns;/; # FreeBSD
}
return $columns if defined $columns;
# The following two methods give us a fighting chance on a non-POSIX
+ system. I don't use them as the defaults
# because I don't want to introduce dependencies.
# http://search.cpan.org/~kjalb/TermReadKey/ReadKey.pm
# Term::ReadKey is not a standard Perl module, and may not be instal
+led. If the user resizes the terminal
# while the program is running, this will correctly reflect the resi
+zing.
eval 'use Term::ReadKey; my ($wchar, $hchar, $wpixels, $hpixels) = G
+etTerminalSize(); $result=$wchar';
return $result if defined $result;
# http://search.cpan.org/~nwclark/perl-5.8.8/lib/Term/ReadLine.pm
# Term::ReadLine is a standard Perl module, but exists in different
+implementations under the hood. On a Linux
# system, it's implemented using Term::ReadLine::Gnu, which supports
+ get_screen_size(). On a default FreeBSD system,
# however, the following won't work; you'd have to install the p5-Re
+adLine-Gnu package to get support for this function.
eval 'use Term::ReadLine; $term = new Term::ReadLine("foo"); my ($r,
+$c)= Term::ReadLine::get_screen_size(); $result=$c';
return $result if defined $result;
return undef;
}
|