File Coverage

blib/lib/Expect.pm
Criterion Covered Total %
statement 638 1164 54.8
branch 217 534 40.6
condition 49 171 28.6
subroutine 35 46 76.0
pod 16 22 72.7
total 955 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   738496 use 5.006;
  23         69  
  23         1016  
18              
19             package Expect;
20 23     23   123 use strict;
  23         39  
  23         730  
21 23     23   88 use warnings;
  23         71  
  23         577  
22              
23 23     23   11904 use IO::Pty 1.11; # We need make_slave_controlling_terminal()
  23         302735  
  23         945  
24 23     23   654 use IO::Tty;
  23         145  
  23         72  
25              
26 23     23   1442 use POSIX qw(:sys_wait_h :unistd_h); # For WNOHANG and isatty
  23         41  
  23         97  
27 23     23   28132 use Fcntl qw(:DEFAULT); # For checking file handle settings.
  23         28  
  23         5915  
28 23     23   98 use Carp qw(cluck croak carp confess);
  23         25  
  23         1075  
29 23     23   76 use IO::Handle ();
  23         22  
  23         309  
30 23     23   134 use Exporter qw(import);
  23         57  
  23         451  
31 23     23   3063 use Errno;
  23         5744  
  23         2434  
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   42 $Expect::VERSION = '1.32';
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         24 $Expect::Log_Group = 1;
47 23         18 $Expect::Debug = 0;
48 23         24 $Expect::Exp_Max_Accum = 0; # unlimited
49 23         22 $Expect::Exp_Internal = 0;
50 23         21 $Expect::IgnoreEintr = 0;
51 23         128 $Expect::Manual_Stty = 0;
52 23         8 $Expect::Multiline_Matching = 1;
53 23         23 $Expect::Do_Soft_Close = 0;
54 23         38 @Expect::Before_List = ();
55 23         23 @Expect::After_List = ();
56 23         20382 %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 198131 my ($class, @args) = @_;
72              
73 126 50       479 $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         1315 my ($self) = IO::Pty->new;
77 126 50       67221 die "$class: Could not assign a pty" unless $self;
78 126         403 bless $self => $class;
79 126         515 $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         5676 ${*$self}{exp_Log_Stdout} = 1;
  126         722  
