File Coverage

blib/lib/Expect.pm
Criterion Covered Total %
statement 637 1163 54.7
branch 215 534 40.2
condition 49 171 28.6
subroutine 35 46 76.0
pod 16 22 72.7
total 952 1936 49.1


line stmt bran cond sub pod time code
1             # -*-cperl-*-
2             # This module is copyrighted as per the usual perl legalese:
3             # Copyright (c) 1997 Austin Schutz.
4             # expect() interface & functionality enhancements (c) 1999 Roland Giersig.
5             #
6             # All rights reserved. This program is free software; you can
7             # redistribute it and/or modify it under the same terms as Perl
8             # itself.
9             #
10             # Don't blame/flame me if you bust your stuff.
11             # Austin Schutz
12             #
13             # This module now is maintained by
14             # Roland Giersig
15             #
16              
17 23     23   584401 use 5.006;
  23         48  
18              
19             package Expect;
20 23     23   71 use strict;
  23         36  
  23         336  
21 23     23   68 use warnings;
  23         68  
  23         501  
22              
23 23     23   9331 use IO::Pty 1.11; # We need make_slave_controlling_terminal()
  23         259673  
  23         856  
24 23     23   96 use IO::Tty;
  23         23  
  23         64  
25              
26 23     23   1206 use POSIX qw(:sys_wait_h :unistd_h); # For WNOHANG and isatty
  23         23  
  23         66  
27 23     23   23506 use Fcntl qw(:DEFAULT); # For checking file handle settings.
  23         40  
  23         4826  
28 23     23   94 use Carp qw(cluck croak carp confess);
  23         23  
  23         911  
29 23     23   71 use IO::Handle ();
  23         23  
  23         278  
30 23     23   112 use Exporter qw(import);
  23         8  
  23         429  
31 23     23   2256 use Errno;
  23         4945  
  23         2218  
