Introducción a la Programación de Terminales

Las ttys trabajan en uno de dos modos básicos: raw y cooked. En modo raw los datos se pasan a la aplicación tal y como se reciben sin que se hagan cambios. En modo cooked - o modo canónico - se suele proveer un editor de línea en el mismo driver de dispositivo y son las líneas ya editadas las que se envían a la aplicación.

En modo cooked ciertos caracteres pasan a ser caracteres de control. Por ejemplo ^U suele estar asociado con kill (borrar la línea), ^V con lnext, etc.

lhp@nereida:~/Lperl/doc$ stty -a
speed 38400 baud; rows 24; columns 59; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D;
eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0
cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase
-tostop -echoprt echoctl echoke
lhp@nereida:~/Lperl/doc$

Ejercicio 7.1.1  
  1. Lea el manual sobre stty
  2. ¿Cuál es el significado de lnext?
  3. Usando el comando stty cambie kill de su valor actual a ^T.
  4. Cambie erase de su valor actual a ^H.
  5. ¿Que hace stty sane?

Perl proporciona acceso a la interfaz POSIX termios a través de su módulo POSIX .

use POSIX qw(:termios_h)
El siguiente ejemplo tomado de [3] obtiene los caracteres de control para las acciones de erase (borrar carácter) y kill (borrar línea) y las cambia para restaurarlas posteriormente a la salida.

lhp@nereida:~/Lperl/src/cookbook/ch15$ cat -n demo1
 1  #!/usr/bin/perl -w
 2  # demo POSIX termios
 3  use strict;
 4  use POSIX qw(:termios_h);
 5
 6  my $term = POSIX::Termios->new;
 7  $term->getattr(fileno(STDIN));  # Rellenamos sus campos
 8                                  # a partir del fd STDIN
 9  my $erase = $term->getcc(VERASE); # código ascii: 127
10  my $kill = $term->getcc(VKILL);
11  printf "Erase is character %d, %s\n", $erase, uncontrol(chr($erase));
12  printf "Kill is character %d, %s\n", $kill, uncontrol(chr($kill));
13
14  $term->setcc(VERASE, ord('#'));
15  $term->setcc(VKILL, ord('@'));
16  $term->setattr(1, TCSANOW); # Poner los atributos inmediatamente
17                              # para stdout (1)
18  print("erase is #, kill is @; type something: ");
19  my $line = <STDIN>;
20  print "You typed: $line";
21
22  $term->setcc(VERASE, $erase);
23  $term->setcc(VKILL, $kill);
24  $term->setattr(1, TCSANOW);
25
26  sub uncontrol {
27      local $_ = shift;
28      s/([\200-\377])/sprintf("M-%c",ord($1) & 0177)/eg;
29      s/([\0-\37\177])/sprintf("^%c",ord($1) ^ 0100)/eg;
30      return $_;
31  }
lhp@nereida:~/Lperl/src/cookbook/ch15$ demo1
Erase is character 127, ^?
Kill is character 21, ^U
erase is #, kill is @; type something: hello world
You typed: hello world
lhp@nereida:~/Lperl/src/cookbook/ch15$

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