File Coverage

blib/lib/Expect.pm
Criterion Covered Total %
statement 638 1164 54.8
branch 218 534 40.8
condition 49 171 28.6
subroutine 35 46 76.0
pod 16 22 72.7
total 956 1937 49.3


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   1912468 use 5.006;
  23         96  
  23         1584  
18              
19             package Expect;
20 23     23   154 use strict;
  23         31  
  23         2340  
21 23     23   151 use warnings;
  23         118  
  23         898  
22              
23 23     23   25357 use IO::Pty 1.11; # We need make_slave_controlling_terminal()
  23         763166  
  23         1159  
24 23     23   221 use IO::Tty;
  23         47  
  23         114  
25              
26 23     23   1575 use POSIX qw(:sys_wait_h :unistd_h); # For WNOHANG and isatty
  23         46  
  23         138  
27 23     23   55945 use Fcntl qw(:DEFAULT); # For checking file handle settings.
  23         48  
  23         7815  
28 23     23   111 use Carp qw(cluck croak carp confess);
  23         53  
  23         1240  
29 23     23   100 use IO::Handle ();
  23         28  
  23         685  
30 23     23   186 use Exporter qw(import);
  23         48  
  23         593  
31 23     23   11357 use Errno;
  23         8803  
  23         3520  
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   50 $Expect::VERSION = '1.31';
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         44 $Expect::Log_Group = 1;
47 23         28 $Expect::Debug = 0;
48 23         42 $Expect::Exp_Max_Accum = 0; # unlimited
49 23         27 $Expect::Exp_Internal = 0;
50 23         357 $Expect::IgnoreEintr = 0;
51 23         132 $Expect::Manual_Stty = 0;
52 23         29 $Expect::Multiline_Matching = 1;
53 23         42 $Expect::Do_Soft_Close = 0;
54 23         31 @Expect::Before_List = ();
55 23         31 @Expect::After_List = ();
56 23         31748 %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 327350 my ($class, @args) = @_;
72              
73 126 50       534 $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         1854 my ($self) = IO::Pty->new;
77 126 50       28330384 die "$class: Could not assign a pty" unless $self;
78 126         552 bless $self => $class;
79 126         686 $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         7603 ${*$self}{exp_Log_Stdout} = 1;
  126         962  
