File Coverage

blib/lib/Expect.pm
Criterion Covered Total %
statement 645 1164 55.4
branch 215 534 40.2
condition 49 171 28.6
subroutine 35 46 76.0
pod 16 22 72.7
total 960 1937 49.5


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             # Dave Jacoby
15             #
16              
17 23     23   963928 use 5.006;
  23         357  
18              
19             package Expect;
20 23     23   132 use strict;
  23         32  
  23         417  
21 23     23   119 use warnings;
  23         79  
  23         760  
22              
23 23     23   10159 use IO::Pty 1.11; # We need make_slave_controlling_terminal()
  23         298401  
  23         986  
24 23     23   159 use IO::Tty;
  23         49  
  23         79  
25              
26 23     23   1495 use POSIX qw(:sys_wait_h :unistd_h); # For WNOHANG and isatty
  23         48  
  23         99  
27 23     23   35840 use Fcntl qw(:DEFAULT); # For checking file handle settings.
  23         53  
  23         5627  
28 23     23   147 use Carp qw(cluck croak carp confess);
  23         33  
  23         1111  
29 23     23   123 use IO::Handle ();
  23         32  
  23         382  
30 23     23   182 use Exporter qw(import);
  23         35  
  23         533  
31 23     23   3465 use Errno;
  23         7969  
  23         2934  
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   62 $Expect::VERSION = '1.35';
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         45 $Expect::Log_Group = 1;
47 23         31 $Expect::Debug = 0;
48 23         45 $Expect::Exp_Max_Accum = 0; # unlimited
49 23         79 $Expect::Exp_Internal = 0;
50 23         44 $Expect::IgnoreEintr = 0;
51 23         136 $Expect::Manual_Stty = 0;
52 23         41 $Expect::Multiline_Matching = 1;
53 23         29 $Expect::Do_Soft_Close = 0;
54 23         46 @Expect::Before_List = ();
55 23         47 @Expect::After_List = ();
56 23         25480 %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 209082 my ($class, @args) = @_;
72              
73 126 50       552 $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         1574 my ($self) = IO::Pty->new;
77 126 50       66739 die "$class: Could not assign a pty" unless $self;
78 126         466 bless $self => $class;
79 126         657 $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         4238 ${*$self}{exp_Log_Stdout} = 1;
  126         699  