32              
33             # This is necessary to make routines within Expect work.
34              
35             @Expect::ISA = qw(IO::Pty);
36             @Expect::EXPORT = qw(expect exp_continue exp_continue_timeout);
37              
38             BEGIN {
39 23     23   49 $Expect::VERSION = '1.33';
40              
41             # These are defaults which may be changed per object, or set as
42             # the user wishes.
43             # This will be unset, since the default behavior differs between
44             # spawned processes and initialized filehandles.
45             # $Expect::Log_Stdout = 1;
46 23         7 $Expect::Log_Group = 1;
47 23         19 $Expect::Debug = 0;
48 23         33 $Expect::Exp_Max_Accum = 0; # unlimited
49 23         32 $Expect::Exp_Internal = 0;
50 23         26 $Expect::IgnoreEintr = 0;
51 23         95 $Expect::Manual_Stty = 0;
52 23         22 $Expect::Multiline_Matching = 1;
53 23         21 $Expect::Do_Soft_Close = 0;
54 23         25 @Expect::Before_List = ();
55 23         18 @Expect::After_List = ();
56 23         18985 %Expect::Spawned_PIDs = ();
57             }
58              
59             sub version {
60 0     0 1 0 my ($version) = @_;
61              
62 0 0 0     0 warn "Version $version is later than $Expect::VERSION. It may not be supported"
63             if ( defined($version) && ( $version > $Expect::VERSION ) );
64              
65 0 0 0     0 die "Versions before 1.03 are not supported in this release"
66             if ( ( defined($version) ) && ( $version < 1.03 ) );
67 0         0 return $Expect::VERSION;
68             }
69              
70             sub new {
71 126     126 1 141285 my ($class, @args) = @_;
72              
73 126 50       392 $class = ref($class) if ref($class); # so we can be called as $exp->new()
74              
75             # Create the pty which we will use to pass process info.
76 126         1009 my ($self) = IO::Pty->new;
77 126 50       46755 die "$class: Could not assign a pty" unless $self;
78 126         282 bless $self => $class;
79 126         353 $self->autoflush(1);
80              
81             # This is defined here since the default is different for
82             # initialized handles as opposed to spawned processes.
83 126         1969 ${*$self}{exp_Log_Stdout} = 1;
  126         450  
84 126         394 $self->_init_vars();
85              
86 126 100       280 if (@args) {
87              
88             # we got add'l parms, so pass them to spawn
89 64         327 return $self->spawn(@args);
90             }
91 62         102 return $self;
92             }
93              
94             sub spawn {
95 126     126 1 17577 my ($class, @cmd) = @_;
96             # spawn is passed command line args.
97              
98 126         147 my $self;
99              
100 126 100       354 if ( ref($class) ) {
101 111         163 $self = $class;
102             } else {
103 15         45 $self = $class->new();
104             }
105              
106             croak "Cannot reuse an object with an already spawned command"
107 126 100       218 if exists ${*$self}{"exp_Command"};
  126         755  
108 125         236 ${*$self}{"exp_Command"} = \@cmd;
  125         382  
109              
110             # set up pipe to detect childs exec error
111 125 50       1561 pipe( FROM_CHILD, TO_PARENT ) or die "Cannot open pipe: $!";
112 125 50       981 pipe( FROM_PARENT, TO_CHILD ) or die "Cannot open pipe: $!";
113 125         762 TO_PARENT->autoflush(1);
114 125         3034 TO_CHILD->autoflush(1);
115 125         1840 eval { fcntl( TO_PARENT, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC ); };
  125         368  
116              
117 125         75872 my $pid = fork;
118              
119 125 50       1730 unless ( defined($pid) ) {
120 0 0       0 warn "Cannot fork: $!" if $^W;
121 0         0 return;
122             }
123              
124 125 100       1831 if ($pid) {
125              
126             # parent
127 108         205 my $errno;
128 108         223 ${*$self}{exp_Pid} = $pid;
  108         3639  
129 108         1796 close TO_PARENT;
130 108         1192 close FROM_PARENT;
131 108         3438 $self->close_slave();
132 108 100 66     9369 $self->set_raw() if $self->raw_pty and isatty($self);
133 108         3210 close TO_CHILD; # so child gets EOF and can go ahead
134              
135             # now wait for child exec (eof due to close-on-exit) or exec error
136 108         80633579 my $errstatus = sysread( FROM_CHILD, $errno, 256 );
137 108 50       787 die "Cannot sync with child: $!" if not defined $errstatus;
138 108         2498 close FROM_CHILD;
139 108 100       516 if ($errstatus) {
140 13         182 $! = $errno + 0;
141 13 50       169 warn "Cannot exec(@cmd): $!\n" if $^W;
142 13         377 return;
143             }
144             } else {
145              
146             # child
147 17         848 close FROM_CHILD;
148 17         278 close TO_CHILD;
149              
150 17         1663 $self->make_slave_controlling_terminal();
151 17 50       8981 my $slv = $self->slave()
152             or die "Cannot get slave: $!";
153              
154 17 100       710 $slv->set_raw() if $self->raw_pty;
155 17         1060 close($self);
156              
157             # wait for parent before we detach
158 17         52 my $buffer;
159 17         92 my $errstatus = sysread( FROM_PARENT, $buffer, 256 );
160 17 50       195 die "Cannot sync with parent: $!" if not defined $errstatus;
161 17         130 close FROM_PARENT;
162              
163 17         50 close(STDIN);
164 17 50       301 open( STDIN, "<&" . $slv->fileno() )
165             or die "Couldn't reopen STDIN for reading, $!\n";
166 17         505 close(STDOUT);
167 17 50       202 open( STDOUT, ">&" . $slv->fileno() )
168             or die "Couldn't reopen STDOUT for writing, $!\n";
169 17         482 close(STDERR);
170 17 50       109 open( STDERR, ">&" . $slv->fileno() )
171             or die "Couldn't reopen STDERR for writing, $!\n";
172              
173 17         340 { exec(@cmd) };
  17         0  
174 0         0 print TO_PARENT $! + 0;
175 0         0 die "Cannot exec(@cmd): $!\n";
176             }
177              
178             # This is sort of for code compatibility, and to make debugging a little
179             # easier. By code compatibility I mean that previously the process's
180             # handle was referenced by $process{Pty_Handle} instead of just $process.
181             # This is almost like 'naming' the handle to the process.
182             # I think this also reflects Tcl Expect-like behavior.
183 95         1533 ${*$self}{exp_Pty_Handle} = "spawn id(" . $self->fileno() . ")";
  95         1963  
184 95 50 33     299 if ( ( ${*$self}{"exp_Debug"} ) or ( ${*$self}{"exp_Exp_Internal"} ) ) {
  95         630  
  95         344  
185 0         0 cluck(
186             "Spawned '@cmd'\r\n",
187 0         0 "\t${*$self}{exp_Pty_Handle}\r\n",
188 0         0 "\tPid: ${*$self}{exp_Pid}\r\n",
189             "\tTty: " . $self->SUPER::ttyname() . "\r\n",
190             );
191             }
192 95         271 $Expect::Spawned_PIDs{ ${*$self}{exp_Pid} } = undef;
  95         377  
193 95         1060 return $self;
194             }
195              
196             sub exp_init {
197 0     0 1 0 my ($class, $self) = @_;
198              
199             # take a filehandle, for use later with expect() or interconnect() .
200             # All the functions are written for reading from a tty, so if the naming
201             # scheme looks odd, that's why.
202 0         0 bless $self, $class;
203 0 0       0 croak "exp_init not passed a file object, stopped"
204             unless defined( $self->fileno() );
205 0         0 $self->autoflush(1);
206              
207             # Define standard variables.. debug states, etc.
208 0         0 $self->_init_vars();
209              
210             # Turn of logging. By default we don't want crap from a file to get spewed
211             # on screen as we read it.
212 0         0 ${*$self}{exp_Log_Stdout} = 0;
  0         0  
213 0         0 ${*$self}{exp_Pty_Handle} = "handle id(" . $self->fileno() . ")";
  0         0  
214 0 0       0 ${*$self}{exp_Pty_Handle} = "STDIN" if $self->fileno() == fileno(STDIN);
  0         0  
215 0         0 print STDERR "Initialized ${*$self}{exp_Pty_Handle}.'\r\n"
216 0 0       0 if ${*$self}{"exp_Debug"};
  0         0  
217 0         0 return $self;
218             }
219              
220             # make an alias
221             *init = \&exp_init;
222              
223             ######################################################################
224             # We're happy OOP people. No direct access to stuff.
225             # For standard read-writeable parameters, we define some autoload magic...
226             my %Writeable_Vars = (
227             debug => 'exp_Debug',
228             exp_internal => 'exp_Exp_Internal',
229             do_soft_close => 'exp_Do_Soft_Close',
230             max_accum => 'exp_Max_Accum',
231             match_max => 'exp_Max_Accum',
232             notransfer => 'exp_NoTransfer',
233             log_stdout => 'exp_Log_Stdout',
234             log_user => 'exp_Log_Stdout',
235             log_group => 'exp_Log_Group',
236             manual_stty => 'exp_Manual_Stty',
237             restart_timeout_upon_receive => 'exp_Continue',
238             raw_pty => 'exp_Raw_Pty',
239             );
240             my %Readable_Vars = (
241             pid => 'exp_Pid',
242             exp_pid => 'exp_Pid',
243             exp_match_number => 'exp_Match_Number',
244             match_number => 'exp_Match_Number',
245             exp_error => 'exp_Error',
246             error => 'exp_Error',
247             exp_command => 'exp_Command',
248             command => 'exp_Command',
249             exp_match => 'exp_Match',
250             match => 'exp_Match',
251             exp_matchlist => 'exp_Matchlist',
252             matchlist => 'exp_Matchlist',
253             exp_before => 'exp_Before',
254             before => 'exp_Before',
255             exp_after => 'exp_After',
256             after => 'exp_After',
257             exp_exitstatus => 'exp_Exit',
258             exitstatus => 'exp_Exit',
259             exp_pty_handle => 'exp_Pty_Handle',
260             pty_handle => 'exp_Pty_Handle',
261             exp_logfile => 'exp_Log_File',
262             logfile => 'exp_Log_File',
263             %Writeable_Vars,
264             );
265              
266             sub AUTOLOAD {
267 324     324   20711 my ($self, @args) = @_;
268              
269 324 50       938 my $type = ref($self)
270             or croak "$self is not an object";
271              
272 23     23   91 use vars qw($AUTOLOAD);
  23         23  
  23         77228  
273 324         441 my $name = $AUTOLOAD;
274 324         3102 $name =~ s/.*:://; # strip fully-qualified portion
275              
276 324 50       1193 unless ( exists $Readable_Vars{$name} ) {
277 0         0 croak "ERROR: cannot find method `$name' in class $type";
278             }
279 324         779 my $varname = $Readable_Vars{$name};
280 324         287 my $tmp;
281 324 100       256 $tmp = ${*$self}{$varname} if exists ${*$self}{$varname};
  196         320  
  324         1033  
282              
283 324 100       685 if (@args) {
284 76 50       248 if ( exists $Writeable_Vars{$name} ) {
285 76         177 my $ref = ref($tmp);
286 76 50       278 if ( $ref eq 'ARRAY' ) {
    50          
287 0         0 ${*$self}{$varname} = [@args];
  0         0  
288             } elsif ( $ref eq 'HASH' ) {
289 0         0 ${*$self}{$varname} = {@args};
  0         0  
290             } else {
291 76         98 ${*$self}{$varname} = shift @args;
  76         225  
292             }
293             } else {
294 0 0       0 carp "Trying to set read-only variable `$name'"
295             if $^W;
296             }
297             }
298              
299 324         694 my $ref = ref($tmp);
300 324 50       698 return ( wantarray ? @{$tmp} : $tmp ) if ( $ref eq 'ARRAY' );
  6 100       40  
301 318 0       688 return ( wantarray ? %{$tmp} : $tmp ) if ( $ref eq 'HASH' );
  0 50       0  
302 318         2697 return $tmp;
303             }
304              
305             ######################################################################
306              
307             sub set_seq {
308 0     0 1 0 my ( $self, $escape_sequence, $function, $params, @args ) = @_;
309              
310             # Set an escape sequence/function combo for a read handle for interconnect.
311             # Ex: $read_handle->set_seq('',\&function,\@parameters);
312 0         0 ${ ${*$self}{exp_Function} }{$escape_sequence} = $function;
  0         0  
  0         0  
313 0 0 0     0 if ( ( !defined($function) ) || ( $function eq 'undef' ) ) {
314 0         0 ${ ${*$self}{exp_Function} }{$escape_sequence} = \&_undef;
  0         0  
  0         0  
315             }
316 0         0 ${ ${*$self}{exp_Parameters} }{$escape_sequence} = $params;
  0         0  
  0         0  
317              
318             # This'll be a joy to execute. :)
319 0 0       0 if ( ${*$self}{"exp_Debug"} ) {
  0         0  
320 0         0 print STDERR "Escape seq. '" . $escape_sequence;
321 0         0 print STDERR "' function for ${*$self}{exp_Pty_Handle} set to '";
  0         0  
322 0         0 print STDERR ${ ${*$self}{exp_Function} }{$escape_sequence};
  0         0  
  0         0  
323 0         0 print STDERR "(" . join( ',', @args ) . ")'\r\n";
324             }
325             }
326              
327             sub set_group {
328 0     0 1 0 my ($self, @args) = @_;
329              
330             # Make sure we can read from the read handle
331 0 0       0 if ( !defined( $args[0] ) ) {
332 0 0       0 if ( defined( ${*$self}{exp_Listen_Group} ) ) {
  0         0  
333 0         0 return @{ ${*$self}{exp_Listen_Group} };
  0         0  
  0         0  
334             } else {
335              
336             # Refrain from referencing an undef
337 0         0 return;
338             }
339             }
340 0         0 @{ ${*$self}{exp_Listen_Group} } = ();
  0         0  
  0         0  
341 0 0       0 if ( $self->_get_mode() !~ 'r' ) {
342 0         0 warn(
343 0         0 "Attempting to set a handle group on ${*$self}{exp_Pty_Handle}, ",
344             "a non-readable handle!\r\n"
345             );
346             }
347 0         0 while ( my $write_handle = shift @args ) {
348 0 0       0 if ( $write_handle->_get_mode() !~ 'w' ) {
349 0         0 warn(
350             "Attempting to set a non-writeable listen handle ",
351 0         0 "${*$write_handle}{exp_Pty_handle} for ",
352 0         0 "${*$self}{exp_Pty_Handle}!\r\n"
353             );
354             }
355 0         0 push( @{ ${*$self}{exp_Listen_Group} }, $write_handle );
  0         0  
  0         0  
356             }
357             }
358              
359             sub log_file {
360 65     65 1 19586 my ($self, $file, $mode) = @_;
361 65   100     425 $mode ||= "a";
362              
363 0         0 return ( ${*$self}{exp_Log_File} )
364 65 50       176 if @_ < 2; # we got no param, return filehandle
365             # $e->log_file(undef) is an acceptable call hence we need to check the number of parameters here
366              
367 65 100 100     76 if ( ${*$self}{exp_Log_File} and ref( ${*$self}{exp_Log_File} ) ne 'CODE' ) {
  65         293  
  25         127  
368 9         36 close( ${*$self}{exp_Log_File} );
  9         182  
369             }
370 65         112 ${*$self}{exp_Log_File} = undef;
  65         112  
371 65 100       247 return if ( not $file );
372 39         66 my $fh = $file;
373 39 100       103 if ( not ref($file) ) {
374              
375             # it's a filename
376 23 50       298 $fh = IO::File->new( $file, $mode )
377             or croak "Cannot open logfile $file: $!";
378             }
379 39 100       121295 if ( ref($file) ne 'CODE' ) {
380 23 50       241 croak "Given logfile doesn't have a 'print' method"
381             if not $fh->can("print");
382 23         154 $fh->autoflush(1); # so logfile is up to date
383             }
384              
385 39         1063 ${*$self}{exp_Log_File} = $fh;
  39         83  
386              
387 39         84 return $fh;
388             }
389              
390             # I'm going to leave this here in case I might need to change something.
391             # Previously this was calling `stty`, in a most bastardized manner.
392             sub exp_stty {
393 0     0 0 0 my ($self) = shift;
394 0         0 my ($mode) = "@_";
395              
396 0 0       0 return unless defined $mode;
397 0 0       0 if ( not defined $INC{"IO/Stty.pm"} ) {
398 0         0 carp "IO::Stty not installed, cannot change mode";
399 0         0 return;
400             }
401              
402 0 0       0 if ( ${*$self}{"exp_Debug"} ) {
  0         0  
403 0         0 print STDERR "Setting ${*$self}{exp_Pty_Handle} to tty mode '$mode'\r\n";
  0         0  
404             }
405 0 0       0 unless ( POSIX::isatty($self) ) {
406 0 0 0     0 if ( ${*$self}{"exp_Debug"} or $^W ) {
  0         0  
407 0         0 warn "${*$self}{exp_Pty_Handle} is not a tty. Not changing mode";
  0         0  
408             }
409 0         0 return ''; # No undef to avoid warnings elsewhere.
410             }
411 0         0 IO::Stty::stty( $self, split( /\s/, $mode ) );
412             }
413              
414             *stty = \&exp_stty;
415              
416             # If we want to clear the buffer. Otherwise Accum will grow during send_slow
417             # etc. and contain the remainder after matches.
418             sub clear_accum {
419 39     39 1 841 my ($self) = @_;
420 39         82 return $self->set_accum('');
421             }
422              
423             sub set_accum {
424 57     57 1 103 my ($self, $accum) = @_;
425              
426 57         41 my $old_accum = ${*$self}{exp_Accum};
  57         122  
427 57         68 ${*$self}{exp_Accum} = $accum;
  57         99  
428              
429             # return the contents of the accumulator.
430 57         176 return $old_accum;
431             }
432             sub get_accum {
433 1     1 0 2 my ($self) = @_;
434 1         1 return ${*$self}{exp_Accum};
  1         6  
435             }
436              
437             ######################################################################
438             # define constants for pattern subs
439 9713     9713 0 35347 sub exp_continue {"exp_continue"}
440 4772     4772 0 9426 sub exp_continue_timeout {"exp_continue_timeout"}
441              
442             ######################################################################
443             # Expect on multiple objects at once.
444             #
445             # Call as Expect::expect($timeout, -i => \@exp_list, @patternlist,
446             # -i => $exp, @pattern_list, ...);
447             # or $exp->expect($timeout, @patternlist, -i => \@exp_list, @patternlist,
448             # -i => $exp, @pattern_list, ...);
449             #
450             # Patterns are arrays that consist of
451             # [ $pattern_type, $pattern, $sub, @subparms ]
452             #
453             # Optional $pattern_type is '-re' (RegExp, default) or '-ex' (exact);
454             #
455             # $sub is optional CODE ref, which is called as &{$sub}($exp, @subparms)
456             # if pattern matched; may return exp_continue or exp_continue_timeout.
457             #
458             # Old-style syntax (pure pattern strings with optional type) also supported.
459             #
460              
461             sub expect {
462 4811     4811 1 54077794 my $self;
463              
464 4811 50       7578 print STDERR ("expect(@_) called...\n") if $Expect::Debug;
465 4811 50       7192 if ( defined( $_[0] ) ) {
466 4811 50 33     24006 if ( ref( $_[0] ) and $_[0]->isa('Expect') ) {
    0          
467 4811         4596 $self = shift;
468             } elsif ( $_[0] eq 'Expect' ) {
469 0         0 shift; # or as Expect->expect
470             }
471             }
472 4811 50       6589 croak "expect(): not enough arguments, should be expect(timeout, [patterns...])"
473             if @_ < 1;
474 4811         3326 my $timeout = shift;
475 4811         3613 my $timeout_hook = undef;
476              
477 4811         3955 my @object_list;
478             my %patterns;
479              
480 0         0 my @pattern_list;
481 0         0 my @timeout_list;
482 0         0 my $curr_list;
483              
484 4811 50       5204 if ($self) {
485 4811         5786 $curr_list = [$self];
486             } else {
487              
488             # called directly, so first parameter must be '-i' to establish
489             # object list.
490 0         0 $curr_list = [];
491 0 0       0 croak
492             "expect(): ERROR: if called directly (not as \$obj->expect(...), but as Expect::expect(...), first parameter MUST be '-i' to set an object (list) for the patterns to work on."
493             if ( $_[0] ne '-i' );
494             }
495              
496             # Let's make a list of patterns wanting to be evaled as regexps.
497 4811         3409 my $parm;
498 4811         3898 my $parm_nr = 1;
499 4811         7021 while ( defined( $parm = shift ) ) {
500 14323 50       15632 print STDERR ("expect(): handling param '$parm'...\n")
501             if $Expect::Debug;
502 14323 100       14476 if ( ref($parm) ) {
503 14214 50       14968 if ( ref($parm) eq 'ARRAY' ) {
504 14214         16440 my $err = _add_patterns_to_list(
505             \@pattern_list, \@timeout_list,
506             $parm_nr, $parm
507             );
508 14214 50       19080 carp(
509             "expect(): Warning: multiple `timeout' patterns (",
510             scalar(@timeout_list), ").\r\n"
511             ) if @timeout_list > 1;
512 14214 100       18127 $timeout_hook = $timeout_list[-1] if $timeout_list[-1];
513 14214 50       15195 croak $err if $err;
514 14214         21611 $parm_nr++;
515             } else {
516 0         0 croak("expect(): Unknown pattern ref $parm");
517             }
518             } else {
519              
520             # not a ref, is an option or raw pattern
521 109 100       247 if ( substr( $parm, 0, 1 ) eq '-' ) {
522              
523             # it's an option
524 21 50       70 print STDERR ("expect(): handling option '$parm'...\n")
525             if $Expect::Debug;
526 21 50 33     155 if ( $parm eq '-i' ) {
    50          
527              
528             # first add collected patterns to object list
529 0 0       0 if ( scalar(@$curr_list) ) {
530             push @object_list, $curr_list
531 0 0       0 if not exists $patterns{"$curr_list"};
532 0         0 push @{ $patterns{"$curr_list"} }, @pattern_list;
  0         0  
533 0         0 @pattern_list = ();
534             }
535              
536             # now put parm(s) into current object list
537 0 0       0 if ( ref( $_[0] ) eq 'ARRAY' ) {
538 0         0 $curr_list = shift;
539             } else {
540 0         0 $curr_list = [shift];
541             }
542             } elsif ( $parm eq '-re'
543             or $parm eq '-ex' )
544             {
545 21 50       62 if ( ref( $_[1] ) eq 'CODE' ) {
546 0         0 push @pattern_list, [ $parm_nr, $parm, shift, shift ];
547             } else {
548 21         71 push @pattern_list, [ $parm_nr, $parm, shift, undef ];
549             }
550 21         66 $parm_nr++;
551             } else {
552 0         0 croak("Unknown option $parm");
553             }
554             } else {
555              
556             # a plain pattern, check if it is followed by a CODE ref
557 88 50       134 if ( ref( $_[0] ) eq 'CODE' ) {
558 0 0       0 if ( $parm eq 'timeout' ) {
    0          
559 0         0 push @timeout_list, shift;
560 0 0       0 carp(
561             "expect(): Warning: multiple `timeout' patterns (",
562             scalar(@timeout_list),
563             ").\r\n"
564             ) if @timeout_list > 1;
565 0 0       0 $timeout_hook = $timeout_list[-1] if $timeout_list[-1];
566             } elsif ( $parm eq 'eof' ) {
567 0         0 push @pattern_list, [ $parm_nr, "-$parm", undef, shift ];
568             } else {
569 0         0 push @pattern_list, [ $parm_nr, '-ex', $parm, shift ];
570             }
571             } else {
572 88 50       143 print STDERR ("expect(): exact match '$parm'...\n")
573             if $Expect::Debug;
574 88         258 push @pattern_list, [ $parm_nr, '-ex', $parm, undef ];
575             }
576 88         189 $parm_nr++;
577             }
578             }
579             }
580              
581             # add rest of collected patterns to object list
582 4811 50       6100 carp "expect(): Empty object list" unless $curr_list;
583 4811 50       9471 push @object_list, $curr_list if not exists $patterns{"$curr_list"};
584 4811         3154 push @{ $patterns{"$curr_list"} }, @pattern_list;
  4811         11728  
585              
586 4811 50       5458 my $debug = $self ? ${*$self}{exp_Debug} : $Expect::Debug;
  4811         7953  
587 4811 50       5680 my $internal = $self ? ${*$self}{exp_Exp_Internal} : $Expect::Exp_Internal;
  4811         4683  
588              
589             # now start matching...
590              
591 4811 50       6964 if (@Expect::Before_List) {
592 0 0 0     0 print STDERR ("Starting BEFORE pattern matching...\r\n")
593             if ( $debug or $internal );
594 0         0 _multi_expect( 0, undef, @Expect::Before_List );
595             }
596              
597 4811 50 33     14198 cluck("Starting EXPECT pattern matching...\r\n")
598             if ( $debug or $internal );
599 4811         3051 my @ret;
600             @ret = _multi_expect(
601             $timeout, $timeout_hook,
602 4811         5011 map { [ $_, @{ $patterns{"$_"} } ] } @object_list
  4811         3082  
  4811         13242  
603             );
604              
605 4811 50       10670 if (@Expect::After_List) {
606 0 0 0     0 print STDERR ("Starting AFTER pattern matching...\r\n")
607             if ( $debug or $internal );
608 0         0 _multi_expect( 0, undef, @Expect::After_List );
609             }
610              
611 4811 50       17505 return wantarray ? @ret : $ret[0];
612             }
613              
614             ######################################################################
615             # the real workhorse
616             #
617             sub _multi_expect {
618 4811     4811   5117 my ($timeout, $timeout_hook, @params) = @_;
619              
620 4811 100       6500 if ($timeout_hook) {
621 4720 50 33     15058 croak "Unknown timeout_hook type $timeout_hook"
622             unless ( ref($timeout_hook) eq 'CODE'
623             or ref($timeout_hook) eq 'ARRAY' );
624             }
625              
626 4811         4946 foreach my $pat (@params) {
627 4811         3928 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  4811         5948  
  4811         4843  
628 4811         4116 foreach my $exp ( @{ $pat->[0] } ) {
  4811         5506  
629 4811         3115 ${*$exp}{exp_New_Data} = 1; # first round we always try to match
  4811         6461  
630 4811 50 33     3437 if ( exists ${*$exp}{"exp_Max_Accum"}
  4811         8635  
631 4811         7990 and ${*$exp}{"exp_Max_Accum"} )
632             {
633 0         0 ${*$exp}{exp_Accum} = $exp->_trim_length(
634 0         0 ${*$exp}{exp_Accum},
635 0         0 ${*$exp}{exp_Max_Accum}
636 0         0 );
637             }
638 4811 0       6081 print STDERR (
    50          
639 0         0 "${*$exp}{exp_Pty_Handle}: beginning expect.\r\n",
640             "\tTimeout: ",
641             ( defined($timeout) ? $timeout : "unlimited" ),
642             " seconds.\r\n",
643             "\tCurrent time: " . localtime() . "\r\n",
644             ) if $Expect::Debug;
645              
646             # What are we expecting? What do you expect? :-)
647 4811 50       2986 if ( ${*$exp}{exp_Exp_Internal} ) {
  4811         9944  
648 0         0 print STDERR "${*$exp}{exp_Pty_Handle}: list of patterns:\r\n";
  0         0  
649 0         0 foreach my $pattern (@patterns) {
650 0 0       0 print STDERR (
651             ' ',
652             defined( $pattern->[0] )
653             ? '#' . $pattern->[0] . ': '
654             : '',
655             $pattern->[1],
656             " `",
657             _make_readable( $pattern->[2] ),
658             "'\r\n"
659             );
660             }
661 0         0 print STDERR "\r\n";
662             }
663             }
664             }
665              
666 4811         3270 my $successful_pattern;
667             my $exp_matched;
668 0         0 my $err;
669 0         0 my $before;
670 0         0 my $after;
671 0         0 my $match;
672 0         0 my @matchlist;
673              
674             # Set the last loop time to now for time comparisons at end of loop.
675 4811         3604 my $start_loop_time = time();
676 4811         3393 my $exp_cont = 1;
677              
678             READLOOP:
679 4811         6152 while ($exp_cont) {
680 9642         6721 $exp_cont = 1;
681 9642         7739 $err = "";
682 9642         6299 my $rmask = '';
683 9642         7246 my $time_left = undef;
684 9642 50       12075 if ( defined $timeout ) {
685 9642         8992 $time_left = $timeout - ( time() - $start_loop_time );
686 9642 50       11693 $time_left = 0 if $time_left < 0;
687             }
688              
689 9642         6251 $exp_matched = undef;
690              
691             # Test for a match first so we can test the current Accum w/out
692             # worrying about an EOF.
693              
694 9642         8523 foreach my $pat (@params) {
695 9642         7053 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  9642         12272  
  9642         9216  
696 9642         7206 foreach my $exp ( @{ $pat->[0] } ) {
  9642         11715  
697              
698             # build mask for select in next section...
699 9642         18580 my $fn = $exp->fileno();
700 9642 50       43636 vec( $rmask, $fn, 1 ) = 1 if defined $fn;
701              
702 9642 100       8949 next unless ${*$exp}{exp_New_Data};
  9642         19120  
703              
704             # clear error status
705 9598         7151 ${*$exp}{exp_Error} = undef;
  9598         8864  
706 9598         6052 ${*$exp}{exp_After} = undef;
  9598         8495  
707 9598         5771 ${*$exp}{exp_Match_Number} = undef;
  9598         7888  
708 9598         6388 ${*$exp}{exp_Match} = undef;
  9598         8429  
709              
710             # This could be huge. We should attempt to do something
711             # about this. Because the output is used for debugging
712             # I'm of the opinion that showing smaller amounts if the
713             # total is huge should be ok.
714             # Thus the 'trim_length'
715             print STDERR (
716 0         0 "\r\n${*$exp}{exp_Pty_Handle}: Does `",
717 0         0 $exp->_trim_length( _make_readable( ${*$exp}{exp_Accum} ) ),
718             "'\r\nmatch:\r\n"
719 9598 50       6979 ) if ${*$exp}{exp_Exp_Internal};
  9598         13712  
720              
721             # we don't keep the parameter number anymore
722             # (clashes with before & after), instead the parameter number is
723             # stored inside the pattern; we keep the pattern ref
724             # and look up the number later.
725 9598         9410 foreach my $pattern (@patterns) {
726             print STDERR (
727             " pattern",
728             defined( $pattern->[0] ) ? ' #' . $pattern->[0] : '',
729             ": ",
730             $pattern->[1],
731             " `",
732             _make_readable( $pattern->[2] ),
733             "'? "
734 14396 0       7987 ) if ( ${*$exp}{exp_Exp_Internal} );
  14396 50       21621  
735              
736             # Matching exactly
737 14396 100       25858 if ( $pattern->[1] eq '-ex' ) {
    100          
738             my $match_index =
739 119         80 index( ${*$exp}{exp_Accum}, $pattern->[2] );
  119         265  
740              
741             # We matched if $match_index > -1
742 119 100       209 if ( $match_index > -1 ) {
743             $before =
744 29         29 substr( ${*$exp}{exp_Accum}, 0, $match_index );
  29         59  
745             $match = substr(
746 29         58 ${*$exp}{exp_Accum},
747 29         85 $match_index, length( $pattern->[2] )
748             );
749             $after = substr(
750 29         72 ${*$exp}{exp_Accum},
751 29         44 $match_index + length( $pattern->[2] )
752             );
753 29         18 ${*$exp}{exp_Before} = $before;
  29         59  
754 29         43 ${*$exp}{exp_Match} = $match;
  29         58  
755 29         43 ${*$exp}{exp_After} = $after;
  29         43  
756 29         71 ${*$exp}{exp_Match_Number} = $pattern->[0];
  29         58  
757 29         43 $exp_matched = $exp;
758             }
759             } elsif ( $pattern->[1] eq '-re' ) {
760              
761 9595 100       10248 if ($Expect::Multiline_Matching) {
762             @matchlist =
763 9581         5996 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m);
  9581         110057  
764             } else {
765             @matchlist =
766 14         12 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/);
  14         226  
767             }
768 9595 100       16452 if (@matchlist) {
769              
770             # Matching regexp
771 4798         4494 $match = shift @matchlist;
772 4798         3200 my $start = index ${*$exp}{exp_Accum}, $match;
  4798         8823  
773 4798 50       7128 die 'The match could not be found' if $start == -1;
774 4798         3102 $before = substr ${*$exp}{exp_Accum}, 0, $start;
  4798         6660  
775 4798         4231 $after = substr ${*$exp}{exp_Accum}, $start + length($match);
  4798         6154  
776              
777 4798         3530 ${*$exp}{exp_Before} = $before;
  4798         5266  
778 4798         5503 ${*$exp}{exp_Match} = $match;
  4798         4794  
779 4798         3373 ${*$exp}{exp_After} = $after;
  4798         4408  
780             #pop @matchlist; # remove kludged empty bracket from end
781 4798         3936 @{ ${*$exp}{exp_Matchlist} } = @matchlist;
  4798         3173  
  4798         7021  
782 4798         3933 ${*$exp}{exp_Match_Number} = $pattern->[0];
  4798         4693  
783 4798         4334 $exp_matched = $exp;
784             }
785             } else {
786              
787             # 'timeout' or 'eof'
788             }
789              
790 14396 100       18525 if ($exp_matched) {
791 4782         5550 ${*$exp}{exp_Accum} = $after
792 4827 100       3054 unless ${*$exp}{exp_NoTransfer};
  4827         8338  
793             print STDERR "YES!!\r\n"
794 4827 50       3527 if ${*$exp}{exp_Exp_Internal};
  4827         7221  
795             print STDERR (
796             " Before match string: `",
797             $exp->_trim_length( _make_readable( ($before) ) ),
798             "'\r\n",
799             " Match string: `",
800             _make_readable($match),
801             "'\r\n",
802             " After match string: `",
803             $exp->_trim_length( _make_readable( ($after) ) ),
804             "'\r\n",
805             " Matchlist: (",
806             join(
807             ", ",
808 0         0 map { "`" . $exp->_trim_length( _make_readable( ($_) ) ) . "'" } @matchlist,
809             ),
810             ")\r\n",
811 4827 50       2979 ) if ( ${*$exp}{exp_Exp_Internal} );
  4827         6908  
812              
813             # call hook function if defined
814 4827 100       7187 if ( $pattern->[3] ) {
815             print STDERR (
816             "Calling hook $pattern->[3]...\r\n",
817             )
818 4778         10915 if ( ${*$exp}{exp_Exp_Internal}
819 4778 50 33     2917 or $Expect::Debug );
820 4778 50       3111 if ( $#{$pattern} > 3 ) {
  4778         7876  
821              
822             # call with parameters if given
823 0         0 $exp_cont = &{ $pattern->[3] }( $exp, @{$pattern}[ 4 .. $#{$pattern} ] );
  0         0  
  0         0  
  0         0  
824             } else {
825 4778         3174 $exp_cont = &{ $pattern->[3] }($exp);
  4778         8984  
826             }
827             }
828 4827 100 66     17164 if ( $exp_cont and $exp_cont eq exp_continue ) {
    50 33        
829             print STDERR ("Continuing expect, restarting timeout...\r\n")
830 64         374 if ( ${*$exp}{exp_Exp_Internal}
831 64 50 33     100 or $Expect::Debug );
832 64         57 $start_loop_time = time(); # restart timeout count
833 64         220 next READLOOP;
834             } elsif ( $exp_cont
835             and $exp_cont eq exp_continue_timeout )
836             {
837             print STDERR ("Continuing expect...\r\n")
838 0         0 if ( ${*$exp}{exp_Exp_Internal}
839 0 0 0     0 or $Expect::Debug );
840 0         0 next READLOOP;
841             }
842 4763         8609 last READLOOP;
843             }
844 9569 50       6170 print STDERR "No.\r\n" if ${*$exp}{exp_Exp_Internal};
  9569         18180  
845             }
846 4771 50       3085 print STDERR "\r\n" if ${*$exp}{exp_Exp_Internal};
  4771         6686  
847              
848             # don't have to match again until we get new data
849 4771         3453 ${*$exp}{exp_New_Data} = 0;
  4771         7718  
850             }
851             } # End of matching section
852              
853             # No match, let's see what is pending on the filehandles...
854 4815 0 33     10476 print STDERR (
    50          
855             "Waiting for new data (",
856             defined($time_left) ? $time_left : 'unlimited',
857             " seconds)...\r\n",
858             ) if ( $Expect::Exp_Internal or $Expect::Debug );
859 4815         3209 my $nfound;
860             SELECT: {
861 4815         3022 $nfound = select( $rmask, undef, undef, $time_left );
  4815         92202445  
862 4815 50       7603 if ( $nfound < 0 ) {
863 0 0 0     0 if ( $!{EINTR} and $Expect::IgnoreEintr ) {
864 0 0 0     0 print STDERR ("ignoring EINTR, restarting select()...\r\n")
865             if ( $Expect::Exp_Internal or $Expect::Debug );
866 0         0 next SELECT;
867             }
868 0 0 0     0 print STDERR ("select() returned error code '$!'\r\n")
869             if ( $Expect::Exp_Internal or $Expect::Debug );
870              
871             # returned error
872 0         0 $err = "4:$!";
873 0         0 last READLOOP;
874             }
875             }
876              
877             # go until we don't find something (== timeout).
878 4815 100       9545 if ( $nfound == 0 ) {
879              
880             # No pattern, no EOF. Did we time out?
881 69         470 $err = "1:TIMEOUT";
882 69         347 foreach my $pat (@params) {
883 69         143 foreach my $exp ( @{ $pat->[0] } ) {
  69         364  
884 69         142 $before = ${*$exp}{exp_Before} = ${*$exp}{exp_Accum};
  69         390  
  69         685  
885 69 50       986 next if not defined $exp->fileno(); # skip already closed
886 69 100       742 ${*$exp}{exp_Error} = $err unless ${*$exp}{exp_Error};
  36         152  
  69         357  
887             }
888             }
889 69 50 33     584 print STDERR ("TIMEOUT\r\n")
890             if ( $Expect::Debug or $Expect::Exp_Internal );
891 69 100       195 if ($timeout_hook) {
892 46         70 my $ret;
893 46 50 33     223 print STDERR ("Calling timeout function $timeout_hook...\r\n")
894             if ( $Expect::Debug or $Expect::Exp_Internal );
895 46 50       206 if ( ref($timeout_hook) eq 'CODE' ) {
896 0         0 $ret = &{$timeout_hook}( $params[0]->[0] );
  0         0  
897             } else {
898 46 50       35 if ( $#{$timeout_hook} > 3 ) {
  46         136  
899 0         0 $ret = &{ $timeout_hook->[3] }(
900             $params[0]->[0],
901 0         0 @{$timeout_hook}[ 4 .. $#{$timeout_hook} ]
  0         0  
  0         0  
902             );
903             } else {
904 46         81 $ret = &{ $timeout_hook->[3] }( $params[0]->[0] );
  46         331  
905             }
906             }
907 46 100 66     207 if ( $ret and $ret eq exp_continue ) {
908 44         110 $start_loop_time = time(); # restart timeout count
909 44         275 next READLOOP;
910             }
911             }
912 25         158 last READLOOP;
913             }
914              
915 4746         16183 my @bits = split( //, unpack( 'b*', $rmask ) );
916 4746         6284 foreach my $pat (@params) {
917 4746         3060 foreach my $exp ( @{ $pat->[0] } ) {
  4746         6047  
918 4746 50       9435 next if not defined $exp->fileno(); # skip already closed
919 4746 50       19871 if ( $bits[ $exp->fileno() ] ) {
920 4746 50       15587 print STDERR ("${*$exp}{exp_Pty_Handle}: new data.\r\n")
  0         0  
921             if $Expect::Debug;
922              
923             # read in what we found.
924 4746         3231 my $buffer;
925 4746         14413 my $nread = sysread( $exp, $buffer, 2048 );
926              
927             # Make errors (nread undef) show up as EOF.
928 4746 100       6342 $nread = 0 unless defined($nread);
929              
930 4746 100       5677 if ( $nread == 0 ) {
931 23 50       37 print STDERR ("${*$exp}{exp_Pty_Handle}: EOF\r\n")
  0         0  
932             if ($Expect::Debug);
933 23         97 $before = ${*$exp}{exp_Before} = $exp->clear_accum();
  23         41  
934 23         23 $err = "2:EOF";
935 23         23 ${*$exp}{exp_Error} = $err;
  23         46  
936 23         23 ${*$exp}{exp_Has_EOF} = 1;
  23         60  
937 23         23 $exp_cont = undef;
938 23         46 foreach my $eof_pat ( grep { $_->[1] eq '-eof' } @{$pat}[ 1 .. $#{$pat} ] ) {
  41         78  
  23         46  
  23         23  
939 9         45 my $ret;
940 9 50       144 print STDERR ( "Calling EOF hook $eof_pat->[3]...\r\n", )
941             if ($Expect::Debug);
942 9 50       18 if ( $#{$eof_pat} > 3 ) {
  9         36  
943              
944             # call with parameters if given
945 0         0 $ret = &{ $eof_pat->[3] }( $exp, @{$eof_pat}[ 4 .. $#{$eof_pat} ] );
  0         0  
  0         0  
  0         0  
946             } else {
947 9         18 $ret = &{ $eof_pat->[3] }($exp);
  9         18  
948             }
949 9 50 33     81 if ($ret
      33        
950             and ( $ret eq exp_continue
951             or $ret eq exp_continue_timeout )
952             )
953             {
954 0         0 $exp_cont = $ret;
955             }
956             }
957              
958             # is it dead?
959 23 50       23 if ( defined( ${*$exp}{exp_Pid} ) ) {
  23         60  
960             my $ret =
961 23         37 waitpid( ${*$exp}{exp_Pid}, POSIX::WNOHANG );
  23         826  
962 23 50       46 if ( $ret == ${*$exp}{exp_Pid} ) {
  23         111  
963             printf STDERR (
964             "%s: exit(0x%02X)\r\n",
965 23 50       79 ${*$exp}{exp_Pty_Handle}, $?
  0         0  
966             ) if ($Expect::Debug);
967 23         79 $err = "3:Child PID ${*$exp}{exp_Pid} exited with status $?";
  23         157  
968 23         51 ${*$exp}{exp_Error} = $err;
  23         74  
969 23         37 ${*$exp}{exp_Exit} = $?;
  23         60  
970 23         60 delete $Expect::Spawned_PIDs{ ${*$exp}{exp_Pid} };
  23         78  
971 23         37 ${*$exp}{exp_Pid} = undef;
  23         60  
972             }
973             }
974 23 50       74 print STDERR ("${*$exp}{exp_Pty_Handle}: closing...\r\n")
  0         0  
975             if ($Expect::Debug);
976 23         157 $exp->hard_close();
977 23         69 next;
978             }
979 4723 50       5517 print STDERR ("${*$exp}{exp_Pty_Handle}: read $nread byte(s).\r\n")
  0         0  
980             if ($Expect::Debug);
981              
982             # ugly hack for broken solaris ttys that spew
983             # into our pretty output
984 4723 100       2903 $buffer =~ s/ \cH//g if not ${*$exp}{exp_Raw_Pty};
  4723         10497  
985              
986             # Append it to the accumulator.
987 4723         3709 ${*$exp}{exp_Accum} .= $buffer;
  4723         8078  
988 4723 50 33     3266 if ( exists ${*$exp}{exp_Max_Accum}
  4723         8010  
989 4723         7156 and ${*$exp}{exp_Max_Accum} )
990             {
991 0         0 ${*$exp}{exp_Accum} = $exp->_trim_length(
992 0         0 ${*$exp}{exp_Accum},
993 0         0 ${*$exp}{exp_Max_Accum}
994 0         0 );
995             }
996 4723         4040 ${*$exp}{exp_New_Data} = 1; # next round we try to match again
  4723         4200  
997              
998             $exp_cont = exp_continue
999 4723         7041 if ( exists ${*$exp}{exp_Continue}
1000 4723 0 33     3420 and ${*$exp}{exp_Continue} );
  0         0  
1001              
1002             # Now propagate what we have read to other listeners...
1003 4723         7947 $exp->_print_handles($buffer);
1004              
1005             # End handle reading section.
1006             }
1007             }
1008             } # end read loop
1009             $start_loop_time = time() # restart timeout count
1010 4746 50 66     10173 if ( $exp_cont and $exp_cont eq exp_continue );
1011             }
1012              
1013             # End READLOOP
1014              
1015             # Post loop. Do we have anything?
1016             # Tell us status
1017 4811 50 33     10066 if ( $Expect::Debug or $Expect::Exp_Internal ) {
1018 0 0       0 if ($exp_matched) {
1019             print STDERR (
1020             "Returning from expect ",
1021 0         0 ${*$exp_matched}{exp_Error} ? 'un' : '',
1022             "successfully.",
1023 0         0 ${*$exp_matched}{exp_Error}
1024 0 0       0 ? "\r\n Error: ${*$exp_matched}{exp_Error}."
  0 0       0  
1025             : '',
1026             "\r\n"
1027             );
1028             } else {
1029 0         0 print STDERR ("Returning from expect with TIMEOUT or EOF\r\n");
1030             }
1031 0 0 0     0 if ( $Expect::Debug and $exp_matched ) {
1032 0         0 print STDERR " ${*$exp_matched}{exp_Pty_Handle}: accumulator: `";
  0         0  
1033 0 0       0 if ( ${*$exp_matched}{exp_Error} ) {
  0         0  
1034             print STDERR (
1035 0         0 $exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Before} ) ),
  0         0  
1036             "'\r\n"
1037             );
1038             } else {
1039             print STDERR (
1040 0         0 $exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Accum} ) ),
  0         0  
1041             "'\r\n"
1042             );
1043             }
1044             }
1045             }
1046              
1047 4811 100       5941 if ($exp_matched) {
1048             return wantarray
1049             ? (
1050 4763         6264 ${*$exp_matched}{exp_Match_Number}, ${*$exp_matched}{exp_Error},
  4763         4405  
1051 4763         4076 ${*$exp_matched}{exp_Match}, ${*$exp_matched}{exp_Before},
  4763         3928  
1052 4763         16084 ${*$exp_matched}{exp_After}, $exp_matched,
1053             )
1054 4763 50       5430 : ${*$exp_matched}{exp_Match_Number};
  0         0  
1055             }
1056              
1057 48 50       348 return wantarray ? ( undef, $err, undef, $before, undef, undef ) : undef;
1058             }
1059              
1060             # Patterns are arrays that consist of
1061             # [ $pattern_type, $pattern, $sub, @subparms ]
1062             # optional $pattern_type is '-re' (RegExp, default) or '-ex' (exact);
1063             # $sub is optional CODE ref, which is called as &{$sub}($exp, @subparms)
1064             # if pattern matched;
1065             # the $parm_nr gets unshifted onto the array for reporting purposes.
1066              
1067             sub _add_patterns_to_list {
1068 14214     14214   13771 my ($listref, $timeoutlistref,$store_parm_nr, @params) = @_;
1069              
1070             # $timeoutlistref gets timeout patterns
1071 14214   50     17494 my $parm_nr = $store_parm_nr || 1;
1072 14214         11798 foreach my $parm (@params) {
1073 14214 50       18117 if ( not ref($parm) eq 'ARRAY' ) {
1074 0         0 return "Parameter #$parm_nr is not an ARRAY ref.";
1075             }
1076 14214         15050 $parm = [@$parm]; # make copy
1077 14214 50       19964 if ( $parm->[0] =~ m/\A-/ ) {
1078              
1079             # it's an option
1080 0 0 0     0 if ( $parm->[0] ne '-re'
1081             and $parm->[0] ne '-ex' )
1082             {
1083 0         0 return "Unknown option $parm->[0] in pattern #$parm_nr";
1084             }
1085             } else {
1086 14214 100       18602 if ( $parm->[0] eq 'timeout' ) {
    100          
1087 4720 50       6696 if ( defined $timeoutlistref ) {
1088 4720         9320 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1089 4720 50       6343 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1090 4720         3940 push @$timeoutlistref, $parm;
1091             }
1092 4720         4913 next;
1093             } elsif ( $parm->[0] eq 'eof' ) {
1094 4720         7804 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1095             } else {
1096 4774         7438 unshift @$parm, '-re'; # defaults to RegExp
1097             }
1098             }
1099 9494 100       10611 if ( @$parm > 2 ) {
1100 9491 50       14182 if ( ref( $parm->[2] ) ne 'CODE' ) {
1101 0         0 croak(
1102             "Pattern #$parm_nr doesn't have a CODE reference",
1103             "after the pattern."
1104             );
1105             }
1106             } else {
1107 3         6 push @$parm, undef; # make sure we have three elements
1108             }
1109              
1110 9494 50       11014 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1111 9494         7061 push @$listref, $parm;
1112 9494         7942 $parm_nr++;
1113             }
1114              
1115 14214         14665 return;
1116             }
1117              
1118             ######################################################################
1119             # $process->interact([$in_handle],[$escape sequence])
1120             # If you don't specify in_handle STDIN will be used.
1121             sub interact {
1122 0     0 1 0 my ($self, $infile, $escape_sequence) = @_;
1123              
1124 0         0 my $outfile;
1125 0         0 my @old_group = $self->set_group();
1126              
1127             # If the handle is STDIN we'll
1128             # $infile->fileno == 0 should be stdin.. follow stdin rules.
1129 23     23   115 no strict 'subs'; # Allow bare word 'STDIN'
  23         21  
  23         66430  
1130 0 0       0 unless ( defined($infile) ) {
    0          
1131             # We need a handle object Associated with STDIN.
1132 0         0 $infile = IO::File->new;
1133 0         0 $infile->IO::File::fdopen( STDIN, 'r' );
1134 0         0 $outfile = IO::File->new;
1135 0         0 $outfile->IO::File::fdopen( STDOUT, 'w' );
1136             } elsif ( fileno($infile) == fileno(STDIN) ) {
1137              
1138             # With STDIN we want output to go to stdout.
1139 0         0 $outfile = IO::File->new;
1140 0         0 $outfile->IO::File::fdopen( STDOUT, 'w' );
1141             } else {
1142 0         0 undef($outfile);
1143             }
1144              
1145             # Here we assure ourselves we have an Expect object.
1146 0         0 my $in_object = Expect->exp_init($infile);
1147 0 0       0 if ( defined($outfile) ) {
1148              
1149             # as above.. we want output to go to stdout if we're given stdin.
1150 0         0 my $out_object = Expect->exp_init($outfile);
1151 0         0 $out_object->manual_stty(1);
1152 0         0 $self->set_group($out_object);
1153             } else {
1154 0         0 $self->set_group($in_object);
1155             }
1156 0         0 $in_object->set_group($self);
1157 0 0       0 $in_object->set_seq( $escape_sequence, undef ) if defined($escape_sequence);
1158              
1159             # interconnect normally sets stty -echo raw. Interact really sort
1160             # of implies we don't do that by default. If anyone wanted to they could
1161             # set it before calling interact, of use interconnect directly.
1162 0         0 my $old_manual_stty_val = $self->manual_stty();
1163 0         0 $self->manual_stty(1);
1164              
1165             # I think this is right. Don't send stuff from in_obj to stdout by default.
1166             # in theory whatever 'self' is should echo what's going on.
1167 0         0 my $old_log_stdout_val = $self->log_stdout();
1168 0         0 $self->log_stdout(0);
1169 0         0 $in_object->log_stdout(0);
1170              
1171             # Allow for the setting of an optional EOF escape function.
1172             # $in_object->set_seq('EOF',undef);
1173             # $self->set_seq('EOF',undef);
1174 0         0 Expect::interconnect( $self, $in_object );
1175 0         0 $self->log_stdout($old_log_stdout_val);
1176 0         0 $self->set_group(@old_group);
1177              
1178             # If old_group was undef, make sure that occurs. This is a slight hack since
1179             # it modifies the value directly.
1180             # Normally an undef passed to set_group will return the current groups.
1181             # It is possible that it may be of worth to make it possible to undef
1182             # The current group without doing this.
1183 0 0       0 unless (@old_group) {
1184 0         0 @{ ${*$self}{exp_Listen_Group} } = ();
  0         0  
  0         0  
1185             }
1186 0         0 $self->manual_stty($old_manual_stty_val);
1187              
1188 0         0 return;
1189             }
1190              
1191             sub interconnect {
1192 0     0 1 0 my (@handles) = @_;
1193              
1194             # my ($handle)=(shift); call as Expect::interconnect($spawn1,$spawn2,...)
1195 0         0 my ( $nread );
1196 0         0 my ( $rout, $emask, $eout );
1197 0         0 my ( $escape_character_buffer );
1198 0         0 my ( $read_mask, $temp_mask ) = ( '', '' );
1199              
1200             # Get read/write handles
1201 0         0 foreach my $handle (@handles) {
1202 0         0 $temp_mask = '';
1203 0         0 vec( $temp_mask, $handle->fileno(), 1 ) = 1;
1204              
1205             # Under Linux w/ 5.001 the next line comes up w/ 'Uninit var.'.
1206             # It appears to be impossible to make the warning go away.
1207             # doing something like $temp_mask='' unless defined ($temp_mask)
1208             # has no effect whatsoever. This may be a bug in 5.001.
1209 0         0 $read_mask = $read_mask | $temp_mask;
1210             }
1211 0 0       0 if ($Expect::Debug) {
1212 0         0 print STDERR "Read handles:\r\n";
1213 0         0 foreach my $handle (@handles) {
1214 0         0 print STDERR "\tRead handle: ";
1215 0         0 print STDERR "'${*$handle}{exp_Pty_Handle}'\r\n";
  0         0  
1216 0         0 print STDERR "\t\tListen Handles:";
1217 0         0 foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) {
  0         0  
  0         0  
1218 0         0 print STDERR " '${*$write_handle}{exp_Pty_Handle}'";
  0         0  
1219             }
1220 0         0 print STDERR ".\r\n";
1221             }
1222             }
1223              
1224             # I think if we don't set raw/-echo here we may have trouble. We don't
1225             # want a bunch of echoing crap making all the handles jabber at each other.
1226 0         0 foreach my $handle (@handles) {
1227 0 0       0 unless ( ${*$handle}{"exp_Manual_Stty"} ) {
  0         0  
1228              
1229             # This is probably O/S specific.
1230 0         0 ${*$handle}{exp_Stored_Stty} = $handle->exp_stty('-g');
  0         0  
1231 0         0 print STDERR "Setting tty for ${*$handle}{exp_Pty_Handle} to 'raw -echo'.\r\n"
1232 0 0       0 if ${*$handle}{"exp_Debug"};
  0         0  
1233 0         0 $handle->exp_stty("raw -echo");
1234             }
1235 0         0 foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) {
  0         0  
  0         0  
1236 0 0       0 unless ( ${*$write_handle}{"exp_Manual_Stty"} ) {
  0         0  
1237 0         0 ${*$write_handle}{exp_Stored_Stty} =
1238 0         0 $write_handle->exp_stty('-g');
1239 0         0 print STDERR "Setting ${*$write_handle}{exp_Pty_Handle} to 'raw -echo'.\r\n"
1240 0 0       0 if ${*$handle}{"exp_Debug"};
  0         0  
1241 0         0 $write_handle->exp_stty("raw -echo");
1242             }
1243             }
1244             }
1245              
1246 0 0       0 print STDERR "Attempting interconnection\r\n" if $Expect::Debug;
1247              
1248             # Wait until the process dies or we get EOF
1249             # In the case of !${*$handle}{exp_Pid} it means
1250             # the handle was exp_inited instead of spawned.
1251             CONNECT_LOOP:
1252              
1253             # Go until we have a reason to stop
1254 0         0 while (1) {
1255              
1256             # test each handle to see if it's still alive.
1257 0         0 foreach my $read_handle (@handles) {
1258 0         0 waitpid( ${*$read_handle}{exp_Pid}, WNOHANG )
1259 0         0 if ( exists( ${*$read_handle}{exp_Pid} )
1260 0 0 0     0 and ${*$read_handle}{exp_Pid} );
  0         0  
1261 0 0 0     0 if ( exists( ${*$read_handle}{exp_Pid} )
  0   0     0  
1262 0         0 and ( ${*$read_handle}{exp_Pid} )
1263 0         0 and ( !kill( 0, ${*$read_handle}{exp_Pid} ) ) )
1264             {
1265             print STDERR
1266 0         0 "Got EOF (${*$read_handle}{exp_Pty_Handle} died) reading ${*$read_handle}{exp_Pty_Handle}\r\n"
  0         0  
1267 0 0       0 if ${*$read_handle}{"exp_Debug"};
  0         0  
1268             last CONNECT_LOOP
1269 0 0       0 unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} );
  0         0  
  0         0  
1270             last CONNECT_LOOP
1271 0         0 unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} }
  0         0  
  0         0  
