Search code examples
perlterminalioctl

How do I get width and height of my terminal with ioctl?


What do I have to change to make this work?

 #!/usr/bin/perl
 use 5.012;
 use warnings;
 require "/usr/lib/perl5/vendor_perl/5.12.1/x86_64-linux-thread-multi/sys/ioctl.ph";
 my ($rows, $cols, $xpix, $ypix);

 my $winsize = "\0" x 8;
 my $TIOCGWINSZ = 0x40087468;  # should be require sys/ioctl.pl
 if (ioctl(STDOUT, $TIOCGWINSZ, $winsize)) {
     ($rows, $cols, $xpix, $ypix) = unpack('S4', $winsize);
 } else {
     say "something didn't work" and exit;
 }

Inspired by tchrist's answer in From column to row.


Solution

  • This works just fine for me:

    #!perl
    
    use strict;
    use warnings;
    
    require 'sys/ioctl.ph';
    
    my $winsize = ""; # Silence warning
    if (ioctl(STDOUT, TIOCGWINSZ() , $winsize)) {
            my ($rows, $cols, $xpix, $ypix) = unpack 'S4', $winsize;
            print join ":", $rows, $cols, $xpix, $ypix;
            print "\n";
    } else {
            warn "Something didn't work.\n";
    }
    

    The require doesn't need (and shouldn't have) the full path; TIOCGWINSZ is already defined by loading the ioctl header, and there's no sign that the destination scalar has to be initialized to the right size (although if it's not initialized at all, perl throws a warning because it doesn't seem to recognize the special read-like nature of ioctl, so I set it to "" just to quiet that).