84 126         741 $self->_init_vars();
85              
86 126 100       348 if (@args) {
87              
88             # we got add'l parms, so pass them to spawn
89 64         313 return $self->spawn(@args);
90             }
91 62         206 return $self;
92             }
93              
94             sub spawn {
95 126     126 1 52696 my ($class, @cmd) = @_;
96             # spawn is passed command line args.
97              
98 126         253 my $self;
99              
100 126 100       401 if ( ref($class) ) {
101 111         230 $self = $class;
102             } else {
103 15         90 $self = $class->new();
104             }
105              
106 126         651 croak "Cannot reuse an object with an already spawned command"
107 126 100       236 if exists ${*$self}{"exp_Command"};
108 125         214 ${*$self}{"exp_Command"} = \@cmd;
  125         482  
109              
110             # set up pipe to detect childs exec error
111 125 50       3365 pipe( FROM_CHILD, TO_PARENT ) or die "Cannot open pipe: $!";
112 125 50       2440 pipe( FROM_PARENT, TO_CHILD ) or die "Cannot open pipe: $!";
113 125         4123 TO_PARENT->autoflush(1);
114 125         8293 TO_CHILD->autoflush(1);
115 125         5980 eval { fcntl( TO_PARENT, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC ); };
  125         689  
116              
117 125         865286 my $pid = fork;
118              
119 125 50       6855 unless ( defined($pid) ) {
120 0 0       0 warn "Cannot fork: $!" if $^W;
121 0         0 return;
122             }
123              
124 125 100       4784 if ($pid) {
125              
126             # parent
127 108         311 my $errno;
128 108         178 ${*$self}{exp_Pid} = $pid;
  108         7771  
129 108         30094 close TO_PARENT;
130 108         2292 close FROM_PARENT;
131 108         7369 $self->close_slave();
132 108 100 66     20743 $self->set_raw() if $self->raw_pty and isatty($self);
133 108         8350 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         339431474 my $errstatus = sysread( FROM_CHILD, $errno, 256 );
137 108 50       1045 die "Cannot sync with child: $!" if not defined $errstatus;
138 108         5550 close FROM_CHILD;
139 108 100       648 if ($errstatus) {
140 13         338 $! = $errno + 0;
141 13 50       364 warn "Cannot exec(@cmd): $!\n" if $^W;
142 13         754 return;
143             }
144             } else {
145              
146             # child
147 17         2225 close FROM_CHILD;
148 17         1298 close TO_CHILD;
149              
150 17         4685 $self->make_slave_controlling_terminal();
151 17 50       24542 my $slv = $self->slave()
152             or die "Cannot get slave: $!";
153              
154 17 100       2262 $slv->set_raw() if $self->raw_pty;
155 17         13124 close($self);
156              
157             # wait for parent before we detach
158 17         171 my $buffer;
159 17         57375 my $errstatus = sysread( FROM_PARENT, $buffer, 256 );
160 17 50       331 die "Cannot sync with parent: $!" if not defined $errstatus;
161 17         375 close FROM_PARENT;
162              
163 17         122 close(STDIN);
164 17 50       3052 open( STDIN, "<&" . $slv->fileno() )
165             or die "Couldn't reopen STDIN for reading, $!\n";
166 17         1221 close(STDOUT);
167 17 50       382 open( STDOUT, ">&" . $slv->fileno() )
168             or die "Couldn't reopen STDOUT for writing, $!\n";
169 17         1384 close(STDERR);
170 17 50       126 open( STDERR, ">&" . $slv->fileno() )
171             or die "Couldn't reopen STDERR for writing, $!\n";
172              
173 17         627 { 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         3299 ${*$self}{exp_Pty_Handle} = "spawn id(" . $self->fileno() . ")";
  95         2989  
184 95 50 33     343 if ( ( ${*$self}{"exp_Debug"} ) or ( ${*$self}{"exp_Exp_Internal"} ) ) {
  95         1492  
  95         824  
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         375 $Expect::Spawned_PIDs{ ${*$self}{exp_Pid} } = undef;
  95         794  
193 95         2179 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"
  0         0  
216 0 0       0 if ${*$self}{"exp_Debug"};
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   41813 my ($self, @args) = @_;
268              
269 324 50       1189 my $type = ref($self)
270             or croak "$self is not an object";
271              
272 23     23   162 use vars qw($AUTOLOAD);
  23         29  
  23         859282  
273 324         974 my $name = $AUTOLOAD;
274 324         6850 $name =~ s/.*:://; # strip fully-qualified portion
275              
276 324 50       1337 unless ( exists $Readable_Vars{$name} ) {
277 0         0 croak "ERROR: cannot find method `$name' in class $type";
278             }
279 324         1682 my $varname = $Readable_Vars{$name};
280 324         428 my $tmp;
281 324 100       608 $tmp = ${*$self}{$varname} if exists ${*$self}{$varname};
  196         669  
  324         1578  
282              
283 324 100       1140 if (@args) {
284 76 50       1157 if ( exists $Writeable_Vars{$name} ) {
285 76         291 my $ref = ref($tmp);
286 76 50       324 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         157 ${*$self}{$varname} = shift @args;
  76         417  
292             }
293             } else {
294 0 0       0 carp "Trying to set read-only variable `$name'"
295             if $^W;
296             }
297             }
298              
299 324         1237 my $ref = ref($tmp);
300 324 50       1273 return ( wantarray ? @{$tmp} : $tmp ) if ( $ref eq 'ARRAY' );
  6 100       71  
301 318 0       811 return ( wantarray ? %{$tmp} : $tmp ) if ( $ref eq 'HASH' );
  0 50       0  
302 318         5271 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 32211 my ($self, $file, $mode) = @_;
361 65   100     817 $mode ||= "a";
362              
363 65 50       265 return ( ${*$self}{exp_Log_File} )
  0         0  
364             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     157 if ( ${*$self}{exp_Log_File} and ref( ${*$self}{exp_Log_File} ) ne 'CODE' ) {
  65         582  
  25         157  
368 9         73 close( ${*$self}{exp_Log_File} );
  9         282  
369             }
370 65         165 ${*$self}{exp_Log_File} = undef;
  65         306  
371 65 100       561 return if ( not $file );
372 39         71 my $fh = $file;
373 39 100       197 if ( not ref($file) ) {
374              
375             # it's a filename
376 23 50       780 $fh = IO::File->new( $file, $mode )
377             or croak "Cannot open logfile $file: $!";
378             }
379 39 100       8388 if ( ref($file) ne 'CODE' ) {
380 23 50       445 croak "Given logfile doesn't have a 'print' method"
381             if not $fh->can("print");
382 23         209 $fh->autoflush(1); # so logfile is up to date
383             }
384              
385 39         2863 ${*$self}{exp_Log_File} = $fh;
  39         205  
386              
387 39         124 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 1487 my ($self) = @_;
420 39         137 return $self->set_accum('');
421             }
422              
423             sub set_accum {
424 57     57 1 144 my ($self, $accum) = @_;
425              
426 57         66 my $old_accum = ${*$self}{exp_Accum};
  57         201  
427 57         110 ${*$self}{exp_Accum} = $accum;
  57         145  
428              
429             # return the contents of the accumulator.
430 57         235 return $old_accum;
431             }
432             sub get_accum {
433 1     1 0 5 my ($self) = @_;
434 1         2 return ${*$self}{exp_Accum};
  1         11  
435             }
436              
437             ######################################################################
438             # define constants for pattern subs
439 9904     9904 0 77904 sub exp_continue {"exp_continue"}
440 4772     4772 0 18247 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 54152272 my $self;
463              
464 4811 50       15213 print STDERR ("expect(@_) called...\n") if $Expect::Debug;
465 4811 50       19374 if ( defined( $_[0] ) ) {
466 4811 50 33     119114 if ( ref( $_[0] ) and $_[0]->isa('Expect') ) {
    0          
467 4811         8871 $self = shift;
468             } elsif ( $_[0] eq 'Expect' ) {
469 0         0 shift; # or as Expect->expect
470             }
471             }
472 4811 50       20922 croak "expect(): not enough arguments, should be expect(timeout, [patterns...])"
473             if @_ < 1;
474 4811         7269 my $timeout = shift;
475 4811         16172 my $timeout_hook = undef;
476              
477 4811         7957 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       9323 if ($self) {
485 4811         10884 $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         6080 my $parm;
498 4811         5875 my $parm_nr = 1;
499 4811         11964 while ( defined( $parm = shift ) ) {
500 14323 50       31207 print STDERR ("expect(): handling param '$parm'...\n")
501             if $Expect::Debug;
502 14323 100       31699 if ( ref($parm) ) {
503 14214 50       33970 if ( ref($parm) eq 'ARRAY' ) {
504 14214         38210 my $err = _add_patterns_to_list(
505             \@pattern_list, \@timeout_list,
506             $parm_nr, $parm
507             );
508 14214 50       39383 carp(
509             "expect(): Warning: multiple `timeout' patterns (",
510             scalar(@timeout_list), ").\r\n"
511             ) if @timeout_list > 1;
512 14214 100       32772 $timeout_hook = $timeout_list[-1] if $timeout_list[-1];
513 14214 50       34692 croak $err if $err;
514 14214         37294 $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       388 if ( substr( $parm, 0, 1 ) eq '-' ) {
522              
523             # it's an option
524 21 50       161 print STDERR ("expect(): handling option '$parm'...\n")
525             if $Expect::Debug;
526 21 50 33     413 if ( $parm eq '-i' ) {
    50          
527              
528             # first add collected patterns to object list
529 0 0       0 if ( scalar(@$curr_list) ) {
530 0 0       0 push @object_list, $curr_list
531             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       128 if ( ref( $_[1] ) eq 'CODE' ) {
546 0         0 push @pattern_list, [ $parm_nr, $parm, shift, shift ];
547             } else {
548 21         145 push @pattern_list, [ $parm_nr, $parm, shift, undef ];
549             }
550 21         96 $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       180 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       210 print STDERR ("expect(): exact match '$parm'...\n")
573             if $Expect::Debug;
574 88         344 push @pattern_list, [ $parm_nr, '-ex', $parm, undef ];
575             }
576 88         358 $parm_nr++;
577             }
578             }
579             }
580              
581             # add rest of collected patterns to object list
582 4811 50       10744 carp "expect(): Empty object list" unless $curr_list;
583 4811 50       17329 push @object_list, $curr_list if not exists $patterns{"$curr_list"};
584 4811         5303 push @{ $patterns{"$curr_list"} }, @pattern_list;
  4811         21397  
585              
586 4811 50       10905 my $debug = $self ? ${*$self}{exp_Debug} : $Expect::Debug;
  4811         15900  
587 4811 50       10783 my $internal = $self ? ${*$self}{exp_Exp_Internal} : $Expect::Exp_Internal;
  4811         9797  
588              
589             # now start matching...
590              
591 4811 50       22641 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     25795 cluck("Starting EXPECT pattern matching...\r\n")
598             if ( $debug or $internal );
599 4811         5545 my @ret;
600 4811         34928 @ret = _multi_expect(
601             $timeout, $timeout_hook,
602 4811         9310 map { [ $_, @{ $patterns{"$_"} } ] } @object_list
  4811         8431  
603             );
604              
605 4811 50       27947 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       39003 return wantarray ? @ret : $ret[0];
612             }
613              
614             ######################################################################
615             # the real workhorse
616             #
617             sub _multi_expect {
618 4811     4811   11625 my ($timeout, $timeout_hook, @params) = @_;
619              
620 4811 100       15714 if ($timeout_hook) {
621 4720 50 33     24066 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         10090 foreach my $pat (@params) {
627 4811         12673 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  4811         10541  
  4811         9407  
628 4811         6769 foreach my $exp ( @{ $pat->[0] } ) {
  4811         81623  
629 4811         6062 ${*$exp}{exp_New_Data} = 1; # first round we always try to match
  4811         100371  
630 4811 50 33     6413 if ( exists ${*$exp}{"exp_Max_Accum"}
  4811         60390  
  4811         20011  
631             and ${*$exp}{"exp_Max_Accum"} )
632             {
633 0         0 ${*$exp}{exp_Accum} = $exp->_trim_length(
  0         0  
634 0         0 ${*$exp}{exp_Accum},
635 0         0 ${*$exp}{exp_Max_Accum}
636             );
637             }
638 4811 0       12617 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       5873 if ( ${*$exp}{exp_Exp_Internal} ) {
  4811         30509  
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         69414 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         7352 my $start_loop_time = time();
676 4811         5210 my $exp_cont = 1;
677              
678             READLOOP:
679 4811         9428 while ($exp_cont) {
680 9833         13128 $exp_cont = 1;
681 9833         14192 $err = "";
682 9833         14966 my $rmask = '';
683 9833         14726 my $time_left = undef;
684 9833 50       24602 if ( defined $timeout ) {
685 9833         20707 $time_left = $timeout - ( time() - $start_loop_time );
686 9833 100       20189 $time_left = 0 if $time_left < 0;
687             }
688              
689 9833         11120 $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 9833         17404 foreach my $pat (@params) {
695 9833         51287 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  9833         20996  
  9833         24552  
696 9833         14236 foreach my $exp ( @{ $pat->[0] } ) {
  9833         21289  
697              
698             # build mask for select in next section...
699 9833         42828 my $fn = $exp->fileno();
700 9833 50       78653 vec( $rmask, $fn, 1 ) = 1 if defined $fn;
701              
702 9833 100       17811 next unless ${*$exp}{exp_New_Data};
  9833         34013  
703              
704             # clear error status
705 9789         14907 ${*$exp}{exp_Error} = undef;
  9789         27474  
706 9789         12013 ${*$exp}{exp_After} = undef;
  9789         27180  
707 9789         13331 ${*$exp}{exp_Match_Number} = undef;
  9789         17602  
708 9789         18963 ${*$exp}{exp_Match} = undef;
  9789         22584  
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 0         0 print STDERR (
716 0         0 "\r\n${*$exp}{exp_Pty_Handle}: Does `",
717 9789         98891 $exp->_trim_length( _make_readable( ${*$exp}{exp_Accum} ) ),
718             "'\r\nmatch:\r\n"
719 9789 50       21520 ) if ${*$exp}{exp_Exp_Internal};
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 9789         17964 foreach my $pattern (@patterns) {
726 14795         42464 print STDERR (
727             " pattern",
728             defined( $pattern->[0] ) ? ' #' . $pattern->[0] : '',
729             ": ",
730             $pattern->[1],
731             " `",
732             _make_readable( $pattern->[2] ),
733             "'? "
734 14795 0       18125 ) if ( ${*$exp}{exp_Exp_Internal} );
    50          
735              
736             # Matching exactly
737 14795 100       101435 if ( $pattern->[1] eq '-ex' ) {
    100          
738 119         424 my $match_index =
739 119         225 index( ${*$exp}{exp_Accum}, $pattern->[2] );
740              
741             # We matched if $match_index > -1
742 119 100       493 if ( $match_index > -1 ) {
743 29         102 $before =
744 29         29 substr( ${*$exp}{exp_Accum}, 0, $match_index );
745 29         116 $match = substr(
746 29         44 ${*$exp}{exp_Accum},
747             $match_index, length( $pattern->[2] )
748             );
749 29         101 $after = substr(
750 29         44 ${*$exp}{exp_Accum},
751             $match_index + length( $pattern->[2] )
752             );
753 29         44 ${*$exp}{exp_Before} = $before;
  29         86  
754 29         44 ${*$exp}{exp_Match} = $match;
  29         58  
755 29         43 ${*$exp}{exp_After} = $after;
  29         58  
756 29         58 ${*$exp}{exp_Match_Number} = $pattern->[0];
  29         72  
757 29         58 $exp_matched = $exp;
758             }
759             } elsif ( $pattern->[1] eq '-re' ) {
760              
761 9803 100       18678 if ($Expect::Multiline_Matching) {
762 9789         208816 @matchlist =
763 9789         11608 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m);
764             } else {
765 14         225 @matchlist =
766 14         17 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/);
767             }
768 9803 100       29146 if (@matchlist) {
769              
770             # Matching regexp
771 4798         9352 $match = shift @matchlist;
772 4798         5732 my $start = index ${*$exp}{exp_Accum}, $match;
  4798         17935  
773 4798 50       11561 die 'The match could not be found' if $start == -1;
774 4798         6406 $before = substr ${*$exp}{exp_Accum}, 0, $start;
  4798         15043  
775 4798         7162 $after = substr ${*$exp}{exp_Accum}, $start + length($match);
  4798         15299  
776              
777 4798         6604 ${*$exp}{exp_Before} = $before;
  4798         9183  
778 4798         5424 ${*$exp}{exp_Match} = $match;
  4798         10954  
779 4798         9506 ${*$exp}{exp_After} = $after;
  4798         8994  
780             #pop @matchlist; # remove kludged empty bracket from end
781 4798         6491 @{ ${*$exp}{exp_Matchlist} } = @matchlist;
  4798         4369  
  4798         10852  
782 4798         8389 ${*$exp}{exp_Match_Number} = $pattern->[0];
  4798         10432  
783 4798         8428 $exp_matched = $exp;
784             }
785             } else {
786              
787             # 'timeout' or 'eof'
788             }
789              
790 14795 100       37399 if ($exp_matched) {
791 4782         17063 ${*$exp}{exp_Accum} = $after
  4827         15772  
792 4827 100       13192 unless ${*$exp}{exp_NoTransfer};
793 4827         13895 print STDERR "YES!!\r\n"
794 4827 50       6745 if ${*$exp}{exp_Exp_Internal};
795 0         0 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 4827         12855 map { "`" . $exp->_trim_length( _make_readable( ($_) ) ) . "'" } @matchlist,
809             ),
810             ")\r\n",
811 4827 50       7309 ) if ( ${*$exp}{exp_Exp_Internal} );
812              
813             # call hook function if defined
814 4827 100       11522 if ( $pattern->[3] ) {
815 4778         21415 print STDERR (
816             "Calling hook $pattern->[3]...\r\n",
817             )
818 4778 50 33     7938 if ( ${*$exp}{exp_Exp_Internal}
819             or $Expect::Debug );
820 4778 50       6493 if ( $#{$pattern} > 3 ) {
  4778         12839  
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         5940 $exp_cont = &{ $pattern->[3] }($exp);
  4778         15411  
826             }
827             }
828 4827 100 66     37196 if ( $exp_cont and $exp_cont eq exp_continue ) {
    50 33        
829 64         742 print STDERR ("Continuing expect, restarting timeout...\r\n")
830 64 50 33     260 if ( ${*$exp}{exp_Exp_Internal}
831             or $Expect::Debug );
832 64         181 $start_loop_time = time(); # restart timeout count
833 64         1369 next READLOOP;
834             } elsif ( $exp_cont
835             and $exp_cont eq exp_continue_timeout )
836             {
837 0         0 print STDERR ("Continuing expect...\r\n")
838 0 0 0     0 if ( ${*$exp}{exp_Exp_Internal}
839             or $Expect::Debug );
840 0         0 next READLOOP;
841             }
842 4763         15576 last READLOOP;
843             }
844 9968 50       10251 print STDERR "No.\r\n" if ${*$exp}{exp_Exp_Internal};
  9968         39344  
845             }
846 4962 50       6703 print STDERR "\r\n" if ${*$exp}{exp_Exp_Internal};
  4962         13790  
847              
848             # don't have to match again until we get new data
849 4962         14997 ${*$exp}{exp_New_Data} = 0;
  4962         56043  
850             }
851             } # End of matching section
852              
853             # No match, let's see what is pending on the filehandles...
854 5006 0 33     18101 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 5006         5504 my $nfound;
860 5006         90490768 SELECT: {
861 5006         5067 $nfound = select( $rmask, undef, undef, $time_left );
862 5006 50       80342 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 5006 100       11862 if ( $nfound == 0 ) {
879              
880             # No pattern, no EOF. Did we time out?
881 69         634 $err = "1:TIMEOUT";
882 69         381 foreach my $pat (@params) {
883 69         209 foreach my $exp ( @{ $pat->[0] } ) {
  69         391  
884 69         224 $before = ${*$exp}{exp_Before} = ${*$exp}{exp_Accum};
  69         370  
  69         695  
885 69 50       892 next if not defined $exp->fileno(); # skip already closed
886 69 100       910 ${*$exp}{exp_Error} = $err unless ${*$exp}{exp_Error};
  36         280  
  69         569  
887             }
888             }
889 69 50 33     806 print STDERR ("TIMEOUT\r\n")
890             if ( $Expect::Debug or $Expect::Exp_Internal );
891 69 100       260 if ($timeout_hook) {
892 46         235 my $ret;
893 46 50 33     328 print STDERR ("Calling timeout function $timeout_hook...\r\n")
894             if ( $Expect::Debug or $Expect::Exp_Internal );
895 46 50       219 if ( ref($timeout_hook) eq 'CODE' ) {
896 0         0 $ret = &{$timeout_hook}( $params[0]->[0] );
  0         0  
897             } else {
898 46 50       90 if ( $#{$timeout_hook} > 3 ) {
  46         219  
899 0         0 $ret = &{ $timeout_hook->[3] }(
  0         0  
900             $params[0]->[0],
901 0         0 @{$timeout_hook}[ 4 .. $#{$timeout_hook} ]
  0         0  
902             );
903             } else {
904 46         125 $ret = &{ $timeout_hook->[3] }( $params[0]->[0] );
  46         311  
905             }
906             }
907 46 100 66     1803 if ( $ret and $ret eq exp_continue ) {
908 44         99 $start_loop_time = time(); # restart timeout count
909 44         275 next READLOOP;
910             }
911             }
912 25         242 last READLOOP;
913             }
914              
915 4937         42884 my @bits = split( //, unpack( 'b*', $rmask ) );
916 4937         12443 foreach my $pat (@params) {
917 4937         7318 foreach my $exp ( @{ $pat->[0] } ) {
  4937         13524  
918 4937 50       17051 next if not defined $exp->fileno(); # skip already closed
919 4937 50       37999 if ( $bits[ $exp->fileno() ] ) {
920 4937 50       29783 print STDERR ("${*$exp}{exp_Pty_Handle}: new data.\r\n")
  0         0  
921             if $Expect::Debug;
922              
923             # read in what we found.
924 4937         7937 my $buffer;
925 4937         47860 my $nread = sysread( $exp, $buffer, 2048 );
926              
927             # Make errors (nread undef) show up as EOF.
928 4937 100       10617 $nread = 0 unless defined($nread);
929              
930 4937 100       9379 if ( $nread == 0 ) {
931 23 50       102 print STDERR ("${*$exp}{exp_Pty_Handle}: EOF\r\n")
  0         0  
932             if ($Expect::Debug);
933 23         111 $before = ${*$exp}{exp_Before} = $exp->clear_accum();
  23         60  
934 23         60 $err = "2:EOF";
935 23         23 ${*$exp}{exp_Error} = $err;
  23         1222  
936 23         37 ${*$exp}{exp_Has_EOF} = 1;
  23         172  
937 23         60 $exp_cont = undef;
938 23         60 foreach my $eof_pat ( grep { $_->[1] eq '-eof' } @{$pat}[ 1 .. $#{$pat} ] ) {
  41         133  
  23         51  
  23         60  
939 9         90 my $ret;
940 9 50       54 print STDERR ( "Calling EOF hook $eof_pat->[3]...\r\n", )
941             if ($Expect::Debug);
942 9 50       45 if ( $#{$eof_pat} > 3 ) {
  9         99  
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         72 $ret = &{ $eof_pat->[3] }($exp);
  9         63  
948             }
949 9 50 33     198 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       46 if ( defined( ${*$exp}{exp_Pid} ) ) {
  23         115  
960 23         864 my $ret =
961 23         23 waitpid( ${*$exp}{exp_Pid}, POSIX::WNOHANG );
962 23 50       46 if ( $ret == ${*$exp}{exp_Pid} ) {
  23         237  
963 0         0 printf STDERR (
964             "%s: exit(0x%02X)\r\n",
965 23 50       74 ${*$exp}{exp_Pty_Handle}, $?
966             ) if ($Expect::Debug);
967 23         51 $err = "3:Child PID ${*$exp}{exp_Pid} exited with status $?";
  23         185  
968 23         51 ${*$exp}{exp_Error} = $err;
  23         69  
969 23         37 ${*$exp}{exp_Exit} = $?;
  23         114  
970 23         60 delete $Expect::Spawned_PIDs{ ${*$exp}{exp_Pid} };
  23         83  
971 23         37 ${*$exp}{exp_Pid} = undef;
  23         60  
972             }
973             }
974 23 50       83 print STDERR ("${*$exp}{exp_Pty_Handle}: closing...\r\n")
  0         0  
975             if ($Expect::Debug);
976 23         239 $exp->hard_close();
977 23         92 next;
978             }
979 4914 50       8978 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 4914 100       62365 $buffer =~ s/ \cH//g if not ${*$exp}{exp_Raw_Pty};
  4914         18466  
985              
986             # Append it to the accumulator.
987 4914         6435 ${*$exp}{exp_Accum} .= $buffer;
  4914         14677  
988 4914 50 33     5695 if ( exists ${*$exp}{exp_Max_Accum}
  4914         26380  
  4914         26499  
989             and ${*$exp}{exp_Max_Accum} )
990             {
991 0         0 ${*$exp}{exp_Accum} = $exp->_trim_length(
  0         0  
992 0         0 ${*$exp}{exp_Accum},
993 0         0 ${*$exp}{exp_Max_Accum}
994             );
995             }
996 4914         8276 ${*$exp}{exp_New_Data} = 1; # next round we try to match again
  4914         9306  
997              
998 4914         22974 $exp_cont = exp_continue
999 0         0 if ( exists ${*$exp}{exp_Continue}
1000 4914 50 33     5339 and ${*$exp}{exp_Continue} );
1001              
1002             # Now propagate what we have read to other listeners...
1003 4914         16953 $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 4937 50 66     19105 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     19856 if ( $Expect::Debug or $Expect::Exp_Internal ) {
1018 0 0       0 if ($exp_matched) {
1019 0         0 print STDERR (
1020             "Returning from expect ",
1021 0         0 ${*$exp_matched}{exp_Error} ? 'un' : '',
1022             "successfully.",
1023 0 0       0 ${*$exp_matched}{exp_Error}
    0          
1024 0         0 ? "\r\n Error: ${*$exp_matched}{exp_Error}."
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 0         0 print STDERR (
1035 0         0 $exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Before} ) ),
1036             "'\r\n"
1037             );
1038             } else {
1039 0         0 print STDERR (
1040 0         0 $exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Accum} ) ),
1041             "'\r\n"
1042             );
1043             }
1044             }
1045             }
1046              
1047 4811 100       10925 if ($exp_matched) {
1048             return wantarray
1049             ? (
1050 4763         21508 ${*$exp_matched}{exp_Match_Number}, ${*$exp_matched}{exp_Error},
  4763         15617  
  4763         8783  
1051 4763         7746 ${*$exp_matched}{exp_Match}, ${*$exp_matched}{exp_Before},
  4763         31966  
1052 0         0 ${*$exp_matched}{exp_After}, $exp_matched,
1053             )
1054 4763 50       8547 : ${*$exp_matched}{exp_Match_Number};
1055             }
1056              
1057 48 50       453 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   34560 my ($listref, $timeoutlistref,$store_parm_nr, @params) = @_;
1069              
1070             # $timeoutlistref gets timeout patterns
1071 14214   50     33982 my $parm_nr = $store_parm_nr || 1;
1072 14214         24524 foreach my $parm (@params) {
1073 14214 50       73768 if ( not ref($parm) eq 'ARRAY' ) {
1074 0         0 return "Parameter #$parm_nr is not an ARRAY ref.";
1075             }
1076 14214         36023 $parm = [@$parm]; # make copy
1077 14214 50       35295 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       39948 if ( $parm->[0] eq 'timeout' ) {
    100          
1087 4720 50       9444 if ( defined $timeoutlistref ) {
1088 4720         19677 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1089 4720 50       13172 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1090 4720         7344 push @$timeoutlistref, $parm;
1091             }
1092 4720         12275 next;
1093             } elsif ( $parm->[0] eq 'eof' ) {
1094 4720         22538 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1095             } else {
1096 4774         12790 unshift @$parm, '-re'; # defaults to RegExp
1097             }
1098             }
1099 9494 100       18062 if ( @$parm > 2 ) {
1100 9491 50       33393 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         9 push @$parm, undef; # make sure we have three elements
1108             }
1109              
1110 9494 50       20877 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1111 9494         13896 push @$listref, $parm;
1112 9494         50784 $parm_nr++;
1113             }
1114              
1115 14214         37863 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   268 no strict 'subs'; # Allow bare word 'STDIN'
  23         51  
  23         159048  
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"
  0         0  
1232 0 0       0 if ${*$handle}{"exp_Debug"};
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} =
  0         0  
1238             $write_handle->exp_stty('-g');
1239 0         0 print STDERR "Setting ${*$write_handle}{exp_Pty_Handle} to 'raw -echo'.\r\n"
  0         0  
1240 0 0       0 if ${*$handle}{"exp_Debug"};
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 )
  0         0  
1259 0         0 if ( exists( ${*$read_handle}{exp_Pid} )
1260 0 0 0     0 and ${*$read_handle}{exp_Pid} );
1261 0 0 0     0 if ( exists( ${*$read_handle}{exp_Pid} )
  0   0     0  
  0         0  
1262 0         0 and ( ${*$read_handle}{exp_Pid} )
1263             and ( !kill( 0, ${*$read_handle}{exp_Pid} ) ) )
1264             {
1265 0         0 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"};
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  
  0         0  
1272 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } );
  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 0         0 $nread = sysread(
1291 0         0 $read_handle, ${*$read_handle}{exp_Pty_Buffer},
1292             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"
  0         0  
1298 0 0       0 if ${*$read_handle}{"exp_Debug"} > 1;
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}"
  0         0  
1307 0 0       0 if ${*$read_handle}{"exp_Debug"} > 1;
1308              
1309             # Make sure it doesn't grow out of bounds.
1310 0         0 $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"} );
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  
  0         0  
1350 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{$escape_sequence} } );
  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 )
  0         0  
1355 0         0 if ( defined( ${*$read_handle}{exp_Pid} )
1356 0 0 0     0 && ${*$read_handle}{exp_Pid} );
1357 0 0       0 if ( $nread == 0 ) {
1358 0         0 print STDERR "Got EOF reading ${*$read_handle}{exp_Pty_Handle}\r\n"
  0         0  
1359 0 0       0 if ${*$read_handle}{"exp_Debug"};
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  
  0         0  
1364 0 0       0 ( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } );
  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 4941     4941 1 32660 my ($self, @params) = @_;
1401              
1402 4941 100       10002 if ( ${*$self}{exp_Log_File} ) {
  4941         28483  
1403 4809 100       5753 if ( ref( ${*$self}{exp_Log_File} ) eq 'CODE' ) {
  4809         16178  
1404 48         104 ${*$self}{exp_Log_File}->(@params);
  48         408  
1405             } else {
1406 4761         5485 ${*$self}{exp_Log_File}->print(@params);
  4761         19134  
1407             }
1408             }
1409              
1410 4941         12145258 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 174368 my ( $self, @args ) = @_;
1417              
1418 4624 50       12218 return if not defined $self->fileno(); # skip if closed
1419 4624 50       24430 if ( ${*$self}{exp_Exp_Internal} ) {
  4624         116087  
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         13622 foreach my $arg (@args) {
1424 4624         9750 while ( length($arg) > 80 ) {
1425 10326         53297 $self->SUPER::print( substr( $arg, 0, 80 ) );
1426 10326         476239 $arg = substr( $arg, 80 );
1427             }
1428 4624         16820 $self->SUPER::print($arg);
1429             }
1430              
1431 4624         503786 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 33288 my ($self, $sleep_time, @chunks) = @_;
1441              
1442 24 50       104 return if not defined $self->fileno(); # skip if closed
1443              
1444             # Flushing makes it so each character can be seen separately.
1445 24         224 my $chunk;
1446 24         88 while ( $chunk = shift @chunks ) {
1447 24         408 my @linechars = split( '', $chunk );
1448 24         144 foreach my $char (@linechars) {
1449              
1450             # How slow?
1451 1040         104876904 select( undef, undef, undef, $sleep_time );
1452              
1453 1040         126144 print $self $char;
1454 0         0 print STDERR "Printed character \'" . _make_readable($char) . "\' to ${*$self}{exp_Pty_Handle}.\r\n"
  1040         73920  
1455 1040 50       4120 if ${*$self}{"exp_Debug"} > 1;
1456              
1457             # I think I can get away with this if I save it in accum
1458 1040 50 33     9584 if ( ${*$self}{"exp_Log_Stdout"} || ${*$self}{exp_Log_Group} ) {
  1040         8208  
  0         0  
1459 1040         3864 my $rmask = "";
1460 1040         16024 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         10704472 while ( select( $rmask, undef, undef, .01 ) ) {
1465 24         144 my $ret = sysread( $self, ${*$self}{exp_Pty_Buffer}, 1024 );
  24         456  
1466 24 50 33     360 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         56 ${*$self}{exp_Accum} .= ${*$self}{exp_Pty_Buffer};
  24         112  
  24         144  
1471 0         0 ${*$self}{exp_Accum} = $self->_trim_length(
  0         0  
1472 0         0 ${*$self}{exp_Accum},
1473 24         152 ${*$self}{"exp_Max_Accum"}
1474 24 50       48 ) if ( ${*$self}{"exp_Max_Accum"} );
1475 24         72 $self->_print_handles( ${*$self}{exp_Pty_Buffer} );
  24         208  
1476 24         245144 print STDERR "Received \'"
1477             . $self->_trim_length( _make_readable($char) )
1478 0         0 . "\' from ${*$self}{exp_Pty_Handle}\r\n"
1479 24 50       64 if ${*$self}{"exp_Debug"} > 1;
1480             }
1481             }
1482             }
1483             }
1484              
1485 24         272 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 9698 my ($self) = @_;
1526              
1527 7         49 my ( $nfound, $nread, $rmask, $end_time, $temp_buffer );
1528              
1529             # Give it 15 seconds to cough up an eof.
1530 7 50       26 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  7         72  
1531 7 50       66 return -1 if not defined $self->fileno(); # skip if handle already closed
1532 7 50 33     87 unless ( exists ${*$self}{exp_Has_EOF} and ${*$self}{exp_Has_EOF} ) {
  7         106  
  0         0  
1533 7         48 $end_time = time() + 15;
1534 7         35 while ( $end_time > time() ) {
1535 10         30 my $select_time = $end_time - time();
1536              
1537             # Sanity check.
1538 10 50       55 $select_time = 0 if $select_time < 0;
1539 10         50 $rmask = '';
1540 10         95 vec( $rmask, $self->fileno(), 1 ) = 1;
1541 10         13990588 ($nfound) = select( $rmask, undef, undef, $select_time );
1542 10 50 33     338 last unless ( defined($nfound) && $nfound );
1543 10         258 $nread = sysread( $self, $temp_buffer, 8096 );
1544              
1545             # 0 = EOF.
1546 10 100 66     158 unless ( defined($nread) && $nread ) {
1547 0         0 print STDERR "Got EOF from ${*$self}{exp_Pty_Handle}.\r\n"
  7         73  
1548 7 50       18 if ${*$self}{exp_Debug};
1549 7         56 last;
1550             }
1551 3         105 $self->_print_handles($temp_buffer);
1552             }
1553 7 50 33     55 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         142 my $close_status = $self->close();
1558 7 50 33     7095152 if ( $close_status && ${*$self}{exp_Debug} ) {
  7         89  
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       40 return $close_status unless defined( ${*$self}{exp_Pid} );
  7         46  
1564              
1565             # Now give it 15 seconds to die.
1566 7         24 $end_time = time() + 15;
1567 7         36 while ( $end_time > time() ) {
1568 7         46 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  7         327  
1569              
1570             # Stop here if the process dies.
1571 7 50 33     97 if ( defined($returned_pid) && $returned_pid ) {
1572 7         56 delete $Expect::Spawned_PIDs{$returned_pid};
1573 7 50       26 if ( ${*$self}{exp_Debug} ) {
  7         59  
1574 0         0 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}, $?
1578             );
1579             }
1580 7         18 ${*$self}{exp_Pid} = undef;
  7         25  
1581 7         18 ${*$self}{exp_Exit} = $?;
  7         91  
1582 7         49 return ${*$self}{exp_Exit};
  7         71  
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 0         0 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}, $?
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 65514 my ($self) = @_;
1620              
1621 167 50       310 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  167         727  
1622              
1623             # Don't wait for an EOF.
1624 167         1245 my $close_status = $self->close();
1625 167 50 66     57707 if ( $close_status && ${*$self}{exp_Debug} ) {
  101         781  
1626 0         0 print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n";
  0         0  
1627             }
1628              
1629             # Return now if handle.
1630 167 100       275 return $close_status unless defined( ${*$self}{exp_Pid} );
  167         670  
1631              
1632             # Now give it 5 seconds to die. Less patience here if it won't die.
1633 78         257 my $end_time = time() + 5;
1634 78         356 while ( $end_time > time() ) {
1635 103         269 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  103         7761  
1636              
1637             # Stop here if the process dies.
1638 103 100 66     1136 if ( defined($returned_pid) && $returned_pid ) {
1639 78         516 delete $Expect::Spawned_PIDs{$returned_pid};
1640 78 50       142 if ( ${*$self}{exp_Debug} ) {
  78         361  
1641 0         0 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}, $?
1645             );
1646             }
1647 78         211 ${*$self}{exp_Pid} = undef;
  78         229  
1648 78         249 ${*$self}{exp_Exit} = $?;
  78         500  
1649 78         273 return ${*$self}{exp_Exit};
  78         918  
1650             }
1651 25         25004250 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 0         0 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}, $?
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 0         0 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}, $?
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   341 my ($self) = @_;
1710              
1711             # for every spawned process or filehandle.
1712 126 50       470 ${*$self}{exp_Log_Stdout} = $Expect::Log_Stdout
  0         0  
