patches to this version of Expect. ------------------------------------------------------------- From: Eric Anderson diff -c -r libexpect-perl-1.15-orig/Expect.pm libexpect-perl-1.15/Expect.pm *** libexpect-perl-1.15-orig/Expect.pm Wed Apr 27 09:13:08 2005 --- libexpect-perl-1.15/Expect.pm Wed Apr 27 09:14:45 2005 *************** *** 1256,1262 **** # .01 sec granularity should work. If we miss something it will # probably get flushed later, maybe in an expect call. while (select($rmask,undef,undef,.01)) { ! sysread($self,${*$self}{exp_Pty_Buffer},1024); # Is this necessary to keep? Probably.. # # if you need to expect it later. ${*$self}{exp_Accum}.= ${*$self}{exp_Pty_Buffer}; --- 1256,1263 ---- # .01 sec granularity should work. If we miss something it will # probably get flushed later, maybe in an expect call. while (select($rmask,undef,undef,.01)) { ! my $amt = sysread($self,${*$self}{exp_Pty_Buffer},1024); ! last unless defined $amt && $amt > 0; # subprocess went away # Is this necessary to keep? Probably.. # # if you need to expect it later. ${*$self}{exp_Accum}.= ${*$self}{exp_Pty_Buffer}; ------------------------------------------------------------- From: Andrew Suffield --- Expect.pm~ 2002-09-03 10:55:49.000000000 +0100 +++ Expect.pm 2002-09-03 12:36:59.000000000 +0100 @@ -178,6 +178,7 @@ # All the functions are written for reading from a tty, so if the naming # scheme looks odd, that's why. my ($class) = shift; + $class = ref($class) if ref($class); # so we can be called as $exp->exp_init() my($self) = shift; bless $self, $class; croak "exp_init not passed a file object, stopped" ------------------------------------------------------------- From: Andrew Suffield aps100@cyclone:~$ cat foo.pl use strict; use warnings; use Expect; my $exp =3D spawn Expect "cat"; exit 0; aps100@cyclone:~$ perl foo.pl aps100@cyclone:~$ echo $? 1 What is happening is that the DESTROY sub for Expect calls soft_close or hard_close, which in turn will call waitpid. waitpid places the exit code of the child that was reaped into $?. When exit has been called, $? contains the value the process will ultimately exit with. The practical result is that allowing any Expect objects to persist and only be garbage-collected at the end of the script, will cause the exit code of the script to be randomly altered. The solution is to modify sub DESTROY so that it preserves $?. --- Expect.pm.old 2002-09-14 12:10:13.000000000 +0100 +++ Expect.pm 2002-09-14 12:10:45.000000000 +0100 @@ -1575,10 +1575,12 @@ # clean up child processes sub DESTROY { my $self = shift; + my $exit = $?; if (${*$self}{exp_Do_Soft_Close}) { $self->soft_close(); } $self->hard_close(); + $? = $exit; } 1; ------------------------------------------------------------- From: Andrew Suffield soft_close and hard_close will loop waiting for the slave process to terminate. In order to keep the loop nice (prevent it consuming all available processing power) they contain "sleep 1" statements. Unfortunately, due to the slow speed at which signals are handled, the first loop will inevitably miss and so the process sleeps for a second - much longer than was necessary. The simplest solution is to use select and 0.01 seconds, which should be a more reasonable delay (it's still a very long time in processing terms - any non-zero delay is actually enough, with normal scheduling algorithms). --- Expect.pm.old 2002-09-15 22:57:44.000000000 +0100 +++ Expect.pm 2002-09-15 22:58:15.000000000 +0100 @@ -1356,7 +1356,7 @@ ${*$self}{exp_Exit} =3D $?; return ${*$self}{exp_Exit}; } - sleep 1; # Keep loop nice. + select undef, undef, undef, 0.01; } # Send it a term if it isn't dead. if (${*$self}{exp_Debug}) { @@ -1377,7 +1377,7 @@ ${*$self}{exp_Exit} =3D $?; return $?; } - sleep 1; + select undef, undef, undef, 0.01; } # Since this is a 'soft' close, sending it a -9 would be inappropriate. return undef; @@ -1411,7 +1411,7 @@ ${*$self}{exp_Exit} =3D $?; return ${*$self}{exp_Exit}; } - sleep 1; # Keep loop nice. + select undef, undef, undef, 0.01; } # Send it a term if it isn't dead. if (${*$self}{exp_Debug}) { @@ -1432,7 +1432,7 @@ ${*$self}{exp_Exit} =3D $?; return ${*$self}{exp_Exit}; } - sleep 1; + select undef, undef, undef, 0.01; } kill KILL =3D> ${*$self}{exp_Pid}; # wait 5 more seconds for it to die. @@ -1449,7 +1449,7 @@ ${*$self}{exp_Exit} =3D $?; return ${*$self}{exp_Exit}; } - sleep 1; + select undef, undef, undef, 0.01; } warn "Pid ${*$self}{exp_Pid} of ${*$self}{exp_Pty_Handle} is HUNG.\r\n"; ${*$self}{exp_Pid} =3D undef;