La función ioctl

La función ioctl provee un mecanismo de bajo nivel para acceder a las características de los dispositivos del sistema. La forma de llamada es:

ioctl FILEHANDLE, REQUEST, SCALAR

El primer argumento es el manejador de fichero, el segundo especifica que operación es la que se solicita y en el tercero es donde queda el resultado de la operación.

Ejercicio 7.1.2   Realice las siguientes actividades:

  1. Pida información sobre ioctl mediante perldoc.
  2. Pida información sobre la función C ioctl mediante man
  3. Lea la información dada mediante man ioctl_list

El siguiente ejemplo calcula el tamaño de la terminal usando ioctl:

lhp@nereida:~/Lperl/src/cookbook/ch12$ cat -n winsz.pl
 1  #!/usr/bin/perl
 2  # winsz - find x and y for chars and pixels
 3  use strict;
 4  require 'sys/ioctl.ph';
 5  die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
 6  my $winsize;
 7  open(TTY, "+</dev/tty")                     or die "No tty: $!";
 8  unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
 9      die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
10  }
11  my ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
12  print "(row,col) = ($row,$col)";
13  print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
14  print "\n";
lhp@nereida:~/Lperl/src/cookbook/ch12$ winsz.pl
(row,col) = (26,90)
lhp@nereida:~/Lperl/src/cookbook/ch12$ stty size
26 90

Para entender el programa anterior tenga en cuenta que:

La misma ejecución del programa anterior winsz.pl en una xterm da como resultado:

lhp@nereida:~/projects/perl/src/cookbook/ch12$ perl -d ./winsz.pl 
Enter h or `h h' for help, or `man perldebug' for more help.
main::(./winsz.pl:4):   require 'sys/ioctl.ph';
  DB<1> !!echo $TERM
xterm
  DB<2> l
4==>    require 'sys/ioctl.ph';
5:      die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
6:      my $winsize;
7:      open(TTY, "+</dev/tty")                     or die "No tty: $!";
8:      unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
9:          die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
10      }
11:     my ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
12:     print "(row,col) = ($row,$col)";
13:     print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
  DB<2> b 5
  DB<3> c
main::(./winsz.pl:5):   die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
  DB<3> x  &TIOCGWINSZ
0  21523
  DB<4> c
(row,col) = (52,166)  (xpixel,ypixel) = (1017,687)

La forma normal de obtener en Perl el tamaño de la ventana es usando el módulo Term::ReadKey:

lhp@nereida:~/Lperl/src/cookbook/ch12$ perl -de 0
  DB<1> use Term::ReadKey
  DB<2> x GetTerminalSize()
0  80  # ancho en caracteres
1  24  # largo en caracteres
2  499 # ancho en pixels
3  316 # largo en pixels

Casiano Rodríguez León
Licencia de Creative Commons
Programación Distribuida y Mejora del Rendimiento
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=44.
2012-06-19