1713             if defined($Expect::Log_Stdout);
1714 126         302 ${*$self}{exp_Log_Group} = $Expect::Log_Group;
  126         404  
1715 126         296 ${*$self}{exp_Debug} = $Expect::Debug;
  126         349  
1716 126         273 ${*$self}{exp_Exp_Internal} = $Expect::Exp_Internal;
  126         325  
1717 126         221 ${*$self}{exp_Manual_Stty} = $Expect::Manual_Stty;
  126         344  
1718 126         269 ${*$self}{exp_Stored_Stty} = 'sane';
  126         492  
1719 126         243 ${*$self}{exp_Do_Soft_Close} = $Expect::Do_Soft_Close;
  126         343  
1720              
1721             # sysread doesn't like my or local vars.
1722 126         260 ${*$self}{exp_Pty_Buffer} = '';
  126         300  
1723              
1724             # Initialize accumulator.
1725 126         295 ${*$self}{exp_Max_Accum} = $Expect::Exp_Max_Accum;
  126         664  
1726 126         257 ${*$self}{exp_Accum} = '';
  126         351  
1727 126         324 ${*$self}{exp_NoTransfer} = 0;
  126         402  
1728              
1729             # create empty expect_before & after lists
1730 126         251 ${*$self}{exp_expect_before_list} = [];
  126         320  
