\n
(véase la sección
1.7). Aún mejor, podemos hacer
lecturas sin bloqueo.
En el ejemplo usamos open2
para
poner en marcha el depurador gdb haciendo que ejecute
un cierto número de comandos bajo el control
de nuestra aplicación y retornar posteriormente el control
al usuario. Cuando ejecute este ejemplo observará
una falta de sincronía entre la escritura de sus comandos
y la respuesta del depurador. Es preciso añadir un retorno
de carro adicional para lograr ver el resultado de nuestro último
comando. Para lograr un control mas adecuado
es mejor hacer uso de una herramienta que provea de terminales
virtuales como Expect (seccion 8.1).
En la línea 35 indicamos que las lecturas desde $RDR
se hacen en forma no bloqueante. El método blocking
esta definido en IO::Handle .
La función readgdb
muestra la forma de leer desde
un manejador sin bloqueo. La función sysread
devuelve undef
si no hay nada disponible.
En tal caso la variable $!
contiene el
código de error EWOULDBLOCK
(definida en POSIX
).
Esta situación no debe confundirse con la devolución de un cero,
la cual indica la presencia del final de fichero.
El manejo de escrituras sin bloqueo es similar.
El retorno de un valor undef
señala la imposibilidad
de escribir. Si la escritura sólo se ha podido hacer parcialmente
es responsabilidad del programador intentarlo posteriormente.
lhp@nereida:~/Lperl/src/perl_networking/ch2$ cat -n open2gdb_1.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use IPC::Open2; 4 use IO::Handle; 5 use POSIX; 6 use constant BUFFERSIZE => 2048; 7 8 my $WTR = IO::Handle->new(); 9 my $RDR = IO::Handle->new(); 10 11 # Lectura sin bloqueo 12 # 0 es EOF; undef es "no hay cadena" 13 sub readgdb { 14 my $line = ''; 15 my $bytes = sysread($RDR, $line, BUFFERSIZE); 16 if (defined($bytes)) { 17 return "$line" if ($bytes); 18 exit 0; # EOF from gdb 19 } 20 return "Press <CR>: " if ($! == EWOULDBLOCK); 21 die "sysread error: $!"; 22 } 23 24 my $init = <<"EOI"; 25 set args 0 1000000 4 26 b main 27 l 28 R 29 n 30 31 EOI 32 33 $init .= "n\n"x5; # 5 next 34 my $pid = open2($RDR, $WTR, 'gdb pi'); 35 $RDR->blocking(0); 36 print readgdb(); 37 my $bytes = syswrite($WTR, $init); 38 print readgdb(); 39 while (<>) { 40 my $bytes = syswrite($WTR, $_); 41 print readgdb(); 42 } 43 wait;
Casiano Rodríguez León