| 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__ |