84 126         829 $self->_init_vars();
85              
86 126 100       469 if (@args) {
87              
88             # we got add'l parms, so pass them to spawn
89 64         281 return $self->spawn(@args);
90             }
91 62         191 return $self;
92             }
93              
94             sub spawn {
95 126     126 1 38811 my ($class, @cmd) = @_;
96             # spawn is passed command line args.
97              
98 126         279 my $self;
99              
100 126 100       484 if ( ref($class) ) {
101 111         305 $self = $class;
102             } else {
103 15         105 $self = $class->new();
104             }
105              
106             croak "Cannot reuse an object with an already spawned command"
107 126 100       213 if exists ${*$self}{"exp_Command"};
  126         1045  
108 125         370 ${*$self}{"exp_Command"} = \@cmd;
  125         543  
109              
110             # set up pipe to detect childs exec error
111 125 50       1830 pipe( FROM_CHILD, TO_PARENT ) or die "Cannot open pipe: $!";
112 125 50       1267 pipe( FROM_PARENT, TO_CHILD ) or die "Cannot open pipe: $!";
113 125         1094 TO_PARENT->autoflush(1);
114 125         5260 TO_CHILD->autoflush(1);
115 125         3871 eval { fcntl( TO_PARENT, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC ); };
  125         518  
116              
117 125         95306 my $pid = fork;
118              
119 125 50       2905 unless ( defined($pid) ) {
120 0 0       0 warn "Cannot fork: $!" if $^W;
121 0         0 return;
122             }
123              
124 125 100       1896 if ($pid) {
125              
126             # parent
127 108         669 my $errno;
128 108         323 ${*$self}{exp_Pid} = $pid;
  108         5587  
129 108         2610 close TO_PARENT;
130 108         1067 close FROM_PARENT;
131 108         4408 $self->close_slave();
132 108 100 66     12297 $self->set_raw() if $self->raw_pty and isatty($self);
133 108         4233 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         82739864 my $errstatus = sysread( FROM_CHILD, $errno, 256 );
137 108 50       1339 die "Cannot sync with child: $!" if not defined $errstatus;
138 108         2485 close FROM_CHILD;
139 108 100       665 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         1243 close FROM_CHILD;
148 17         401 close TO_CHILD;
149              
150 17         1994 $self->make_slave_controlling_terminal();
151 17 50       11283 my $slv = $self->slave()
152             or die "Cannot get slave: $!";
153              
154 17 100       968 $slv->set_raw() if $self->raw_pty;
155 17         1850 close($self);
156              
157             # wait for parent before we detach
158 17         159 my $buffer;
159 17         264 my $errstatus = sysread( FROM_PARENT, $buffer, 256 );
160 17 50       283 die "Cannot sync with parent: $!" if not defined $errstatus;
161 17         242 close FROM_PARENT;
162              
163 17         183 close(STDIN);
164 17 50       412 open( STDIN, "<&" . $slv->fileno() )
165             or die "Couldn't reopen STDIN for reading, $!\n";
166 17         518 close(STDOUT);
167 17 50       232 open( STDOUT, ">&" . $slv->fileno() )
168             or die "Couldn't reopen STDOUT for writing, $!\n";
169 17         418 close(STDERR);
170 17 50       163 open( STDERR, ">&" . $slv->fileno() )
171             or die "Couldn't reopen STDERR for writing, $!\n";
172              
173 17         377 { 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         2008 ${*$self}{exp_Pty_Handle} = "spawn id(" . $self->fileno() . ")";
  95         2432  
184 95 50 33     353 if ( ( ${*$self}{"exp_Debug"} ) or ( ${*$self}{"exp_Exp_Internal"} ) ) {
  95         1072  
  95         671  
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         348 $Expect::Spawned_PIDs{ ${*$self}{exp_Pid} } = undef;
  95         657  
193 95         1228 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   32512 my ($self, @args) = @_;
268              
269 324 50       1503 my $type = ref($self)
270             or croak "$self is not an object";
271              
272 23     23   185 use vars qw($AUTOLOAD);
  23         48  
  23         93356  
273 324         1027 my $name = $AUTOLOAD;
274 324         4578 $name =~ s/.*:://; # strip fully-qualified portion
275              
276 324 50       1669 unless ( exists $Readable_Vars{$name} ) {
277 0         0 croak "ERROR: cannot find method `$name' in class $type";
278             }
279 324         1519 my $varname = $Readable_Vars{$name};
280 324         554 my $tmp;
281 324 100       614 $tmp = ${*$self}{$varname} if exists ${*$self}{$varname};
  196         668  
  324         1814  
282              
283 324 100       1225 if (@args) {
284 76 50       294 if ( exists $Writeable_Vars{$name} ) {
285 76         237 my $ref = ref($tmp);
286 76 50       396 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         214 ${*$self}{$varname} = shift @args;
  76         270  
292             }
293             } else {
294 0 0       0 carp "Trying to set read-only variable `$name'"
295             if $^W;
296             }
297             }
298              
299 324         1336 my $ref = ref($tmp);
300 324 50       1163 return ( wantarray ? @{$tmp} : $tmp ) if ( $ref eq 'ARRAY' );
  6 100       46  
301 318 0       1015 return ( wantarray ? %{$tmp} : $tmp ) if ( $ref eq 'HASH' );
  0 50       0  
302 318         3942 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 41415 my ($self, $file, $mode) = @_;
361 65   100     639 $mode ||= "a";
362              
363 0         0 return ( ${*$self}{exp_Log_File} )
364 65 50       320 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     152 if ( ${*$self}{exp_Log_File} and ref( ${*$self}{exp_Log_File} ) ne 'CODE' ) {
  65         490  
  25         267  
368 9         72 close( ${*$self}{exp_Log_File} );
  9         187  
369             }
370 65         228 ${*$self}{exp_Log_File} = undef;
  65         286  
371 65 100       420 return if ( not $file );
372 39         112 my $fh = $file;
373 39 100       187 if ( not ref($file) ) {
374              
375             # it's a filename
376 23 50       426 $fh = IO::File->new( $file, $mode )
377             or croak "Cannot open logfile $file: $!";
378             }
379 39 100       70649 if ( ref($file) ne 'CODE' ) {
380 23 50       642 croak "Given logfile doesn't have a 'print' method"
381             if not $fh->can("print");
382 23         188 $fh->autoflush(1); # so logfile is up to date
383             }
384              
385 39         1606 ${*$self}{exp_Log_File} = $fh;
  39         158  
386              
387 39         148 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 1450 my ($self) = @_;
420 39         152 return $self->set_accum('');
421             }
422              
423             sub set_accum {
424 57     57 1 211 my ($self, $accum) = @_;
425              
426 57         107 my $old_accum = ${*$self}{exp_Accum};
  57         221  
427 57         132 ${*$self}{exp_Accum} = $accum;
  57         177  
428              
429             # return the contents of the accumulator.
430 57         288 return $old_accum;
431             }
432             sub get_accum {
433 1     1 0 5 my ($self) = @_;
434 1         3 return ${*$self}{exp_Accum};
  1         11  
435             }
436              
437             ######################################################################
438             # define constants for pattern subs
439 9716     9716 0 47843 sub exp_continue {"exp_continue"}
440 4772     4772 0 14837 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 54110701 my $self;
463              
464 4811 50       11394 print STDERR ("expect(@_) called...\n") if $Expect::Debug;
465 4811 50       10886 if ( defined( $_[0] ) ) {
466 4811 50 33     30503 if ( ref( $_[0] ) and $_[0]->isa('Expect') ) {
    0          
467 4811         8844 $self = shift;
468             } elsif ( $_[0] eq 'Expect' ) {
469 0         0 shift; # or as Expect->expect
470             }
471             }
472 4811 50       12216 croak "expect(): not enough arguments, should be expect(timeout, [patterns...])"
473             if @_ < 1;
474 4811         7135 my $timeout = shift;
475 4811         7352 my $timeout_hook = undef;
476              
477 4811         16708 my @object_list;
478             my %patterns;
479              
480 4811         0 my @pattern_list;
481 4811         0 my @timeout_list;
482 4811         0 my $curr_list;
483              
484 4811 50       9479 if ($self) {
485 4811         10664 $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         7264 my $parm;
498 4811         7564 my $parm_nr = 1;
499 4811         11594 while ( defined( $parm = shift ) ) {
500 14323 50       28080 print STDERR ("expect(): handling param '$parm'...\n")
501             if $Expect::Debug;
502 14323 100       26041 if ( ref($parm) ) {
503 14214 50       26547 if ( ref($parm) eq 'ARRAY' ) {
504 14214         29367 my $err = _add_patterns_to_list(
505             \@pattern_list, \@timeout_list,
506             $parm_nr, $parm
507             );
508 14214 50       32122 carp(
509             "expect(): Warning: multiple `timeout' patterns (",
510             scalar(@timeout_list), ").\r\n"
511             ) if @timeout_list > 1;
512 14214 100       31465 $timeout_hook = $timeout_list[-1] if $timeout_list[-1];
513 14214 50       27405 croak $err if $err;
514 14214         33484 $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       399 if ( substr( $parm, 0, 1 ) eq '-' ) {
522              
523             # it's an option
524 21 50       102 print STDERR ("expect(): handling option '$parm'...\n")
525             if $Expect::Debug;
526 21 50 33     224 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       152 if ( ref( $_[1] ) eq 'CODE' ) {
546 0         0 push @pattern_list, [ $parm_nr, $parm, shift, shift ];
547             } else {
548 21         130 push @pattern_list, [ $parm_nr, $parm, shift, undef ];
549             }
550 21         108 $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       269 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       198 print STDERR ("expect(): exact match '$parm'...\n")
573             if $Expect::Debug;
574 88         322 push @pattern_list, [ $parm_nr, '-ex', $parm, undef ];
575             }
576 88         300 $parm_nr++;
577             }
578             }
579             }
580              
581             # add rest of collected patterns to object list
582 4811 50       10007 carp "expect(): Empty object list" unless $curr_list;
583 4811 50       14993 push @object_list, $curr_list if not exists $patterns{"$curr_list"};
584 4811         6856 push @{ $patterns{"$curr_list"} }, @pattern_list;
  4811         16623  
585              
586 4811 50       10770 my $debug = $self ? ${*$self}{exp_Debug} : $Expect::Debug;
  4811         12501  
587 4811 50       10383 my $internal = $self ? ${*$self}{exp_Exp_Internal} : $Expect::Exp_Internal;
  4811         8625  
588              
589             # now start matching...
590              
591 4811 50       11444 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     20897 cluck("Starting EXPECT pattern matching...\r\n")
598             if ( $debug or $internal );
599 4811         7019 my @ret;
600             @ret = _multi_expect(
601             $timeout, $timeout_hook,
602 4811         9862 map { [ $_, @{ $patterns{"$_"} } ] } @object_list
  4811         6793  
  4811         19539  
603             );
604              
605 4811 50       15044 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       23541 return wantarray ? @ret : $ret[0];
612             }
613              
614             ######################################################################
615             # the real workhorse
616             #
617             sub _multi_expect {
618 4811     4811   10798 my ($timeout, $timeout_hook, @params) = @_;
619              
620 4811 100       10653 if ($timeout_hook) {
621 4720 50 33     21397 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         8358 foreach my $pat (@params) {
627 4811         7574 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  4811         10070  
  4811         8402  
628 4811         7660 foreach my $exp ( @{ $pat->[0] } ) {
  4811         8841  
629 4811         6774 ${*$exp}{exp_New_Data} = 1; # first round we always try to match
  4811         10858  
630 4811 50 33     7215 if ( exists ${*$exp}{"exp_Max_Accum"}
  4811         13125  
631 4811         11707 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       10570 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       6531 if ( ${*$exp}{exp_Exp_Internal} ) {
  4811         14706  
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         22845 my $successful_pattern;
667             my $exp_matched;
668 4811         0 my $err;
669 4811         0 my $before;
670 4811         0 my $after;
671 4811         0 my $match;
672 4811         0 my @matchlist;
673              
674             # Set the last loop time to now for time comparisons at end of loop.
675 4811         7705 my $start_loop_time = time();
676 4811         7265 my $exp_cont = 1;
677              
678             READLOOP:
679 4811         10184 while ($exp_cont) {
680 9645         14264 $exp_cont = 1;
681 9645         16033 $err = "";
682 9645         14356 my $rmask = '';
683 9645         14472 my $time_left = undef;
684 9645 50       19759 if ( defined $timeout ) {
685 9645         15880 $time_left = $timeout - ( time() - $start_loop_time );
686 9645 50       20015 $time_left = 0 if $time_left < 0;
687             }
688              
689 9645         13299 $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 9645         15415 foreach my $pat (@params) {
695 9645         13640 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  9645         20624  
  9645         16044  
696 9645         15431 foreach my $exp ( @{ $pat->[0] } ) {
  9645         17067  
697              
698             # build mask for select in next section...
699 9645         27582 my $fn = $exp->fileno();
700 9645 50       68758 vec( $rmask, $fn, 1 ) = 1 if defined $fn;
701              
702 9645 100       19152 next unless ${*$exp}{exp_New_Data};
  9645         27553  
703              
704             # clear error status
705 9601         16666 ${*$exp}{exp_Error} = undef;
  9601         17789  
706 9601         14627 ${*$exp}{exp_After} = undef;
  9601         16083  
707 9601         13715 ${*$exp}{exp_Match_Number} = undef;
  9601         17325  
708 9601         14497 ${*$exp}{exp_Match} = undef;
  9601         16518  
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 9601 50       13957 ) if ${*$exp}{exp_Exp_Internal};
  9601         24349  
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 9601         18578 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 14411 0       19199 ) if ( ${*$exp}{exp_Exp_Internal} );
  14411 50       32937  
735              
736             # Matching exactly
737 14411 100       41559 if ( $pattern->[1] eq '-ex' ) {
    100          
738             my $match_index =
739 119         197 index( ${*$exp}{exp_Accum}, $pattern->[2] );
  119         378  
740              
741             # We matched if $match_index > -1
742 119 100       404 if ( $match_index > -1 ) {
743             $before =
744 29         60 substr( ${*$exp}{exp_Accum}, 0, $match_index );
  29         101  
745             $match = substr(
746 29         105 ${*$exp}{exp_Accum},
747 29         52 $match_index, length( $pattern->[2] )
748             );
749             $after = substr(
750 29         146 ${*$exp}{exp_Accum},
751 29         45 $match_index + length( $pattern->[2] )
752             );
753 29         74 ${*$exp}{exp_Before} = $before;
  29         63  
754 29         73 ${*$exp}{exp_Match} = $match;
  29         46  
755 29         60 ${*$exp}{exp_After} = $after;
  29         46  
756 29         45 ${*$exp}{exp_Match_Number} = $pattern->[0];
  29         121  
757 29         115 $exp_matched = $exp;
758             }
759             } elsif ( $pattern->[1] eq '-re' ) {
760              
761 9607 100       17525 if ($Expect::Multiline_Matching) {
762             @matchlist =
763 9593         14713 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m);
  9593         143294  
764             } else {
765             @matchlist =
766 14         29 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/);
  14         298  
767             }
768 9607 100       30550 if (@matchlist) {
769              
770             # Matching regexp
771 4798         8891 $match = shift @matchlist;
772 4798         6935 my $start = index ${*$exp}{exp_Accum}, $match;
  4798         13961  
773 4798 50       11642 die 'The match could not be found' if $start == -1;
774 4798         6713 $before = substr ${*$exp}{exp_Accum}, 0, $start;
  4798         11719  
775 4798         7438 $after = substr ${*$exp}{exp_Accum}, $start + length($match);
  4798         11424  
776              
777 4798         7595 ${*$exp}{exp_Before} = $before;
  4798         8857  
778 4798         6868 ${*$exp}{exp_Match} = $match;
  4798         9498  
779 4798         7138 ${*$exp}{exp_After} = $after;
  4798         8697  
780             #pop @matchlist; # remove kludged empty bracket from end
781 4798         7972 @{ ${*$exp}{exp_Matchlist} } = @matchlist;
  4798         7145  
  4798         10737  
782 4798         7543 ${*$exp}{exp_Match_Number} = $pattern->[0];
  4798         8281  
783 4798         8271 $exp_matched = $exp;
784             }
785             } else {
786              
787             # 'timeout' or 'eof'
788             }
789              
790 14411 100       31163 if ($exp_matched) {
791 4782         9668 ${*$exp}{exp_Accum} = $after
792 4827 100       6451 unless ${*$exp}{exp_NoTransfer};
  4827         13329  
793             print STDERR "YES!!\r\n"
794 4827 50       8020 if ${*$exp}{exp_Exp_Internal};
  4827         11425  
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       7048 ) if ( ${*$exp}{exp_Exp_Internal} );
  4827         10990  
812              
813             # call hook function if defined
814 4827 100       10702 if ( $pattern->[3] ) {
815             print STDERR (
816             "Calling hook $pattern->[3]...\r\n",
817             )
818 4778         16588 if ( ${*$exp}{exp_Exp_Internal}
819 4778 50 33     6386 or $Expect::Debug );
820 4778 50       7772 if ( $#{$pattern} > 3 ) {
  4778         11283  
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         7013 $exp_cont = &{ $pattern->[3] }($exp);
  4778         12901  
826             }
827             }
828 4827 100 66     27646 if ( $exp_cont and $exp_cont eq exp_continue ) {
    50 33        
829             print STDERR ("Continuing expect, restarting timeout...\r\n")
830 64         670 if ( ${*$exp}{exp_Exp_Internal}
831 64 50 33     228 or $Expect::Debug );
832 64         216 $start_loop_time = time(); # restart timeout count
833 64         407 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         12825 last READLOOP;
843             }
844 9584 50       12560 print STDERR "No.\r\n" if ${*$exp}{exp_Exp_Internal};
  9584         27626  
845             }
846 4774 50       6625 print STDERR "\r\n" if ${*$exp}{exp_Exp_Internal};
  4774         11381  
847              
848             # don't have to match again until we get new data
849 4774         7557 ${*$exp}{exp_New_Data} = 0;
  4774         12422  
850             }
851             } # End of matching section
852              
853             # No match, let's see what is pending on the filehandles...
854 4818 0 33     15875 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 4818         6750 my $nfound;
860             SELECT: {
861 4818         6480 $nfound = select( $rmask, undef, undef, $time_left );
  4818         92166958  
862 4818 50       12426 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 4818 100       10930 if ( $nfound == 0 ) {
879              
880             # No pattern, no EOF. Did we time out?
881 69         410 $err = "1:TIMEOUT";
882 69         334 foreach my $pat (@params) {
883 69         196 foreach my $exp ( @{ $pat->[0] } ) {
  69         468  
884 69         399 $before = ${*$exp}{exp_Before} = ${*$exp}{exp_Accum};
  69         435  
  69         1009  
885 69 50       907 next if not defined $exp->fileno(); # skip already closed
886 69 100       971 ${*$exp}{exp_Error} = $err unless ${*$exp}{exp_Error};
  36         202  
  69         443  
887             }
888             }
889 69 50 33     774 print STDERR ("TIMEOUT\r\n")
890             if ( $Expect::Debug or $Expect::Exp_Internal );
891 69 100       300 if ($timeout_hook) {
892 46         116 my $ret;
893 46 50 33     260 print STDERR ("Calling timeout function $timeout_hook...\r\n")
894             if ( $Expect::Debug or $Expect::Exp_Internal );
895 46 50       302 if ( ref($timeout_hook) eq 'CODE' ) {
896 0         0 $ret = &{$timeout_hook}( $params[0]->[0] );
  0         0  
897             } else {
898 46 50       81 if ( $#{$timeout_hook} > 3 ) {
  46         183  
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         129 $ret = &{ $timeout_hook->[3] }( $params[0]->[0] );
  46         306  
905             }
906             }
907 46 100 66     347 if ( $ret and $ret eq exp_continue ) {
908 44         143 $start_loop_time = time(); # restart timeout count
909 44         297 next READLOOP;
910             }
911             }
912 25         185 last READLOOP;
913             }
914              
915 4749         22652 my @bits = split( //, unpack( 'b*', $rmask ) );
916 4749         10696 foreach my $pat (@params) {
917 4749         7199 foreach my $exp ( @{ $pat->[0] } ) {
  4749         8936  
918 4749 50       13949 next if not defined $exp->fileno(); # skip already closed
919 4749 50       30859 if ( $bits[ $exp->fileno() ] ) {
920 4749 50       26277 print STDERR ("${*$exp}{exp_Pty_Handle}: new data.\r\n")
  0         0  
921             if $Expect::Debug;
922              
923             # read in what we found.
924 4749         7165 my $buffer;
925 4749         23129 my $nread = sysread( $exp, $buffer, 2048 );
926              
927             # Make errors (nread undef) show up as EOF.
928 4749 100       11881 $nread = 0 unless defined($nread);
929              
930 4749 100       10016 if ( $nread == 0 ) {
931 23 50       92 print STDERR ("${*$exp}{exp_Pty_Handle}: EOF\r\n")
  0         0  
932             if ($Expect::Debug);
933 23         125 $before = ${*$exp}{exp_Before} = $exp->clear_accum();
  23         55  
934 23         46 $err = "2:EOF";
935 23         46 ${*$exp}{exp_Error} = $err;
  23         46  
936 23         37 ${*$exp}{exp_Has_EOF} = 1;
  23         74  
937 23         46 $exp_cont = undef;
938 23         60 foreach my $eof_pat ( grep { $_->[1] eq '-eof' } @{$pat}[ 1 .. $#{$pat} ] ) {
  41         133  
  23         46  
  23         37  
939 9         45 my $ret;
940 9 50       135 print STDERR ( "Calling EOF hook $eof_pat->[3]...\r\n", )
941             if ($Expect::Debug);
942 9 50       36 if ( $#{$eof_pat} > 3 ) {
  9         54  
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         45  
948             }
949 9 50 33     153 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             my $ret =
961 23         46 waitpid( ${*$exp}{exp_Pid}, POSIX::WNOHANG );
  23         498  
962 23 50       60 if ( $ret == ${*$exp}{exp_Pid} ) {
  23         92  
963             printf STDERR (
964             "%s: exit(0x%02X)\r\n",
965 23 50       74 ${*$exp}{exp_Pty_Handle}, $?
  0         0  
966             ) if ($Expect::Debug);
967 23         37 $err = "3:Child PID ${*$exp}{exp_Pid} exited with status $?";
  23         124  
968 23         60 ${*$exp}{exp_Error} = $err;
  23         46  
969 23         46 ${*$exp}{exp_Exit} = $?;
  23         83  
970 23         46 delete $Expect::Spawned_PIDs{ ${*$exp}{exp_Pid} };
  23         87  
971 23         46 ${*$exp}{exp_Pid} = undef;
  23         46  
972             }
973             }
974 23 50       60 print STDERR ("${*$exp}{exp_Pty_Handle}: closing...\r\n")
  0         0  
975             if ($Expect::Debug);
976 23         217 $exp->hard_close();
977 23         69 next;
978             }
979 4726 50       10016 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 4726 100       6237 $buffer =~ s/ \cH//g if not ${*$exp}{exp_Raw_Pty};
  4726         15704  
985              
986             # Append it to the accumulator.
987 4726         7785 ${*$exp}{exp_Accum} .= $buffer;
  4726         13163  
988 4726 50 33     7674 if ( exists ${*$exp}{exp_Max_Accum}
  4726         13211  
989 4726         12150 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 4726         7660 ${*$exp}{exp_New_Data} = 1; # next round we try to match again
  4726         8695  
997              
998             $exp_cont = exp_continue
999 4726         11378 if ( exists ${*$exp}{exp_Continue}
1000 4726 0 33     7109 and ${*$exp}{exp_Continue} );
  0         0  
1001              
1002             # Now propagate what we have read to other listeners...
1003 4726         11691 $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 4749 50 66     15201 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     15685 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       10241 if ($exp_matched) {
1048             return wantarray
1049             ? (
1050 4763         9868 ${*$exp_matched}{exp_Match_Number}, ${*$exp_matched}{exp_Error},
  4763         8568  
1051 4763         8172 ${*$exp_matched}{exp_Match}, ${*$exp_matched}{exp_Before},
  4763         7786  
1052 4763         25154 ${*$exp_matched}{exp_After}, $exp_matched,
1053             )
1054 4763 50       9755 : ${*$exp_matched}{exp_Match_Number};
  0         0  
1055             }
1056              
1057 48 50       461 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   31158 my ($listref, $timeoutlistref,$store_parm_nr, @params) = @_;
1069              
1070             # $timeoutlistref gets timeout patterns
1071 14214   50     30078 my $parm_nr = $store_parm_nr || 1;
1072 14214         23596 foreach my $parm (@params) {
1073 14214 50       30775 if ( not ref($parm) eq 'ARRAY' ) {
1074 0         0 return "Parameter #$parm_nr is not an ARRAY ref.";
1075             }
1076 14214         29209 $parm = [@$parm]; # make copy
1077 14214 50       35260 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       31652 if ( $parm->[0] eq 'timeout' ) {
    100          
1087 4720 50       10296 if ( defined $timeoutlistref ) {
1088 4720         13649 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1089 4720 50       11765 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1090 4720         9552 push @$timeoutlistref, $parm;
1091             }
1092 4720         8946 next;
1093             } elsif ( $parm->[0] eq 'eof' ) {
1094 4720         11663 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1095             } else {
1096 4774         12262 unshift @$parm, '-re'; # defaults to RegExp
1097             }
1098             }
1099 9494 100       18908 if ( @$parm > 2 ) {
1100 9491 50       22212 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         10 push @$parm, undef; # make sure we have three elements
1108             }
1109              
1110 9494 50       20324 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1111 9494         14507 push @$listref, $parm;
1112 9494         15056 $parm_nr++;
1113             }
1114              
1115 14214         26996 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   206 no strict 'subs'; # Allow bare word 'STDIN'
  23         53  
  23         79964  
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 0         0 } 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 4753     4753 1 11613 my ($self, @params) = @_;
1401              
1402 4753 100       7301 if ( ${*$self}{exp_Log_File} ) {
  4753         12400  
1403 4629 100       6420 if ( ref( ${*$self}{exp_Log_File} ) eq 'CODE' ) {
  4629         12298  
1404 48         152 ${*$self}{exp_Log_File}->(@params);
  48         288  
1405             } else {
1406 4581         6826 ${*$self}{exp_Log_File}->print(@params);
  4581         13969  
1407             }
1408             }
1409              
1410 4753         99801 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 113477 my ( $self, @args ) = @_;
1417              
1418 4624 50       11992 return if not defined $self->fileno(); # skip if closed
1419 4624 50       25890 if ( ${*$self}{exp_Exp_Internal} ) {
  4624         13770  
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         9380 foreach my $arg (@args) {
1424 4624         10947 while ( length($arg) > 80 ) {
1425 10326         34053 $self->SUPER::print( substr( $arg, 0, 80 ) );
1426 10326         273387 $arg = substr( $arg, 80 );
1427             }
1428 4624         11862 $self->SUPER::print($arg);
1429             }
1430              
1431 4624         127078 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 27072 my ($self, $sleep_time, @chunks) = @_;
1441              
1442 24 50       112 return if not defined $self->fileno(); # skip if closed
1443              
1444             # Flushing makes it so each character can be seen separately.
1445 24         240 my $chunk;
1446 24         112 while ( $chunk = shift @chunks ) {
1447 24         280 my @linechars = split( '', $chunk );
1448 24         88 foreach my $char (@linechars) {
1449              
1450             # How slow?
1451 1040         104163072 select( undef, undef, undef, $sleep_time );
1452              
1453 1040         55000 print $self $char;
1454 0         0 print STDERR "Printed character \'" . _make_readable($char) . "\' to ${*$self}{exp_Pty_Handle}.\r\n"
1455 1040 50       3936 if ${*$self}{"exp_Debug"} > 1;
  1040         13312  
1456              
1457             # I think I can get away with this if I save it in accum
1458 1040 50 33     3752 if ( ${*$self}{"exp_Log_Stdout"} || ${*$self}{exp_Log_Group} ) {
  1040         8376  
  0         0  
1459 1040         3136 my $rmask = "";
1460 1040         11672 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         10282056 while ( select( $rmask, undef, undef, .01 ) ) {
1465 24         104 my $ret = sysread( $self, ${*$self}{exp_Pty_Buffer}, 1024 );
  24         360  
1466 24 50 33     264 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         80 ${*$self}{exp_Accum} .= ${*$self}{exp_Pty_Buffer};
  24         264  
  24         112  
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       176 ) if ( ${*$self}{"exp_Max_Accum"} );
  24         128  
1475 24         80 $self->_print_handles( ${*$self}{exp_Pty_Buffer} );
  24         192  
1476             print STDERR "Received \'"
1477             . $self->_trim_length( _make_readable($char) )
1478 0         0 . "\' from ${*$self}{exp_Pty_Handle}\r\n"
1479 24 50       56 if ${*$self}{"exp_Debug"} > 1;
  24         243208  
1480             }
1481             }
1482             }
1483             }
1484              
1485 24         192 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 5387 my ($self) = @_;
1526              
1527 7         21 my ( $nfound, $nread, $rmask, $end_time, $temp_buffer );
1528              
1529             # Give it 15 seconds to cough up an eof.
1530 7 50       11 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  7         65  
1531 7 50       32 return -1 if not defined $self->fileno(); # skip if handle already closed
1532 7 50 33     57 unless ( exists ${*$self}{exp_Has_EOF} and ${*$self}{exp_Has_EOF} ) {
  7         54  
  0         0  
1533 7         26 $end_time = time() + 15;
1534 7         25 while ( $end_time > time() ) {
1535 10         34 my $select_time = $end_time - time();
1536              
1537             # Sanity check.
1538 10 50       37 $select_time = 0 if $select_time < 0;
1539 10         28 $rmask = '';
1540 10         45 vec( $rmask, $self->fileno(), 1 ) = 1;
1541 10         13993735 ($nfound) = select( $rmask, undef, undef, $select_time );
1542 10 50 33     187 last unless ( defined($nfound) && $nfound );
1543 10         143 $nread = sysread( $self, $temp_buffer, 8096 );
1544              
1545             # 0 = EOF.
1546 10 100 66     129 unless ( defined($nread) && $nread ) {
1547 0         0 print STDERR "Got EOF from ${*$self}{exp_Pty_Handle}.\r\n"
1548 7 50       26 if ${*$self}{exp_Debug};
  7         71  
1549 7         25 last;
1550             }
1551 3         36 $self->_print_handles($temp_buffer);
1552             }
1553 7 0 33     40 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         56 my $close_status = $self->close();
1558 7 50 33     462 if ( $close_status && ${*$self}{exp_Debug} ) {
  7         55  
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         67  
1564              
1565             # Now give it 15 seconds to die.
1566 7         30 $end_time = time() + 15;
1567 7         41 while ( $end_time > time() ) {
1568 7         18 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  7         213  
1569              
1570             # Stop here if the process dies.
1571 7 50 33     75 if ( defined($returned_pid) && $returned_pid ) {
1572 7         46 delete $Expect::Spawned_PIDs{$returned_pid};
1573 7 50       14 if ( ${*$self}{exp_Debug} ) {
  7         40  
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         33 ${*$self}{exp_Pid} = undef;
  7         18  
1581 7         14 ${*$self}{exp_Exit} = $?;
  7         28  
1582 7         18 return ${*$self}{exp_Exit};
  7         46  
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 57608 my ($self) = @_;
1620              
1621 167 50       314 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  167         632  
1622              
1623             # Don't wait for an EOF.
1624 167         883 my $close_status = $self->close();
1625 167 50 66     21249 if ( $close_status && ${*$self}{exp_Debug} ) {
  101         678  
1626 0         0 print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n";
  0         0  
1627             }
1628              
1629             # Return now if handle.
1630 167 100       381 return $close_status unless defined( ${*$self}{exp_Pid} );
  167         711  
1631              
1632             # Now give it 5 seconds to die. Less patience here if it won't die.
1633 78         283 my $end_time = time() + 5;
1634 78         336 while ( $end_time > time() ) {
1635 109         437 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  109         3729  
1636              
1637             # Stop here if the process dies.
1638 109 100 66     1021 if ( defined($returned_pid) && $returned_pid ) {
1639 78         522 delete $Expect::Spawned_PIDs{$returned_pid};
1640 78 50       210 if ( ${*$self}{exp_Debug} ) {
  78         473  
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         247 ${*$self}{exp_Pid} = undef;
  78         346  
1648 78         198 ${*$self}{exp_Exit} = $?;
  78         434  
1649 78         254 return ${*$self}{exp_Exit};
  78         960  
1650             }
1651 31         31003596 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   360 my ($self) = @_;
1710              
1711             # for every spawned process or filehandle.
1712 126 50       471 ${*$self}{exp_Log_Stdout} = $Expect::Log_Stdout
  0         0  
1713             if defined($Expect::Log_Stdout);
1714 126         294 ${*$self}{exp_Log_Group} = $Expect::Log_Group;
  126         400  
1715 126         291 ${*$self}{exp_Debug} = $Expect::Debug;
  126         370  
1716 126         266 ${*$self}{exp_Exp_Internal} = $Expect::Exp_Internal;
  126         440  
1717 126         279 ${*$self}{exp_Manual_Stty} = $Expect::Manual_Stty;
  126         387  
1718 126         270 ${*$self}{exp_Stored_Stty} = 'sane';
  126         638  
1719 126         305 ${*$self}{exp_Do_Soft_Close} = $Expect::Do_Soft_Close;
  126         335  
1720              
1721             # sysread doesn't like my or local vars.
1722 126         281 ${*$self}{exp_Pty_Buffer} = '';
  126         400  
1723              
1724             # Initialize accumulator.
1725 126         322 ${*$self}{exp_Max_Accum} = $Expect::Exp_Max_Accum;
  126         398  
1726 126         270 ${*$self}{exp_Accum} = '';
  126         344  
1727 126         257 ${*$self}{exp_NoTransfer} = 0;
  126         374  
1728              
1729             # create empty expect_before & after lists
1730 126         335 ${*$self}{exp_expect_before_list} = [];
  126         343  
1731 126         318 ${*$self}{exp_expect_after_list} = [];
  126         399  
1732              
1733 126         266 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   1343 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       323 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     38 and ${*$self}{"exp_Debug"} >= 3
  7   33     39  
1774             and ( !( defined($length) ) ) );
1775 15 100       33 my $indicate_truncation = ($length ? '' : '...');
1776 15   100     51 $length ||= 1021;
1777 15 100       83 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         52 return $indicate_truncation . substr( $string, ( length($string) - $length ), $length );
1783             }
1784              
1785             sub _print_handles {
1786 4753     4753   10863 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 4753 50       6562 if ( ${*$self}{exp_Log_Group} ) {
  4753         12721  
1791 4753         6974 foreach my $handle ( @{ ${*$self}{exp_Listen_Group} } ) {
  4753         6171  
  4753         13397  
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 4753 100       7598 if ${*$self}{"exp_Log_Stdout"};
  4753         36012  
1806 4753         15156 $self->print_log_file($print_this);
1807 4753         10430 $| = 1; # This should not be necessary but autoflush() doesn't always work.
1808              
1809 4753         10985 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   61211 my ($self) = @_;
1843              
1844 109         411 my $status = $?; # save this as it gets mangled by the terminating spawned children
1845 109 50       241 if ( ${*$self}{exp_Do_Soft_Close} ) {
  109         633  
1846 0         0 $self->soft_close();
1847             }
1848 109         680 $self->hard_close();
1849 109         347 $? = $status; # restore it. otherwise deleting an Expect object may mangle $?, which is unintuitive
1850              
1851 109         2671 return;
1852             }
1853              
1854             1;
1855             __END__