1272 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } );
  0         0  
  0         0  
  0         0  
1273             }
1274             }
1275              
1276             # Every second? No, go until we get something from someone.
1277 0         0 my $nfound = select( $rout = $read_mask, undef, $eout = $emask, undef );
1278              
1279             # Is there anything to share? May be -1 if interrupted by a signal...
1280 0 0 0     0 next CONNECT_LOOP if not defined $nfound or $nfound < 1;
1281              
1282             # Which handles have stuff?
1283 0         0 my @bits = split( //, unpack( 'b*', $rout ) );
1284 0 0       0 $eout = 0 unless defined($eout);
1285 0         0 my @ebits = split( //, unpack( 'b*', $eout ) );
1286              
1287             # print "Ebits: $eout\r\n";
1288 0         0 foreach my $read_handle (@handles) {
1289 0 0       0 if ( $bits[ $read_handle->fileno() ] ) {
1290             $nread = sysread(
1291 0         0 $read_handle, ${*$read_handle}{exp_Pty_Buffer},
1292 0         0 1024
1293             );
1294              
1295             # Appease perl -w
1296 0 0       0 $nread = 0 unless defined($nread);
1297 0         0 print STDERR "interconnect: read $nread byte(s) from ${*$read_handle}{exp_Pty_Handle}.\r\n"
1298 0 0       0 if ${*$read_handle}{"exp_Debug"} > 1;
  0         0  
1299              
1300             # Test for escape seq. before printing.
1301             # Appease perl -w
1302 0 0       0 $escape_character_buffer = ''
1303             unless defined($escape_character_buffer);
1304 0         0 $escape_character_buffer .= ${*$read_handle}{exp_Pty_Buffer};
  0         0  
1305 0         0 foreach my $escape_sequence ( keys( %{ ${*$read_handle}{exp_Function} } ) ) {
  0         0  
  0         0  
1306 0         0 print STDERR "Tested escape sequence $escape_sequence from ${*$read_handle}{exp_Pty_Handle}"
1307 0 0       0 if ${*$read_handle}{"exp_Debug"} > 1;
  0         0  
1308              
1309             # Make sure it doesn't grow out of bounds.
1310             $escape_character_buffer = $read_handle->_trim_length(
1311             $escape_character_buffer,
1312 0         0 ${*$read_handle}{"exp_Max_Accum"}
1313 0 0       0 ) if ( ${*$read_handle}{"exp_Max_Accum"} );
  0         0  
1314 0 0       0 if ( $escape_character_buffer =~ /($escape_sequence)/ ) {
1315 0         0 my $match = $1;
1316 0 0       0 if ( ${*$read_handle}{"exp_Debug"} ) {
  0         0  
1317 0         0 print STDERR
1318 0         0 "\r\ninterconnect got escape sequence from ${*$read_handle}{exp_Pty_Handle}.\r\n";
1319              
1320             # I'm going to make the esc. seq. pretty because it will
1321             # probably contain unprintable characters.
1322 0         0 print STDERR "\tEscape Sequence: '"
1323             . _trim_length(
1324             undef,
1325             _make_readable($escape_sequence)
1326             ) . "'\r\n";
1327 0         0 print STDERR "\tMatched by string: '" . _trim_length( undef, _make_readable($match) ) . "'\r\n";
1328             }
1329              
1330             # Print out stuff before the escape.
1331             # Keep in mind that the sequence may have been split up
1332             # over several reads.
1333             # Let's get rid of it from this read. If part of it was
1334             # in the last read there's not a lot we can do about it now.
1335 0 0       0 if ( ${*$read_handle}{exp_Pty_Buffer} =~ /([\w\W]*)($escape_sequence)/ ) {
  0         0  
1336 0         0 $read_handle->_print_handles($1);
1337             } else {
1338 0         0 $read_handle->_print_handles( ${*$read_handle}{exp_Pty_Buffer} );
  0         0  
1339             }
1340              
1341             # Clear the buffer so no more matches can be made and it will
1342             # only be printed one time.
1343 0         0 ${*$read_handle}{exp_Pty_Buffer} = '';
  0         0  
1344 0         0 $escape_character_buffer = '';
1345              
1346             # Do the function here. Must return non-zero to continue.
1347             # More cool syntax. Maybe I should turn these in to objects.
1348             last CONNECT_LOOP
1349 0         0 unless &{ ${ ${*$read_handle}{exp_Function} }{$escape_sequence} }
  0         0  
  0         0  
1350 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{$escape_sequence} } );
  0         0  
  0         0  
  0         0  
1351             }
1352             }
1353 0 0       0 $nread = 0 unless defined($nread); # Appease perl -w?
1354 0         0 waitpid( ${*$read_handle}{exp_Pid}, WNOHANG )
1355 0         0 if ( defined( ${*$read_handle}{exp_Pid} )
1356 0 0 0     0 && ${*$read_handle}{exp_Pid} );
  0         0  
1357 0 0       0 if ( $nread == 0 ) {
1358 0         0 print STDERR "Got EOF reading ${*$read_handle}{exp_Pty_Handle}\r\n"
1359 0 0       0 if ${*$read_handle}{"exp_Debug"};
  0         0  
1360             last CONNECT_LOOP
1361 0 0       0 unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} );
  0         0  
  0         0  
1362             last CONNECT_LOOP
1363 0         0 unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} }
  0         0  
  0         0  