1731 126         273 ${*$self}{exp_expect_after_list} = [];
  126         282  
1732              
1733 126         243 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   2877 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       257 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 7         97 return ($string)
1772             if (defined($self)
1773 15 50 66     46 and ${*$self}{"exp_Debug"} >= 3
      33        
1774             and ( !( defined($length) ) ) );
1775 15 100       153 my $indicate_truncation = ($length ? '' : '...');
1776 15   100     47 $length ||= 1021;
1777 15 100       231 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         73 return $indicate_truncation . substr( $string, ( length($string) - $length ), $length );
1783             }
1784              
1785             sub _print_handles {
1786 4941     4941   9605 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 4941 50       5630 if ( ${*$self}{exp_Log_Group} ) {
  4941         32945  
1791 4941         5894 foreach my $handle ( @{ ${*$self}{exp_Listen_Group} } ) {
  4941         5879  
  4941         16110  
1792 0 0       0 $print_this = '' unless defined($print_this);
1793              
1794             # Appease perl -w
1795 0         0 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 );
1799 0         0 print $handle $print_this;
1800             }
1801             }
1802              
1803             # If ${*$self}{exp_Pty_Handle} is STDIN this would make it echo.
1804 4941         77226 print STDOUT $print_this
1805 4941 100       8405 if ${*$self}{"exp_Log_Stdout"};
1806 4941         15905 $self->print_log_file($print_this);
1807 4941         10259 $| = 1; # This should not be necessary but autoflush() doesn't always work.
1808              
1809 4941         23242 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   213036 my ($self) = @_;
1843              
1844 109         356 my $status = $?; # save this as it gets mangled by the terminating spawned children
1845 109 50       248 if ( ${*$self}{exp_Do_Soft_Close} ) {
  109         736  
1846 0         0 $self->soft_close();
1847             }
1848 109         712 $self->hard_close();
1849 109         256 $? = $status; # restore it. otherwise deleting an Expect object may mangle $?, which is unintuitive
1850              
1851 109         6357 return;
1852             }
1853              
1854             1;
1855             __END__