Как узнать ширину и высоту моего терминала с помощью ioctl? - PullRequest
2 голосов
/ 26 ноября 2010

Что я должен изменить, чтобы сделать эту работу?

 #!/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;
 }

Вдохновленный ответом Триста в От столбца к строке .

Ответы [ 5 ]

3 голосов
/ 26 ноября 2010

Чтобы получить количество строк и столбцов, я делаю это:

#!/usr/bin/perl
use strict;
use warnings;

my $cols = 80;
my $rows = 24;
for (`stty -a`) {
    /columns ([0-9]+);/ and do { if ($1 > 0) { $cols = $1; }};
    /rows ([0-9]+);/    and do { if ($1 > 0) { $rows = $1; }};
}
print "cols=$cols\trows=$rows\n";
2 голосов
/ 22 апреля 2012

Почему бы просто не использовать Term::Size? При этом используется метод ioctl(), заключенный в красивый аккуратный код XS, полностью готовый к использованию из Perl.

1 голос
/ 26 ноября 2010

Это прекрасно работает для меня:

#!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";
}

Требование не нуждается (и не должно иметь) полного пути; TIOCGWINSZ уже определен загрузкой заголовка ioctl, и нет никаких признаков того, что скаляр назначения должен быть инициализирован до нужного размера (хотя, если он вообще не инициализирован, perl выдает предупреждение, потому что он, кажется, не распознает специальный 1004 * -подобная природа ioctl, поэтому я установил ее на "", чтобы это успокоить).

0 голосов
/ 10 июля 2015

Term::ReadKey имеет встроенный метод получения размера терминала, и он поддерживает ряд различных терминалов , включая Windows. Учитывая огромное количество модулей на CPAN, которые используют этот модуль , вы, вероятно, уже установили его.

#!/usr/bin/perl -w
use strict;
use Term::ReadKey   qw/ GetTerminalSize /;

my @winsize = &GetTerminalSize(\*STDOUT);
my ($cols, $rows, $xpix, $ypix) = @winsize;
print "cols:$cols rows:$rows xpix:$xpix ypix:$ypix\n";
0 голосов
/ 26 ноября 2010

В другом случае вам нужно будет попросить С сказать вам, каково значение TIOCGWINSZ.Возможно, он покажет вам размер другого аргумента, пока вы на нем.

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termios.h>

int
main(argc, argv)
    int   argc;
    char *argv[];
{
    struct winsize mywinsize;
    int ttyfd;

    if ((ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY)) == -1) {
        perror("open /dev/tty");
        exit(-1);
    }

    if (ioctl(ttyfd, TIOCGWINSZ, &mywinsize) == -1) {
        perror("ioctl TIOCGWINSZ");
        exit(-1);
    }

    printf("TIOCGWINSZ %#08lx\n",           TIOCGWINSZ             );
    printf("sizeof struct winsize %lu\n",   sizeof(struct winsize) ); 
    printf("rows %d\n",                     mywinsize.ws_row       );
    printf("cols %d\n",                     mywinsize.ws_col       );

    if (fclose(stdout) == EOF) {
        perror("close stdout");
        exit(-1);
    }

    exit(0);
}

Возможно, какая-то добрая душа может показать вам, как обернуть это в Inline::C для васНо между тем этого должно быть достаточно.Обратите внимание, что это переносимая программа, потому что она работает на «̲b̲o̲t̲h» системах:

☺ BSD ☺

    OpenBSD% cc getwinsz.c && a.out
    TIOCGWINSZ 0x40087468
    sizeof struct winsize 8
    rows 81
    cols 166

    Darwin% cc getwinsz.c && a.out
    TIOCGWINSZ 0x40087468
    sizeof struct winsize 8
    rows 37
    cols 126

☹ SysV ☹

   Slolaris% cc getwinsz.c && a.out
   TIOCGWINSZ 0x005468
   sizeof struct winsize 8
   rows 37
   cols 126

   Leenooxe% cc getwinsz.c && a.out
   TIOCGWINSZ 0x005413
   sizeof struct winsize 8
   rows 37
   cols 126
...