84 126         885 $self->_init_vars();
85              
86 126 100       337 if (@args) {
87              
88             # we got add'l parms, so pass them to spawn
89 64         304 return $self->spawn(@args);
90             }
91 62         181 return $self;
92             }
93              
94             sub spawn {
95 126     126 1 22402 my ($class, @cmd) = @_;
96             # spawn is passed command line args.
97              
98 126         170 my $self;
99              
100 126 100       393 if ( ref($class) ) {
101 111         213 $self = $class;
102             } else {
103 15         60 $self = $class->new();
104             }
105              
106 126         493 croak "Cannot reuse an object with an already spawned command"
107 126 100       167 if exists ${*$self}{"exp_Command"};
108 125         296 ${*$self}{"exp_Command"} = \@cmd;
  125         513  
109              
110             # set up pipe to detect childs exec error
111 125 50       1720 pipe( FROM_CHILD, TO_PARENT ) or die "Cannot open pipe: $!";
112 125 50       1133 pipe( FROM_PARENT, TO_CHILD ) or die "Cannot open pipe: $!";
113 125         668 TO_PARENT->autoflush(1);
114 125         6843 TO_CHILD->autoflush(1);
115 125         4931 eval { fcntl( TO_PARENT, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC ); };
  125         467  
116              
117 125         94278 my $pid = fork;
118              
119 125 50       2484 unless ( defined($pid) ) {
120 0 0       0 warn "Cannot fork: $!" if $^W;
121 0         0 return;
122             }
123              
124 125 100       2326 if ($pid) {
125              
126             # parent
127 108         218 my $errno;
128 108         223 ${*$self}{exp_Pid} = $pid;
  108         4827  
129 108         2772 close TO_PARENT;
130 108         1054 close FROM_PARENT;
131 108         4466 $self->close_slave();
132 108 100 66     12608 $self->set_raw() if $self->raw_pty and isatty($self);
133 108         5375 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         98127749 my $errstatus = sysread( FROM_CHILD, $errno, 256 );
137 108 50       966 die "Cannot sync with child: $!" if not defined $errstatus;
138 108         3109 close FROM_CHILD;
139 108 100       650 if ($errstatus) {
140 13         182 $! = $errno + 0;
141 13 50       208 warn "Cannot exec(@cmd): $!\n" if $^W;
142 13         442 return;
143             }
144             } else {
145              
146             # child
147 17         1026 close FROM_CHILD;
148 17         436 close TO_CHILD;
149              
150 17         1858 $self->make_slave_controlling_terminal();
151 17 50       13191 my $slv = $self->slave()
152             or die "Cannot get slave: $!";
153              
154 17 100       853 $slv->set_raw() if $self->raw_pty;
155 17         1524 close($self);
156              
157             # wait for parent before we detach
158 17         150 my $buffer;
159 17         214 my $errstatus = sysread( FROM_PARENT, $buffer, 256 );
160 17 50       249 die "Cannot sync with parent: $!" if not defined $errstatus;
161 17         189 close FROM_PARENT;
162              
163 17         75 close(STDIN);
164 17 50       440 open( STDIN, "<&" . $slv->fileno() )
165             or die "Couldn't reopen STDIN for reading, $!\n";
166 17         669 close(STDOUT);
167 17 50       318 open( STDOUT, ">&" . $slv->fileno() )
168             or die "Couldn't reopen STDOUT for writing, $!\n";
169 17         444 close(STDERR);
170 17 50       128 open( STDERR, ">&" . $slv->fileno() )
171             or die "Couldn't reopen STDERR for writing, $!\n";
172              
173 17         280 { 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         1964 ${*$self}{exp_Pty_Handle} = "spawn id(" . $self->fileno() . ")";
  95         2262  
184 95 50 33     438 if ( ( ${*$self}{"exp_Debug"} ) or ( ${*$self}{"exp_Exp_Internal"} ) ) {
  95         857  
  95         676  
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         256 $Expect::Spawned_PIDs{ ${*$self}{exp_Pid} } = undef;
  95         708  
193 95         1550 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   28851 my ($self, @args) = @_;
268              
269 324 50       1097 my $type = ref($self)
270             or croak "$self is not an object";
271              
272 23     23   121 use vars qw($AUTOLOAD);
  23         23  
  23         96878  
273 324         686 my $name = $AUTOLOAD;
274 324         4682 $name =~ s/.*:://; # strip fully-qualified portion
275              
276 324 50       1125 unless ( exists $Readable_Vars{$name} ) {
277 0         0 croak "ERROR: cannot find method `$name' in class $type";
278             }
279 324         751 my $varname = $Readable_Vars{$name};
280 324         348 my $tmp;
281 324 100       360 $tmp = ${*$self}{$varname} if exists ${*$self}{$varname};
  196         440  
  324         1270  
282              
283 324 100       1147 if (@args) {
284 76 50       255 if ( exists $Writeable_Vars{$name} ) {
285 76         130 my $ref = ref($tmp);
286 76 50       275 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         124 ${*$self}{$varname} = shift @args;
  76         281  
292             }
293             } else {
294 0 0       0 carp "Trying to set read-only variable `$name'"
295             if $^W;
296             }
297             }
298              
299 324         1269 my $ref = ref($tmp);
300 324 50       924 return ( wantarray ? @{$tmp} : $tmp ) if ( $ref eq 'ARRAY' );
  6 100       41  
301 318 0       728 return ( wantarray ? %{$tmp} : $tmp ) if ( $ref eq 'HASH' );
  0 50       0  
302 318         3236 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 34519 my ($self, $file, $mode) = @_;
361 65   100     502 $mode ||= "a";
362              
363 65 50       262 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     134 if ( ${*$self}{exp_Log_File} and ref( ${*$self}{exp_Log_File} ) ne 'CODE' ) {
  65         433  
  25         167  
368 9         29 close( ${*$self}{exp_Log_File} );
  9         345  
369             }
370 65         154 ${*$self}{exp_Log_File} = undef;
  65         186  
371 65 100       448 return if ( not $file );
372 39         60 my $fh = $file;
373 39 100       163 if ( not ref($file) ) {
374              
375             # it's a filename
376 23 50       385 $fh = IO::File->new( $file, $mode )
377             or croak "Cannot open logfile $file: $!";
378             }
379 39 100       6085 if ( ref($file) ne 'CODE' ) {
380 23 50       367 croak "Given logfile doesn't have a 'print' method"
381             if not $fh->can("print");
382 23         189 $fh->autoflush(1); # so logfile is up to date
383             }
384              
385 39         2156 ${*$self}{exp_Log_File} = $fh;
  39         115  
386              
387 39         91 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 1111 my ($self) = @_;
420 39         146 return $self->set_accum('');
421             }
422              
423             sub set_accum {
424 57     57 1 146 my ($self, $accum) = @_;
425              
426 57         93 my $old_accum = ${*$self}{exp_Accum};
  57         255  
427 57         100 ${*$self}{exp_Accum} = $accum;
  57         148  
428              
429             # return the contents of the accumulator.
430 57         271 return $old_accum;
431             }
432             sub get_accum {
433 1     1 0 2 my ($self) = @_;
434 1         2 return ${*$self}{exp_Accum};
  1         13  
435             }
436              
437             ######################################################################
438             # define constants for pattern subs
439 9783     9783 0 41037 sub exp_continue {"exp_continue"}
440 4772     4772 0 11513 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 54100012 my $self;
463              
464 4811 50       8452 print STDERR ("expect(@_) called...\n") if $Expect::Debug;
465 4811 50       7618 if ( defined( $_[0] ) ) {
466 4811 50 33     26177 if ( ref( $_[0] ) and $_[0]->isa('Expect') ) {
    0          
467 4811         5654 $self = shift;
468             } elsif ( $_[0] eq 'Expect' ) {
469 0         0 shift; # or as Expect->expect
470             }
471             }
472 4811 50       8169 croak "expect(): not enough arguments, should be expect(timeout, [patterns...])"
473             if @_ < 1;
474 4811         4572 my $timeout = shift;
475 4811         4046 my $timeout_hook = undef;
476              
477 4811         3851 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       6036 if ($self) {
485 4811         6352 $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         4012 my $parm;
498 4811         3432 my $parm_nr = 1;
499 4811         7679 while ( defined( $parm = shift ) ) {
500 14323 50       18485 print STDERR ("expect(): handling param '$parm'...\n")
501             if $Expect::Debug;
502 14323 100       16774 if ( ref($parm) ) {
503 14214 50       17570 if ( ref($parm) eq 'ARRAY' ) {
504 14214         21160 my $err = _add_patterns_to_list(
505             \@pattern_list, \@timeout_list,
506             $parm_nr, $parm
507             );
508 14214 50       20617 carp(
509             "expect(): Warning: multiple `timeout' patterns (",
510             scalar(@timeout_list), ").\r\n"
511             ) if @timeout_list > 1;
512 14214 100       20200 $timeout_hook = $timeout_list[-1] if $timeout_list[-1];
513 14214 50       18007 croak $err if $err;
514 14214         23651 $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       403 if ( substr( $parm, 0, 1 ) eq '-' ) {
522              
523             # it's an option
524 21 50       87 print STDERR ("expect(): handling option '$parm'...\n")
525             if $Expect::Debug;
526 21 50 33     441 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       74 if ( ref( $_[1] ) eq 'CODE' ) {
546 0         0 push @pattern_list, [ $parm_nr, $parm, shift, shift ];
547             } else {
548 21         79 push @pattern_list, [ $parm_nr, $parm, shift, undef ];
549             }
550 21         73 $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       173 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       169 print STDERR ("expect(): exact match '$parm'...\n")
573             if $Expect::Debug;
574 88         255 push @pattern_list, [ $parm_nr, '-ex', $parm, undef ];
575             }
576 88         266 $parm_nr++;
577             }
578             }
579             }
580              
581             # add rest of collected patterns to object list
582 4811 50       6831 carp "expect(): Empty object list" unless $curr_list;
583 4811 50       12448 push @object_list, $curr_list if not exists $patterns{"$curr_list"};
584 4811         3997 push @{ $patterns{"$curr_list"} }, @pattern_list;
  4811         12308  
585              
586 4811 50       6080 my $debug = $self ? ${*$self}{exp_Debug} : $Expect::Debug;
  4811         11354  
587 4811 50       6921 my $internal = $self ? ${*$self}{exp_Exp_Internal} : $Expect::Exp_Internal;
  4811         6164  
588              
589             # now start matching...
590              
591 4811 50       8107 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     15307 cluck("Starting EXPECT pattern matching...\r\n")
598             if ( $debug or $internal );
599 4811         3282 my @ret;
600 4811         16575 @ret = _multi_expect(
601             $timeout, $timeout_hook,
602 4811         6096 map { [ $_, @{ $patterns{"$_"} } ] } @object_list
  4811         3894  
603             );
604              
605 4811 50       12913 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       21674 return wantarray ? @ret : $ret[0];
612             }
613              
614             ######################################################################
615             # the real workhorse
616             #
617             sub _multi_expect {
618 4811     4811   6083 my ($timeout, $timeout_hook, @params) = @_;
619              
620 4811 100       6954 if ($timeout_hook) {
621 4720 50 33     16645 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         5130 foreach my $pat (@params) {
627 4811         4674 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  4811         7327  
  4811         6341  
628 4811         4708 foreach my $exp ( @{ $pat->[0] } ) {
  4811         5981  
629 4811         3430 ${*$exp}{exp_New_Data} = 1; # first round we always try to match
  4811         7728  
630 4811 50 33     3700 if ( exists ${*$exp}{"exp_Max_Accum"}
  4811         11009  
  4811         11766  
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       7557 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       3140 if ( ${*$exp}{exp_Exp_Internal} ) {
  4811         14819  
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         4197 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         4291 my $start_loop_time = time();
676 4811         3611 my $exp_cont = 1;
677              
678             READLOOP:
679 4811         7228 while ($exp_cont) {
680 9712         7503 $exp_cont = 1;
681 9712         7918 $err = "";
682 9712         7877 my $rmask = '';
683 9712         7145 my $time_left = undef;
684 9712 50       15740 if ( defined $timeout ) {
685 9712         10872 $time_left = $timeout - ( time() - $start_loop_time );
686 9712 50       14668 $time_left = 0 if $time_left < 0;
687             }
688              
689 9712         7843 $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 9712         9599 foreach my $pat (@params) {
695 9712         8969 my @patterns = @{$pat}[ 1 .. $#{$pat} ];
  9712         14521  
  9712         12957  
696 9712         8418 foreach my $exp ( @{ $pat->[0] } ) {
  9712         12194  
697              
698             # build mask for select in next section...
699 9712         19863 my $fn = $exp->fileno();
700 9712 50       52801 vec( $rmask, $fn, 1 ) = 1 if defined $fn;
701              
702 9712 100       11316 next unless ${*$exp}{exp_New_Data};
  9712         22569  
703              
704             # clear error status
705 9668         8400 ${*$exp}{exp_Error} = undef;
  9668         11445  
706 9668         7873 ${*$exp}{exp_After} = undef;
  9668         11132  
707 9668         7463 ${*$exp}{exp_Match_Number} = undef;
  9668         10219  
708 9668         6970 ${*$exp}{exp_Match} = undef;
  9668         11577  
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 9668         18460 $exp->_trim_length( _make_readable( ${*$exp}{exp_Accum} ) ),
718             "'\r\nmatch:\r\n"
719 9668 50       7545 ) 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 9668         10351 foreach my $pattern (@patterns) {
726 14522         24506 print STDERR (
727             " pattern",
728             defined( $pattern->[0] ) ? ' #' . $pattern->[0] : '',
729             ": ",
730             $pattern->[1],
731             " `",
732             _make_readable( $pattern->[2] ),
733             "'? "
734 14522 0       8978 ) if ( ${*$exp}{exp_Exp_Internal} );
    50          
735              
736             # Matching exactly
737 14522 100       29060 if ( $pattern->[1] eq '-ex' ) {
    100          
738 245         580 my $match_index =
739 245         246 index( ${*$exp}{exp_Accum}, $pattern->[2] );
740              
741             # We matched if $match_index > -1
742 245 100       545 if ( $match_index > -1 ) {
743 29         116 $before =
744 29         44 substr( ${*$exp}{exp_Accum}, 0, $match_index );
745 29         88 $match = substr(
746 29         44 ${*$exp}{exp_Accum},
747             $match_index, length( $pattern->[2] )
748             );
749 29         103 $after = substr(
750 29         44 ${*$exp}{exp_Accum},
751             $match_index + length( $pattern->[2] )
752             );
753 29         45 ${*$exp}{exp_Before} = $before;
  29         73  
754 29         44 ${*$exp}{exp_Match} = $match;
  29         30  
755 29         58 ${*$exp}{exp_After} = $after;
  29         45  
756 29         45 ${*$exp}{exp_Match_Number} = $pattern->[0];
  29         59  
757 29         45 $exp_matched = $exp;
758             }
759             } elsif ( $pattern->[1] eq '-re' ) {
760              
761 9595 100       13027 if ($Expect::Multiline_Matching) {
762 9581         138290 @matchlist =
763 9581         6635 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m);
764             } else {
765 14         237 @matchlist =
766 14         19 ( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/);
767             }
768 9595 100       18630 if (@matchlist) {
769              
770             # Matching regexp
771 4798         5033 $match = shift @matchlist;
772 4798         3680 my $start = index ${*$exp}{exp_Accum}, $match;
  4798         10264  
773 4798 50       7502 die 'The match could not be found' if $start == -1;
774 4798         3085 $before = substr ${*$exp}{exp_Accum}, 0, $start;
  4798         8232  
775 4798         3801 $after = substr ${*$exp}{exp_Accum}, $start + length($match);
  4798         7794  
776              
777 4798         3682 ${*$exp}{exp_Before} = $before;
  4798         5189  
778 4798         3475 ${*$exp}{exp_Match} = $match;
  4798         6410  
779 4798         3776 ${*$exp}{exp_After} = $after;
  4798         5232  
780             #pop @matchlist; # remove kludged empty bracket from end
781 4798         4356 @{ ${*$exp}{exp_Matchlist} } = @matchlist;
  4798         3292  
  4798         6498  
782 4798         5556 ${*$exp}{exp_Match_Number} = $pattern->[0];
  4798         5195  
783 4798         5142 $exp_matched = $exp;
784             }
785             } else {
786              
787             # 'timeout' or 'eof'
788             }
789              
790 14522 100       21069 if ($exp_matched) {
791 4782         8383 ${*$exp}{exp_Accum} = $after
  4827         9767  
792 4827 100       3557 unless ${*$exp}{exp_NoTransfer};
793 4827         8381 print STDERR "YES!!\r\n"
794 4827 50       4334 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         8103 map { "`" . $exp->_trim_length( _make_readable( ($_) ) ) . "'" } @matchlist,
809             ),
810             ")\r\n",
811 4827 50       3656 ) if ( ${*$exp}{exp_Exp_Internal} );
812              
813             # call hook function if defined
814 4827 100       7559 if ( $pattern->[3] ) {
815 4778         12437 print STDERR (
816             "Calling hook $pattern->[3]...\r\n",
817             )
818 4778 50 33     3409 if ( ${*$exp}{exp_Exp_Internal}
819             or $Expect::Debug );
820 4778 50       3885 if ( $#{$pattern} > 3 ) {
  4778         8410  
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         3676 $exp_cont = &{ $pattern->[3] }($exp);
  4778         11024  
826             }
827             }
828 4827 100 66     21004 if ( $exp_cont and $exp_cont eq exp_continue ) {
    50 33        
829 64         405 print STDERR ("Continuing expect, restarting timeout...\r\n")
830 64 50 33     112 if ( ${*$exp}{exp_Exp_Internal}
831             or $Expect::Debug );
832 64         69 $start_loop_time = time(); # restart timeout count
833 64         232 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         9902 last READLOOP;
843             }
844 9695 50       6437 print STDERR "No.\r\n" if ${*$exp}{exp_Exp_Internal};
  9695         21518  
845             }
846 4841 50       5096 print STDERR "\r\n" if ${*$exp}{exp_Exp_Internal};
  4841         8029  
847              
848             # don't have to match again until we get new data
849 4841         4571 ${*$exp}{exp_New_Data} = 0;
  4841         11257  
850             }
851             } # End of matching section
852              
853             # No match, let's see what is pending on the filehandles...
854 4885 0 33     12752 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 4885         4060 my $nfound;
860 4885         92267147 SELECT: {
861 4885         3159 $nfound = select( $rmask, undef, undef, $time_left );
862 4885 50       9372 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 4885 100       7696 if ( $nfound == 0 ) {
879              
880             # No pattern, no EOF. Did we time out?
881 69         635 $err = "1:TIMEOUT";
882 69         486 foreach my $pat (@params) {
883 69         170 foreach my $exp ( @{ $pat->[0] } ) {
  69         494  
884 69         113 $before = ${*$exp}{exp_Before} = ${*$exp}{exp_Accum};
  69         414  
  69         922  
885 69 50       1210 next if not defined $exp->fileno(); # skip already closed
886 69 100       990 ${*$exp}{exp_Error} = $err unless ${*$exp}{exp_Error};
  36         269  
  69         583  
887             }
888             }
889 69 50 33     719 print STDERR ("TIMEOUT\r\n")
890             if ( $Expect::Debug or $Expect::Exp_Internal );
891 69 100       216 if ($timeout_hook) {
892 46         92 my $ret;
893 46 50 33     265 print STDERR ("Calling timeout function $timeout_hook...\r\n")
894             if ( $Expect::Debug or $Expect::Exp_Internal );
895 46 50       285 if ( ref($timeout_hook) eq 'CODE' ) {
896 0         0 $ret = &{$timeout_hook}( $params[0]->[0] );
  0         0  
897             } else {
898 46 50       68 if ( $#{$timeout_hook} > 3 ) {
  46         182  
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         103 $ret = &{ $timeout_hook->[3] }( $params[0]->[0] );
  46         230  
905             }
906             }
907 46 100 66     284 if ( $ret and $ret eq exp_continue ) {
908 44         88 $start_loop_time = time(); # restart timeout count
909 44         297 next READLOOP;
910             }
911             }
912 25         201 last READLOOP;
913             }
914              
915 4816         25227 my @bits = split( //, unpack( 'b*', $rmask ) );
916 4816         8358 foreach my $pat (@params) {
917 4816         3636 foreach my $exp ( @{ $pat->[0] } ) {
  4816         6548  
918 4816 50       11221 next if not defined $exp->fileno(); # skip already closed
919 4816 50       22767 if ( $bits[ $exp->fileno() ] ) {
920 4816 50       18330 print STDERR ("${*$exp}{exp_Pty_Handle}: new data.\r\n")
  0         0  
921             if $Expect::Debug;
922              
923             # read in what we found.
924 4816         3245 my $buffer;
925 4816         17772 my $nread = sysread( $exp, $buffer, 2048 );
926              
927             # Make errors (nread undef) show up as EOF.
928 4816 100       7342 $nread = 0 unless defined($nread);
929              
930 4816 100       6656 if ( $nread == 0 ) {
931 23 50       92 print STDERR ("${*$exp}{exp_Pty_Handle}: EOF\r\n")
  0         0  
932             if ($Expect::Debug);
933 23         143 $before = ${*$exp}{exp_Before} = $exp->clear_accum();
  23         87  
934 23         55 $err = "2:EOF";
935 23         32 ${*$exp}{exp_Error} = $err;
  23         78  
936 23         60 ${*$exp}{exp_Has_EOF} = 1;
  23         64  
937 23         46 $exp_cont = undef;
938 23         60 foreach my $eof_pat ( grep { $_->[1] eq '-eof' } @{$pat}[ 1 .. $#{$pat} ] ) {
  41         183  
  23         78  
  23         55  
939 9         81 my $ret;
940 9 50       90 print STDERR ( "Calling EOF hook $eof_pat->[3]...\r\n", )
941             if ($Expect::Debug);
942 9 50       27 if ( $#{$eof_pat} > 3 ) {
  9         63  
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         54 $ret = &{ $eof_pat->[3] }($exp);
  9         90  
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       55 if ( defined( ${*$exp}{exp_Pid} ) ) {
  23         142  
960 23         1263 my $ret =
961 23         46 waitpid( ${*$exp}{exp_Pid}, POSIX::WNOHANG );
962 23 50       55 if ( $ret == ${*$exp}{exp_Pid} ) {
  23         312  
963 0         0 printf STDERR (
964             "%s: exit(0x%02X)\r\n",
965 23 50       87 ${*$exp}{exp_Pty_Handle}, $?
966             ) if ($Expect::Debug);
967 23         51 $err = "3:Child PID ${*$exp}{exp_Pid} exited with status $?";
  23         184  
968 23         60 ${*$exp}{exp_Error} = $err;
  23         69  
969 23         23 ${*$exp}{exp_Exit} = $?;
  23         69  
970 23         46 delete $Expect::Spawned_PIDs{ ${*$exp}{exp_Pid} };
  23         384  
971 23         46 ${*$exp}{exp_Pid} = undef;
  23         64  
972             }
973             }
974 23 50       83 print STDERR ("${*$exp}{exp_Pty_Handle}: closing...\r\n")
  0         0  
975             if ($Expect::Debug);
976 23         161 $exp->hard_close();
977 23         124 next;
978             }
979 4793 50       6371 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 4793 100       4413 $buffer =~ s/ \cH//g if not ${*$exp}{exp_Raw_Pty};
  4793         12742  
985              
986             # Append it to the accumulator.
987 4793         4324 ${*$exp}{exp_Accum} .= $buffer;
  4793         7670  
988 4793 50 33     3792 if ( exists ${*$exp}{exp_Max_Accum}
  4793         10072  
  4793         14087  
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 4793         3955 ${*$exp}{exp_New_Data} = 1; # next round we try to match again
  4793         5964  
997              
998 4793         9473 $exp_cont = exp_continue
999 0         0 if ( exists ${*$exp}{exp_Continue}
1000 4793 50 33     4023 and ${*$exp}{exp_Continue} );
1001              
1002             # Now propagate what we have read to other listeners...
1003 4793         9166 $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 4816 50 66     12802 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     12554 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       6897 if ($exp_matched) {
1048             return wantarray
1049             ? (
1050 4763         7023 ${*$exp_matched}{exp_Match_Number}, ${*$exp_matched}{exp_Error},
  4763         5244  
  4763         4441  
1051 4763         4266 ${*$exp_matched}{exp_Match}, ${*$exp_matched}{exp_Before},
  4763         19727  
1052 0         0 ${*$exp_matched}{exp_After}, $exp_matched,
1053             )
1054 4763 50       6136 : ${*$exp_matched}{exp_Match_Number};
1055             }
1056              
1057 48 50       488 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   19996 my ($listref, $timeoutlistref,$store_parm_nr, @params) = @_;
1069              
1070             # $timeoutlistref gets timeout patterns
1071 14214   50     20081 my $parm_nr = $store_parm_nr || 1;
1072 14214         14706 foreach my $parm (@params) {
1073 14214 50       19570 if ( not ref($parm) eq 'ARRAY' ) {
1074 0         0 return "Parameter #$parm_nr is not an ARRAY ref.";
1075             }
1076 14214         19491 $parm = [@$parm]; # make copy
1077 14214 50       23579 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       24409 if ( $parm->[0] eq 'timeout' ) {
    100          
1087 4720 50       6943 if ( defined $timeoutlistref ) {
1088 4720         10826 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1089 4720 50       7798 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1090 4720         4882 push @$timeoutlistref, $parm;
1091             }
1092 4720         6693 next;
1093             } elsif ( $parm->[0] eq 'eof' ) {
1094 4720         8921 splice @$parm, 0, 1, ( "-$parm->[0]", undef );
1095             } else {
1096 4774         8258 unshift @$parm, '-re'; # defaults to RegExp
1097             }
1098             }
1099 9494 100       11020 if ( @$parm > 2 ) {
1100 9491 50       16731 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         7 push @$parm, undef; # make sure we have three elements
1108             }
1109              
1110 9494 50       13154 unshift @$parm, $store_parm_nr ? $parm_nr : undef;
1111 9494         8302 push @$listref, $parm;
1112 9494         11306 $parm_nr++;
1113             }
1114              
1115 14214         18293 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   146 no strict 'subs'; # Allow bare word 'STDIN'
  23         40  
  23         81869  
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 4820     4820 1 6784 my ($self, @params) = @_;
1401              
1402 4820 100       3135 if ( ${*$self}{exp_Log_File} ) {
  4820         9511  
1403 4635 100       3397 if ( ref( ${*$self}{exp_Log_File} ) eq 'CODE' ) {
  4635         9807  
1404 48         72 ${*$self}{exp_Log_File}->(@params);
  48         208  
1405             } else {
1406 4587         3271 ${*$self}{exp_Log_File}->print(@params);
  4587         10763  
1407             }
1408             }
1409              
1410 4820         121600 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 93956 my ( $self, @args ) = @_;
1417              
1418 4624 50       8369 return if not defined $self->fileno(); # skip if closed
1419 4624 50       16980 if ( ${*$self}{exp_Exp_Internal} ) {
  4624         10568  
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         5654 foreach my $arg (@args) {
1424 4624         7555 while ( length($arg) > 80 ) {
1425 10326         26578 $self->SUPER::print( substr( $arg, 0, 80 ) );
1426 10326         224375 $arg = substr( $arg, 80 );
1427             }
1428 4624         10476 $self->SUPER::print($arg);
1429             }
1430              
1431 4624         113479 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 28256 my ($self, $sleep_time, @chunks) = @_;
1441              
1442 24 50       96 return if not defined $self->fileno(); # skip if closed
1443              
1444             # Flushing makes it so each character can be seen separately.
1445 24         176 my $chunk;
1446 24         104 while ( $chunk = shift @chunks ) {
1447 24         424 my @linechars = split( '', $chunk );
1448 24         112 foreach my $char (@linechars) {
1449              
1450             # How slow?
1451 1040         104252896 select( undef, undef, undef, $sleep_time );
1452              
1453 1040         85840 print $self $char;
1454 0         0 print STDERR "Printed character \'" . _make_readable($char) . "\' to ${*$self}{exp_Pty_Handle}.\r\n"
  1040         24432  
1455 1040 50       4488 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     5952 if ( ${*$self}{"exp_Log_Stdout"} || ${*$self}{exp_Log_Group} ) {
  1040         8008  
  0         0  
1459 1040         4088 my $rmask = "";
1460 1040         14024 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         10376408 while ( select( $rmask, undef, undef, .01 ) ) {
1465 24         72 my $ret = sysread( $self, ${*$self}{exp_Pty_Buffer}, 1024 );
  24         312  
1466 24 50 33     304 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         112 ${*$self}{exp_Accum} .= ${*$self}{exp_Pty_Buffer};
  24         64  
  24         112  
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         56 $self->_print_handles( ${*$self}{exp_Pty_Buffer} );
  24         168  
1476 24         245120 print STDERR "Received \'"
1477             . $self->_trim_length( _make_readable($char) )
1478 0         0 . "\' from ${*$self}{exp_Pty_Handle}\r\n"
1479 24 50       40 if ${*$self}{"exp_Debug"} > 1;
1480             }
1481             }
1482             }
1483             }
1484              
1485 24         216 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 5386 my ($self) = @_;
1526              
1527 7         28 my ( $nfound, $nread, $rmask, $end_time, $temp_buffer );
1528              
1529             # Give it 15 seconds to cough up an eof.
1530 7 50       14 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  7         45  
1531 7 50       32 return -1 if not defined $self->fileno(); # skip if handle already closed
1532 7 50 33     52 unless ( exists ${*$self}{exp_Has_EOF} and ${*$self}{exp_Has_EOF} ) {
  7         39  
  0         0  
1533 7         21 $end_time = time() + 15;
1534 7         39 while ( $end_time > time() ) {
1535 10         28 my $select_time = $end_time - time();
1536              
1537             # Sanity check.
1538 10 50       37 $select_time = 0 if $select_time < 0;
1539 10         17 $rmask = '';
1540 10         54 vec( $rmask, $self->fileno(), 1 ) = 1;
1541 10         13993283 ($nfound) = select( $rmask, undef, undef, $select_time );
1542 10 50 33     173 last unless ( defined($nfound) && $nfound );
1543 10         115 $nread = sysread( $self, $temp_buffer, 8096 );
1544              
1545             # 0 = EOF.
1546 10 100 66     76 unless ( defined($nread) && $nread ) {
1547 0         0 print STDERR "Got EOF from ${*$self}{exp_Pty_Handle}.\r\n"
  7         63  
1548 7 50       11 if ${*$self}{exp_Debug};
1549 7         29 last;
1550             }
1551 3         30 $self->_print_handles($temp_buffer);
1552             }
1553 7 50 33     35 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         79 my $close_status = $self->close();
1558 7 50 33     428 if ( $close_status && ${*$self}{exp_Debug} ) {
  7         42  
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       11 return $close_status unless defined( ${*$self}{exp_Pid} );
  7         32  
1564              
1565             # Now give it 15 seconds to die.
1566 7         18 $end_time = time() + 15;
1567 7         36 while ( $end_time > time() ) {
1568 7         7 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  7         155  
1569              
1570             # Stop here if the process dies.
1571 7 50 33     64 if ( defined($returned_pid) && $returned_pid ) {
1572 7         42 delete $Expect::Spawned_PIDs{$returned_pid};
1573 7 50       11 if ( ${*$self}{exp_Debug} ) {
  7         28  
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         14 ${*$self}{exp_Pid} = undef;
  7         15  
1581 7         18 ${*$self}{exp_Exit} = $?;
  7         64  
1582 7         18 return ${*$self}{exp_Exit};
  7         44  
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 56480 my ($self) = @_;
1620              
1621 167 50       235 cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug};
  0         0  
  167         1272  
1622              
1623             # Don't wait for an EOF.
1624 167         988 my $close_status = $self->close();
1625 167 50 66     20893 if ( $close_status && ${*$self}{exp_Debug} ) {
  101         821  
1626 0         0 print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n";
  0         0  
1627             }
1628              
1629             # Return now if handle.
1630 167 100       380 return $close_status unless defined( ${*$self}{exp_Pid} );
  167         701  
1631              
1632             # Now give it 5 seconds to die. Less patience here if it won't die.
1633 78         338 my $end_time = time() + 5;
1634 78         334 while ( $end_time > time() ) {
1635 112         297 my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG );
  112         4900  
1636              
1637             # Stop here if the process dies.
1638 112 100 66     1386 if ( defined($returned_pid) && $returned_pid ) {
1639 78         1283 delete $Expect::Spawned_PIDs{$returned_pid};
1640 78 50       139 if ( ${*$self}{exp_Debug} ) {
  78         452  
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         191 ${*$self}{exp_Pid} = undef;
  78         210  
1648 78         258 ${*$self}{exp_Exit} = $?;
  78         449  
1649 78         331 return ${*$self}{exp_Exit};
  78         918  
1650             }
1651 34         34005846 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   225 my ($self) = @_;
1710              
1711             # for every spawned process or filehandle.
1712 126 50       463 ${*$self}{exp_Log_Stdout} = $Expect::Log_Stdout
  0         0  
1713             if defined($Expect::Log_Stdout);
1714 126         173 ${*$self}{exp_Log_Group} = $Expect::Log_Group;
  126         392  
1715 126         178 ${*$self}{exp_Debug} = $Expect::Debug;
  126         299  
1716 126         144 ${*$self}{exp_Exp_Internal} = $Expect::Exp_Internal;
  126         361  
1717 126         184 ${*$self}{exp_Manual_Stty} = $Expect::Manual_Stty;
  126         252  
1718 126         223 ${*$self}{exp_Stored_Stty} = 'sane';
  126         399  
1719 126         195 ${*$self}{exp_Do_Soft_Close} = $Expect::Do_Soft_Close;
  126         307  
1720              
1721             # sysread doesn't like my or local vars.
1722 126         225 ${*$self}{exp_Pty_Buffer} = '';
  126         304  
1723              
1724             # Initialize accumulator.
1725 126         270 ${*$self}{exp_Max_Accum} = $Expect::Exp_Max_Accum;
  126         297  
1726 126         141 ${*$self}{exp_Accum} = '';
  126         463  
1727 126         149 ${*$self}{exp_NoTransfer} = 0;
  126         263  
1728              
1729             # create empty expect_before & after lists
1730 126         228 ${*$self}{exp_expect_before_list} = [];
  126         287  
1731 126         212 ${*$self}{exp_expect_after_list} = [];
  126         252  
1732              
1733 126         205 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   1169 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       68 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         35 return ($string)
1772             if (defined($self)
1773 15 50 66     31 and ${*$self}{"exp_Debug"} >= 3
      33        
1774             and ( !( defined($length) ) ) );
1775 15 100       25 my $indicate_truncation = ($length ? '' : '...');
1776 15   100     38 $length ||= 1021;
1777 15 100       58 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         59 return $indicate_truncation . substr( $string, ( length($string) - $length ), $length );
1783             }
1784              
1785             sub _print_handles {
1786 4820     4820   6987 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 4820 50       3297 if ( ${*$self}{exp_Log_Group} ) {
  4820         9896  
1791 4820         4141 foreach my $handle ( @{ ${*$self}{exp_Listen_Group} } ) {
  4820         3594  
  4820         9105  
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 4820         47286 print STDOUT $print_this
1805 4820 100       4397 if ${*$self}{"exp_Log_Stdout"};
1806 4820         7814 $self->print_log_file($print_this);
1807 4820         7297 $| = 1; # This should not be necessary but autoflush() doesn't always work.
1808              
1809 4820         12908 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   54330 my ($self) = @_;
1843              
1844 109         269 my $status = $?; # save this as it gets mangled by the terminating spawned children
1845 109 50       156 if ( ${*$self}{exp_Do_Soft_Close} ) {
  109         572  
1846 0         0 $self->soft_close();
1847             }
1848 109         491 $self->hard_close();
1849 109         319 $? = $status; # restore it. otherwise deleting an Expect object may mangle $?, which is unintuitive
1850              
1851 109         3056 return;
1852             }
1853              
1854             1;
1855             __END__