1364 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } );
  0         0  
  0         0  
  0         0  
1365             }
1366 0 0       0 last CONNECT_LOOP if ( $nread < 0 ); # This would be an error
1367 0         0 $read_handle->_print_handles( ${*$read_handle}{exp_Pty_Buffer} );
  0         0  
1368             }
1369              
1370             # I'm removing this because I haven't determined what causes exceptions
1371             # consistently.
1372 0         0 if (0) #$ebits[$read_handle->fileno()])
1373             {
1374             print STDERR "Got Exception reading ${*$read_handle}{exp_Pty_Handle}\r\n"
1375             if ${*$read_handle}{"exp_Debug"};
1376             last CONNECT_LOOP
1377             unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} );
1378             last CONNECT_LOOP
1379             unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} }
1380             ( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } );
1381             }
1382             }
1383             }
1384 0         0 foreach my $handle (@handles) {
1385 0 0       0 unless ( ${*$handle}{"exp_Manual_Stty"} ) {
  0         0  
1386 0         0 $handle->exp_stty( ${*$handle}{exp_Stored_Stty} );
  0         0  
1387             }
1388 0         0 foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) {
  0         0  
  0         0  
1389 0 0       0 unless ( ${*$write_handle}{"exp_Manual_Stty"} ) {
  0         0  
1390 0         0 $write_handle->exp_stty( ${*$write_handle}{exp_Stored_Stty} );
  0         0  
1391             }
1392             }
1393             }
1394              
1395 0         0 return;
1396             }
1397              
1398             # user can decide if log output gets also sent to logfile
1399             sub print_log_file {
1400 4750     4750 1 6647 my ($self, @params) = @_;
1401              
1402 4750 100       2987 if ( ${*$self}{exp_Log_File} ) {
  4750         8839  
1403 4635 100       2988 if ( ref( ${*$self}{exp_Log_File} ) eq 'CODE' ) {
  4635         7934  
1404 48         64 ${*$self}{exp_Log_File}->(@params);
  48         160  
1405             } else {
1406 4587         3057 ${*$self}{exp_Log_File}->print(@params);
  4587         8633  
1407             }
1408             }
1409              
1410 4750         135570 return;
1411             }
1412              
1413             # we provide our own print so we can debug what gets sent to the
1414             # processes...
1415             sub print {
1416 4624     4624 1 70868 my ( $self, @args ) = @_;
1417              
1418 4624 50       7364 return if not defined $self->fileno(); # skip if closed
1419 4624 50       14498 if ( ${*$self}{exp_Exp_Internal} ) {
  4624         8808  
1420 0         0 my $args = _make_readable( join( '', @args ) );
1421 0         0 cluck "Sending '$args' to ${*$self}{exp_Pty_Handle}\r\n";
  0         0  
1422             }
1423 4624         5422 foreach my $arg (@args) {
1424 4624         6425 while ( length($arg) > 80 ) {
1425 10326         19672 $self->SUPER::print( substr( $arg, 0, 80 ) );
1426 10326         178012 $arg = substr( $arg, 80 );
1427             }
1428 4624         7548 $self->SUPER::print($arg);
1429             }
1430              
1431 4624         80801 return;
1432             }
1433              
1434             # make an alias for Tcl/Expect users for a DWIM experience...
1435             *send = \&print;
1436              
1437             # This is an Expect standard. It's nice for talking to modems and the like
1438             # where from time to time they get unhappy if you send items too quickly.
1439             sub send_slow {
1440 24     24 1 15992 my ($self, $sleep_time, @chunks) = @_;
1441              
1442 24 50       72 return if not defined $self->fileno(); # skip if closed
1443              
1444             # Flushing makes it so each character can be seen separately.
1445 24         136 my $chunk;
1446 24         64 while ( $chunk = shift @chunks ) {
1447 24         136 my @linechars = split( '', $chunk );
1448 24         56 foreach my $char (@linechars) {
1449              
1450             # How slow?
1451 1040         104173904 select( undef, undef, undef, $sleep_time );
1452              
1453 1040         51840 print $self $char;
1454 0         0 print STDERR "Printed character \'" . _make_readable($char) . "\' to ${*$self}{exp_Pty_Handle}.\r\n"
1455 1040 50       2712 if ${*$self}{"exp_Debug"} > 1;
  1040         14528  
1456              
1457             # I think I can get away with this if I save it in accum
1458 1040 50 33     2800 if ( ${*$self}{"exp_Log_Stdout"} || ${*$self}{exp_Log_Group} ) {
  1040         4872  
  0         0  
1459 1040         2528 my $rmask = "";
1460 1040         10504 vec( $rmask, $self->fileno(), 1 ) = 1;
1461              
1462             # .01 sec granularity should work. If we miss something it will
1463             # probably get flushed later, maybe in an expect call.
1464 1040         10271720 while ( select( $rmask, undef, undef, .01 ) ) {
1465 24         48 my $ret = sysread( $self, ${*$self}{exp_Pty_Buffer}, 1024 );
  24         224  
1466 24 50 33     232 last if not defined $ret or $ret == 0;
1467              
1468             # Is this necessary to keep? Probably.. #
1469             # if you need to expect it later.
1470 24         24 ${*$self}{exp_Accum} .= ${*$self}{exp_Pty_Buffer};
  24         56  
  24         96  
1471 0         0 ${*$self}{exp_Accum} = $self->_trim_length(
1472 0         0 ${*$self}{exp_Accum},
1473 0         0 ${*$self}{"exp_Max_Accum"}
1474 24 50       32 ) if ( ${*$self}{"exp_Max_Accum"} );
  24         80  
1475 24         32 $self->_print_handles( ${*$self}{exp_Pty_Buffer} );
  24         112  
1476             print STDERR "Received \'"
1477             . $self->_trim_length( _make_readable($char) )
1478 0         0 . "\' from ${*$self}{exp_Pty_Handle}\r\n"
1479 24 50       32 if ${*$self}{"exp_Debug"} > 1;
  24         242416  
1480             }
1481             }
1482             }
1483             }
1484              
1485 24         80 return;
1486             }
1487              
1488             sub test_handles {
1489 0     0 1 0 my ($timeout, @handle_list) = @_;
1490              
1491             # This should be called by Expect::test_handles($timeout,@objects);
1492 0         0 my ( $allmask, $rout );
1493 0         0 foreach my $handle (@handle_list) {
1494 0         0 my $rmask = '';
1495 0         0 vec( $rmask, $handle->fileno(), 1 ) = 1;
1496 0 0       0 $allmask = '' unless defined($allmask);
1497 0         0 $allmask = $allmask | $rmask;
1498             }
1499 0         0 my $nfound = select( $rout = $allmask, undef, undef, $timeout );
1500 0 0       0 return () unless $nfound;
1501              
1502             # Which handles have stuff?
1503 0         0 my @bits = split( //, unpack( 'b*', $rout ) );
1504              
1505 0         0 my $handle_num = 0;
1506 0         0 my @return_list = ();
1507 0         0 foreach my $handle (@handle_list) {
1508              
1509             # I go to great lengths to get perl -w to shut the hell up.
1510 0 0 0     0 if ( defined( $bits[ $handle->fileno() ] )
1511             and ( $bits[ $handle->fileno() ] ) )
1512             {
1513 0         0 push( @return_list, $handle_num );
1514             }
1515             } continue {
1516 0         0 $handle_num++;
1517             }
1518              
1519 0         0 return @return_list;
1520             }
1521              
1522             # Be nice close. This should emulate what an interactive shell does after a
1523             # command finishes... sort of. We're not as patient as a shell.
1524             sub soft_close {
1525 7     7 0 3780 my ($self) = @_;
1526              
1527 7         15 my ( $nfound, $nread, $rmask, $end_time, $temp_buffer );
1528              
1529             # Give it 15 seconds to cough up an eof.
1530 7 50       14 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  7         47  
1531 7 50       26 return -1 if not defined $self->fileno(); # skip if handle already closed
1532 7 50 33     47 unless ( exists ${*$self}{exp_Has_EOF} and ${*$self}{exp_Has_EOF} ) {
  7         39  
  0         0  
1533 7         7 $end_time = time() + 15;
1534 7         26 while ( $end_time > time() ) {
1535 10         23 my $select_time = $end_time - time();
1536              
1537             # Sanity check.
1538 10 50       30 $select_time = 0 if $select_time < 0;
1539 10         17 $rmask = '';
1540 10         35 vec( $rmask, $self->fileno(), 1 ) = 1;
1541 10         13996191 ($nfound) = select( $rmask, undef, undef, $select_time );
1542 10 50 33     170 last unless ( defined($nfound) && $nfound );
1543 10         139 $nread = sysread( $self, $temp_buffer, 8096 );
1544              
1545             # 0 = EOF.
1546 10 100 66     91 unless ( defined($nread) && $nread ) {
1547 0         0 print STDERR "Got EOF from ${*$self}{exp_Pty_Handle}.\r\n"
1548 7 50       11 if ${*$self}{exp_Debug};
  7         62  
1549 7         18 last;
1550             }
1551 3         42 $self->_print_handles($temp_buffer);
1552             }
1553 7 0 33     29 if ( ( $end_time <= time() ) && ${*$self}{exp_Debug} ) {
  0         0  
1554 0         0 print STDERR "Timed out waiting for an EOF from ${*$self}{exp_Pty_Handle}.\r\n";
  0         0  
1555             }
1556             }
1557 7         75 my $close_status = $self->close();
1558 7 50 33     409 if ( $close_status && ${*$self}{exp_Debug} ) {
  7         31  
1559 0         0 print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n";
  0         0  
1560             }
1561              
1562             # quit now if it isn't a process.
1563 7 50       18 return $close_status unless defined( ${*$self}{exp_Pid} );
  7         40  
1564              
1565             # Now give it 15 seconds to die.
1566 7         17 $end_time = time() + 15;
1567 7         25 while ( $end_time > time() ) {
1568 7         14 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  7         154  
1569              
1570             # Stop here if the process dies.
1571 7 50 33     59 if ( defined($returned_pid) && $returned_pid ) {
1572 7         38 delete $Expect::Spawned_PIDs{$returned_pid};
1573 7 50       11 if ( ${*$self}{exp_Debug} ) {
  7         27  
1574             printf STDERR (
1575             "Pid %d of %s exited, Status: 0x%02X\r\n",
1576 0         0 ${*$self}{exp_Pid},
1577 0         0 ${*$self}{exp_Pty_Handle}, $?
  0         0  
1578             );
1579             }
1580 7         17 ${*$self}{exp_Pid} = undef;
  7         22  
1581 7         14 ${*$self}{exp_Exit} = $?;
  7         185  
1582 7         21 return ${*$self}{exp_Exit};
  7         55  
1583             }
1584 0         0 sleep 1; # Keep loop nice.
1585             }
1586              
1587             # Send it a term if it isn't dead.
1588 0 0       0 if ( ${*$self}{exp_Debug} ) {
  0         0  
1589 0         0 print STDERR "${*$self}{exp_Pty_Handle} not exiting, sending TERM.\r\n";
  0         0  
1590             }
1591 0         0 kill TERM => ${*$self}{exp_Pid};
  0         0  
1592              
1593             # Now to be anal retentive.. wait 15 more seconds for it to die.
1594 0         0 $end_time = time() + 15;
1595 0         0 while ( $end_time > time() ) {
1596 0         0 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  0         0  
1597 0 0 0     0 if ( defined($returned_pid) && $returned_pid ) {
1598 0         0 delete $Expect::Spawned_PIDs{$returned_pid};
1599 0 0       0 if ( ${*$self}{exp_Debug} ) {
  0         0  
1600             printf STDERR (
1601             "Pid %d of %s terminated, Status: 0x%02X\r\n",
1602 0         0 ${*$self}{exp_Pid},
1603 0         0 ${*$self}{exp_Pty_Handle}, $?
  0         0  
1604             );
1605             }
1606 0         0 ${*$self}{exp_Pid} = undef;
  0         0  
1607 0         0 ${*$self}{exp_Exit} = $?;
  0         0  
1608 0         0 return $?;
1609             }
1610 0         0 sleep 1;
1611             }
1612              
1613             # Since this is a 'soft' close, sending it a -9 would be inappropriate.
1614 0         0 return;
1615             }
1616              
1617             # 'Make it go away' close.
1618             sub hard_close {
1619 167     167 0 36921 my ($self) = @_;
1620              
1621 167 50       160 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  167         419  
1622              
1623             # Don't wait for an EOF.
1624 167         692 my $close_status = $self->close();
1625 167 50 66     16729 if ( $close_status && ${*$self}{exp_Debug} ) {
  101         387  
1626 0         0 print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n";
  0         0  
1627             }
1628              
1629             # Return now if handle.
1630 167 100       109 return $close_status unless defined( ${*$self}{exp_Pid} );
  167         424  
1631              
1632             # Now give it 5 seconds to die. Less patience here if it won't die.
1633 78         142 my $end_time = time() + 5;
1634 78         202 while ( $end_time > time() ) {
1635 110         184 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  110         4653  
1636              
1637             # Stop here if the process dies.
1638 110 100 66     821 if ( defined($returned_pid) && $returned_pid ) {
1639 78         529 delete $Expect::Spawned_PIDs{$returned_pid};
1640 78 50       122 if ( ${*$self}{exp_Debug} ) {
  78         339  
1641             printf STDERR (
1642             "Pid %d of %s terminated, Status: 0x%02X\r\n",
1643 0         0 ${*$self}{exp_Pid},
1644 0         0 ${*$self}{exp_Pty_Handle}, $?
  0         0  
1645             );
1646             }
1647 78         128 ${*$self}{exp_Pid} = undef;
  78         207  
1648 78         134 ${*$self}{exp_Exit} = $?;
  78         491  
1649 78         219 return ${*$self}{exp_Exit};
  78         432  
1650             }
1651 32         32004752 sleep 1; # Keep loop nice.
1652             }
1653              
1654             # Send it a term if it isn't dead.
1655 0 0       0 if ( ${*$self}{exp_Debug} ) {
  0         0  
1656 0         0 print STDERR "${*$self}{exp_Pty_Handle} not exiting, sending TERM.\r\n";
  0         0  
1657             }
1658 0         0 kill TERM => ${*$self}{exp_Pid};
  0         0  
1659              
1660             # wait 15 more seconds for it to die.
1661 0         0 $end_time = time() + 15;
1662 0         0 while ( $end_time > time() ) {
1663 0         0 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  0         0  
1664 0 0 0     0 if ( defined($returned_pid) && $returned_pid ) {
1665 0         0 delete $Expect::Spawned_PIDs{$returned_pid};
1666 0 0       0 if ( ${*$self}{exp_Debug} ) {
  0         0  
1667             printf STDERR (
1668             "Pid %d of %s terminated, Status: 0x%02X\r\n",
1669 0         0 ${*$self}{exp_Pid},
1670 0         0 ${*$self}{exp_Pty_Handle}, $?
  0         0  
1671             );
1672             }
1673 0         0 ${*$self}{exp_Pid} = undef;
  0         0  
1674 0         0 ${*$self}{exp_Exit} = $?;
  0         0  
1675 0         0 return ${*$self}{exp_Exit};
  0         0  
1676             }
1677 0         0 sleep 1;
1678             }
1679 0         0 kill KILL => ${*$self}{exp_Pid};
  0         0  
1680              
1681             # wait 5 more seconds for it to die.
1682 0         0 $end_time = time() + 5;
1683 0         0 while ( $end_time > time() ) {
1684 0         0 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  0         0  
1685 0 0 0     0 if ( defined($returned_pid) && $returned_pid ) {
1686 0         0 delete $Expect::Spawned_PIDs{$returned_pid};
1687 0 0       0 if ( ${*$self}{exp_Debug} ) {
  0         0  
1688             printf STDERR (
1689             "Pid %d of %s killed, Status: 0x%02X\r\n",
1690 0         0 ${*$self}{exp_Pid},
1691 0         0 ${*$self}{exp_Pty_Handle}, $?
  0         0  
1692             );
1693             }
1694 0         0 ${*$self}{exp_Pid} = undef;
  0         0  
1695 0         0 ${*$self}{exp_Exit} = $?;
  0         0  
1696 0         0 return ${*$self}{exp_Exit};
  0         0  
1697             }
1698 0         0 sleep 1;
1699             }
1700 0         0 warn "Pid ${*$self}{exp_Pid} of ${*$self}{exp_Pty_Handle} is HUNG.\r\n";
  0         0  
  0         0  
1701 0         0 ${*$self}{exp_Pid} = undef;
  0         0  
1702              
1703 0         0 return;
1704             }
1705              
1706             # These should not be called externally.
1707              
1708             sub _init_vars {
1709 126     126   158 my ($self) = @_;
1710              
1711             # for every spawned process or filehandle.
1712 126 50       313 ${*$self}{exp_Log_Stdout} = $Expect::Log_Stdout
  0         0  
1713             if defined($Expect::Log_Stdout);
1714 126         159 ${*$self}{exp_Log_Group} = $Expect::Log_Group;
  126         189  
1715 126         151 ${*$self}{exp_Debug} = $Expect::Debug;
  126         185  
1716 126         168 ${*$self}{exp_Exp_Internal} = $Expect::Exp_Internal;
  126         206  
1717 126         134 ${*$self}{exp_Manual_Stty} = $Expect::Manual_Stty;
  126         209  
1718 126         95 ${*$self}{exp_Stored_Stty} = 'sane';
  126         318  
1719 126         111 ${*$self}{exp_Do_Soft_Close} = $Expect::Do_Soft_Close;
  126         227  
1720              
1721             # sysread doesn't like my or local vars.
1722 126         171 ${*$self}{exp_Pty_Buffer} = '';
  126         182  
1723              
1724             # Initialize accumulator.
1725 126         187 ${*$self}{exp_Max_Accum} = $Expect::Exp_Max_Accum;
  126         198  
1726 126         85 ${*$self}{exp_Accum} = '';
  126         184  
1727 126         123 ${*$self}{exp_NoTransfer} = 0;
  126         177  
1728              
1729             # create empty expect_before & after lists
1730 126         172 ${*$self}{exp_expect_before_list} = [];
  126         169  
1731 126         167 ${*$self}{exp_expect_after_list} = [];
  126         189  
1732              
1733 126         144 return;
1734             }
1735              
1736             sub _make_readable {
1737 0     0   0 my ($s) = @_;
1738              
1739 0 0       0 $s = '' if not defined($s);
1740 0         0 study $s; # Speed things up?
1741 0         0 $s =~ s/\\/\\\\/g; # So we can tell easily(?) what is a backslash
1742 0         0 $s =~ s/\n/\\n/g;
1743 0         0 $s =~ s/\r/\\r/g;
1744 0         0 $s =~ s/\t/\\t/g;
1745 0         0 $s =~ s/\'/\\\'/g; # So we can tell whassa quote and whassa notta quote.
1746 0         0 $s =~ s/\"/\\\"/g;
1747              
1748             # Formfeed (does anyone use formfeed?)
1749 0         0 $s =~ s/\f/\\f/g;
1750 0         0 $s =~ s/\010/\\b/g;
1751              
1752             # escape control chars high/low, but allow ISO 8859-1 chars
1753 0         0 $s =~ s/([\000-\037\177-\237\377])/sprintf("\\%03lo",ord($1))/ge;
  0         0  
1754              
1755 0         0 return $s;
1756             }
1757              
1758             sub _trim_length {
1759 17     17   974 my ($self, $string, $length) = @_;
1760              
1761             # This is sort of a reverse truncation function
1762             # Mostly so we don't have to see the full output when we're using
1763             # Also used if Max_Accum gets set to limit the size of the accumulator
1764             # for matching functions.
1765             # exp_internal
1766              
1767 17 100       259 croak('No string passed') if not defined $string;
1768              
1769             # If we're not passed a length (_trim_length is being used for debugging
1770             # purposes) AND debug >= 3, don't trim.
1771             return ($string)
1772             if (defined($self)
1773 15 50 66     28 and ${*$self}{"exp_Debug"} >= 3
  7   33     32  
1774             and ( !( defined($length) ) ) );
1775 15 100       20 my $indicate_truncation = ($length ? '' : '...');
1776 15   100     31 $length ||= 1021;
1777 15 100       40 return $string if $length >= length $string;
1778              
1779             # We wouldn't want the accumulator to begin with '...' if max_accum is passed
1780             # This is because this funct. gets called internally w/ max_accum
1781             # and is also used to print information back to the user.
1782 8         40 return $indicate_truncation . substr( $string, ( length($string) - $length ), $length );
1783             }
1784              
1785             sub _print_handles {
1786 4750     4750   5820 my ($self, $print_this) = @_;
1787              
1788             # Given crap from 'self' and the handles self wants to print to, print to
1789             # them. these are indicated by the handle's 'group'
1790 4750 50       3989 if ( ${*$self}{exp_Log_Group} ) {
  4750         7759  
1791 4750         2989 foreach my $handle ( @{ ${*$self}{exp_Listen_Group} } ) {
  4750         3035  
  4750         7931  
1792 0 0       0 $print_this = '' unless defined($print_this);
1793              
1794             # Appease perl -w
1795             print STDERR "Printed '"
1796             . $self->_trim_length( _make_readable($print_this) )
1797 0         0 . "' to ${*$handle}{exp_Pty_Handle} from ${*$self}{exp_Pty_Handle}.\r\n"
  0         0  
1798 0 0       0 if ( ${*$handle}{"exp_Debug"} > 1 );
  0         0  
1799 0         0 print $handle $print_this;
1800             }
1801             }
1802              
1803             # If ${*$self}{exp_Pty_Handle} is STDIN this would make it echo.
1804             print STDOUT $print_this
1805 4750 100       3840 if ${*$self}{"exp_Log_Stdout"};
  4750         33137  
1806 4750         6631 $self->print_log_file($print_this);
1807 4750         6286 $| = 1; # This should not be necessary but autoflush() doesn't always work.
1808              
1809 4750         7224 return;
1810             }
1811              
1812             sub _get_mode {
1813 0     0   0 my ($handle) = @_;
1814              
1815 0         0 my ($fcntl_flags) = '';
1816              
1817             # What mode are we opening with? use fcntl to find out.
1818 0         0 $fcntl_flags = fcntl( \*{$handle}, Fcntl::F_GETFL, $fcntl_flags );
  0         0  
1819 0 0       0 die "fcntl returned undef during exp_init of $handle, $!\r\n"
1820             unless defined($fcntl_flags);
1821 0 0       0 if ( $fcntl_flags | (Fcntl::O_RDWR) ) {
    0          
1822 0         0 return 'rw';
1823             } elsif ( $fcntl_flags | (Fcntl::O_WRONLY) ) {
1824 0         0 return 'w';
1825             } else {
1826              
1827             # Under Solaris (among others?) O_RDONLY is implemented as 0. so |O_RDONLY would fail.
1828 0         0 return 'r';
1829             }
1830             }
1831              
1832             sub _undef {
1833 0     0   0 return undef;
1834              
1835             # Seems a little retarded but &CORE::undef fails in interconnect.
1836             # This is used for the default escape sequence function.
1837             # w/out the leading & it won't compile.
1838             }
1839              
1840             # clean up child processes
1841             sub DESTROY {
1842 109     109   39173 my ($self) = @_;
1843              
1844 109         204 my $status = $?; # save this as it gets mangled by the terminating spawned children
1845 109 50       114 if ( ${*$self}{exp_Do_Soft_Close} ) {
  109         406  
1846 0         0 $self->soft_close();
1847             }
1848 109         396 $self->hard_close();
1849 109         199 $? = $status; # restore it. otherwise deleting an Expect object may mangle $?, which is unintuitive
1850              
1851 109         2671 return;
1852             }
1853              
1854             1;
1855             __END__