| 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 <ASchutz@users.sourceforge.net> |
|
12
|
|
|
|
|
|
|
# |
|
13
|
|
|
|
|
|
|
# This module now is maintained by |
|
14
|
|
|
|
|
|
|
# Dave Jacoby <jacoby@cpan.org> |
|
15
|
|
|
|
|
|
|
# |
|
16
|
|
|
|
|
|
|
|
|
17
|
29
|
|
|
29
|
|
3724391
|
use 5.006; |
|
|
29
|
|
|
|
|
114
|
|
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
package Expect; |
|
20
|
29
|
|
|
29
|
|
143
|
use strict; |
|
|
29
|
|
|
|
|
92
|
|
|
|
29
|
|
|
|
|
881
|
|
|
21
|
29
|
|
|
29
|
|
147
|
use warnings; |
|
|
29
|
|
|
|
|
73
|
|
|
|
29
|
|
|
|
|
2145
|
|
|
22
|
|
|
|
|
|
|
|
|
23
|
29
|
|
|
29
|
|
14946
|
use IO::Pty 1.11; # We need make_slave_controlling_terminal() |
|
|
29
|
|
|
|
|
600581
|
|
|
|
29
|
|
|
|
|
1836
|
|
|
24
|
29
|
|
|
29
|
|
275
|
use IO::Tty; |
|
|
29
|
|
|
|
|
34
|
|
|
|
29
|
|
|
|
|
119
|
|
|
25
|
|
|
|
|
|
|
|
|
26
|
29
|
|
|
29
|
|
2361
|
use POSIX qw(:sys_wait_h :unistd_h); # For WNOHANG and isatty |
|
|
29
|
|
|
|
|
53
|
|
|
|
29
|
|
|
|
|
123
|
|
|
27
|
29
|
|
|
29
|
|
60420
|
use Fcntl qw(:DEFAULT); # For checking file handle settings. |
|
|
29
|
|
|
|
|
58
|
|
|
|
29
|
|
|
|
|
9117
|
|
|
28
|
29
|
|
|
29
|
|
234
|
use Carp qw(cluck croak carp confess); |
|
|
29
|
|
|
|
|
58
|
|
|
|
29
|
|
|
|
|
1549
|
|
|
29
|
29
|
|
|
29
|
|
150
|
use IO::Handle (); |
|
|
29
|
|
|
|
|
34
|
|
|
|
29
|
|
|
|
|
837
|
|
|
30
|
29
|
|
|
29
|
|
134
|
use Exporter qw(import); |
|
|
29
|
|
|
|
|
37
|
|
|
|
29
|
|
|
|
|
855
|
|
|
31
|
29
|
|
|
29
|
|
6012
|
use Errno; |
|
|
29
|
|
|
|
|
19804
|
|
|
|
29
|
|
|
|
|
1244
|
|
|
32
|
29
|
|
|
29
|
|
157
|
use Scalar::Util qw/ looks_like_number /; |
|
|
29
|
|
|
|
|
55
|
|
|
|
29
|
|
|
|
|
4582
|
|
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# This is necessary to make routines within Expect work. |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
@Expect::ISA = qw(IO::Pty); |
|
37
|
|
|
|
|
|
|
@Expect::EXPORT = qw(expect exp_continue exp_continue_timeout); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
BEGIN { |
|
40
|
29
|
|
|
29
|
|
93
|
$Expect::VERSION = '1.38'; |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# These are defaults which may be changed per object, or set as |
|
43
|
|
|
|
|
|
|
# the user wishes. |
|
44
|
|
|
|
|
|
|
# This will be unset, since the default behavior differs between |
|
45
|
|
|
|
|
|
|
# spawned processes and initialized filehandles. |
|
46
|
|
|
|
|
|
|
# $Expect::Log_Stdout = 1; |
|
47
|
29
|
|
|
|
|
65
|
$Expect::Log_Group = 1; |
|
48
|
29
|
|
|
|
|
35
|
$Expect::Debug = 0; |
|
49
|
29
|
|
|
|
|
35
|
$Expect::Exp_Max_Accum = 0; # unlimited |
|
50
|
29
|
|
|
|
|
53
|
$Expect::Exp_Internal = 0; |
|
51
|
29
|
|
|
|
|
38
|
$Expect::IgnoreEintr = 0; |
|
52
|
29
|
|
|
|
|
120
|
$Expect::Manual_Stty = 0; |
|
53
|
29
|
|
|
|
|
200
|
$Expect::Multiline_Matching = 1; |
|
54
|
29
|
|
|
|
|
65
|
$Expect::Do_Soft_Close = 0; |
|
55
|
29
|
|
|
|
|
39
|
@Expect::Before_List = (); |
|
56
|
29
|
|
|
|
|
53
|
@Expect::After_List = (); |
|
57
|
29
|
|
|
|
|
42318
|
%Expect::Spawned_PIDs = (); |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub version { |
|
61
|
0
|
|
|
0
|
1
|
0
|
my ($version) = @_; |
|
62
|
|
|
|
|
|
|
|
|
63
|
0
|
0
|
0
|
|
|
0
|
warn "Version $version is later than $Expect::VERSION. It may not be supported" |
|
64
|
|
|
|
|
|
|
if ( defined($version) && ( $version > $Expect::VERSION ) ); |
|
65
|
|
|
|
|
|
|
|
|
66
|
0
|
0
|
0
|
|
|
0
|
die "Versions before 1.03 are not supported in this release" |
|
67
|
|
|
|
|
|
|
if ( ( defined($version) ) && ( $version < 1.03 ) ); |
|
68
|
0
|
|
|
|
|
0
|
return $Expect::VERSION; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub new { |
|
72
|
151
|
|
|
151
|
1
|
2713588
|
my ($class, @args) = @_; |
|
73
|
|
|
|
|
|
|
|
|
74
|
151
|
50
|
|
|
|
802
|
$class = ref($class) if ref($class); # so we can be called as $exp->new() |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# Create the pty which we will use to pass process info. |
|
77
|
151
|
|
|
|
|
2990
|
my ($self) = IO::Pty->new; |
|
78
|
151
|
50
|
|
|
|
131235
|
die "$class: Could not assign a pty" unless $self; |
|
79
|
151
|
|
|
|
|
1568
|
bless $self => $class; |
|
80
|
151
|
|
|
|
|
1030
|
$self->autoflush(1); |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# This is defined here since the default is different for |
|
83
|
|
|
|
|
|
|
# initialized handles as opposed to spawned processes. |
|
84
|
151
|
|
|
|
|
5953
|
${*$self}{exp_Log_Stdout} = 1; |
|
|
151
|
|
|
|
|
1230
|
|
|
85
|
151
|
|
|
|
|
1292
|
$self->_init_vars(); |
|
86
|
|
|
|
|
|
|
|
|
87
|
151
|
100
|
|
|
|
697
|
if (@args) { |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# we got add'l parms, so pass them to spawn |
|
90
|
72
|
|
|
|
|
475
|
return $self->spawn(@args); |
|
91
|
|
|
|
|
|
|
} |
|
92
|
79
|
|
|
|
|
310
|
return $self; |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub timeout { |
|
96
|
14
|
|
|
14
|
0
|
97
|
my $self = shift; |
|
97
|
14
|
100
|
|
|
|
54
|
${*$self}{expect_timeout} = shift if @_; |
|
|
6
|
|
|
|
|
25
|
|
|
98
|
14
|
|
|
|
|
23
|
return ${*$self}{expect_timeout}; |
|
|
14
|
|
|
|
|
55
|
|
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub spawn { |
|
102
|
152
|
|
|
152
|
1
|
4459113
|
my ($class, @cmd) = @_; |
|
103
|
|
|
|
|
|
|
# spawn is passed command line args. |
|
104
|
|
|
|
|
|
|
|
|
105
|
152
|
|
|
|
|
343
|
my $self; |
|
106
|
|
|
|
|
|
|
|
|
107
|
152
|
100
|
|
|
|
949
|
if ( ref($class) ) { |
|
108
|
125
|
|
|
|
|
308
|
$self = $class; |
|
109
|
|
|
|
|
|
|
} else { |
|
110
|
27
|
|
|
|
|
220
|
$self = $class->new(); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
croak "Cannot reuse an object with an already spawned command" |
|
114
|
152
|
100
|
|
|
|
482
|
if exists ${*$self}{"exp_Command"}; |
|
|
152
|
|
|
|
|
2853
|
|
|
115
|
150
|
|
|
|
|
380
|
${*$self}{"exp_Command"} = \@cmd; |
|
|
150
|
|
|
|
|
425
|
|
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# set up pipe to detect childs exec error |
|
118
|
150
|
50
|
|
|
|
6818
|
pipe( FROM_CHILD, TO_PARENT ) or die "Cannot open pipe: $!"; |
|
119
|
150
|
50
|
|
|
|
3501
|
pipe( FROM_PARENT, TO_CHILD ) or die "Cannot open pipe: $!"; |
|
120
|
150
|
|
|
|
|
1355
|
TO_PARENT->autoflush(1); |
|
121
|
150
|
|
|
|
|
7812
|
TO_CHILD->autoflush(1); |
|
122
|
150
|
|
|
|
|
4601
|
eval { fcntl( TO_PARENT, Fcntl::F_SETFD, Fcntl::FD_CLOEXEC ); }; |
|
|
150
|
|
|
|
|
2169
|
|
|
123
|
|
|
|
|
|
|
|
|
124
|
150
|
|
|
|
|
413504
|
my $pid = fork; |
|
125
|
|
|
|
|
|
|
|
|
126
|
150
|
50
|
|
|
|
8257
|
unless ( defined($pid) ) { |
|
127
|
0
|
0
|
|
|
|
0
|
warn "Cannot fork: $!" if $^W; |
|
128
|
0
|
|
|
|
|
0
|
return; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
|
|
|
|
|
|
|
|
131
|
150
|
100
|
|
|
|
6438
|
if ($pid) { |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# parent |
|
134
|
129
|
|
|
|
|
564
|
my $errno; |
|
135
|
129
|
|
|
|
|
648
|
${*$self}{exp_Pid} = $pid; |
|
|
129
|
|
|
|
|
18493
|
|
|
136
|
129
|
|
|
|
|
10337
|
close TO_PARENT; |
|
137
|
129
|
|
|
|
|
3960
|
close FROM_PARENT; |
|
138
|
129
|
|
|
|
|
15920
|
$self->close_slave(); |
|
139
|
129
|
100
|
66
|
|
|
44285
|
$self->set_raw() if $self->raw_pty and isatty($self); |
|
140
|
129
|
|
|
|
|
13381
|
close TO_CHILD; # so child gets EOF and can go ahead |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# now wait for child exec (eof due to close-on-exit) or exec error |
|
143
|
129
|
|
|
|
|
171320479
|
my $errstatus = sysread( FROM_CHILD, $errno, 256 ); |
|
144
|
129
|
50
|
|
|
|
1672
|
die "Cannot sync with child: $!" if not defined $errstatus; |
|
145
|
129
|
|
|
|
|
4587
|
close FROM_CHILD; |
|
146
|
129
|
100
|
|
|
|
780
|
if ($errstatus) { |
|
147
|
14
|
|
|
|
|
490
|
$! = $errno + 0; |
|
148
|
14
|
50
|
|
|
|
378
|
warn "Cannot exec(@cmd): $!\n" if $^W; |
|
149
|
14
|
|
|
|
|
1876
|
return; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
} else { |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# child |
|
154
|
21
|
|
|
|
|
3360
|
close FROM_CHILD; |
|
155
|
21
|
|
|
|
|
1344
|
close TO_CHILD; |
|
156
|
|
|
|
|
|
|
|
|
157
|
21
|
|
|
|
|
5909
|
$self->make_slave_controlling_terminal(); |
|
158
|
21
|
50
|
|
|
|
48070
|
my $slv = $self->slave() |
|
159
|
|
|
|
|
|
|
or die "Cannot get slave: $!"; |
|
160
|
|
|
|
|
|
|
|
|
161
|
21
|
100
|
|
|
|
2682
|
$slv->set_raw() if $self->raw_pty; |
|
162
|
21
|
|
|
|
|
2840
|
close($self); |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# wait for parent before we detach |
|
165
|
21
|
|
|
|
|
321
|
my $buffer; |
|
166
|
21
|
|
|
|
|
3135
|
my $errstatus = sysread( FROM_PARENT, $buffer, 256 ); |
|
167
|
21
|
50
|
|
|
|
1114
|
die "Cannot sync with parent: $!" if not defined $errstatus; |
|
168
|
21
|
|
|
|
|
1189
|
close FROM_PARENT; |
|
169
|
|
|
|
|
|
|
|
|
170
|
21
|
|
|
|
|
264
|
close(STDIN); |
|
171
|
21
|
50
|
|
|
|
2431
|
open( STDIN, "<&" . $slv->fileno() ) |
|
172
|
|
|
|
|
|
|
or die "Couldn't reopen STDIN for reading, $!\n"; |
|
173
|
21
|
|
|
|
|
1528
|
close(STDOUT); |
|
174
|
21
|
50
|
|
|
|
653
|
open( STDOUT, ">&" . $slv->fileno() ) |
|
175
|
|
|
|
|
|
|
or die "Couldn't reopen STDOUT for writing, $!\n"; |
|
176
|
21
|
|
|
|
|
1301
|
close(STDERR); |
|
177
|
21
|
50
|
|
|
|
478
|
open( STDERR, ">&" . $slv->fileno() ) |
|
178
|
|
|
|
|
|
|
or die "Couldn't reopen STDERR for writing, $!\n"; |
|
179
|
|
|
|
|
|
|
|
|
180
|
21
|
|
|
|
|
1467
|
{ exec(@cmd) }; |
|
|
21
|
|
|
|
|
0
|
|
|
181
|
0
|
|
|
|
|
0
|
print TO_PARENT $! + 0; |
|
182
|
0
|
|
|
|
|
0
|
die "Cannot exec(@cmd): $!\n"; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# This is sort of for code compatibility, and to make debugging a little |
|
186
|
|
|
|
|
|
|
# easier. By code compatibility I mean that previously the process's |
|
187
|
|
|
|
|
|
|
# handle was referenced by $process{Pty_Handle} instead of just $process. |
|
188
|
|
|
|
|
|
|
# This is almost like 'naming' the handle to the process. |
|
189
|
|
|
|
|
|
|
# I think this also reflects Tcl Expect-like behavior. |
|
190
|
115
|
|
|
|
|
3563
|
${*$self}{exp_Pty_Handle} = "spawn id(" . $self->fileno() . ")"; |
|
|
115
|
|
|
|
|
4290
|
|
|
191
|
115
|
50
|
33
|
|
|
390
|
if ( ( ${*$self}{"exp_Debug"} ) or ( ${*$self}{"exp_Exp_Internal"} ) ) { |
|
|
115
|
|
|
|
|
1706
|
|
|
|
115
|
|
|
|
|
967
|
|
|
192
|
0
|
|
|
|
|
0
|
cluck( |
|
193
|
|
|
|
|
|
|
"Spawned '@cmd'\r\n", |
|
194
|
0
|
|
|
|
|
0
|
"\t${*$self}{exp_Pty_Handle}\r\n", |
|
195
|
0
|
|
|
|
|
0
|
"\tPid: ${*$self}{exp_Pid}\r\n", |
|
196
|
|
|
|
|
|
|
"\tTty: " . $self->SUPER::ttyname() . "\r\n", |
|
197
|
|
|
|
|
|
|
); |
|
198
|
|
|
|
|
|
|
} |
|
199
|
115
|
|
|
|
|
489
|
$Expect::Spawned_PIDs{ ${*$self}{exp_Pid} } = undef; |
|
|
115
|
|
|
|
|
2328
|
|
|
200
|
115
|
|
|
|
|
3493
|
return $self; |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub exp_init { |
|
204
|
0
|
|
|
0
|
1
|
0
|
my ($class, $self) = @_; |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# take a filehandle, for use later with expect() or interconnect() . |
|
207
|
|
|
|
|
|
|
# All the functions are written for reading from a tty, so if the naming |
|
208
|
|
|
|
|
|
|
# scheme looks odd, that's why. |
|
209
|
0
|
|
|
|
|
0
|
bless $self, $class; |
|
210
|
0
|
0
|
|
|
|
0
|
croak "exp_init not passed a file object, stopped" |
|
211
|
|
|
|
|
|
|
unless defined( $self->fileno() ); |
|
212
|
0
|
|
|
|
|
0
|
$self->autoflush(1); |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# Define standard variables.. debug states, etc. |
|
215
|
0
|
|
|
|
|
0
|
$self->_init_vars(); |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# Turn of logging. By default we don't want crap from a file to get spewed |
|
218
|
|
|
|
|
|
|
# on screen as we read it. |
|
219
|
0
|
|
|
|
|
0
|
${*$self}{exp_Log_Stdout} = 0; |
|
|
0
|
|
|
|
|
0
|
|
|
220
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle} = "handle id(" . $self->fileno() . ")"; |
|
|
0
|
|
|
|
|
0
|
|
|
221
|
0
|
0
|
|
|
|
0
|
${*$self}{exp_Pty_Handle} = "STDIN" if $self->fileno() == fileno(STDIN); |
|
|
0
|
|
|
|
|
0
|
|
|
222
|
0
|
|
|
|
|
0
|
print STDERR "Initialized ${*$self}{exp_Pty_Handle}.'\r\n" |
|
223
|
0
|
0
|
|
|
|
0
|
if ${*$self}{"exp_Debug"}; |
|
|
0
|
|
|
|
|
0
|
|
|
224
|
0
|
|
|
|
|
0
|
return $self; |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# make an alias |
|
228
|
|
|
|
|
|
|
*init = \&exp_init; |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
###################################################################### |
|
231
|
|
|
|
|
|
|
# We're happy OOP people. No direct access to stuff. |
|
232
|
|
|
|
|
|
|
# For standard read-writeable parameters, we define some autoload magic... |
|
233
|
|
|
|
|
|
|
my %Writeable_Vars = ( |
|
234
|
|
|
|
|
|
|
debug => 'exp_Debug', |
|
235
|
|
|
|
|
|
|
exp_internal => 'exp_Exp_Internal', |
|
236
|
|
|
|
|
|
|
do_soft_close => 'exp_Do_Soft_Close', |
|
237
|
|
|
|
|
|
|
max_accum => 'exp_Max_Accum', |
|
238
|
|
|
|
|
|
|
match_max => 'exp_Max_Accum', |
|
239
|
|
|
|
|
|
|
notransfer => 'exp_NoTransfer', |
|
240
|
|
|
|
|
|
|
log_stdout => 'exp_Log_Stdout', |
|
241
|
|
|
|
|
|
|
log_user => 'exp_Log_Stdout', |
|
242
|
|
|
|
|
|
|
log_group => 'exp_Log_Group', |
|
243
|
|
|
|
|
|
|
manual_stty => 'exp_Manual_Stty', |
|
244
|
|
|
|
|
|
|
restart_timeout_upon_receive => 'exp_Continue', |
|
245
|
|
|
|
|
|
|
raw_pty => 'exp_Raw_Pty', |
|
246
|
|
|
|
|
|
|
); |
|
247
|
|
|
|
|
|
|
my %Readable_Vars = ( |
|
248
|
|
|
|
|
|
|
pid => 'exp_Pid', |
|
249
|
|
|
|
|
|
|
exp_pid => 'exp_Pid', |
|
250
|
|
|
|
|
|
|
exp_match_number => 'exp_Match_Number', |
|
251
|
|
|
|
|
|
|
match_number => 'exp_Match_Number', |
|
252
|
|
|
|
|
|
|
exp_error => 'exp_Error', |
|
253
|
|
|
|
|
|
|
error => 'exp_Error', |
|
254
|
|
|
|
|
|
|
exp_command => 'exp_Command', |
|
255
|
|
|
|
|
|
|
command => 'exp_Command', |
|
256
|
|
|
|
|
|
|
exp_match => 'exp_Match', |
|
257
|
|
|
|
|
|
|
match => 'exp_Match', |
|
258
|
|
|
|
|
|
|
exp_matchlist => 'exp_Matchlist', |
|
259
|
|
|
|
|
|
|
matchlist => 'exp_Matchlist', |
|
260
|
|
|
|
|
|
|
exp_before => 'exp_Before', |
|
261
|
|
|
|
|
|
|
before => 'exp_Before', |
|
262
|
|
|
|
|
|
|
exp_after => 'exp_After', |
|
263
|
|
|
|
|
|
|
after => 'exp_After', |
|
264
|
|
|
|
|
|
|
exp_exitstatus => 'exp_Exit', |
|
265
|
|
|
|
|
|
|
exitstatus => 'exp_Exit', |
|
266
|
|
|
|
|
|
|
exp_pty_handle => 'exp_Pty_Handle', |
|
267
|
|
|
|
|
|
|
pty_handle => 'exp_Pty_Handle', |
|
268
|
|
|
|
|
|
|
exp_logfile => 'exp_Log_File', |
|
269
|
|
|
|
|
|
|
logfile => 'exp_Log_File', |
|
270
|
|
|
|
|
|
|
%Writeable_Vars, |
|
271
|
|
|
|
|
|
|
); |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
sub AUTOLOAD { |
|
274
|
374
|
|
|
374
|
|
104877
|
my ($self, @args) = @_; |
|
275
|
|
|
|
|
|
|
|
|
276
|
374
|
50
|
|
|
|
2849
|
my $type = ref($self) |
|
277
|
|
|
|
|
|
|
or croak "$self is not an object"; |
|
278
|
|
|
|
|
|
|
|
|
279
|
29
|
|
|
29
|
|
224
|
use vars qw($AUTOLOAD); |
|
|
29
|
|
|
|
|
90
|
|
|
|
29
|
|
|
|
|
134693
|
|
|
280
|
374
|
|
|
|
|
2255
|
my $name = $AUTOLOAD; |
|
281
|
374
|
|
|
|
|
10554
|
$name =~ s/.*:://; # strip fully-qualified portion |
|
282
|
|
|
|
|
|
|
|
|
283
|
374
|
50
|
|
|
|
2170
|
unless ( exists $Readable_Vars{$name} ) { |
|
284
|
0
|
|
|
|
|
0
|
croak "ERROR: cannot find method `$name' in class $type"; |
|
285
|
|
|
|
|
|
|
} |
|
286
|
374
|
|
|
|
|
3925
|
my $varname = $Readable_Vars{$name}; |
|
287
|
374
|
|
|
|
|
1475
|
my $tmp; |
|
288
|
374
|
100
|
|
|
|
633
|
$tmp = ${*$self}{$varname} if exists ${*$self}{$varname}; |
|
|
221
|
|
|
|
|
1896
|
|
|
|
374
|
|
|
|
|
4577
|
|
|
289
|
|
|
|
|
|
|
|
|
290
|
374
|
100
|
|
|
|
1340
|
if (@args) { |
|
291
|
90
|
50
|
|
|
|
501
|
if ( exists $Writeable_Vars{$name} ) { |
|
292
|
90
|
|
|
|
|
270
|
my $ref = ref($tmp); |
|
293
|
90
|
50
|
|
|
|
740
|
if ( $ref eq 'ARRAY' ) { |
|
|
|
50
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
0
|
${*$self}{$varname} = [@args]; |
|
|
0
|
|
|
|
|
0
|
|
|
295
|
|
|
|
|
|
|
} elsif ( $ref eq 'HASH' ) { |
|
296
|
0
|
|
|
|
|
0
|
${*$self}{$varname} = {@args}; |
|
|
0
|
|
|
|
|
0
|
|
|
297
|
|
|
|
|
|
|
} else { |
|
298
|
90
|
|
|
|
|
283
|
${*$self}{$varname} = shift @args; |
|
|
90
|
|
|
|
|
428
|
|
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
} else { |
|
301
|
0
|
0
|
|
|
|
0
|
carp "Trying to set read-only variable `$name'" |
|
302
|
|
|
|
|
|
|
if $^W; |
|
303
|
|
|
|
|
|
|
} |
|
304
|
|
|
|
|
|
|
} |
|
305
|
|
|
|
|
|
|
|
|
306
|
374
|
|
|
|
|
1218
|
my $ref = ref($tmp); |
|
307
|
374
|
50
|
|
|
|
1382
|
return ( wantarray ? @{$tmp} : $tmp ) if ( $ref eq 'ARRAY' ); |
|
|
7
|
100
|
|
|
|
67
|
|
|
308
|
367
|
0
|
|
|
|
1306
|
return ( wantarray ? %{$tmp} : $tmp ) if ( $ref eq 'HASH' ); |
|
|
0
|
50
|
|
|
|
0
|
|
|
309
|
367
|
|
|
|
|
10678
|
return $tmp; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
###################################################################### |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
sub set_seq { |
|
315
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $escape_sequence, $function, $params, @args ) = @_; |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# Set an escape sequence/function combo for a read handle for interconnect. |
|
318
|
|
|
|
|
|
|
# Ex: $read_handle->set_seq('',\&function,\@parameters); |
|
319
|
0
|
|
|
|
|
0
|
${ ${*$self}{exp_Function} }{$escape_sequence} = $function; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
320
|
0
|
0
|
0
|
|
|
0
|
if ( ( !defined($function) ) || ( $function eq 'undef' ) ) { |
|
321
|
0
|
|
|
|
|
0
|
${ ${*$self}{exp_Function} }{$escape_sequence} = \&_undef; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
322
|
|
|
|
|
|
|
} |
|
323
|
0
|
|
|
|
|
0
|
${ ${*$self}{exp_Parameters} }{$escape_sequence} = $params; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# This'll be a joy to execute. :) |
|
326
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{"exp_Debug"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
327
|
0
|
|
|
|
|
0
|
print STDERR "Escape seq. '" . $escape_sequence; |
|
328
|
0
|
|
|
|
|
0
|
print STDERR "' function for ${*$self}{exp_Pty_Handle} set to '"; |
|
|
0
|
|
|
|
|
0
|
|
|
329
|
0
|
|
|
|
|
0
|
print STDERR ${ ${*$self}{exp_Function} }{$escape_sequence}; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
330
|
0
|
|
|
|
|
0
|
print STDERR "(" . join( ',', @args ) . ")'\r\n"; |
|
331
|
|
|
|
|
|
|
} |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub set_group { |
|
335
|
0
|
|
|
0
|
1
|
0
|
my ($self, @args) = @_; |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# Make sure we can read from the read handle |
|
338
|
0
|
0
|
|
|
|
0
|
if ( !defined( $args[0] ) ) { |
|
339
|
0
|
0
|
|
|
|
0
|
if ( defined( ${*$self}{exp_Listen_Group} ) ) { |
|
|
0
|
|
|
|
|
0
|
|
|
340
|
0
|
|
|
|
|
0
|
return @{ ${*$self}{exp_Listen_Group} }; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
341
|
|
|
|
|
|
|
} else { |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
# Refrain from referencing an undef |
|
344
|
0
|
|
|
|
|
0
|
return; |
|
345
|
|
|
|
|
|
|
} |
|
346
|
|
|
|
|
|
|
} |
|
347
|
0
|
|
|
|
|
0
|
@{ ${*$self}{exp_Listen_Group} } = (); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
348
|
0
|
0
|
|
|
|
0
|
if ( $self->_get_mode() !~ 'r' ) { |
|
349
|
0
|
|
|
|
|
0
|
warn( |
|
350
|
0
|
|
|
|
|
0
|
"Attempting to set a handle group on ${*$self}{exp_Pty_Handle}, ", |
|
351
|
|
|
|
|
|
|
"a non-readable handle!\r\n" |
|
352
|
|
|
|
|
|
|
); |
|
353
|
|
|
|
|
|
|
} |
|
354
|
0
|
|
|
|
|
0
|
while ( my $write_handle = shift @args ) { |
|
355
|
0
|
0
|
|
|
|
0
|
if ( $write_handle->_get_mode() !~ 'w' ) { |
|
356
|
0
|
|
|
|
|
0
|
warn( |
|
357
|
|
|
|
|
|
|
"Attempting to set a non-writeable listen handle ", |
|
358
|
0
|
|
|
|
|
0
|
"${*$write_handle}{exp_Pty_handle} for ", |
|
359
|
0
|
|
|
|
|
0
|
"${*$self}{exp_Pty_Handle}!\r\n" |
|
360
|
|
|
|
|
|
|
); |
|
361
|
|
|
|
|
|
|
} |
|
362
|
0
|
|
|
|
|
0
|
push( @{ ${*$self}{exp_Listen_Group} }, $write_handle ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
363
|
|
|
|
|
|
|
} |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
sub log_file { |
|
367
|
73
|
|
|
73
|
1
|
168910
|
my ($self, $file, $mode) = @_; |
|
368
|
73
|
|
100
|
|
|
762
|
$mode ||= "a"; |
|
369
|
|
|
|
|
|
|
|
|
370
|
0
|
|
|
|
|
0
|
return ( ${*$self}{exp_Log_File} ) |
|
371
|
73
|
50
|
|
|
|
552
|
if @_ < 2; # we got no param, return filehandle |
|
372
|
|
|
|
|
|
|
# $e->log_file(undef) is an acceptable call hence we need to check the number of parameters here |
|
373
|
|
|
|
|
|
|
|
|
374
|
73
|
100
|
100
|
|
|
171
|
if ( ${*$self}{exp_Log_File} and ref( ${*$self}{exp_Log_File} ) ne 'CODE' ) { |
|
|
73
|
|
|
|
|
596
|
|
|
|
28
|
|
|
|
|
183
|
|
|
375
|
10
|
|
|
|
|
81
|
close( ${*$self}{exp_Log_File} ); |
|
|
10
|
|
|
|
|
453
|
|
|
376
|
|
|
|
|
|
|
} |
|
377
|
73
|
|
|
|
|
210
|
${*$self}{exp_Log_File} = undef; |
|
|
73
|
|
|
|
|
415
|
|
|
378
|
73
|
100
|
|
|
|
490
|
return if ( not $file ); |
|
379
|
44
|
|
|
|
|
125
|
my $fh = $file; |
|
380
|
44
|
100
|
|
|
|
223
|
if ( not ref($file) ) { |
|
381
|
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
# it's a filename |
|
383
|
26
|
50
|
|
|
|
1547
|
$fh = IO::File->new( $file, $mode ) |
|
384
|
|
|
|
|
|
|
or croak "Cannot open logfile $file: $!"; |
|
385
|
|
|
|
|
|
|
} |
|
386
|
44
|
100
|
|
|
|
11944
|
if ( ref($file) ne 'CODE' ) { |
|
387
|
26
|
50
|
|
|
|
506
|
croak "Given logfile doesn't have a 'print' method" |
|
388
|
|
|
|
|
|
|
if not $fh->can("print"); |
|
389
|
26
|
|
|
|
|
310
|
$fh->autoflush(1); # so logfile is up to date |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
|
|
392
|
44
|
|
|
|
|
2851
|
${*$self}{exp_Log_File} = $fh; |
|
|
44
|
|
|
|
|
184
|
|
|
393
|
|
|
|
|
|
|
|
|
394
|
44
|
|
|
|
|
255
|
return $fh; |
|
395
|
|
|
|
|
|
|
} |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# I'm going to leave this here in case I might need to change something. |
|
398
|
|
|
|
|
|
|
# Previously this was calling `stty`, in a most bastardized manner. |
|
399
|
|
|
|
|
|
|
sub exp_stty { |
|
400
|
0
|
|
|
0
|
0
|
0
|
my ($self) = shift; |
|
401
|
0
|
|
|
|
|
0
|
my ($mode) = "@_"; |
|
402
|
|
|
|
|
|
|
|
|
403
|
0
|
0
|
|
|
|
0
|
return unless defined $mode; |
|
404
|
0
|
0
|
|
|
|
0
|
if ( not defined $INC{"IO/Stty.pm"} ) { |
|
405
|
0
|
|
|
|
|
0
|
carp "IO::Stty not installed, cannot change mode"; |
|
406
|
0
|
|
|
|
|
0
|
return; |
|
407
|
|
|
|
|
|
|
} |
|
408
|
|
|
|
|
|
|
|
|
409
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{"exp_Debug"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
410
|
0
|
|
|
|
|
0
|
print STDERR "Setting ${*$self}{exp_Pty_Handle} to tty mode '$mode'\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
411
|
|
|
|
|
|
|
} |
|
412
|
0
|
0
|
|
|
|
0
|
unless ( POSIX::isatty($self) ) { |
|
413
|
0
|
0
|
0
|
|
|
0
|
if ( ${*$self}{"exp_Debug"} or $^W ) { |
|
|
0
|
|
|
|
|
0
|
|
|
414
|
0
|
|
|
|
|
0
|
warn "${*$self}{exp_Pty_Handle} is not a tty. Not changing mode"; |
|
|
0
|
|
|
|
|
0
|
|
|
415
|
|
|
|
|
|
|
} |
|
416
|
0
|
|
|
|
|
0
|
return ''; # No undef to avoid warnings elsewhere. |
|
417
|
|
|
|
|
|
|
} |
|
418
|
0
|
|
|
|
|
0
|
IO::Stty::stty( $self, split( /\s/, $mode ) ); |
|
419
|
|
|
|
|
|
|
} |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
*stty = \&exp_stty; |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
# If we want to clear the buffer. Otherwise Accum will grow during send_slow |
|
424
|
|
|
|
|
|
|
# etc. and contain the remainder after matches. |
|
425
|
|
|
|
|
|
|
sub clear_accum { |
|
426
|
41
|
|
|
41
|
1
|
1152
|
my ($self) = @_; |
|
427
|
41
|
|
|
|
|
163
|
return $self->set_accum(''); |
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
sub set_accum { |
|
431
|
61
|
|
|
61
|
1
|
888
|
my ($self, $accum) = @_; |
|
432
|
|
|
|
|
|
|
|
|
433
|
61
|
|
|
|
|
130
|
my $old_accum = ${*$self}{exp_Accum}; |
|
|
61
|
|
|
|
|
343
|
|
|
434
|
61
|
|
|
|
|
160
|
${*$self}{exp_Accum} = $accum; |
|
|
61
|
|
|
|
|
173
|
|
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# return the contents of the accumulator. |
|
437
|
61
|
|
|
|
|
282
|
return $old_accum; |
|
438
|
|
|
|
|
|
|
} |
|
439
|
|
|
|
|
|
|
sub get_accum { |
|
440
|
1
|
|
|
1
|
0
|
4
|
my ($self) = @_; |
|
441
|
1
|
|
|
|
|
2
|
return ${*$self}{exp_Accum}; |
|
|
1
|
|
|
|
|
27
|
|
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
###################################################################### |
|
445
|
|
|
|
|
|
|
# define constants for pattern subs |
|
446
|
11153
|
|
|
11153
|
0
|
54406
|
sub exp_continue {"exp_continue"} |
|
447
|
5473
|
|
|
5473
|
0
|
12936
|
sub exp_continue_timeout {"exp_continue_timeout"} |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
###################################################################### |
|
450
|
|
|
|
|
|
|
# Expect on multiple objects at once. |
|
451
|
|
|
|
|
|
|
# |
|
452
|
|
|
|
|
|
|
# Call as Expect::expect($timeout, -i => \@exp_list, @patternlist, |
|
453
|
|
|
|
|
|
|
# -i => $exp, @pattern_list, ...); |
|
454
|
|
|
|
|
|
|
# or $exp->expect($timeout, @patternlist, -i => \@exp_list, @patternlist, |
|
455
|
|
|
|
|
|
|
# -i => $exp, @pattern_list, ...); |
|
456
|
|
|
|
|
|
|
# |
|
457
|
|
|
|
|
|
|
# Patterns are arrays that consist of |
|
458
|
|
|
|
|
|
|
# [ $pattern_type, $pattern, $sub, @subparms ] |
|
459
|
|
|
|
|
|
|
# |
|
460
|
|
|
|
|
|
|
# Optional $pattern_type is '-re' (RegExp, default) or '-ex' (exact); |
|
461
|
|
|
|
|
|
|
# |
|
462
|
|
|
|
|
|
|
# $sub is optional CODE ref, which is called as &{$sub}($exp, @subparms) |
|
463
|
|
|
|
|
|
|
# if pattern matched; may return exp_continue or exp_continue_timeout. |
|
464
|
|
|
|
|
|
|
# |
|
465
|
|
|
|
|
|
|
# Old-style syntax (pure pattern strings with optional type) also supported. |
|
466
|
|
|
|
|
|
|
# |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
sub expect { |
|
469
|
5521
|
|
|
5521
|
1
|
60305145
|
my $self; |
|
470
|
|
|
|
|
|
|
|
|
471
|
5521
|
50
|
|
|
|
16749
|
print STDERR ("expect(@_) called...\n") if $Expect::Debug; |
|
472
|
5521
|
50
|
|
|
|
13819
|
if ( defined( $_[0] ) ) { |
|
473
|
5521
|
50
|
33
|
|
|
40305
|
if ( ref( $_[0] ) and $_[0]->isa('Expect') ) { |
|
|
|
0
|
|
|
|
|
|
|
474
|
5521
|
|
|
|
|
25346
|
$self = shift; |
|
475
|
|
|
|
|
|
|
} elsif ( $_[0] eq 'Expect' ) { |
|
476
|
0
|
|
|
|
|
0
|
shift; # or as Expect->expect |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
} |
|
479
|
5521
|
50
|
|
|
|
12913
|
croak "expect(): not enough arguments, should be expect(timeout, [patterns...])" |
|
480
|
|
|
|
|
|
|
if @_ < 1; |
|
481
|
5521
|
|
|
|
|
9290
|
my $timeout; |
|
482
|
5521
|
100
|
100
|
|
|
24450
|
if ( looks_like_number($_[0]) or not defined $_[0] ) { |
|
483
|
5513
|
|
|
|
|
9154
|
$timeout = shift; |
|
484
|
|
|
|
|
|
|
} |
|
485
|
|
|
|
|
|
|
else { |
|
486
|
8
|
|
|
|
|
41
|
$timeout = $self->timeout; |
|
487
|
|
|
|
|
|
|
} |
|
488
|
5521
|
|
|
|
|
9163
|
my $timeout_hook = undef; |
|
489
|
|
|
|
|
|
|
|
|
490
|
5521
|
|
|
|
|
21083
|
my @object_list; |
|
491
|
|
|
|
|
|
|
my %patterns; |
|
492
|
|
|
|
|
|
|
|
|
493
|
5521
|
|
|
|
|
0
|
my @pattern_list; |
|
494
|
5521
|
|
|
|
|
0
|
my @timeout_list; |
|
495
|
5521
|
|
|
|
|
0
|
my $curr_list; |
|
496
|
|
|
|
|
|
|
|
|
497
|
5521
|
50
|
|
|
|
10750
|
if ($self) { |
|
498
|
5521
|
|
|
|
|
12698
|
$curr_list = [$self]; |
|
499
|
|
|
|
|
|
|
} else { |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
# called directly, so first parameter must be '-i' to establish |
|
502
|
|
|
|
|
|
|
# object list. |
|
503
|
0
|
|
|
|
|
0
|
$curr_list = []; |
|
504
|
0
|
0
|
|
|
|
0
|
croak |
|
505
|
|
|
|
|
|
|
"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." |
|
506
|
|
|
|
|
|
|
if ( $_[0] ne '-i' ); |
|
507
|
|
|
|
|
|
|
} |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# Let's make a list of patterns wanting to be evaled as regexps. |
|
510
|
5521
|
|
|
|
|
8454
|
my $parm; |
|
511
|
5521
|
|
|
|
|
8493
|
my $parm_nr = 1; |
|
512
|
5521
|
|
|
|
|
14578
|
while ( defined( $parm = shift ) ) { |
|
513
|
16429
|
50
|
|
|
|
27740
|
print STDERR ("expect(): handling param '$parm'...\n") |
|
514
|
|
|
|
|
|
|
if $Expect::Debug; |
|
515
|
16429
|
100
|
|
|
|
28453
|
if ( ref($parm) ) { |
|
516
|
16310
|
100
|
|
|
|
42990
|
if ( ref($parm) eq 'Regexp' ) { |
|
|
|
50
|
|
|
|
|
|
|
517
|
1
|
|
|
|
|
38
|
push @pattern_list, [ $parm_nr, '-re', $parm, undef ]; |
|
518
|
|
|
|
|
|
|
} |
|
519
|
|
|
|
|
|
|
elsif ( ref($parm) eq 'ARRAY' ) { |
|
520
|
|
|
|
|
|
|
# if ( ref($parm) eq 'ARRAY' ) { |
|
521
|
16309
|
|
|
|
|
38948
|
my $err = _add_patterns_to_list( |
|
522
|
|
|
|
|
|
|
\@pattern_list, \@timeout_list, |
|
523
|
|
|
|
|
|
|
$parm_nr, $parm |
|
524
|
|
|
|
|
|
|
); |
|
525
|
16309
|
50
|
|
|
|
35158
|
carp( |
|
526
|
|
|
|
|
|
|
"expect(): Warning: multiple `timeout' patterns (", |
|
527
|
|
|
|
|
|
|
scalar(@timeout_list), ").\r\n" |
|
528
|
|
|
|
|
|
|
) if @timeout_list > 1; |
|
529
|
16309
|
100
|
|
|
|
34081
|
$timeout_hook = $timeout_list[-1] if $timeout_list[-1]; |
|
530
|
16309
|
50
|
|
|
|
29673
|
croak $err if $err; |
|
531
|
16309
|
|
|
|
|
36767
|
$parm_nr++; |
|
532
|
|
|
|
|
|
|
} else { |
|
533
|
0
|
|
|
|
|
0
|
croak("expect(): Unknown pattern ref $parm"); |
|
534
|
|
|
|
|
|
|
} |
|
535
|
|
|
|
|
|
|
} else { |
|
536
|
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
# not a ref, is an option or raw pattern |
|
538
|
119
|
100
|
|
|
|
421
|
if ( substr( $parm, 0, 1 ) eq '-' ) { |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
# it's an option |
|
541
|
22
|
50
|
|
|
|
150
|
print STDERR ("expect(): handling option '$parm'...\n") |
|
542
|
|
|
|
|
|
|
if $Expect::Debug; |
|
543
|
22
|
50
|
33
|
|
|
274
|
if ( $parm eq '-i' ) { |
|
|
|
50
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
# first add collected patterns to object list |
|
546
|
0
|
0
|
|
|
|
0
|
if ( scalar(@$curr_list) ) { |
|
547
|
|
|
|
|
|
|
push @object_list, $curr_list |
|
548
|
0
|
0
|
|
|
|
0
|
if not exists $patterns{"$curr_list"}; |
|
549
|
0
|
|
|
|
|
0
|
push @{ $patterns{"$curr_list"} }, @pattern_list; |
|
|
0
|
|
|
|
|
0
|
|
|
550
|
0
|
|
|
|
|
0
|
@pattern_list = (); |
|
551
|
|
|
|
|
|
|
} |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
# now put parm(s) into current object list |
|
554
|
0
|
0
|
|
|
|
0
|
if ( ref( $_[0] ) eq 'ARRAY' ) { |
|
555
|
0
|
|
|
|
|
0
|
$curr_list = shift; |
|
556
|
|
|
|
|
|
|
} else { |
|
557
|
0
|
|
|
|
|
0
|
$curr_list = [shift]; |
|
558
|
|
|
|
|
|
|
} |
|
559
|
|
|
|
|
|
|
} elsif ( $parm eq '-re' |
|
560
|
|
|
|
|
|
|
or $parm eq '-ex' ) |
|
561
|
|
|
|
|
|
|
{ |
|
562
|
22
|
50
|
|
|
|
296
|
if ( ref( $_[1] ) eq 'CODE' ) { |
|
563
|
0
|
|
|
|
|
0
|
push @pattern_list, [ $parm_nr, $parm, shift, shift ]; |
|
564
|
|
|
|
|
|
|
} else { |
|
565
|
22
|
|
|
|
|
151
|
push @pattern_list, [ $parm_nr, $parm, shift, undef ]; |
|
566
|
|
|
|
|
|
|
} |
|
567
|
22
|
|
|
|
|
95
|
$parm_nr++; |
|
568
|
|
|
|
|
|
|
} else { |
|
569
|
0
|
|
|
|
|
0
|
croak("Unknown option $parm"); |
|
570
|
|
|
|
|
|
|
} |
|
571
|
|
|
|
|
|
|
} else { |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
# a plain pattern, check if it is followed by a CODE ref |
|
574
|
97
|
50
|
|
|
|
292
|
if ( ref( $_[0] ) eq 'CODE' ) { |
|
575
|
0
|
0
|
|
|
|
0
|
if ( $parm eq 'timeout' ) { |
|
|
|
0
|
|
|
|
|
|
|
576
|
0
|
|
|
|
|
0
|
push @timeout_list, shift; |
|
577
|
0
|
0
|
|
|
|
0
|
carp( |
|
578
|
|
|
|
|
|
|
"expect(): Warning: multiple `timeout' patterns (", |
|
579
|
|
|
|
|
|
|
scalar(@timeout_list), |
|
580
|
|
|
|
|
|
|
").\r\n" |
|
581
|
|
|
|
|
|
|
) if @timeout_list > 1; |
|
582
|
0
|
0
|
|
|
|
0
|
$timeout_hook = $timeout_list[-1] if $timeout_list[-1]; |
|
583
|
|
|
|
|
|
|
} elsif ( $parm eq 'eof' ) { |
|
584
|
0
|
|
|
|
|
0
|
push @pattern_list, [ $parm_nr, "-$parm", undef, shift ]; |
|
585
|
|
|
|
|
|
|
} else { |
|
586
|
0
|
|
|
|
|
0
|
push @pattern_list, [ $parm_nr, '-ex', $parm, shift ]; |
|
587
|
|
|
|
|
|
|
} |
|
588
|
|
|
|
|
|
|
} else { |
|
589
|
97
|
50
|
|
|
|
247
|
print STDERR ("expect(): exact match '$parm'...\n") |
|
590
|
|
|
|
|
|
|
if $Expect::Debug; |
|
591
|
97
|
|
|
|
|
411
|
push @pattern_list, [ $parm_nr, '-ex', $parm, undef ]; |
|
592
|
|
|
|
|
|
|
} |
|
593
|
97
|
|
|
|
|
695
|
$parm_nr++; |
|
594
|
|
|
|
|
|
|
} |
|
595
|
|
|
|
|
|
|
} |
|
596
|
|
|
|
|
|
|
} |
|
597
|
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
# add rest of collected patterns to object list |
|
599
|
5521
|
50
|
|
|
|
12241
|
carp "expect(): Empty object list" unless $curr_list; |
|
600
|
5521
|
50
|
|
|
|
20425
|
push @object_list, $curr_list if not exists $patterns{"$curr_list"}; |
|
601
|
5521
|
|
|
|
|
6897
|
push @{ $patterns{"$curr_list"} }, @pattern_list; |
|
|
5521
|
|
|
|
|
25059
|
|
|
602
|
|
|
|
|
|
|
|
|
603
|
5521
|
50
|
|
|
|
11405
|
my $debug = $self ? ${*$self}{exp_Debug} : $Expect::Debug; |
|
|
5521
|
|
|
|
|
19286
|
|
|
604
|
5521
|
50
|
|
|
|
11152
|
my $internal = $self ? ${*$self}{exp_Exp_Internal} : $Expect::Exp_Internal; |
|
|
5521
|
|
|
|
|
9413
|
|
|
605
|
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
# now start matching... |
|
607
|
|
|
|
|
|
|
|
|
608
|
5521
|
50
|
|
|
|
13132
|
if (@Expect::Before_List) { |
|
609
|
0
|
0
|
0
|
|
|
0
|
print STDERR ("Starting BEFORE pattern matching...\r\n") |
|
610
|
|
|
|
|
|
|
if ( $debug or $internal ); |
|
611
|
0
|
|
|
|
|
0
|
_multi_expect( 0, undef, @Expect::Before_List ); |
|
612
|
|
|
|
|
|
|
} |
|
613
|
|
|
|
|
|
|
|
|
614
|
5521
|
50
|
33
|
|
|
21056
|
cluck("Starting EXPECT pattern matching...\r\n") |
|
615
|
|
|
|
|
|
|
if ( $debug or $internal ); |
|
616
|
5521
|
|
|
|
|
7714
|
my @ret; |
|
617
|
|
|
|
|
|
|
@ret = _multi_expect( |
|
618
|
|
|
|
|
|
|
$timeout, $timeout_hook, |
|
619
|
5521
|
|
|
|
|
16718
|
map { [ $_, @{ $patterns{"$_"} } ] } @object_list |
|
|
5521
|
|
|
|
|
7277
|
|
|
|
5521
|
|
|
|
|
26037
|
|
|
620
|
|
|
|
|
|
|
); |
|
621
|
|
|
|
|
|
|
|
|
622
|
5521
|
50
|
|
|
|
17862
|
if (@Expect::After_List) { |
|
623
|
0
|
0
|
0
|
|
|
0
|
print STDERR ("Starting AFTER pattern matching...\r\n") |
|
624
|
|
|
|
|
|
|
if ( $debug or $internal ); |
|
625
|
0
|
|
|
|
|
0
|
_multi_expect( 0, undef, @Expect::After_List ); |
|
626
|
|
|
|
|
|
|
} |
|
627
|
|
|
|
|
|
|
|
|
628
|
5521
|
50
|
|
|
|
38621
|
return wantarray ? @ret : $ret[0]; |
|
629
|
|
|
|
|
|
|
} |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
###################################################################### |
|
632
|
|
|
|
|
|
|
# the real workhorse |
|
633
|
|
|
|
|
|
|
# |
|
634
|
|
|
|
|
|
|
sub _multi_expect { |
|
635
|
5521
|
|
|
5521
|
|
11640
|
my ($timeout, $timeout_hook, @params) = @_; |
|
636
|
|
|
|
|
|
|
|
|
637
|
5521
|
100
|
|
|
|
10844
|
if ($timeout_hook) { |
|
638
|
5415
|
50
|
33
|
|
|
20596
|
croak "Unknown timeout_hook type $timeout_hook" |
|
639
|
|
|
|
|
|
|
unless ( ref($timeout_hook) eq 'CODE' |
|
640
|
|
|
|
|
|
|
or ref($timeout_hook) eq 'ARRAY' ); |
|
641
|
|
|
|
|
|
|
} |
|
642
|
|
|
|
|
|
|
|
|
643
|
5521
|
|
|
|
|
10212
|
foreach my $pat (@params) { |
|
644
|
5521
|
|
|
|
|
8775
|
my @patterns = @{$pat}[ 1 .. $#{$pat} ]; |
|
|
5521
|
|
|
|
|
12434
|
|
|
|
5521
|
|
|
|
|
9719
|
|
|
645
|
5521
|
|
|
|
|
9547
|
foreach my $exp ( @{ $pat->[0] } ) { |
|
|
5521
|
|
|
|
|
10294
|
|
|
646
|
5521
|
|
|
|
|
6695
|
${*$exp}{exp_New_Data} = 1; # first round we always try to match |
|
|
5521
|
|
|
|
|
12547
|
|
|
647
|
5521
|
50
|
33
|
|
|
9339
|
if ( exists ${*$exp}{"exp_Max_Accum"} |
|
|
5521
|
|
|
|
|
13952
|
|
|
648
|
5521
|
|
|
|
|
15956
|
and ${*$exp}{"exp_Max_Accum"} ) |
|
649
|
|
|
|
|
|
|
{ |
|
650
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Accum} = $exp->_trim_length( |
|
651
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Accum}, |
|
652
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Max_Accum} |
|
653
|
0
|
|
|
|
|
0
|
); |
|
654
|
|
|
|
|
|
|
} |
|
655
|
5521
|
0
|
|
|
|
10997
|
print STDERR ( |
|
|
|
50
|
|
|
|
|
|
|
656
|
0
|
|
|
|
|
0
|
"${*$exp}{exp_Pty_Handle}: beginning expect.\r\n", |
|
657
|
|
|
|
|
|
|
"\tTimeout: ", |
|
658
|
|
|
|
|
|
|
( defined($timeout) ? $timeout : "unlimited" ), |
|
659
|
|
|
|
|
|
|
" seconds.\r\n", |
|
660
|
|
|
|
|
|
|
"\tCurrent time: " . localtime() . "\r\n", |
|
661
|
|
|
|
|
|
|
) if $Expect::Debug; |
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
# What are we expecting? What do you expect? :-) |
|
664
|
5521
|
50
|
|
|
|
6426
|
if ( ${*$exp}{exp_Exp_Internal} ) { |
|
|
5521
|
|
|
|
|
18279
|
|
|
665
|
0
|
|
|
|
|
0
|
print STDERR "${*$exp}{exp_Pty_Handle}: list of patterns:\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
666
|
0
|
|
|
|
|
0
|
foreach my $pattern (@patterns) { |
|
667
|
0
|
0
|
|
|
|
0
|
print STDERR ( |
|
668
|
|
|
|
|
|
|
' ', |
|
669
|
|
|
|
|
|
|
defined( $pattern->[0] ) |
|
670
|
|
|
|
|
|
|
? '#' . $pattern->[0] . ': ' |
|
671
|
|
|
|
|
|
|
: '', |
|
672
|
|
|
|
|
|
|
$pattern->[1], |
|
673
|
|
|
|
|
|
|
" `", |
|
674
|
|
|
|
|
|
|
_make_readable( $pattern->[2] ), |
|
675
|
|
|
|
|
|
|
"'\r\n" |
|
676
|
|
|
|
|
|
|
); |
|
677
|
|
|
|
|
|
|
} |
|
678
|
0
|
|
|
|
|
0
|
print STDERR "\r\n"; |
|
679
|
|
|
|
|
|
|
} |
|
680
|
|
|
|
|
|
|
} |
|
681
|
|
|
|
|
|
|
} |
|
682
|
|
|
|
|
|
|
|
|
683
|
5521
|
|
|
|
|
23597
|
my $successful_pattern; |
|
684
|
|
|
|
|
|
|
my $exp_matched; |
|
685
|
5521
|
|
|
|
|
0
|
my $err; |
|
686
|
5521
|
|
|
|
|
0
|
my $before; |
|
687
|
5521
|
|
|
|
|
0
|
my $after; |
|
688
|
5521
|
|
|
|
|
0
|
my $match; |
|
689
|
5521
|
|
|
|
|
0
|
my @matchlist; |
|
690
|
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
# Set the last loop time to now for time comparisons at end of loop. |
|
692
|
5521
|
|
|
|
|
8243
|
my $start_loop_time = time(); |
|
693
|
5521
|
|
|
|
|
8013
|
my $exp_cont = 1; |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
READLOOP: |
|
696
|
5521
|
|
|
|
|
9997
|
while ($exp_cont) { |
|
697
|
11080
|
|
|
|
|
16797
|
$exp_cont = 1; |
|
698
|
11080
|
|
|
|
|
18275
|
$err = ""; |
|
699
|
11080
|
|
|
|
|
15763
|
my $rmask = ''; |
|
700
|
11080
|
|
|
|
|
17171
|
my $time_left = undef; |
|
701
|
11080
|
100
|
|
|
|
22074
|
if ( defined $timeout ) { |
|
702
|
11077
|
|
|
|
|
19110
|
$time_left = $timeout - ( time() - $start_loop_time ); |
|
703
|
11077
|
50
|
|
|
|
22103
|
$time_left = 0 if $time_left < 0; |
|
704
|
|
|
|
|
|
|
} |
|
705
|
|
|
|
|
|
|
|
|
706
|
11080
|
|
|
|
|
13752
|
$exp_matched = undef; |
|
707
|
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
# Test for a match first so we can test the current Accum w/out |
|
709
|
|
|
|
|
|
|
# worrying about an EOF. |
|
710
|
|
|
|
|
|
|
|
|
711
|
11080
|
|
|
|
|
17548
|
foreach my $pat (@params) { |
|
712
|
11080
|
|
|
|
|
17512
|
my @patterns = @{$pat}[ 1 .. $#{$pat} ]; |
|
|
11080
|
|
|
|
|
23594
|
|
|
|
11080
|
|
|
|
|
18840
|
|
|
713
|
11080
|
|
|
|
|
15629
|
foreach my $exp ( @{ $pat->[0] } ) { |
|
|
11080
|
|
|
|
|
18309
|
|
|
714
|
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
# build mask for select in next section... |
|
716
|
11080
|
|
|
|
|
33040
|
my $fn = $exp->fileno(); |
|
717
|
11080
|
50
|
|
|
|
89369
|
vec( $rmask, $fn, 1 ) = 1 if defined $fn; |
|
718
|
|
|
|
|
|
|
|
|
719
|
11080
|
100
|
|
|
|
20540
|
next unless ${*$exp}{exp_New_Data}; |
|
|
11080
|
|
|
|
|
33034
|
|
|
720
|
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
# clear error status |
|
722
|
11032
|
|
|
|
|
15516
|
${*$exp}{exp_Error} = undef; |
|
|
11032
|
|
|
|
|
18961
|
|
|
723
|
11032
|
|
|
|
|
14621
|
${*$exp}{exp_After} = undef; |
|
|
11032
|
|
|
|
|
18314
|
|
|
724
|
11032
|
|
|
|
|
14341
|
${*$exp}{exp_Match_Number} = undef; |
|
|
11032
|
|
|
|
|
20356
|
|
|
725
|
11032
|
|
|
|
|
14708
|
${*$exp}{exp_Match} = undef; |
|
|
11032
|
|
|
|
|
21615
|
|
|
726
|
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
# This could be huge. We should attempt to do something |
|
728
|
|
|
|
|
|
|
# about this. Because the output is used for debugging |
|
729
|
|
|
|
|
|
|
# I'm of the opinion that showing smaller amounts if the |
|
730
|
|
|
|
|
|
|
# total is huge should be ok. |
|
731
|
|
|
|
|
|
|
# Thus the 'trim_length' |
|
732
|
|
|
|
|
|
|
print STDERR ( |
|
733
|
0
|
|
|
|
|
0
|
"\r\n${*$exp}{exp_Pty_Handle}: Does `", |
|
734
|
0
|
|
|
|
|
0
|
$exp->_trim_length( _make_readable( ${*$exp}{exp_Accum} ) ), |
|
735
|
|
|
|
|
|
|
"'\r\nmatch:\r\n" |
|
736
|
11032
|
50
|
|
|
|
14227
|
) if ${*$exp}{exp_Exp_Internal}; |
|
|
11032
|
|
|
|
|
24083
|
|
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# we don't keep the parameter number anymore |
|
739
|
|
|
|
|
|
|
# (clashes with before & after), instead the parameter number is |
|
740
|
|
|
|
|
|
|
# stored inside the pattern; we keep the pattern ref |
|
741
|
|
|
|
|
|
|
# and look up the number later. |
|
742
|
11032
|
|
|
|
|
18957
|
foreach my $pattern (@patterns) { |
|
743
|
|
|
|
|
|
|
print STDERR ( |
|
744
|
|
|
|
|
|
|
" pattern", |
|
745
|
|
|
|
|
|
|
defined( $pattern->[0] ) ? ' #' . $pattern->[0] : '', |
|
746
|
|
|
|
|
|
|
": ", |
|
747
|
|
|
|
|
|
|
$pattern->[1], |
|
748
|
|
|
|
|
|
|
" `", |
|
749
|
|
|
|
|
|
|
_make_readable( $pattern->[2] ), |
|
750
|
|
|
|
|
|
|
"'? " |
|
751
|
16539
|
0
|
|
|
|
21781
|
) if ( ${*$exp}{exp_Exp_Internal} ); |
|
|
16539
|
50
|
|
|
|
36990
|
|
|
752
|
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
# Matching exactly |
|
754
|
16539
|
100
|
|
|
|
47612
|
if ( $pattern->[1] eq '-ex' ) { |
|
|
|
100
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
my $match_index = |
|
756
|
136
|
|
|
|
|
199
|
index( ${*$exp}{exp_Accum}, $pattern->[2] ); |
|
|
136
|
|
|
|
|
524
|
|
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
# We matched if $match_index > -1 |
|
759
|
136
|
100
|
|
|
|
412
|
if ( $match_index > -1 ) { |
|
760
|
|
|
|
|
|
|
$before = |
|
761
|
34
|
|
|
|
|
67
|
substr( ${*$exp}{exp_Accum}, 0, $match_index ); |
|
|
34
|
|
|
|
|
142
|
|
|
762
|
|
|
|
|
|
|
$match = substr( |
|
763
|
34
|
|
|
|
|
120
|
${*$exp}{exp_Accum}, |
|
764
|
34
|
|
|
|
|
70
|
$match_index, length( $pattern->[2] ) |
|
765
|
|
|
|
|
|
|
); |
|
766
|
|
|
|
|
|
|
$after = substr( |
|
767
|
34
|
|
|
|
|
204
|
${*$exp}{exp_Accum}, |
|
768
|
34
|
|
|
|
|
70
|
$match_index + length( $pattern->[2] ) |
|
769
|
|
|
|
|
|
|
); |
|
770
|
34
|
|
|
|
|
71
|
${*$exp}{exp_Before} = $before; |
|
|
34
|
|
|
|
|
147
|
|
|
771
|
34
|
|
|
|
|
71
|
${*$exp}{exp_Match} = $match; |
|
|
34
|
|
|
|
|
85
|
|
|
772
|
34
|
|
|
|
|
56
|
${*$exp}{exp_After} = $after; |
|
|
34
|
|
|
|
|
98
|
|
|
773
|
34
|
|
|
|
|
70
|
${*$exp}{exp_Match_Number} = $pattern->[0]; |
|
|
34
|
|
|
|
|
140
|
|
|
774
|
34
|
|
|
|
|
56
|
$exp_matched = $exp; |
|
775
|
|
|
|
|
|
|
} |
|
776
|
|
|
|
|
|
|
} elsif ( $pattern->[1] eq '-re' ) { |
|
777
|
|
|
|
|
|
|
|
|
778
|
11023
|
100
|
|
|
|
18470
|
if ($Expect::Multiline_Matching) { |
|
779
|
|
|
|
|
|
|
@matchlist = |
|
780
|
11009
|
|
|
|
|
15256
|
( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m); |
|
|
11009
|
|
|
|
|
246259
|
|
|
781
|
|
|
|
|
|
|
} else { |
|
782
|
|
|
|
|
|
|
@matchlist = |
|
783
|
14
|
|
|
|
|
43
|
( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/); |
|
|
14
|
|
|
|
|
263
|
|
|
784
|
|
|
|
|
|
|
} |
|
785
|
11023
|
100
|
|
|
|
30962
|
if (@matchlist) { |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
# Matching regexp |
|
788
|
5503
|
|
|
|
|
9853
|
$match = shift @matchlist; |
|
789
|
5503
|
|
|
|
|
7225
|
my $start = index ${*$exp}{exp_Accum}, $match; |
|
|
5503
|
|
|
|
|
25536
|
|
|
790
|
5503
|
50
|
|
|
|
11835
|
die 'The match could not be found' if $start == -1; |
|
791
|
5503
|
|
|
|
|
6947
|
$before = substr ${*$exp}{exp_Accum}, 0, $start; |
|
|
5503
|
|
|
|
|
14309
|
|
|
792
|
5503
|
|
|
|
|
7247
|
$after = substr ${*$exp}{exp_Accum}, $start + length($match); |
|
|
5503
|
|
|
|
|
12684
|
|
|
793
|
|
|
|
|
|
|
|
|
794
|
5503
|
|
|
|
|
7396
|
${*$exp}{exp_Before} = $before; |
|
|
5503
|
|
|
|
|
10989
|
|
|
795
|
5503
|
|
|
|
|
7579
|
${*$exp}{exp_Match} = $match; |
|
|
5503
|
|
|
|
|
10547
|
|
|
796
|
5503
|
|
|
|
|
6678
|
${*$exp}{exp_After} = $after; |
|
|
5503
|
|
|
|
|
10212
|
|
|
797
|
|
|
|
|
|
|
#pop @matchlist; # remove kludged empty bracket from end |
|
798
|
5503
|
|
|
|
|
8420
|
@{ ${*$exp}{exp_Matchlist} } = @matchlist; |
|
|
5503
|
|
|
|
|
6841
|
|
|
|
5503
|
|
|
|
|
13295
|
|
|
799
|
5503
|
|
|
|
|
7862
|
${*$exp}{exp_Match_Number} = $pattern->[0]; |
|
|
5503
|
|
|
|
|
9445
|
|
|
800
|
5503
|
|
|
|
|
9388
|
$exp_matched = $exp; |
|
801
|
|
|
|
|
|
|
} |
|
802
|
|
|
|
|
|
|
} else { |
|
803
|
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
# 'timeout' or 'eof' |
|
805
|
|
|
|
|
|
|
} |
|
806
|
|
|
|
|
|
|
|
|
807
|
16539
|
100
|
|
|
|
30358
|
if ($exp_matched) { |
|
808
|
5487
|
|
|
|
|
11656
|
${*$exp}{exp_Accum} = $after |
|
809
|
5537
|
100
|
|
|
|
7534
|
unless ${*$exp}{exp_NoTransfer}; |
|
|
5537
|
|
|
|
|
13814
|
|
|
810
|
|
|
|
|
|
|
print STDERR "YES!!\r\n" |
|
811
|
5537
|
50
|
|
|
|
7575
|
if ${*$exp}{exp_Exp_Internal}; |
|
|
5537
|
|
|
|
|
11845
|
|
|
812
|
|
|
|
|
|
|
print STDERR ( |
|
813
|
|
|
|
|
|
|
" Before match string: `", |
|
814
|
|
|
|
|
|
|
$exp->_trim_length( _make_readable( ($before) ) ), |
|
815
|
|
|
|
|
|
|
"'\r\n", |
|
816
|
|
|
|
|
|
|
" Match string: `", |
|
817
|
|
|
|
|
|
|
_make_readable($match), |
|
818
|
|
|
|
|
|
|
"'\r\n", |
|
819
|
|
|
|
|
|
|
" After match string: `", |
|
820
|
|
|
|
|
|
|
$exp->_trim_length( _make_readable( ($after) ) ), |
|
821
|
|
|
|
|
|
|
"'\r\n", |
|
822
|
|
|
|
|
|
|
" Matchlist: (", |
|
823
|
|
|
|
|
|
|
join( |
|
824
|
|
|
|
|
|
|
", ", |
|
825
|
0
|
|
|
|
|
0
|
map { "`" . $exp->_trim_length( _make_readable( ($_) ) ) . "'" } @matchlist, |
|
826
|
|
|
|
|
|
|
), |
|
827
|
|
|
|
|
|
|
")\r\n", |
|
828
|
5537
|
50
|
|
|
|
7146
|
) if ( ${*$exp}{exp_Exp_Internal} ); |
|
|
5537
|
|
|
|
|
11808
|
|
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
# call hook function if defined |
|
831
|
5537
|
100
|
|
|
|
11958
|
if ( $pattern->[3] ) { |
|
832
|
|
|
|
|
|
|
print STDERR ( |
|
833
|
|
|
|
|
|
|
"Calling hook $pattern->[3]...\r\n", |
|
834
|
|
|
|
|
|
|
) |
|
835
|
5481
|
|
|
|
|
20550
|
if ( ${*$exp}{exp_Exp_Internal} |
|
836
|
5481
|
50
|
33
|
|
|
6622
|
or $Expect::Debug ); |
|
837
|
5481
|
50
|
|
|
|
8346
|
if ( $#{$pattern} > 3 ) { |
|
|
5481
|
|
|
|
|
11358
|
|
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
# call with parameters if given |
|
840
|
0
|
|
|
|
|
0
|
$exp_cont = &{ $pattern->[3] }( $exp, @{$pattern}[ 4 .. $#{$pattern} ] ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
841
|
|
|
|
|
|
|
} else { |
|
842
|
5481
|
|
|
|
|
6991
|
$exp_cont = &{ $pattern->[3] }($exp); |
|
|
5481
|
|
|
|
|
19009
|
|
|
843
|
|
|
|
|
|
|
} |
|
844
|
|
|
|
|
|
|
} |
|
845
|
5537
|
100
|
100
|
|
|
33329
|
if ( $exp_cont and $exp_cont eq exp_continue ) { |
|
|
|
50
|
66
|
|
|
|
|
|
846
|
|
|
|
|
|
|
print STDERR ("Continuing expect, restarting timeout...\r\n") |
|
847
|
70
|
|
|
|
|
690
|
if ( ${*$exp}{exp_Exp_Internal} |
|
848
|
70
|
50
|
33
|
|
|
291
|
or $Expect::Debug ); |
|
849
|
70
|
|
|
|
|
219
|
$start_loop_time = time(); # restart timeout count |
|
850
|
70
|
|
|
|
|
429
|
next READLOOP; |
|
851
|
|
|
|
|
|
|
} elsif ( $exp_cont |
|
852
|
|
|
|
|
|
|
and $exp_cont eq exp_continue_timeout ) |
|
853
|
|
|
|
|
|
|
{ |
|
854
|
|
|
|
|
|
|
print STDERR ("Continuing expect...\r\n") |
|
855
|
0
|
|
|
|
|
0
|
if ( ${*$exp}{exp_Exp_Internal} |
|
856
|
0
|
0
|
0
|
|
|
0
|
or $Expect::Debug ); |
|
857
|
0
|
|
|
|
|
0
|
next READLOOP; |
|
858
|
|
|
|
|
|
|
} |
|
859
|
5467
|
|
|
|
|
17904
|
last READLOOP; |
|
860
|
|
|
|
|
|
|
} |
|
861
|
11002
|
50
|
|
|
|
12818
|
print STDERR "No.\r\n" if ${*$exp}{exp_Exp_Internal}; |
|
|
11002
|
|
|
|
|
28328
|
|
|
862
|
|
|
|
|
|
|
} |
|
863
|
5495
|
50
|
|
|
|
6258
|
print STDERR "\r\n" if ${*$exp}{exp_Exp_Internal}; |
|
|
5495
|
|
|
|
|
11297
|
|
|
864
|
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
# don't have to match again until we get new data |
|
866
|
5495
|
|
|
|
|
8209
|
${*$exp}{exp_New_Data} = 0; |
|
|
5495
|
|
|
|
|
14840
|
|
|
867
|
|
|
|
|
|
|
} |
|
868
|
|
|
|
|
|
|
} # End of matching section |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
# No match, let's see what is pending on the filehandles... |
|
871
|
5543
|
0
|
33
|
|
|
35694
|
print STDERR ( |
|
|
|
50
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
"Waiting for new data (", |
|
873
|
|
|
|
|
|
|
defined($time_left) ? $time_left : 'unlimited', |
|
874
|
|
|
|
|
|
|
" seconds)...\r\n", |
|
875
|
|
|
|
|
|
|
) if ( $Expect::Exp_Internal or $Expect::Debug ); |
|
876
|
5543
|
|
|
|
|
8109
|
my $nfound; |
|
877
|
|
|
|
|
|
|
SELECT: { |
|
878
|
5543
|
|
|
|
|
6905
|
$nfound = select( $rmask, undef, undef, $time_left ); |
|
|
5543
|
|
|
|
|
156897301
|
|
|
879
|
5543
|
50
|
|
|
|
30792
|
if ( $nfound < 0 ) { |
|
880
|
0
|
0
|
0
|
|
|
0
|
if ( $!{EINTR} and $Expect::IgnoreEintr ) { |
|
881
|
0
|
0
|
0
|
|
|
0
|
print STDERR ("ignoring EINTR, restarting select()...\r\n") |
|
882
|
|
|
|
|
|
|
if ( $Expect::Exp_Internal or $Expect::Debug ); |
|
883
|
0
|
|
|
|
|
0
|
next SELECT; |
|
884
|
|
|
|
|
|
|
} |
|
885
|
0
|
0
|
0
|
|
|
0
|
print STDERR ("select() returned error code '$!'\r\n") |
|
886
|
|
|
|
|
|
|
if ( $Expect::Exp_Internal or $Expect::Debug ); |
|
887
|
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
# returned error |
|
889
|
0
|
|
|
|
|
0
|
$err = "4:$!"; |
|
890
|
0
|
|
|
|
|
0
|
last READLOOP; |
|
891
|
|
|
|
|
|
|
} |
|
892
|
|
|
|
|
|
|
} |
|
893
|
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
# go until we don't find something (== timeout). |
|
895
|
5543
|
100
|
|
|
|
11993
|
if ( $nfound == 0 ) { |
|
896
|
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
# No pattern, no EOF. Did we time out? |
|
898
|
77
|
|
|
|
|
790
|
$err = "1:TIMEOUT"; |
|
899
|
77
|
|
|
|
|
405
|
foreach my $pat (@params) { |
|
900
|
77
|
|
|
|
|
314
|
foreach my $exp ( @{ $pat->[0] } ) { |
|
|
77
|
|
|
|
|
429
|
|
|
901
|
77
|
|
|
|
|
453
|
$before = ${*$exp}{exp_Before} = ${*$exp}{exp_Accum}; |
|
|
77
|
|
|
|
|
577
|
|
|
|
77
|
|
|
|
|
943
|
|
|
902
|
77
|
50
|
|
|
|
1864
|
next if not defined $exp->fileno(); # skip already closed |
|
903
|
77
|
100
|
|
|
|
1128
|
${*$exp}{exp_Error} = $err unless ${*$exp}{exp_Error}; |
|
|
41
|
|
|
|
|
187
|
|
|
|
77
|
|
|
|
|
647
|
|
|
904
|
|
|
|
|
|
|
} |
|
905
|
|
|
|
|
|
|
} |
|
906
|
77
|
50
|
33
|
|
|
1098
|
print STDERR ("TIMEOUT\r\n") |
|
907
|
|
|
|
|
|
|
if ( $Expect::Debug or $Expect::Exp_Internal ); |
|
908
|
77
|
100
|
|
|
|
474
|
if ($timeout_hook) { |
|
909
|
51
|
|
|
|
|
138
|
my $ret; |
|
910
|
51
|
50
|
33
|
|
|
381
|
print STDERR ("Calling timeout function $timeout_hook...\r\n") |
|
911
|
|
|
|
|
|
|
if ( $Expect::Debug or $Expect::Exp_Internal ); |
|
912
|
51
|
50
|
|
|
|
264
|
if ( ref($timeout_hook) eq 'CODE' ) { |
|
913
|
0
|
|
|
|
|
0
|
$ret = &{$timeout_hook}( $params[0]->[0] ); |
|
|
0
|
|
|
|
|
0
|
|
|
914
|
|
|
|
|
|
|
} else { |
|
915
|
51
|
50
|
|
|
|
90
|
if ( $#{$timeout_hook} > 3 ) { |
|
|
51
|
|
|
|
|
291
|
|
|
916
|
0
|
|
|
|
|
0
|
$ret = &{ $timeout_hook->[3] }( |
|
917
|
|
|
|
|
|
|
$params[0]->[0], |
|
918
|
0
|
|
|
|
|
0
|
@{$timeout_hook}[ 4 .. $#{$timeout_hook} ] |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
919
|
|
|
|
|
|
|
); |
|
920
|
|
|
|
|
|
|
} else { |
|
921
|
51
|
|
|
|
|
165
|
$ret = &{ $timeout_hook->[3] }( $params[0]->[0] ); |
|
|
51
|
|
|
|
|
324
|
|
|
922
|
|
|
|
|
|
|
} |
|
923
|
|
|
|
|
|
|
} |
|
924
|
51
|
100
|
66
|
|
|
663
|
if ( $ret and $ret eq exp_continue ) { |
|
925
|
48
|
|
|
|
|
120
|
$start_loop_time = time(); # restart timeout count |
|
926
|
48
|
|
|
|
|
864
|
next READLOOP; |
|
927
|
|
|
|
|
|
|
} |
|
928
|
|
|
|
|
|
|
} |
|
929
|
29
|
|
|
|
|
334
|
last READLOOP; |
|
930
|
|
|
|
|
|
|
} |
|
931
|
|
|
|
|
|
|
|
|
932
|
5466
|
|
|
|
|
37781
|
my @bits = split( //, unpack( 'b*', $rmask ) ); |
|
933
|
5466
|
|
|
|
|
15845
|
foreach my $pat (@params) { |
|
934
|
5466
|
|
|
|
|
7736
|
foreach my $exp ( @{ $pat->[0] } ) { |
|
|
5466
|
|
|
|
|
11180
|
|
|
935
|
5466
|
50
|
|
|
|
19415
|
next if not defined $exp->fileno(); # skip already closed |
|
936
|
5466
|
50
|
|
|
|
34927
|
if ( $bits[ $exp->fileno() ] ) { |
|
937
|
5466
|
50
|
|
|
|
29901
|
print STDERR ("${*$exp}{exp_Pty_Handle}: new data.\r\n") |
|
|
0
|
|
|
|
|
0
|
|
|
938
|
|
|
|
|
|
|
if $Expect::Debug; |
|
939
|
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
# read in what we found. |
|
941
|
5466
|
|
|
|
|
8948
|
my $buffer; |
|
942
|
5466
|
|
|
|
|
48585
|
my $nread = sysread( $exp, $buffer, 2048 ); |
|
943
|
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
# Make errors (nread undef) show up as EOF. |
|
945
|
5466
|
100
|
|
|
|
11118
|
$nread = 0 unless defined($nread); |
|
946
|
|
|
|
|
|
|
|
|
947
|
5466
|
100
|
|
|
|
9913
|
if ( $nread == 0 ) { |
|
948
|
25
|
50
|
|
|
|
80
|
print STDERR ("${*$exp}{exp_Pty_Handle}: EOF\r\n") |
|
|
0
|
|
|
|
|
0
|
|
|
949
|
|
|
|
|
|
|
if ($Expect::Debug); |
|
950
|
25
|
|
|
|
|
460
|
$before = ${*$exp}{exp_Before} = $exp->clear_accum(); |
|
|
25
|
|
|
|
|
90
|
|
|
951
|
25
|
|
|
|
|
85
|
$err = "2:EOF"; |
|
952
|
25
|
|
|
|
|
50
|
${*$exp}{exp_Error} = $err; |
|
|
25
|
|
|
|
|
50
|
|
|
953
|
25
|
|
|
|
|
75
|
${*$exp}{exp_Has_EOF} = 1; |
|
|
25
|
|
|
|
|
150
|
|
|
954
|
25
|
|
|
|
|
65
|
$exp_cont = undef; |
|
955
|
25
|
|
|
|
|
60
|
foreach my $eof_pat ( grep { $_->[1] eq '-eof' } @{$pat}[ 1 .. $#{$pat} ] ) { |
|
|
45
|
|
|
|
|
155
|
|
|
|
25
|
|
|
|
|
75
|
|
|
|
25
|
|
|
|
|
65
|
|
|
956
|
10
|
|
|
|
|
130
|
my $ret; |
|
957
|
10
|
50
|
|
|
|
70
|
print STDERR ( "Calling EOF hook $eof_pat->[3]...\r\n", ) |
|
958
|
|
|
|
|
|
|
if ($Expect::Debug); |
|
959
|
10
|
50
|
|
|
|
50
|
if ( $#{$eof_pat} > 3 ) { |
|
|
10
|
|
|
|
|
70
|
|
|
960
|
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
# call with parameters if given |
|
962
|
0
|
|
|
|
|
0
|
$ret = &{ $eof_pat->[3] }( $exp, @{$eof_pat}[ 4 .. $#{$eof_pat} ] ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
963
|
|
|
|
|
|
|
} else { |
|
964
|
10
|
|
|
|
|
80
|
$ret = &{ $eof_pat->[3] }($exp); |
|
|
10
|
|
|
|
|
90
|
|
|
965
|
|
|
|
|
|
|
} |
|
966
|
10
|
50
|
33
|
|
|
200
|
if ($ret |
|
|
|
|
33
|
|
|
|
|
|
967
|
|
|
|
|
|
|
and ( $ret eq exp_continue |
|
968
|
|
|
|
|
|
|
or $ret eq exp_continue_timeout ) |
|
969
|
|
|
|
|
|
|
) |
|
970
|
|
|
|
|
|
|
{ |
|
971
|
0
|
|
|
|
|
0
|
$exp_cont = $ret; |
|
972
|
|
|
|
|
|
|
} |
|
973
|
|
|
|
|
|
|
} |
|
974
|
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
# is it dead? |
|
976
|
25
|
50
|
|
|
|
65
|
if ( defined( ${*$exp}{exp_Pid} ) ) { |
|
|
25
|
|
|
|
|
115
|
|
|
977
|
|
|
|
|
|
|
my $ret = |
|
978
|
25
|
|
|
|
|
65
|
waitpid( ${*$exp}{exp_Pid}, POSIX::WNOHANG ); |
|
|
25
|
|
|
|
|
1625
|
|
|
979
|
25
|
50
|
|
|
|
90
|
if ( $ret == ${*$exp}{exp_Pid} ) { |
|
|
25
|
|
|
|
|
115
|
|
|
980
|
|
|
|
|
|
|
printf STDERR ( |
|
981
|
|
|
|
|
|
|
"%s: exit(0x%02X)\r\n", |
|
982
|
25
|
50
|
|
|
|
105
|
${*$exp}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
983
|
|
|
|
|
|
|
) if ($Expect::Debug); |
|
984
|
25
|
|
|
|
|
50
|
$err = "3:Child PID ${*$exp}{exp_Pid} exited with status $?"; |
|
|
25
|
|
|
|
|
180
|
|
|
985
|
25
|
|
|
|
|
50
|
${*$exp}{exp_Error} = $err; |
|
|
25
|
|
|
|
|
65
|
|
|
986
|
25
|
|
|
|
|
50
|
${*$exp}{exp_Exit} = $?; |
|
|
25
|
|
|
|
|
75
|
|
|
987
|
25
|
|
|
|
|
75
|
delete $Expect::Spawned_PIDs{ ${*$exp}{exp_Pid} }; |
|
|
25
|
|
|
|
|
130
|
|
|
988
|
25
|
|
|
|
|
50
|
${*$exp}{exp_Pid} = undef; |
|
|
25
|
|
|
|
|
65
|
|
|
989
|
|
|
|
|
|
|
} |
|
990
|
|
|
|
|
|
|
} |
|
991
|
25
|
50
|
|
|
|
295
|
print STDERR ("${*$exp}{exp_Pty_Handle}: closing...\r\n") |
|
|
0
|
|
|
|
|
0
|
|
|
992
|
|
|
|
|
|
|
if ($Expect::Debug); |
|
993
|
25
|
|
|
|
|
205
|
$exp->hard_close(); |
|
994
|
25
|
|
|
|
|
125
|
next; |
|
995
|
|
|
|
|
|
|
} |
|
996
|
5441
|
50
|
|
|
|
8991
|
print STDERR ("${*$exp}{exp_Pty_Handle}: read $nread byte(s).\r\n") |
|
|
0
|
|
|
|
|
0
|
|
|
997
|
|
|
|
|
|
|
if ($Expect::Debug); |
|
998
|
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
# ugly hack for broken solaris ttys that spew <blank><backspace> |
|
1000
|
|
|
|
|
|
|
# into our pretty output |
|
1001
|
5441
|
100
|
|
|
|
8587
|
$buffer =~ s/ \cH//g if not ${*$exp}{exp_Raw_Pty}; |
|
|
5441
|
|
|
|
|
21441
|
|
|
1002
|
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
# Append it to the accumulator. |
|
1004
|
5441
|
|
|
|
|
9252
|
${*$exp}{exp_Accum} .= $buffer; |
|
|
5441
|
|
|
|
|
18109
|
|
|
1005
|
5441
|
50
|
33
|
|
|
7496
|
if ( exists ${*$exp}{exp_Max_Accum} |
|
|
5441
|
|
|
|
|
15138
|
|
|
1006
|
5441
|
|
|
|
|
18204
|
and ${*$exp}{exp_Max_Accum} ) |
|
1007
|
|
|
|
|
|
|
{ |
|
1008
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Accum} = $exp->_trim_length( |
|
1009
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Accum}, |
|
1010
|
0
|
|
|
|
|
0
|
${*$exp}{exp_Max_Accum} |
|
1011
|
0
|
|
|
|
|
0
|
); |
|
1012
|
|
|
|
|
|
|
} |
|
1013
|
5441
|
|
|
|
|
8373
|
${*$exp}{exp_New_Data} = 1; # next round we try to match again |
|
|
5441
|
|
|
|
|
10611
|
|
|
1014
|
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
$exp_cont = exp_continue |
|
1016
|
5441
|
|
|
|
|
12156
|
if ( exists ${*$exp}{exp_Continue} |
|
1017
|
5441
|
0
|
33
|
|
|
6713
|
and ${*$exp}{exp_Continue} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1018
|
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
# Now propagate what we have read to other listeners... |
|
1020
|
5441
|
|
|
|
|
17988
|
$exp->_print_handles($buffer); |
|
1021
|
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
# End handle reading section. |
|
1023
|
|
|
|
|
|
|
} |
|
1024
|
|
|
|
|
|
|
} |
|
1025
|
|
|
|
|
|
|
} # end read loop |
|
1026
|
|
|
|
|
|
|
$start_loop_time = time() # restart timeout count |
|
1027
|
5466
|
50
|
66
|
|
|
18932
|
if ( $exp_cont and $exp_cont eq exp_continue ); |
|
1028
|
|
|
|
|
|
|
} |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
# End READLOOP |
|
1031
|
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
# Post loop. Do we have anything? |
|
1033
|
|
|
|
|
|
|
# Tell us status |
|
1034
|
5521
|
50
|
33
|
|
|
18855
|
if ( $Expect::Debug or $Expect::Exp_Internal ) { |
|
1035
|
0
|
0
|
|
|
|
0
|
if ($exp_matched) { |
|
1036
|
|
|
|
|
|
|
print STDERR ( |
|
1037
|
|
|
|
|
|
|
"Returning from expect ", |
|
1038
|
0
|
|
|
|
|
0
|
${*$exp_matched}{exp_Error} ? 'un' : '', |
|
1039
|
|
|
|
|
|
|
"successfully.", |
|
1040
|
0
|
|
|
|
|
0
|
${*$exp_matched}{exp_Error} |
|
1041
|
0
|
0
|
|
|
|
0
|
? "\r\n Error: ${*$exp_matched}{exp_Error}." |
|
|
0
|
0
|
|
|
|
0
|
|
|
1042
|
|
|
|
|
|
|
: '', |
|
1043
|
|
|
|
|
|
|
"\r\n" |
|
1044
|
|
|
|
|
|
|
); |
|
1045
|
|
|
|
|
|
|
} else { |
|
1046
|
0
|
|
|
|
|
0
|
print STDERR ("Returning from expect with TIMEOUT or EOF\r\n"); |
|
1047
|
|
|
|
|
|
|
} |
|
1048
|
0
|
0
|
0
|
|
|
0
|
if ( $Expect::Debug and $exp_matched ) { |
|
1049
|
0
|
|
|
|
|
0
|
print STDERR " ${*$exp_matched}{exp_Pty_Handle}: accumulator: `"; |
|
|
0
|
|
|
|
|
0
|
|
|
1050
|
0
|
0
|
|
|
|
0
|
if ( ${*$exp_matched}{exp_Error} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1051
|
|
|
|
|
|
|
print STDERR ( |
|
1052
|
0
|
|
|
|
|
0
|
$exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Before} ) ), |
|
|
0
|
|
|
|
|
0
|
|
|
1053
|
|
|
|
|
|
|
"'\r\n" |
|
1054
|
|
|
|
|
|
|
); |
|
1055
|
|
|
|
|
|
|
} else { |
|
1056
|
|
|
|
|
|
|
print STDERR ( |
|
1057
|
0
|
|
|
|
|
0
|
$exp_matched->_trim_length( _make_readable( ${*$exp_matched}{exp_Accum} ) ), |
|
|
0
|
|
|
|
|
0
|
|
|
1058
|
|
|
|
|
|
|
"'\r\n" |
|
1059
|
|
|
|
|
|
|
); |
|
1060
|
|
|
|
|
|
|
} |
|
1061
|
|
|
|
|
|
|
} |
|
1062
|
|
|
|
|
|
|
} |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
5521
|
100
|
|
|
|
11860
|
if ($exp_matched) { |
|
1065
|
|
|
|
|
|
|
return wantarray |
|
1066
|
|
|
|
|
|
|
? ( |
|
1067
|
5467
|
|
|
|
|
11879
|
${*$exp_matched}{exp_Match_Number}, ${*$exp_matched}{exp_Error}, |
|
|
5467
|
|
|
|
|
11818
|
|
|
1068
|
5467
|
|
|
|
|
8905
|
${*$exp_matched}{exp_Match}, ${*$exp_matched}{exp_Before}, |
|
|
5467
|
|
|
|
|
9943
|
|
|
1069
|
5467
|
|
|
|
|
33736
|
${*$exp_matched}{exp_After}, $exp_matched, |
|
1070
|
|
|
|
|
|
|
) |
|
1071
|
5467
|
50
|
|
|
|
10062
|
: ${*$exp_matched}{exp_Match_Number}; |
|
|
0
|
|
|
|
|
0
|
|
|
1072
|
|
|
|
|
|
|
} |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
54
|
50
|
|
|
|
482
|
return wantarray ? ( undef, $err, undef, $before, undef, undef ) : undef; |
|
1075
|
|
|
|
|
|
|
} |
|
1076
|
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
# Patterns are arrays that consist of |
|
1078
|
|
|
|
|
|
|
# [ $pattern_type, $pattern, $sub, @subparms ] |
|
1079
|
|
|
|
|
|
|
# optional $pattern_type is '-re' (RegExp, default) or '-ex' (exact); |
|
1080
|
|
|
|
|
|
|
# $sub is optional CODE ref, which is called as &{$sub}($exp, @subparms) |
|
1081
|
|
|
|
|
|
|
# if pattern matched; |
|
1082
|
|
|
|
|
|
|
# the $parm_nr gets unshifted onto the array for reporting purposes. |
|
1083
|
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
sub _add_patterns_to_list { |
|
1085
|
16309
|
|
|
16309
|
|
38934
|
my ($listref, $timeoutlistref,$store_parm_nr, @params) = @_; |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
# $timeoutlistref gets timeout patterns |
|
1088
|
16309
|
|
50
|
|
|
36281
|
my $parm_nr = $store_parm_nr || 1; |
|
1089
|
16309
|
|
|
|
|
29872
|
foreach my $parm (@params) { |
|
1090
|
16309
|
50
|
|
|
|
37292
|
if ( not ref($parm) eq 'ARRAY' ) { |
|
1091
|
0
|
|
|
|
|
0
|
return "Parameter #$parm_nr is not an ARRAY ref."; |
|
1092
|
|
|
|
|
|
|
} |
|
1093
|
16309
|
|
|
|
|
36407
|
$parm = [@$parm]; # make copy |
|
1094
|
16309
|
50
|
|
|
|
40356
|
if ( $parm->[0] =~ m/\A-/ ) { |
|
1095
|
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
# it's an option |
|
1097
|
0
|
0
|
0
|
|
|
0
|
if ( $parm->[0] ne '-re' |
|
1098
|
|
|
|
|
|
|
and $parm->[0] ne '-ex' ) |
|
1099
|
|
|
|
|
|
|
{ |
|
1100
|
0
|
|
|
|
|
0
|
return "Unknown option $parm->[0] in pattern #$parm_nr"; |
|
1101
|
|
|
|
|
|
|
} |
|
1102
|
|
|
|
|
|
|
} else { |
|
1103
|
16309
|
100
|
|
|
|
35687
|
if ( $parm->[0] eq 'timeout' ) { |
|
|
|
100
|
|
|
|
|
|
|
1104
|
5415
|
50
|
|
|
|
10272
|
if ( defined $timeoutlistref ) { |
|
1105
|
5415
|
|
|
|
|
20713
|
splice @$parm, 0, 1, ( "-$parm->[0]", undef ); |
|
1106
|
5415
|
50
|
|
|
|
14208
|
unshift @$parm, $store_parm_nr ? $parm_nr : undef; |
|
1107
|
5415
|
|
|
|
|
8650
|
push @$timeoutlistref, $parm; |
|
1108
|
|
|
|
|
|
|
} |
|
1109
|
5415
|
|
|
|
|
11576
|
next; |
|
1110
|
|
|
|
|
|
|
} elsif ( $parm->[0] eq 'eof' ) { |
|
1111
|
5415
|
|
|
|
|
18450
|
splice @$parm, 0, 1, ( "-$parm->[0]", undef ); |
|
1112
|
|
|
|
|
|
|
} else { |
|
1113
|
5479
|
|
|
|
|
16748
|
unshift @$parm, '-re'; # defaults to RegExp |
|
1114
|
|
|
|
|
|
|
} |
|
1115
|
|
|
|
|
|
|
} |
|
1116
|
10894
|
100
|
|
|
|
21142
|
if ( @$parm > 2 ) { |
|
1117
|
10891
|
50
|
|
|
|
27868
|
if ( ref( $parm->[2] ) ne 'CODE' ) { |
|
1118
|
0
|
|
|
|
|
0
|
croak( |
|
1119
|
|
|
|
|
|
|
"Pattern #$parm_nr doesn't have a CODE reference", |
|
1120
|
|
|
|
|
|
|
"after the pattern." |
|
1121
|
|
|
|
|
|
|
); |
|
1122
|
|
|
|
|
|
|
} |
|
1123
|
|
|
|
|
|
|
} else { |
|
1124
|
3
|
|
|
|
|
10
|
push @$parm, undef; # make sure we have three elements |
|
1125
|
|
|
|
|
|
|
} |
|
1126
|
|
|
|
|
|
|
|
|
1127
|
10894
|
50
|
|
|
|
24993
|
unshift @$parm, $store_parm_nr ? $parm_nr : undef; |
|
1128
|
10894
|
|
|
|
|
17307
|
push @$listref, $parm; |
|
1129
|
10894
|
|
|
|
|
18318
|
$parm_nr++; |
|
1130
|
|
|
|
|
|
|
} |
|
1131
|
|
|
|
|
|
|
|
|
1132
|
16309
|
|
|
|
|
34024
|
return; |
|
1133
|
|
|
|
|
|
|
} |
|
1134
|
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
###################################################################### |
|
1136
|
|
|
|
|
|
|
# $process->interact([$in_handle],[$escape sequence]) |
|
1137
|
|
|
|
|
|
|
# If you don't specify in_handle STDIN will be used. |
|
1138
|
|
|
|
|
|
|
sub interact { |
|
1139
|
0
|
|
|
0
|
1
|
0
|
my ($self, $infile, $escape_sequence) = @_; |
|
1140
|
|
|
|
|
|
|
|
|
1141
|
0
|
|
|
|
|
0
|
my $outfile; |
|
1142
|
0
|
|
|
|
|
0
|
my @old_group = $self->set_group(); |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
# If the handle is STDIN we'll |
|
1145
|
|
|
|
|
|
|
# $infile->fileno == 0 should be stdin.. follow stdin rules. |
|
1146
|
29
|
|
|
29
|
|
24534
|
no strict 'subs'; # Allow bare word 'STDIN' |
|
|
29
|
|
|
|
|
44
|
|
|
|
29
|
|
|
|
|
132939
|
|
|
1147
|
0
|
0
|
|
|
|
0
|
unless ( defined($infile) ) { |
|
|
|
0
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
# We need a handle object Associated with STDIN. |
|
1149
|
0
|
|
|
|
|
0
|
$infile = IO::File->new; |
|
1150
|
0
|
|
|
|
|
0
|
$infile->IO::File::fdopen( STDIN, 'r' ); |
|
1151
|
0
|
|
|
|
|
0
|
$outfile = IO::File->new; |
|
1152
|
0
|
|
|
|
|
0
|
$outfile->IO::File::fdopen( STDOUT, 'w' ); |
|
1153
|
0
|
|
|
|
|
0
|
} elsif ( fileno($infile) == fileno(STDIN) ) { |
|
1154
|
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
# With STDIN we want output to go to stdout. |
|
1156
|
0
|
|
|
|
|
0
|
$outfile = IO::File->new; |
|
1157
|
0
|
|
|
|
|
0
|
$outfile->IO::File::fdopen( STDOUT, 'w' ); |
|
1158
|
|
|
|
|
|
|
} else { |
|
1159
|
0
|
|
|
|
|
0
|
undef($outfile); |
|
1160
|
|
|
|
|
|
|
} |
|
1161
|
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
# Here we assure ourselves we have an Expect object. |
|
1163
|
0
|
|
|
|
|
0
|
my $in_object = Expect->exp_init($infile); |
|
1164
|
0
|
0
|
|
|
|
0
|
if ( defined($outfile) ) { |
|
1165
|
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
# as above.. we want output to go to stdout if we're given stdin. |
|
1167
|
0
|
|
|
|
|
0
|
my $out_object = Expect->exp_init($outfile); |
|
1168
|
0
|
|
|
|
|
0
|
$out_object->manual_stty(1); |
|
1169
|
0
|
|
|
|
|
0
|
$self->set_group($out_object); |
|
1170
|
|
|
|
|
|
|
} else { |
|
1171
|
0
|
|
|
|
|
0
|
$self->set_group($in_object); |
|
1172
|
|
|
|
|
|
|
} |
|
1173
|
0
|
|
|
|
|
0
|
$in_object->set_group($self); |
|
1174
|
0
|
0
|
|
|
|
0
|
$in_object->set_seq( $escape_sequence, undef ) if defined($escape_sequence); |
|
1175
|
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
# interconnect normally sets stty -echo raw. Interact really sort |
|
1177
|
|
|
|
|
|
|
# of implies we don't do that by default. If anyone wanted to they could |
|
1178
|
|
|
|
|
|
|
# set it before calling interact, of use interconnect directly. |
|
1179
|
0
|
|
|
|
|
0
|
my $old_manual_stty_val = $self->manual_stty(); |
|
1180
|
0
|
|
|
|
|
0
|
$self->manual_stty(1); |
|
1181
|
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
# I think this is right. Don't send stuff from in_obj to stdout by default. |
|
1183
|
|
|
|
|
|
|
# in theory whatever 'self' is should echo what's going on. |
|
1184
|
0
|
|
|
|
|
0
|
my $old_log_stdout_val = $self->log_stdout(); |
|
1185
|
0
|
|
|
|
|
0
|
$self->log_stdout(0); |
|
1186
|
0
|
|
|
|
|
0
|
$in_object->log_stdout(0); |
|
1187
|
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
# Allow for the setting of an optional EOF escape function. |
|
1189
|
|
|
|
|
|
|
# $in_object->set_seq('EOF',undef); |
|
1190
|
|
|
|
|
|
|
# $self->set_seq('EOF',undef); |
|
1191
|
0
|
|
|
|
|
0
|
Expect::interconnect( $self, $in_object ); |
|
1192
|
0
|
|
|
|
|
0
|
$self->log_stdout($old_log_stdout_val); |
|
1193
|
0
|
|
|
|
|
0
|
$self->set_group(@old_group); |
|
1194
|
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
# If old_group was undef, make sure that occurs. This is a slight hack since |
|
1196
|
|
|
|
|
|
|
# it modifies the value directly. |
|
1197
|
|
|
|
|
|
|
# Normally an undef passed to set_group will return the current groups. |
|
1198
|
|
|
|
|
|
|
# It is possible that it may be of worth to make it possible to undef |
|
1199
|
|
|
|
|
|
|
# The current group without doing this. |
|
1200
|
0
|
0
|
|
|
|
0
|
unless (@old_group) { |
|
1201
|
0
|
|
|
|
|
0
|
@{ ${*$self}{exp_Listen_Group} } = (); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1202
|
|
|
|
|
|
|
} |
|
1203
|
0
|
|
|
|
|
0
|
$self->manual_stty($old_manual_stty_val); |
|
1204
|
|
|
|
|
|
|
|
|
1205
|
0
|
|
|
|
|
0
|
return; |
|
1206
|
|
|
|
|
|
|
} |
|
1207
|
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
sub interconnect { |
|
1209
|
0
|
|
|
0
|
1
|
0
|
my (@handles) = @_; |
|
1210
|
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
# my ($handle)=(shift); call as Expect::interconnect($spawn1,$spawn2,...) |
|
1212
|
0
|
|
|
|
|
0
|
my ( $nread ); |
|
1213
|
0
|
|
|
|
|
0
|
my ( $rout, $emask, $eout ); |
|
1214
|
0
|
|
|
|
|
0
|
my ( $escape_character_buffer ); |
|
1215
|
0
|
|
|
|
|
0
|
my ( $read_mask, $temp_mask ) = ( '', '' ); |
|
1216
|
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
# Get read/write handles |
|
1218
|
0
|
|
|
|
|
0
|
foreach my $handle (@handles) { |
|
1219
|
0
|
|
|
|
|
0
|
$temp_mask = ''; |
|
1220
|
0
|
|
|
|
|
0
|
vec( $temp_mask, $handle->fileno(), 1 ) = 1; |
|
1221
|
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
# Under Linux w/ 5.001 the next line comes up w/ 'Uninit var.'. |
|
1223
|
|
|
|
|
|
|
# It appears to be impossible to make the warning go away. |
|
1224
|
|
|
|
|
|
|
# doing something like $temp_mask='' unless defined ($temp_mask) |
|
1225
|
|
|
|
|
|
|
# has no effect whatsoever. This may be a bug in 5.001. |
|
1226
|
0
|
|
|
|
|
0
|
$read_mask = $read_mask | $temp_mask; |
|
1227
|
|
|
|
|
|
|
} |
|
1228
|
0
|
0
|
|
|
|
0
|
if ($Expect::Debug) { |
|
1229
|
0
|
|
|
|
|
0
|
print STDERR "Read handles:\r\n"; |
|
1230
|
0
|
|
|
|
|
0
|
foreach my $handle (@handles) { |
|
1231
|
0
|
|
|
|
|
0
|
print STDERR "\tRead handle: "; |
|
1232
|
0
|
|
|
|
|
0
|
print STDERR "'${*$handle}{exp_Pty_Handle}'\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1233
|
0
|
|
|
|
|
0
|
print STDERR "\t\tListen Handles:"; |
|
1234
|
0
|
|
|
|
|
0
|
foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1235
|
0
|
|
|
|
|
0
|
print STDERR " '${*$write_handle}{exp_Pty_Handle}'"; |
|
|
0
|
|
|
|
|
0
|
|
|
1236
|
|
|
|
|
|
|
} |
|
1237
|
0
|
|
|
|
|
0
|
print STDERR ".\r\n"; |
|
1238
|
|
|
|
|
|
|
} |
|
1239
|
|
|
|
|
|
|
} |
|
1240
|
|
|
|
|
|
|
|
|
1241
|
|
|
|
|
|
|
# I think if we don't set raw/-echo here we may have trouble. We don't |
|
1242
|
|
|
|
|
|
|
# want a bunch of echoing crap making all the handles jabber at each other. |
|
1243
|
0
|
|
|
|
|
0
|
foreach my $handle (@handles) { |
|
1244
|
0
|
0
|
|
|
|
0
|
unless ( ${*$handle}{"exp_Manual_Stty"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1245
|
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
# This is probably O/S specific. |
|
1247
|
0
|
|
|
|
|
0
|
${*$handle}{exp_Stored_Stty} = $handle->exp_stty('-g'); |
|
|
0
|
|
|
|
|
0
|
|
|
1248
|
0
|
|
|
|
|
0
|
print STDERR "Setting tty for ${*$handle}{exp_Pty_Handle} to 'raw -echo'.\r\n" |
|
1249
|
0
|
0
|
|
|
|
0
|
if ${*$handle}{"exp_Debug"}; |
|
|
0
|
|
|
|
|
0
|
|
|
1250
|
0
|
|
|
|
|
0
|
$handle->exp_stty("raw -echo"); |
|
1251
|
|
|
|
|
|
|
} |
|
1252
|
0
|
|
|
|
|
0
|
foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1253
|
0
|
0
|
|
|
|
0
|
unless ( ${*$write_handle}{"exp_Manual_Stty"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1254
|
0
|
|
|
|
|
0
|
${*$write_handle}{exp_Stored_Stty} = |
|
1255
|
0
|
|
|
|
|
0
|
$write_handle->exp_stty('-g'); |
|
1256
|
0
|
|
|
|
|
0
|
print STDERR "Setting ${*$write_handle}{exp_Pty_Handle} to 'raw -echo'.\r\n" |
|
1257
|
0
|
0
|
|
|
|
0
|
if ${*$handle}{"exp_Debug"}; |
|
|
0
|
|
|
|
|
0
|
|
|
1258
|
0
|
|
|
|
|
0
|
$write_handle->exp_stty("raw -echo"); |
|
1259
|
|
|
|
|
|
|
} |
|
1260
|
|
|
|
|
|
|
} |
|
1261
|
|
|
|
|
|
|
} |
|
1262
|
|
|
|
|
|
|
|
|
1263
|
0
|
0
|
|
|
|
0
|
print STDERR "Attempting interconnection\r\n" if $Expect::Debug; |
|
1264
|
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
# Wait until the process dies or we get EOF |
|
1266
|
|
|
|
|
|
|
# In the case of !${*$handle}{exp_Pid} it means |
|
1267
|
|
|
|
|
|
|
# the handle was exp_inited instead of spawned. |
|
1268
|
|
|
|
|
|
|
CONNECT_LOOP: |
|
1269
|
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
# Go until we have a reason to stop |
|
1271
|
0
|
|
|
|
|
0
|
while (1) { |
|
1272
|
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
# test each handle to see if it's still alive. |
|
1274
|
0
|
|
|
|
|
0
|
foreach my $read_handle (@handles) { |
|
1275
|
0
|
|
|
|
|
0
|
waitpid( ${*$read_handle}{exp_Pid}, WNOHANG ) |
|
1276
|
0
|
|
|
|
|
0
|
if ( exists( ${*$read_handle}{exp_Pid} ) |
|
1277
|
0
|
0
|
0
|
|
|
0
|
and ${*$read_handle}{exp_Pid} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1278
|
0
|
0
|
0
|
|
|
0
|
if ( exists( ${*$read_handle}{exp_Pid} ) |
|
|
0
|
|
0
|
|
|
0
|
|
|
1279
|
0
|
|
|
|
|
0
|
and ( ${*$read_handle}{exp_Pid} ) |
|
1280
|
0
|
|
|
|
|
0
|
and ( !kill( 0, ${*$read_handle}{exp_Pid} ) ) ) |
|
1281
|
|
|
|
|
|
|
{ |
|
1282
|
|
|
|
|
|
|
print STDERR |
|
1283
|
0
|
|
|
|
|
0
|
"Got EOF (${*$read_handle}{exp_Pty_Handle} died) reading ${*$read_handle}{exp_Pty_Handle}\r\n" |
|
|
0
|
|
|
|
|
0
|
|
|
1284
|
0
|
0
|
|
|
|
0
|
if ${*$read_handle}{"exp_Debug"}; |
|
|
0
|
|
|
|
|
0
|
|
|
1285
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1286
|
0
|
0
|
|
|
|
0
|
unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1287
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1288
|
0
|
|
|
|
|
0
|
unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1289
|
0
|
0
|
|
|
|
0
|
( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1290
|
|
|
|
|
|
|
} |
|
1291
|
|
|
|
|
|
|
} |
|
1292
|
|
|
|
|
|
|
|
|
1293
|
|
|
|
|
|
|
# Every second? No, go until we get something from someone. |
|
1294
|
0
|
|
|
|
|
0
|
my $nfound = select( $rout = $read_mask, undef, $eout = $emask, undef ); |
|
1295
|
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
# Is there anything to share? May be -1 if interrupted by a signal... |
|
1297
|
0
|
0
|
0
|
|
|
0
|
next CONNECT_LOOP if not defined $nfound or $nfound < 1; |
|
1298
|
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
# Which handles have stuff? |
|
1300
|
0
|
|
|
|
|
0
|
my @bits = split( //, unpack( 'b*', $rout ) ); |
|
1301
|
0
|
0
|
|
|
|
0
|
$eout = 0 unless defined($eout); |
|
1302
|
0
|
|
|
|
|
0
|
my @ebits = split( //, unpack( 'b*', $eout ) ); |
|
1303
|
|
|
|
|
|
|
|
|
1304
|
|
|
|
|
|
|
# print "Ebits: $eout\r\n"; |
|
1305
|
0
|
|
|
|
|
0
|
foreach my $read_handle (@handles) { |
|
1306
|
0
|
0
|
|
|
|
0
|
if ( $bits[ $read_handle->fileno() ] ) { |
|
1307
|
|
|
|
|
|
|
$nread = sysread( |
|
1308
|
0
|
|
|
|
|
0
|
$read_handle, ${*$read_handle}{exp_Pty_Buffer}, |
|
1309
|
0
|
|
|
|
|
0
|
1024 |
|
1310
|
|
|
|
|
|
|
); |
|
1311
|
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
# Appease perl -w |
|
1313
|
0
|
0
|
|
|
|
0
|
$nread = 0 unless defined($nread); |
|
1314
|
0
|
|
|
|
|
0
|
print STDERR "interconnect: read $nread byte(s) from ${*$read_handle}{exp_Pty_Handle}.\r\n" |
|
1315
|
0
|
0
|
|
|
|
0
|
if ${*$read_handle}{"exp_Debug"} > 1; |
|
|
0
|
|
|
|
|
0
|
|
|
1316
|
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
# Test for escape seq. before printing. |
|
1318
|
|
|
|
|
|
|
# Appease perl -w |
|
1319
|
0
|
0
|
|
|
|
0
|
$escape_character_buffer = '' |
|
1320
|
|
|
|
|
|
|
unless defined($escape_character_buffer); |
|
1321
|
0
|
|
|
|
|
0
|
$escape_character_buffer .= ${*$read_handle}{exp_Pty_Buffer}; |
|
|
0
|
|
|
|
|
0
|
|
|
1322
|
0
|
|
|
|
|
0
|
foreach my $escape_sequence ( keys( %{ ${*$read_handle}{exp_Function} } ) ) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1323
|
0
|
|
|
|
|
0
|
print STDERR "Tested escape sequence $escape_sequence from ${*$read_handle}{exp_Pty_Handle}" |
|
1324
|
0
|
0
|
|
|
|
0
|
if ${*$read_handle}{"exp_Debug"} > 1; |
|
|
0
|
|
|
|
|
0
|
|
|
1325
|
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
# Make sure it doesn't grow out of bounds. |
|
1327
|
|
|
|
|
|
|
$escape_character_buffer = $read_handle->_trim_length( |
|
1328
|
|
|
|
|
|
|
$escape_character_buffer, |
|
1329
|
0
|
|
|
|
|
0
|
${*$read_handle}{"exp_Max_Accum"} |
|
1330
|
0
|
0
|
|
|
|
0
|
) if ( ${*$read_handle}{"exp_Max_Accum"} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1331
|
0
|
0
|
|
|
|
0
|
if ( $escape_character_buffer =~ /($escape_sequence)/ ) { |
|
1332
|
0
|
|
|
|
|
0
|
my $match = $1; |
|
1333
|
0
|
0
|
|
|
|
0
|
if ( ${*$read_handle}{"exp_Debug"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1334
|
0
|
|
|
|
|
0
|
print STDERR |
|
1335
|
0
|
|
|
|
|
0
|
"\r\ninterconnect got escape sequence from ${*$read_handle}{exp_Pty_Handle}.\r\n"; |
|
1336
|
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
# I'm going to make the esc. seq. pretty because it will |
|
1338
|
|
|
|
|
|
|
# probably contain unprintable characters. |
|
1339
|
0
|
|
|
|
|
0
|
print STDERR "\tEscape Sequence: '" |
|
1340
|
|
|
|
|
|
|
. _trim_length( |
|
1341
|
|
|
|
|
|
|
undef, |
|
1342
|
|
|
|
|
|
|
_make_readable($escape_sequence) |
|
1343
|
|
|
|
|
|
|
) . "'\r\n"; |
|
1344
|
0
|
|
|
|
|
0
|
print STDERR "\tMatched by string: '" . _trim_length( undef, _make_readable($match) ) . "'\r\n"; |
|
1345
|
|
|
|
|
|
|
} |
|
1346
|
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
# Print out stuff before the escape. |
|
1348
|
|
|
|
|
|
|
# Keep in mind that the sequence may have been split up |
|
1349
|
|
|
|
|
|
|
# over several reads. |
|
1350
|
|
|
|
|
|
|
# Let's get rid of it from this read. If part of it was |
|
1351
|
|
|
|
|
|
|
# in the last read there's not a lot we can do about it now. |
|
1352
|
0
|
0
|
|
|
|
0
|
if ( ${*$read_handle}{exp_Pty_Buffer} =~ /([\w\W]*)($escape_sequence)/ ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1353
|
0
|
|
|
|
|
0
|
$read_handle->_print_handles($1); |
|
1354
|
|
|
|
|
|
|
} else { |
|
1355
|
0
|
|
|
|
|
0
|
$read_handle->_print_handles( ${*$read_handle}{exp_Pty_Buffer} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1356
|
|
|
|
|
|
|
} |
|
1357
|
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
# Clear the buffer so no more matches can be made and it will |
|
1359
|
|
|
|
|
|
|
# only be printed one time. |
|
1360
|
0
|
|
|
|
|
0
|
${*$read_handle}{exp_Pty_Buffer} = ''; |
|
|
0
|
|
|
|
|
0
|
|
|
1361
|
0
|
|
|
|
|
0
|
$escape_character_buffer = ''; |
|
1362
|
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
# Do the function here. Must return non-zero to continue. |
|
1364
|
|
|
|
|
|
|
# More cool syntax. Maybe I should turn these in to objects. |
|
1365
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1366
|
0
|
|
|
|
|
0
|
unless &{ ${ ${*$read_handle}{exp_Function} }{$escape_sequence} } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1367
|
0
|
0
|
|
|
|
0
|
( @{ ${ ${*$read_handle}{exp_Parameters} }{$escape_sequence} } ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1368
|
|
|
|
|
|
|
} |
|
1369
|
|
|
|
|
|
|
} |
|
1370
|
0
|
0
|
|
|
|
0
|
$nread = 0 unless defined($nread); # Appease perl -w? |
|
1371
|
0
|
|
|
|
|
0
|
waitpid( ${*$read_handle}{exp_Pid}, WNOHANG ) |
|
1372
|
0
|
|
|
|
|
0
|
if ( defined( ${*$read_handle}{exp_Pid} ) |
|
1373
|
0
|
0
|
0
|
|
|
0
|
&& ${*$read_handle}{exp_Pid} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1374
|
0
|
0
|
|
|
|
0
|
if ( $nread == 0 ) { |
|
1375
|
0
|
|
|
|
|
0
|
print STDERR "Got EOF reading ${*$read_handle}{exp_Pty_Handle}\r\n" |
|
1376
|
0
|
0
|
|
|
|
0
|
if ${*$read_handle}{"exp_Debug"}; |
|
|
0
|
|
|
|
|
0
|
|
|
1377
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1378
|
0
|
0
|
|
|
|
0
|
unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1379
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1380
|
0
|
|
|
|
|
0
|
unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1381
|
0
|
0
|
|
|
|
0
|
( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } ); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1382
|
|
|
|
|
|
|
} |
|
1383
|
0
|
0
|
|
|
|
0
|
last CONNECT_LOOP if ( $nread < 0 ); # This would be an error |
|
1384
|
0
|
|
|
|
|
0
|
$read_handle->_print_handles( ${*$read_handle}{exp_Pty_Buffer} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1385
|
|
|
|
|
|
|
} |
|
1386
|
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
# I'm removing this because I haven't determined what causes exceptions |
|
1388
|
|
|
|
|
|
|
# consistently. |
|
1389
|
0
|
|
|
|
|
0
|
if (0) #$ebits[$read_handle->fileno()]) |
|
1390
|
|
|
|
|
|
|
{ |
|
1391
|
|
|
|
|
|
|
print STDERR "Got Exception reading ${*$read_handle}{exp_Pty_Handle}\r\n" |
|
1392
|
|
|
|
|
|
|
if ${*$read_handle}{"exp_Debug"}; |
|
1393
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1394
|
|
|
|
|
|
|
unless defined( ${ ${*$read_handle}{exp_Function} }{"EOF"} ); |
|
1395
|
|
|
|
|
|
|
last CONNECT_LOOP |
|
1396
|
|
|
|
|
|
|
unless &{ ${ ${*$read_handle}{exp_Function} }{"EOF"} } |
|
1397
|
|
|
|
|
|
|
( @{ ${ ${*$read_handle}{exp_Parameters} }{"EOF"} } ); |
|
1398
|
|
|
|
|
|
|
} |
|
1399
|
|
|
|
|
|
|
} |
|
1400
|
|
|
|
|
|
|
} |
|
1401
|
0
|
|
|
|
|
0
|
foreach my $handle (@handles) { |
|
1402
|
0
|
0
|
|
|
|
0
|
unless ( ${*$handle}{"exp_Manual_Stty"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1403
|
0
|
|
|
|
|
0
|
$handle->exp_stty( ${*$handle}{exp_Stored_Stty} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1404
|
|
|
|
|
|
|
} |
|
1405
|
0
|
|
|
|
|
0
|
foreach my $write_handle ( @{ ${*$handle}{exp_Listen_Group} } ) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1406
|
0
|
0
|
|
|
|
0
|
unless ( ${*$write_handle}{"exp_Manual_Stty"} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1407
|
0
|
|
|
|
|
0
|
$write_handle->exp_stty( ${*$write_handle}{exp_Stored_Stty} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1408
|
|
|
|
|
|
|
} |
|
1409
|
|
|
|
|
|
|
} |
|
1410
|
|
|
|
|
|
|
} |
|
1411
|
|
|
|
|
|
|
|
|
1412
|
0
|
|
|
|
|
0
|
return; |
|
1413
|
|
|
|
|
|
|
} |
|
1414
|
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
# user can decide if log output gets also sent to logfile |
|
1416
|
|
|
|
|
|
|
sub print_log_file { |
|
1417
|
5472
|
|
|
5472
|
1
|
15360
|
my ($self, @params) = @_; |
|
1418
|
|
|
|
|
|
|
|
|
1419
|
5472
|
100
|
|
|
|
8584
|
if ( ${*$self}{exp_Log_File} ) { |
|
|
5472
|
|
|
|
|
14168
|
|
|
1420
|
5326
|
100
|
|
|
|
7389
|
if ( ref( ${*$self}{exp_Log_File} ) eq 'CODE' ) { |
|
|
5326
|
|
|
|
|
16753
|
|
|
1421
|
54
|
|
|
|
|
135
|
${*$self}{exp_Log_File}->(@params); |
|
|
54
|
|
|
|
|
675
|
|
|
1422
|
|
|
|
|
|
|
} else { |
|
1423
|
5272
|
|
|
|
|
7872
|
${*$self}{exp_Log_File}->print(@params); |
|
|
5272
|
|
|
|
|
18120
|
|
|
1424
|
|
|
|
|
|
|
} |
|
1425
|
|
|
|
|
|
|
} |
|
1426
|
|
|
|
|
|
|
|
|
1427
|
5472
|
|
|
|
|
206996
|
return; |
|
1428
|
|
|
|
|
|
|
} |
|
1429
|
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
# we provide our own print so we can debug what gets sent to the |
|
1431
|
|
|
|
|
|
|
# processes... |
|
1432
|
|
|
|
|
|
|
sub print { |
|
1433
|
5308
|
|
|
5308
|
1
|
235757
|
my ( $self, @args ) = @_; |
|
1434
|
|
|
|
|
|
|
|
|
1435
|
5308
|
50
|
|
|
|
13681
|
return if not defined $self->fileno(); # skip if closed |
|
1436
|
5308
|
50
|
|
|
|
29716
|
if ( ${*$self}{exp_Exp_Internal} ) { |
|
|
5308
|
|
|
|
|
14069
|
|
|
1437
|
0
|
|
|
|
|
0
|
my $args = _make_readable( join( '', @args ) ); |
|
1438
|
0
|
|
|
|
|
0
|
cluck "Sending '$args' to ${*$self}{exp_Pty_Handle}\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1439
|
|
|
|
|
|
|
} |
|
1440
|
5308
|
|
|
|
|
10163
|
foreach my $arg (@args) { |
|
1441
|
5308
|
|
|
|
|
11198
|
while ( length($arg) > 80 ) { |
|
1442
|
11814
|
|
|
|
|
46502
|
$self->SUPER::print( substr( $arg, 0, 80 ) ); |
|
1443
|
11814
|
|
|
|
|
619754
|
$arg = substr( $arg, 80 ); |
|
1444
|
|
|
|
|
|
|
} |
|
1445
|
5308
|
|
|
|
|
16395
|
$self->SUPER::print($arg); |
|
1446
|
|
|
|
|
|
|
} |
|
1447
|
|
|
|
|
|
|
|
|
1448
|
5308
|
|
|
|
|
379493
|
return; |
|
1449
|
|
|
|
|
|
|
} |
|
1450
|
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
# make an alias for Tcl/Expect users for a DWIM experience... |
|
1452
|
|
|
|
|
|
|
*send = \&print; |
|
1453
|
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
# This is an Expect standard. It's nice for talking to modems and the like |
|
1455
|
|
|
|
|
|
|
# where from time to time they get unhappy if you send items too quickly. |
|
1456
|
|
|
|
|
|
|
sub send_slow { |
|
1457
|
27
|
|
|
27
|
1
|
68049
|
my ($self, $sleep_time, @chunks) = @_; |
|
1458
|
|
|
|
|
|
|
|
|
1459
|
27
|
50
|
|
|
|
135
|
return if not defined $self->fileno(); # skip if closed |
|
1460
|
|
|
|
|
|
|
|
|
1461
|
|
|
|
|
|
|
# Flushing makes it so each character can be seen separately. |
|
1462
|
27
|
|
|
|
|
225
|
my $chunk; |
|
1463
|
27
|
|
|
|
|
108
|
while ( $chunk = shift @chunks ) { |
|
1464
|
27
|
|
|
|
|
765
|
my @linechars = split( '', $chunk ); |
|
1465
|
27
|
|
|
|
|
108
|
foreach my $char (@linechars) { |
|
1466
|
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
# How slow? |
|
1468
|
1170
|
|
|
|
|
117722394
|
select( undef, undef, undef, $sleep_time ); |
|
1469
|
|
|
|
|
|
|
|
|
1470
|
1170
|
|
|
|
|
242496
|
print $self $char; |
|
1471
|
0
|
|
|
|
|
0
|
print STDERR "Printed character \'" . _make_readable($char) . "\' to ${*$self}{exp_Pty_Handle}.\r\n" |
|
1472
|
1170
|
50
|
|
|
|
5265
|
if ${*$self}{"exp_Debug"} > 1; |
|
|
1170
|
|
|
|
|
20889
|
|
|
1473
|
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
# I think I can get away with this if I save it in accum |
|
1475
|
1170
|
50
|
33
|
|
|
4545
|
if ( ${*$self}{"exp_Log_Stdout"} || ${*$self}{exp_Log_Group} ) { |
|
|
1170
|
|
|
|
|
8352
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1476
|
1170
|
|
|
|
|
3600
|
my $rmask = ""; |
|
1477
|
1170
|
|
|
|
|
14958
|
vec( $rmask, $self->fileno(), 1 ) = 1; |
|
1478
|
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
# .01 sec granularity should work. If we miss something it will |
|
1480
|
|
|
|
|
|
|
# probably get flushed later, maybe in an expect call. |
|
1481
|
1170
|
|
|
|
|
12364623
|
while ( select( $rmask, undef, undef, .01 ) ) { |
|
1482
|
27
|
|
|
|
|
234
|
my $ret = sysread( $self, ${*$self}{exp_Pty_Buffer}, 1024 ); |
|
|
27
|
|
|
|
|
4392
|
|
|
1483
|
27
|
50
|
33
|
|
|
594
|
last if not defined $ret or $ret == 0; |
|
1484
|
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
# Is this necessary to keep? Probably.. # |
|
1486
|
|
|
|
|
|
|
# if you need to expect it later. |
|
1487
|
27
|
|
|
|
|
54
|
${*$self}{exp_Accum} .= ${*$self}{exp_Pty_Buffer}; |
|
|
27
|
|
|
|
|
864
|
|
|
|
27
|
|
|
|
|
1494
|
|
|
1488
|
0
|
|
|
|
|
0
|
${*$self}{exp_Accum} = $self->_trim_length( |
|
1489
|
0
|
|
|
|
|
0
|
${*$self}{exp_Accum}, |
|
1490
|
0
|
|
|
|
|
0
|
${*$self}{"exp_Max_Accum"} |
|
1491
|
27
|
50
|
|
|
|
108
|
) if ( ${*$self}{"exp_Max_Accum"} ); |
|
|
27
|
|
|
|
|
315
|
|
|
1492
|
27
|
|
|
|
|
90
|
$self->_print_handles( ${*$self}{exp_Pty_Buffer} ); |
|
|
27
|
|
|
|
|
360
|
|
|
1493
|
|
|
|
|
|
|
print STDERR "Received \'" |
|
1494
|
|
|
|
|
|
|
. $self->_trim_length( _make_readable($char) ) |
|
1495
|
0
|
|
|
|
|
0
|
. "\' from ${*$self}{exp_Pty_Handle}\r\n" |
|
1496
|
27
|
50
|
|
|
|
54
|
if ${*$self}{"exp_Debug"} > 1; |
|
|
27
|
|
|
|
|
274689
|
|
|
1497
|
|
|
|
|
|
|
} |
|
1498
|
|
|
|
|
|
|
} |
|
1499
|
|
|
|
|
|
|
} |
|
1500
|
|
|
|
|
|
|
} |
|
1501
|
|
|
|
|
|
|
|
|
1502
|
27
|
|
|
|
|
504
|
return; |
|
1503
|
|
|
|
|
|
|
} |
|
1504
|
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
sub test_handles { |
|
1506
|
0
|
|
|
0
|
1
|
0
|
my ($timeout, @handle_list) = @_; |
|
1507
|
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
# This should be called by Expect::test_handles($timeout,@objects); |
|
1509
|
0
|
|
|
|
|
0
|
my ( $allmask, $rout ); |
|
1510
|
0
|
|
|
|
|
0
|
foreach my $handle (@handle_list) { |
|
1511
|
0
|
|
|
|
|
0
|
my $rmask = ''; |
|
1512
|
0
|
|
|
|
|
0
|
vec( $rmask, $handle->fileno(), 1 ) = 1; |
|
1513
|
0
|
0
|
|
|
|
0
|
$allmask = '' unless defined($allmask); |
|
1514
|
0
|
|
|
|
|
0
|
$allmask = $allmask | $rmask; |
|
1515
|
|
|
|
|
|
|
} |
|
1516
|
0
|
|
|
|
|
0
|
my $nfound = select( $rout = $allmask, undef, undef, $timeout ); |
|
1517
|
0
|
0
|
|
|
|
0
|
return () unless $nfound; |
|
1518
|
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
# Which handles have stuff? |
|
1520
|
0
|
|
|
|
|
0
|
my @bits = split( //, unpack( 'b*', $rout ) ); |
|
1521
|
|
|
|
|
|
|
|
|
1522
|
0
|
|
|
|
|
0
|
my $handle_num = 0; |
|
1523
|
0
|
|
|
|
|
0
|
my @return_list = (); |
|
1524
|
0
|
|
|
|
|
0
|
foreach my $handle (@handle_list) { |
|
1525
|
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
# I go to great lengths to get perl -w to shut the hell up. |
|
1527
|
0
|
0
|
0
|
|
|
0
|
if ( defined( $bits[ $handle->fileno() ] ) |
|
1528
|
|
|
|
|
|
|
and ( $bits[ $handle->fileno() ] ) ) |
|
1529
|
|
|
|
|
|
|
{ |
|
1530
|
0
|
|
|
|
|
0
|
push( @return_list, $handle_num ); |
|
1531
|
|
|
|
|
|
|
} |
|
1532
|
|
|
|
|
|
|
} continue { |
|
1533
|
0
|
|
|
|
|
0
|
$handle_num++; |
|
1534
|
|
|
|
|
|
|
} |
|
1535
|
|
|
|
|
|
|
|
|
1536
|
0
|
|
|
|
|
0
|
return @return_list; |
|
1537
|
|
|
|
|
|
|
} |
|
1538
|
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
# Be nice close. This should emulate what an interactive shell does after a |
|
1540
|
|
|
|
|
|
|
# command finishes... sort of. We're not as patient as a shell. |
|
1541
|
|
|
|
|
|
|
sub soft_close { |
|
1542
|
9
|
|
|
9
|
0
|
20830
|
my ($self) = @_; |
|
1543
|
|
|
|
|
|
|
|
|
1544
|
9
|
|
|
|
|
33
|
my ( $nfound, $nread, $rmask, $end_time, $temp_buffer ); |
|
1545
|
|
|
|
|
|
|
|
|
1546
|
|
|
|
|
|
|
# Give it 15 seconds to cough up an eof. |
|
1547
|
9
|
50
|
|
|
|
18
|
cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug}; |
|
|
0
|
|
|
|
|
0
|
|
|
|
9
|
|
|
|
|
70
|
|
|
1548
|
9
|
50
|
|
|
|
61
|
return -1 if not defined $self->fileno(); # skip if handle already closed |
|
1549
|
9
|
50
|
33
|
|
|
82
|
unless ( exists ${*$self}{exp_Has_EOF} and ${*$self}{exp_Has_EOF} ) { |
|
|
9
|
|
|
|
|
52
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1550
|
9
|
|
|
|
|
33
|
$end_time = time() + 15; |
|
1551
|
9
|
|
|
|
|
45
|
while ( $end_time > time() ) { |
|
1552
|
13
|
|
|
|
|
40
|
my $select_time = $end_time - time(); |
|
1553
|
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
# Sanity check. |
|
1555
|
13
|
50
|
|
|
|
62
|
$select_time = 0 if $select_time < 0; |
|
1556
|
13
|
|
|
|
|
54
|
$rmask = ''; |
|
1557
|
13
|
|
|
|
|
72
|
vec( $rmask, $self->fileno(), 1 ) = 1; |
|
1558
|
13
|
|
|
|
|
18585970
|
($nfound) = select( $rmask, undef, undef, $select_time ); |
|
1559
|
13
|
50
|
33
|
|
|
529
|
last unless ( defined($nfound) && $nfound ); |
|
1560
|
13
|
|
|
|
|
344
|
$nread = sysread( $self, $temp_buffer, 8096 ); |
|
1561
|
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
# 0 = EOF. |
|
1563
|
13
|
100
|
66
|
|
|
194
|
unless ( defined($nread) && $nread ) { |
|
1564
|
0
|
|
|
|
|
0
|
print STDERR "Got EOF from ${*$self}{exp_Pty_Handle}.\r\n" |
|
1565
|
9
|
50
|
|
|
|
22
|
if ${*$self}{exp_Debug}; |
|
|
9
|
|
|
|
|
148
|
|
|
1566
|
9
|
|
|
|
|
103
|
last; |
|
1567
|
|
|
|
|
|
|
} |
|
1568
|
4
|
|
|
|
|
224
|
$self->_print_handles($temp_buffer); |
|
1569
|
|
|
|
|
|
|
} |
|
1570
|
9
|
0
|
33
|
|
|
115
|
if ( ( $end_time <= time() ) && ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1571
|
0
|
|
|
|
|
0
|
print STDERR "Timed out waiting for an EOF from ${*$self}{exp_Pty_Handle}.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1572
|
|
|
|
|
|
|
} |
|
1573
|
|
|
|
|
|
|
} |
|
1574
|
9
|
|
|
|
|
185
|
my $close_status = $self->close(); |
|
1575
|
9
|
50
|
33
|
|
|
1022
|
if ( $close_status && ${*$self}{exp_Debug} ) { |
|
|
9
|
|
|
|
|
130
|
|
|
1576
|
0
|
|
|
|
|
0
|
print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1577
|
|
|
|
|
|
|
} |
|
1578
|
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
# quit now if it isn't a process. |
|
1580
|
9
|
50
|
|
|
|
17
|
return $close_status unless defined( ${*$self}{exp_Pid} ); |
|
|
9
|
|
|
|
|
59
|
|
|
1581
|
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
# Now give it 15 seconds to die. |
|
1583
|
9
|
|
|
|
|
27
|
$end_time = time() + 15; |
|
1584
|
9
|
|
|
|
|
31
|
while ( $end_time > time() ) { |
|
1585
|
9
|
|
|
|
|
18
|
my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG ); |
|
|
9
|
|
|
|
|
763
|
|
|
1586
|
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
# Stop here if the process dies. |
|
1588
|
9
|
50
|
33
|
|
|
272
|
if ( defined($returned_pid) && $returned_pid ) { |
|
1589
|
9
|
|
|
|
|
100
|
delete $Expect::Spawned_PIDs{$returned_pid}; |
|
1590
|
9
|
50
|
|
|
|
23
|
if ( ${*$self}{exp_Debug} ) { |
|
|
9
|
|
|
|
|
48
|
|
|
1591
|
|
|
|
|
|
|
printf STDERR ( |
|
1592
|
|
|
|
|
|
|
"Pid %d of %s exited, Status: 0x%02X\r\n", |
|
1593
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid}, |
|
1594
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
1595
|
|
|
|
|
|
|
); |
|
1596
|
|
|
|
|
|
|
} |
|
1597
|
9
|
|
|
|
|
87
|
${*$self}{exp_Pid} = undef; |
|
|
9
|
|
|
|
|
37
|
|
|
1598
|
9
|
|
|
|
|
22
|
${*$self}{exp_Exit} = $?; |
|
|
9
|
|
|
|
|
49
|
|
|
1599
|
9
|
|
|
|
|
53
|
return ${*$self}{exp_Exit}; |
|
|
9
|
|
|
|
|
75
|
|
|
1600
|
|
|
|
|
|
|
} |
|
1601
|
0
|
|
|
|
|
0
|
sleep 1; # Keep loop nice. |
|
1602
|
|
|
|
|
|
|
} |
|
1603
|
|
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
# Send it a term if it isn't dead. |
|
1605
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1606
|
0
|
|
|
|
|
0
|
print STDERR "${*$self}{exp_Pty_Handle} not exiting, sending TERM.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1607
|
|
|
|
|
|
|
} |
|
1608
|
0
|
|
|
|
|
0
|
kill TERM => ${*$self}{exp_Pid}; |
|
|
0
|
|
|
|
|
0
|
|
|
1609
|
|
|
|
|
|
|
|
|
1610
|
|
|
|
|
|
|
# Now to be anal retentive.. wait 15 more seconds for it to die. |
|
1611
|
0
|
|
|
|
|
0
|
$end_time = time() + 15; |
|
1612
|
0
|
|
|
|
|
0
|
while ( $end_time > time() ) { |
|
1613
|
0
|
|
|
|
|
0
|
my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG ); |
|
|
0
|
|
|
|
|
0
|
|
|
1614
|
0
|
0
|
0
|
|
|
0
|
if ( defined($returned_pid) && $returned_pid ) { |
|
1615
|
0
|
|
|
|
|
0
|
delete $Expect::Spawned_PIDs{$returned_pid}; |
|
1616
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1617
|
|
|
|
|
|
|
printf STDERR ( |
|
1618
|
|
|
|
|
|
|
"Pid %d of %s terminated, Status: 0x%02X\r\n", |
|
1619
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid}, |
|
1620
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
1621
|
|
|
|
|
|
|
); |
|
1622
|
|
|
|
|
|
|
} |
|
1623
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid} = undef; |
|
|
0
|
|
|
|
|
0
|
|
|
1624
|
0
|
|
|
|
|
0
|
${*$self}{exp_Exit} = $?; |
|
|
0
|
|
|
|
|
0
|
|
|
1625
|
0
|
|
|
|
|
0
|
return $?; |
|
1626
|
|
|
|
|
|
|
} |
|
1627
|
0
|
|
|
|
|
0
|
sleep 1; |
|
1628
|
|
|
|
|
|
|
} |
|
1629
|
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
# Since this is a 'soft' close, sending it a -9 would be inappropriate. |
|
1631
|
0
|
|
|
|
|
0
|
return; |
|
1632
|
|
|
|
|
|
|
} |
|
1633
|
|
|
|
|
|
|
|
|
1634
|
|
|
|
|
|
|
# 'Make it go away' close. |
|
1635
|
|
|
|
|
|
|
sub hard_close { |
|
1636
|
194
|
|
|
194
|
0
|
260247
|
my ($self) = @_; |
|
1637
|
|
|
|
|
|
|
|
|
1638
|
194
|
50
|
|
|
|
399
|
cluck "Closing ${*$self}{exp_Pty_Handle}.\r\n" if ${*$self}{exp_Debug}; |
|
|
0
|
|
|
|
|
0
|
|
|
|
194
|
|
|
|
|
945
|
|
|
1639
|
|
|
|
|
|
|
|
|
1640
|
|
|
|
|
|
|
# Don't wait for an EOF. |
|
1641
|
194
|
|
|
|
|
2190
|
my $close_status = $self->close(); |
|
1642
|
194
|
50
|
66
|
|
|
132732
|
if ( $close_status && ${*$self}{exp_Debug} ) { |
|
|
120
|
|
|
|
|
1135
|
|
|
1643
|
0
|
|
|
|
|
0
|
print STDERR "${*$self}{exp_Pty_Handle} closed.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1644
|
|
|
|
|
|
|
} |
|
1645
|
|
|
|
|
|
|
|
|
1646
|
|
|
|
|
|
|
# Return now if handle. |
|
1647
|
194
|
100
|
|
|
|
964
|
return $close_status unless defined( ${*$self}{exp_Pid} ); |
|
|
194
|
|
|
|
|
1003
|
|
|
1648
|
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
# Now give it 5 seconds to die. Less patience here if it won't die. |
|
1650
|
95
|
|
|
|
|
349
|
my $end_time = time() + 5; |
|
1651
|
95
|
|
|
|
|
420
|
while ( $end_time > time() ) { |
|
1652
|
188
|
|
|
|
|
854
|
my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG ); |
|
|
188
|
|
|
|
|
13253
|
|
|
1653
|
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
# Stop here if the process dies. |
|
1655
|
188
|
100
|
66
|
|
|
2716
|
if ( defined($returned_pid) && $returned_pid ) { |
|
1656
|
95
|
|
|
|
|
1981
|
delete $Expect::Spawned_PIDs{$returned_pid}; |
|
1657
|
95
|
50
|
|
|
|
218
|
if ( ${*$self}{exp_Debug} ) { |
|
|
95
|
|
|
|
|
774
|
|
|
1658
|
|
|
|
|
|
|
printf STDERR ( |
|
1659
|
|
|
|
|
|
|
"Pid %d of %s terminated, Status: 0x%02X\r\n", |
|
1660
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid}, |
|
1661
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
1662
|
|
|
|
|
|
|
); |
|
1663
|
|
|
|
|
|
|
} |
|
1664
|
95
|
|
|
|
|
220
|
${*$self}{exp_Pid} = undef; |
|
|
95
|
|
|
|
|
365
|
|
|
1665
|
95
|
|
|
|
|
275
|
${*$self}{exp_Exit} = $?; |
|
|
95
|
|
|
|
|
1786
|
|
|
1666
|
95
|
|
|
|
|
308
|
return ${*$self}{exp_Exit}; |
|
|
95
|
|
|
|
|
1088
|
|
|
1667
|
|
|
|
|
|
|
} |
|
1668
|
93
|
|
|
|
|
93055514
|
sleep 1; # Keep loop nice. |
|
1669
|
|
|
|
|
|
|
} |
|
1670
|
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
# Send it a term if it isn't dead. |
|
1672
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1673
|
0
|
|
|
|
|
0
|
print STDERR "${*$self}{exp_Pty_Handle} not exiting, sending TERM.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
1674
|
|
|
|
|
|
|
} |
|
1675
|
0
|
|
|
|
|
0
|
kill TERM => ${*$self}{exp_Pid}; |
|
|
0
|
|
|
|
|
0
|
|
|
1676
|
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
# wait 15 more seconds for it to die. |
|
1678
|
0
|
|
|
|
|
0
|
$end_time = time() + 15; |
|
1679
|
0
|
|
|
|
|
0
|
while ( $end_time > time() ) { |
|
1680
|
0
|
|
|
|
|
0
|
my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG ); |
|
|
0
|
|
|
|
|
0
|
|
|
1681
|
0
|
0
|
0
|
|
|
0
|
if ( defined($returned_pid) && $returned_pid ) { |
|
1682
|
0
|
|
|
|
|
0
|
delete $Expect::Spawned_PIDs{$returned_pid}; |
|
1683
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1684
|
|
|
|
|
|
|
printf STDERR ( |
|
1685
|
|
|
|
|
|
|
"Pid %d of %s terminated, Status: 0x%02X\r\n", |
|
1686
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid}, |
|
1687
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
1688
|
|
|
|
|
|
|
); |
|
1689
|
|
|
|
|
|
|
} |
|
1690
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid} = undef; |
|
|
0
|
|
|
|
|
0
|
|
|
1691
|
0
|
|
|
|
|
0
|
${*$self}{exp_Exit} = $?; |
|
|
0
|
|
|
|
|
0
|
|
|
1692
|
0
|
|
|
|
|
0
|
return ${*$self}{exp_Exit}; |
|
|
0
|
|
|
|
|
0
|
|
|
1693
|
|
|
|
|
|
|
} |
|
1694
|
0
|
|
|
|
|
0
|
sleep 1; |
|
1695
|
|
|
|
|
|
|
} |
|
1696
|
0
|
|
|
|
|
0
|
kill KILL => ${*$self}{exp_Pid}; |
|
|
0
|
|
|
|
|
0
|
|
|
1697
|
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
# wait 5 more seconds for it to die. |
|
1699
|
0
|
|
|
|
|
0
|
$end_time = time() + 5; |
|
1700
|
0
|
|
|
|
|
0
|
while ( $end_time > time() ) { |
|
1701
|
0
|
|
|
|
|
0
|
my $returned_pid = waitpid( ${*$self}{exp_Pid}, &WNOHANG ); |
|
|
0
|
|
|
|
|
0
|
|
|
1702
|
0
|
0
|
0
|
|
|
0
|
if ( defined($returned_pid) && $returned_pid ) { |
|
1703
|
0
|
|
|
|
|
0
|
delete $Expect::Spawned_PIDs{$returned_pid}; |
|
1704
|
0
|
0
|
|
|
|
0
|
if ( ${*$self}{exp_Debug} ) { |
|
|
0
|
|
|
|
|
0
|
|
|
1705
|
|
|
|
|
|
|
printf STDERR ( |
|
1706
|
|
|
|
|
|
|
"Pid %d of %s killed, Status: 0x%02X\r\n", |
|
1707
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid}, |
|
1708
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pty_Handle}, $? |
|
|
0
|
|
|
|
|
0
|
|
|
1709
|
|
|
|
|
|
|
); |
|
1710
|
|
|
|
|
|
|
} |
|
1711
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid} = undef; |
|
|
0
|
|
|
|
|
0
|
|
|
1712
|
0
|
|
|
|
|
0
|
${*$self}{exp_Exit} = $?; |
|
|
0
|
|
|
|
|
0
|
|
|
1713
|
0
|
|
|
|
|
0
|
return ${*$self}{exp_Exit}; |
|
|
0
|
|
|
|
|
0
|
|
|
1714
|
|
|
|
|
|
|
} |
|
1715
|
0
|
|
|
|
|
0
|
sleep 1; |
|
1716
|
|
|
|
|
|
|
} |
|
1717
|
0
|
|
|
|
|
0
|
warn "Pid ${*$self}{exp_Pid} of ${*$self}{exp_Pty_Handle} is HUNG.\r\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
1718
|
0
|
|
|
|
|
0
|
${*$self}{exp_Pid} = undef; |
|
|
0
|
|
|
|
|
0
|
|
|
1719
|
|
|
|
|
|
|
|
|
1720
|
0
|
|
|
|
|
0
|
return; |
|
1721
|
|
|
|
|
|
|
} |
|
1722
|
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
# These should not be called externally. |
|
1724
|
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
sub _init_vars { |
|
1726
|
151
|
|
|
151
|
|
780
|
my ($self) = @_; |
|
1727
|
|
|
|
|
|
|
|
|
1728
|
|
|
|
|
|
|
# for every spawned process or filehandle. |
|
1729
|
151
|
50
|
|
|
|
824
|
${*$self}{exp_Log_Stdout} = $Expect::Log_Stdout |
|
|
0
|
|
|
|
|
0
|
|
|
1730
|
|
|
|
|
|
|
if defined($Expect::Log_Stdout); |
|
1731
|
151
|
|
|
|
|
846
|
${*$self}{exp_Log_Group} = $Expect::Log_Group; |
|
|
151
|
|
|
|
|
584
|
|
|
1732
|
151
|
|
|
|
|
380
|
${*$self}{exp_Debug} = $Expect::Debug; |
|
|
151
|
|
|
|
|
740
|
|
|
1733
|
151
|
|
|
|
|
362
|
${*$self}{exp_Exp_Internal} = $Expect::Exp_Internal; |
|
|
151
|
|
|
|
|
429
|
|
|
1734
|
151
|
|
|
|
|
310
|
${*$self}{exp_Manual_Stty} = $Expect::Manual_Stty; |
|
|
151
|
|
|
|
|
737
|
|
|
1735
|
151
|
|
|
|
|
600
|
${*$self}{exp_Stored_Stty} = 'sane'; |
|
|
151
|
|
|
|
|
528
|
|
|
1736
|
151
|
|
|
|
|
306
|
${*$self}{exp_Do_Soft_Close} = $Expect::Do_Soft_Close; |
|
|
151
|
|
|
|
|
400
|
|
|
1737
|
|
|
|
|
|
|
|
|
1738
|
|
|
|
|
|
|
# sysread doesn't like my or local vars. |
|
1739
|
151
|
|
|
|
|
370
|
${*$self}{exp_Pty_Buffer} = ''; |
|
|
151
|
|
|
|
|
609
|
|
|
1740
|
|
|
|
|
|
|
|
|
1741
|
|
|
|
|
|
|
# Initialize accumulator. |
|
1742
|
151
|
|
|
|
|
301
|
${*$self}{exp_Max_Accum} = $Expect::Exp_Max_Accum; |
|
|
151
|
|
|
|
|
488
|
|
|
1743
|
151
|
|
|
|
|
343
|
${*$self}{exp_Accum} = ''; |
|
|
151
|
|
|
|
|
669
|
|
|
1744
|
151
|
|
|
|
|
380
|
${*$self}{exp_NoTransfer} = 0; |
|
|
151
|
|
|
|
|
704
|
|
|
1745
|
|
|
|
|
|
|
|
|
1746
|
|
|
|
|
|
|
# create empty expect_before & after lists |
|
1747
|
151
|
|
|
|
|
376
|
${*$self}{exp_expect_before_list} = []; |
|
|
151
|
|
|
|
|
625
|
|
|
1748
|
151
|
|
|
|
|
320
|
${*$self}{exp_expect_after_list} = []; |
|
|
151
|
|
|
|
|
422
|
|
|
1749
|
|
|
|
|
|
|
|
|
1750
|
151
|
|
|
|
|
401
|
return; |
|
1751
|
|
|
|
|
|
|
} |
|
1752
|
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
sub _make_readable { |
|
1754
|
0
|
|
|
0
|
|
0
|
my ($s) = @_; |
|
1755
|
|
|
|
|
|
|
|
|
1756
|
0
|
0
|
|
|
|
0
|
$s = '' if not defined($s); |
|
1757
|
0
|
|
|
|
|
0
|
study $s; # Speed things up? |
|
1758
|
0
|
|
|
|
|
0
|
$s =~ s/\\/\\\\/g; # So we can tell easily(?) what is a backslash |
|
1759
|
0
|
|
|
|
|
0
|
$s =~ s/\n/\\n/g; |
|
1760
|
0
|
|
|
|
|
0
|
$s =~ s/\r/\\r/g; |
|
1761
|
0
|
|
|
|
|
0
|
$s =~ s/\t/\\t/g; |
|
1762
|
0
|
|
|
|
|
0
|
$s =~ s/\'/\\\'/g; # So we can tell whassa quote and whassa notta quote. |
|
1763
|
0
|
|
|
|
|
0
|
$s =~ s/\"/\\\"/g; |
|
1764
|
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
# Formfeed (does anyone use formfeed?) |
|
1766
|
0
|
|
|
|
|
0
|
$s =~ s/\f/\\f/g; |
|
1767
|
0
|
|
|
|
|
0
|
$s =~ s/\010/\\b/g; |
|
1768
|
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
# escape control chars high/low, but allow ISO 8859-1 chars |
|
1770
|
0
|
|
|
|
|
0
|
$s =~ s/([\000-\037\177-\237\377])/sprintf("\\%03lo",ord($1))/ge; |
|
|
0
|
|
|
|
|
0
|
|
|
1771
|
|
|
|
|
|
|
|
|
1772
|
0
|
|
|
|
|
0
|
return $s; |
|
1773
|
|
|
|
|
|
|
} |
|
1774
|
|
|
|
|
|
|
|
|
1775
|
|
|
|
|
|
|
sub _trim_length { |
|
1776
|
17
|
|
|
17
|
|
2051
|
my ($self, $string, $length) = @_; |
|
1777
|
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
# This is sort of a reverse truncation function |
|
1779
|
|
|
|
|
|
|
# Mostly so we don't have to see the full output when we're using |
|
1780
|
|
|
|
|
|
|
# Also used if Max_Accum gets set to limit the size of the accumulator |
|
1781
|
|
|
|
|
|
|
# for matching functions. |
|
1782
|
|
|
|
|
|
|
# exp_internal |
|
1783
|
|
|
|
|
|
|
|
|
1784
|
17
|
100
|
|
|
|
584
|
croak('No string passed') if not defined $string; |
|
1785
|
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
# If we're not passed a length (_trim_length is being used for debugging |
|
1787
|
|
|
|
|
|
|
# purposes) AND debug >= 3, don't trim. |
|
1788
|
|
|
|
|
|
|
return ($string) |
|
1789
|
|
|
|
|
|
|
if (defined($self) |
|
1790
|
15
|
50
|
66
|
|
|
49
|
and ${*$self}{"exp_Debug"} >= 3 |
|
|
7
|
|
33
|
|
|
53
|
|
|
1791
|
|
|
|
|
|
|
and ( !( defined($length) ) ) ); |
|
1792
|
15
|
100
|
|
|
|
48
|
my $indicate_truncation = ($length ? '' : '...'); |
|
1793
|
15
|
|
100
|
|
|
75
|
$length ||= 1021; |
|
1794
|
15
|
100
|
|
|
|
71
|
return $string if $length >= length $string; |
|
1795
|
|
|
|
|
|
|
|
|
1796
|
|
|
|
|
|
|
# We wouldn't want the accumulator to begin with '...' if max_accum is passed |
|
1797
|
|
|
|
|
|
|
# This is because this funct. gets called internally w/ max_accum |
|
1798
|
|
|
|
|
|
|
# and is also used to print information back to the user. |
|
1799
|
8
|
|
|
|
|
106
|
return $indicate_truncation . substr( $string, ( length($string) - $length ), $length ); |
|
1800
|
|
|
|
|
|
|
} |
|
1801
|
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
sub _print_handles { |
|
1803
|
5472
|
|
|
5472
|
|
15296
|
my ($self, $print_this) = @_; |
|
1804
|
|
|
|
|
|
|
|
|
1805
|
|
|
|
|
|
|
# Given crap from 'self' and the handles self wants to print to, print to |
|
1806
|
|
|
|
|
|
|
# them. these are indicated by the handle's 'group' |
|
1807
|
5472
|
50
|
|
|
|
6884
|
if ( ${*$self}{exp_Log_Group} ) { |
|
|
5472
|
|
|
|
|
12394
|
|
|
1808
|
5472
|
|
|
|
|
6765
|
foreach my $handle ( @{ ${*$self}{exp_Listen_Group} } ) { |
|
|
5472
|
|
|
|
|
6411
|
|
|
|
5472
|
|
|
|
|
17558
|
|
|
1809
|
0
|
0
|
|
|
|
0
|
$print_this = '' unless defined($print_this); |
|
1810
|
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
# Appease perl -w |
|
1812
|
|
|
|
|
|
|
print STDERR "Printed '" |
|
1813
|
|
|
|
|
|
|
. $self->_trim_length( _make_readable($print_this) ) |
|
1814
|
0
|
|
|
|
|
0
|
. "' to ${*$handle}{exp_Pty_Handle} from ${*$self}{exp_Pty_Handle}.\r\n" |
|
|
0
|
|
|
|
|
0
|
|
|
1815
|
0
|
0
|
|
|
|
0
|
if ( ${*$handle}{"exp_Debug"} > 1 ); |
|
|
0
|
|
|
|
|
0
|
|
|
1816
|
0
|
|
|
|
|
0
|
print $handle $print_this; |
|
1817
|
|
|
|
|
|
|
} |
|
1818
|
|
|
|
|
|
|
} |
|
1819
|
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
# If ${*$self}{exp_Pty_Handle} is STDIN this would make it echo. |
|
1821
|
|
|
|
|
|
|
print STDOUT $print_this |
|
1822
|
5472
|
100
|
|
|
|
9089
|
if ${*$self}{"exp_Log_Stdout"}; |
|
|
5472
|
|
|
|
|
71939
|
|
|
1823
|
5472
|
|
|
|
|
19754
|
$self->print_log_file($print_this); |
|
1824
|
5472
|
|
|
|
|
18198
|
$| = 1; # This should not be necessary but autoflush() doesn't always work. |
|
1825
|
|
|
|
|
|
|
|
|
1826
|
5472
|
|
|
|
|
15894
|
return; |
|
1827
|
|
|
|
|
|
|
} |
|
1828
|
|
|
|
|
|
|
|
|
1829
|
|
|
|
|
|
|
sub _get_mode { |
|
1830
|
0
|
|
|
0
|
|
0
|
my ($handle) = @_; |
|
1831
|
|
|
|
|
|
|
|
|
1832
|
0
|
|
|
|
|
0
|
my ($fcntl_flags) = ''; |
|
1833
|
|
|
|
|
|
|
|
|
1834
|
|
|
|
|
|
|
# What mode are we opening with? use fcntl to find out. |
|
1835
|
0
|
|
|
|
|
0
|
$fcntl_flags = fcntl( \*{$handle}, Fcntl::F_GETFL, $fcntl_flags ); |
|
|
0
|
|
|
|
|
0
|
|
|
1836
|
0
|
0
|
|
|
|
0
|
die "fcntl returned undef during exp_init of $handle, $!\r\n" |
|
1837
|
|
|
|
|
|
|
unless defined($fcntl_flags); |
|
1838
|
0
|
0
|
|
|
|
0
|
if ( $fcntl_flags | (Fcntl::O_RDWR) ) { |
|
|
|
0
|
|
|
|
|
|
|
1839
|
0
|
|
|
|
|
0
|
return 'rw'; |
|
1840
|
|
|
|
|
|
|
} elsif ( $fcntl_flags | (Fcntl::O_WRONLY) ) { |
|
1841
|
0
|
|
|
|
|
0
|
return 'w'; |
|
1842
|
|
|
|
|
|
|
} else { |
|
1843
|
|
|
|
|
|
|
|
|
1844
|
|
|
|
|
|
|
# Under Solaris (among others?) O_RDONLY is implemented as 0. so |O_RDONLY would fail. |
|
1845
|
0
|
|
|
|
|
0
|
return 'r'; |
|
1846
|
|
|
|
|
|
|
} |
|
1847
|
|
|
|
|
|
|
} |
|
1848
|
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
sub _undef { |
|
1850
|
0
|
|
|
0
|
|
0
|
return undef; |
|
1851
|
|
|
|
|
|
|
|
|
1852
|
|
|
|
|
|
|
# Seems a little retarded but &CORE::undef fails in interconnect. |
|
1853
|
|
|
|
|
|
|
# This is used for the default escape sequence function. |
|
1854
|
|
|
|
|
|
|
# w/out the leading & it won't compile. |
|
1855
|
|
|
|
|
|
|
} |
|
1856
|
|
|
|
|
|
|
|
|
1857
|
|
|
|
|
|
|
# clean up child processes |
|
1858
|
|
|
|
|
|
|
sub DESTROY { |
|
1859
|
130
|
|
|
130
|
|
234172
|
my ($self) = @_; |
|
1860
|
|
|
|
|
|
|
|
|
1861
|
130
|
|
|
|
|
471
|
my $status = $?; # save this as it gets mangled by the terminating spawned children |
|
1862
|
130
|
50
|
|
|
|
286
|
if ( ${*$self}{exp_Do_Soft_Close} ) { |
|
|
130
|
|
|
|
|
971
|
|
|
1863
|
0
|
|
|
|
|
0
|
$self->soft_close(); |
|
1864
|
|
|
|
|
|
|
} |
|
1865
|
130
|
|
|
|
|
1140
|
$self->hard_close(); |
|
1866
|
130
|
|
|
|
|
429
|
$? = $status; # restore it. otherwise deleting an Expect object may mangle $?, which is unintuitive |
|
1867
|
|
|
|
|
|
|
|
|
1868
|
130
|
|
|
|
|
3304
|
return; |
|
1869
|
|
|
|
|
|
|
} |
|
1870
|
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
1; |
|
1872
|
|
|
|
|
|
|
__END__ |
|
1873
|
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
=head1 NAME |
|
1875
|
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
Expect - automate interactions with command line programs that expose a text terminal interface. |
|
1877
|
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
1879
|
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
use Expect; |
|
1881
|
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
# create an Expect object by spawning another process |
|
1883
|
|
|
|
|
|
|
my $exp = Expect->spawn($command, @params) |
|
1884
|
|
|
|
|
|
|
or die "Cannot spawn $command: $!\n"; |
|
1885
|
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
# or by using an already opened filehandle (e.g. from Net::Telnet) |
|
1887
|
|
|
|
|
|
|
my $exp = Expect->exp_init(\*FILEHANDLE); |
|
1888
|
|
|
|
|
|
|
|
|
1889
|
|
|
|
|
|
|
# if you prefer the OO mindset: |
|
1890
|
|
|
|
|
|
|
my $exp = Expect->new; |
|
1891
|
|
|
|
|
|
|
$exp->raw_pty(1); |
|
1892
|
|
|
|
|
|
|
$exp->spawn($command, @parameters) |
|
1893
|
|
|
|
|
|
|
or die "Cannot spawn $command: $!\n"; |
|
1894
|
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
# send some string there: |
|
1896
|
|
|
|
|
|
|
$exp->send("string\n"); |
|
1897
|
|
|
|
|
|
|
|
|
1898
|
|
|
|
|
|
|
# or, for the filehandle mindset: |
|
1899
|
|
|
|
|
|
|
print $exp "string\n"; |
|
1900
|
|
|
|
|
|
|
|
|
1901
|
|
|
|
|
|
|
# then do some pattern matching with either the simple interface |
|
1902
|
|
|
|
|
|
|
$patidx = $exp->expect($timeout, @match_patterns); |
|
1903
|
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
# or multi-match on several spawned commands with callbacks, |
|
1905
|
|
|
|
|
|
|
# just like the Tcl version |
|
1906
|
|
|
|
|
|
|
$exp->expect($timeout, |
|
1907
|
|
|
|
|
|
|
[ qr/regex1/ => sub { my $exp = shift; |
|
1908
|
|
|
|
|
|
|
$exp->send("response\n"); |
|
1909
|
|
|
|
|
|
|
exp_continue; } ], |
|
1910
|
|
|
|
|
|
|
[ "regexp2" , \&callback, @cbparms ], |
|
1911
|
|
|
|
|
|
|
); |
|
1912
|
|
|
|
|
|
|
|
|
1913
|
|
|
|
|
|
|
# if no longer needed, do a soft_close to nicely shut down the command |
|
1914
|
|
|
|
|
|
|
$exp->soft_close(); |
|
1915
|
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
# or be less patient with |
|
1917
|
|
|
|
|
|
|
$exp->hard_close(); |
|
1918
|
|
|
|
|
|
|
|
|
1919
|
|
|
|
|
|
|
Expect.pm is built to either spawn a process or take an existing filehandle |
|
1920
|
|
|
|
|
|
|
and interact with it such that normally interactive tasks can be done |
|
1921
|
|
|
|
|
|
|
without operator assistance. This concept makes more sense if you are |
|
1922
|
|
|
|
|
|
|
already familiar with the versatile Tcl version of Expect. |
|
1923
|
|
|
|
|
|
|
The public functions that make up Expect.pm are: |
|
1924
|
|
|
|
|
|
|
|
|
1925
|
|
|
|
|
|
|
Expect->new() |
|
1926
|
|
|
|
|
|
|
Expect::interconnect(@objects_to_be_read_from) |
|
1927
|
|
|
|
|
|
|
Expect::test_handles($timeout, @objects_to_test) |
|
1928
|
|
|
|
|
|
|
Expect::version($version_requested | undef); |
|
1929
|
|
|
|
|
|
|
$object->spawn(@command) |
|
1930
|
|
|
|
|
|
|
$object->clear_accum() |
|
1931
|
|
|
|
|
|
|
$object->set_accum($value) |
|
1932
|
|
|
|
|
|
|
$object->debug($debug_level) |
|
1933
|
|
|
|
|
|
|
$object->exp_internal(0 | 1) |
|
1934
|
|
|
|
|
|
|
$object->notransfer(0 | 1) |
|
1935
|
|
|
|
|
|
|
$object->raw_pty(0 | 1) |
|
1936
|
|
|
|
|
|
|
$object->stty(@stty_modes) # See the IO::Stty docs |
|
1937
|
|
|
|
|
|
|
$object->slave() |
|
1938
|
|
|
|
|
|
|
$object->before(); |
|
1939
|
|
|
|
|
|
|
$object->match(); |
|
1940
|
|
|
|
|
|
|
$object->after(); |
|
1941
|
|
|
|
|
|
|
$object->matchlist(); |
|
1942
|
|
|
|
|
|
|
$object->match_number(); |
|
1943
|
|
|
|
|
|
|
$object->error(); |
|
1944
|
|
|
|
|
|
|
$object->command(); |
|
1945
|
|
|
|
|
|
|
$object->exitstatus(); |
|
1946
|
|
|
|
|
|
|
$object->pty_handle(); |
|
1947
|
|
|
|
|
|
|
$object->do_soft_close(); |
|
1948
|
|
|
|
|
|
|
$object->restart_timeout_upon_receive(0 | 1); |
|
1949
|
|
|
|
|
|
|
$object->interact($other_object, $escape_sequence) |
|
1950
|
|
|
|
|
|
|
$object->log_group(0 | 1 | undef) |
|
1951
|
|
|
|
|
|
|
$object->log_user(0 | 1 | undef) |
|
1952
|
|
|
|
|
|
|
$object->log_file("filename" | $filehandle | \&coderef | undef) |
|
1953
|
|
|
|
|
|
|
$object->manual_stty(0 | 1 | undef) |
|
1954
|
|
|
|
|
|
|
$object->match_max($max_buffersize or undef) |
|
1955
|
|
|
|
|
|
|
$object->pid(); |
|
1956
|
|
|
|
|
|
|
$object->send_slow($delay, @strings_to_send) |
|
1957
|
|
|
|
|
|
|
$object->set_group(@listen_group_objects | undef) |
|
1958
|
|
|
|
|
|
|
$object->set_seq($sequence,\&function,\@parameters); |
|
1959
|
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
There are several configurable package variables that affect the behavior of Expect. They are: |
|
1961
|
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
$Expect::Debug; |
|
1963
|
|
|
|
|
|
|
$Expect::Exp_Internal; |
|
1964
|
|
|
|
|
|
|
$Expect::IgnoreEintr; |
|
1965
|
|
|
|
|
|
|
$Expect::Log_Group; |
|
1966
|
|
|
|
|
|
|
$Expect::Log_Stdout; |
|
1967
|
|
|
|
|
|
|
$Expect::Manual_Stty; |
|
1968
|
|
|
|
|
|
|
$Expect::Multiline_Matching; |
|
1969
|
|
|
|
|
|
|
$Expect::Do_Soft_Close; |
|
1970
|
|
|
|
|
|
|
|
|
1971
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
1972
|
|
|
|
|
|
|
|
|
1973
|
|
|
|
|
|
|
See an explanation of L<What is Expect|http://code-maven.com/expect> |
|
1974
|
|
|
|
|
|
|
|
|
1975
|
|
|
|
|
|
|
The Expect module is a successor of Comm.pl and a descendent of Chat.pl. It |
|
1976
|
|
|
|
|
|
|
more closely resembles the Tcl Expect language than its predecessors. It |
|
1977
|
|
|
|
|
|
|
does not contain any of the networking code found in Comm.pl. I suspect this |
|
1978
|
|
|
|
|
|
|
would be obsolete anyway given the advent of IO::Socket and external tools |
|
1979
|
|
|
|
|
|
|
such as netcat. |
|
1980
|
|
|
|
|
|
|
|
|
1981
|
|
|
|
|
|
|
Expect.pm is an attempt to have more of a switch() & case feeling to make |
|
1982
|
|
|
|
|
|
|
decision processing more fluid. Three separate types of debugging have |
|
1983
|
|
|
|
|
|
|
been implemented to make code production easier. |
|
1984
|
|
|
|
|
|
|
|
|
1985
|
|
|
|
|
|
|
It is possible to interconnect multiple file handles (and processes) much |
|
1986
|
|
|
|
|
|
|
like Tcl's Expect. An attempt was made to enable all the features of Tcl's |
|
1987
|
|
|
|
|
|
|
Expect without forcing Tcl on the victim programmer :-) . |
|
1988
|
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
Please, before you consider using Expect, read the FAQs about |
|
1990
|
|
|
|
|
|
|
L</"I want to automate password entry for su/ssh/scp/rsh/..."> and |
|
1991
|
|
|
|
|
|
|
L</"I want to use Expect to automate [anything with a buzzword]..."> |
|
1992
|
|
|
|
|
|
|
|
|
1993
|
|
|
|
|
|
|
|
|
1994
|
|
|
|
|
|
|
=head1 USAGE |
|
1995
|
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
=over 4 |
|
1997
|
|
|
|
|
|
|
|
|
1998
|
|
|
|
|
|
|
=item new |
|
1999
|
|
|
|
|
|
|
|
|
2000
|
|
|
|
|
|
|
Creates a new Expect object, i.e. a pty. You can change parameters on |
|
2001
|
|
|
|
|
|
|
it before actually spawning a command. This is important if you want |
|
2002
|
|
|
|
|
|
|
to modify the terminal settings for the slave. See slave() below. |
|
2003
|
|
|
|
|
|
|
The object returned is actually a reblessed IO::Pty filehandle, so see |
|
2004
|
|
|
|
|
|
|
there for additional methods. |
|
2005
|
|
|
|
|
|
|
|
|
2006
|
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
=item Expect->exp_init(\*FILEHANDLE) I<or> |
|
2008
|
|
|
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
=item Expect->init(\*FILEHANDLE) |
|
2010
|
|
|
|
|
|
|
|
|
2011
|
|
|
|
|
|
|
Initializes $new_handle_object for use with other Expect functions. It must |
|
2012
|
|
|
|
|
|
|
be passed a B<_reference_> to FILEHANDLE if you want it to work properly. |
|
2013
|
|
|
|
|
|
|
IO::File objects are preferable. Returns a reference to the newly created |
|
2014
|
|
|
|
|
|
|
object. |
|
2015
|
|
|
|
|
|
|
|
|
2016
|
|
|
|
|
|
|
You can use only real filehandles, certain tied filehandles |
|
2017
|
|
|
|
|
|
|
(e.g. Net::SSH2) that lack a fileno() will not work. Net::Telnet |
|
2018
|
|
|
|
|
|
|
objects can be used but have been reported to work only for certain |
|
2019
|
|
|
|
|
|
|
hosts. YMMV. |
|
2020
|
|
|
|
|
|
|
|
|
2021
|
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
=item Expect->spawn($command, @parameters) I<or> |
|
2023
|
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
=item $object->spawn($command, @parameters) I<or> |
|
2025
|
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
=item Expect->new($command, @parameters) |
|
2027
|
|
|
|
|
|
|
|
|
2028
|
|
|
|
|
|
|
Forks and execs $command. Returns an Expect object upon success or |
|
2029
|
|
|
|
|
|
|
C<undef> if the fork was unsuccessful or the command could not be |
|
2030
|
|
|
|
|
|
|
found. spawn() passes its parameters unchanged to Perls exec(), so |
|
2031
|
|
|
|
|
|
|
look there for detailed semantics. |
|
2032
|
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
Note that if spawn cannot exec() the given command, the Expect object |
|
2034
|
|
|
|
|
|
|
is still valid and the next expect() will see "Cannot exec", so you |
|
2035
|
|
|
|
|
|
|
can use that for error handling. |
|
2036
|
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
Also note that you cannot reuse an object with an already spawned |
|
2038
|
|
|
|
|
|
|
command, even if that command has exited. Sorry, but you have to |
|
2039
|
|
|
|
|
|
|
allocate a new object... |
|
2040
|
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
=item $object->debug(0 | 1 | 2 | 3 | undef) |
|
2043
|
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
Sets debug level for $object. 1 refers to general debugging |
|
2045
|
|
|
|
|
|
|
information, 2 refers to verbose debugging and 0 refers to no |
|
2046
|
|
|
|
|
|
|
debugging. If you call debug() with no parameters it will return the |
|
2047
|
|
|
|
|
|
|
current debugging level. When the object is created the debugging |
|
2048
|
|
|
|
|
|
|
level will match that $Expect::Debug, normally 0. |
|
2049
|
|
|
|
|
|
|
|
|
2050
|
|
|
|
|
|
|
The '3' setting is new with 1.05, and adds the additional |
|
2051
|
|
|
|
|
|
|
functionality of having the _full_ accumulated buffer printed every |
|
2052
|
|
|
|
|
|
|
time data is read from an Expect object. This was implemented by |
|
2053
|
|
|
|
|
|
|
request. I recommend against using this unless you think you need it |
|
2054
|
|
|
|
|
|
|
as it can create quite a quantity of output under some circumstances.. |
|
2055
|
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
|
|
2057
|
|
|
|
|
|
|
=item $object->exp_internal(1 | 0) |
|
2058
|
|
|
|
|
|
|
|
|
2059
|
|
|
|
|
|
|
Sets/unsets 'exp_internal' debugging. This is similar in nature to its Tcl |
|
2060
|
|
|
|
|
|
|
counterpart. It is extremely valuable when debugging expect() sequences. |
|
2061
|
|
|
|
|
|
|
When the object is created the exp_internal setting will match the value of |
|
2062
|
|
|
|
|
|
|
$Expect::Exp_Internal, normally 0. Returns the current setting if called |
|
2063
|
|
|
|
|
|
|
without parameters. It is highly recommended that you make use of the |
|
2064
|
|
|
|
|
|
|
debugging features lest you have angry code. |
|
2065
|
|
|
|
|
|
|
|
|
2066
|
|
|
|
|
|
|
|
|
2067
|
|
|
|
|
|
|
=item $object->raw_pty(1 | 0) |
|
2068
|
|
|
|
|
|
|
|
|
2069
|
|
|
|
|
|
|
Set pty to raw mode before spawning. This disables echoing, CR->LF |
|
2070
|
|
|
|
|
|
|
translation and an ugly hack for broken Solaris TTYs (which send |
|
2071
|
|
|
|
|
|
|
<space><backspace> to slow things down) and thus gives a more |
|
2072
|
|
|
|
|
|
|
pipe-like behaviour (which is important if you want to transfer binary |
|
2073
|
|
|
|
|
|
|
content). Note that this must be set I<before> spawning the program. |
|
2074
|
|
|
|
|
|
|
|
|
2075
|
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
=item $object->stty(qw(mode1 mode2...)) |
|
2077
|
|
|
|
|
|
|
|
|
2078
|
|
|
|
|
|
|
Sets the tty mode for $object's associated terminal to the given |
|
2079
|
|
|
|
|
|
|
modes. Note that on many systems the master side of the pty is not a |
|
2080
|
|
|
|
|
|
|
tty, so you have to modify the slave pty instead, see next item. This |
|
2081
|
|
|
|
|
|
|
needs IO::Stty installed, which is no longer required. |
|
2082
|
|
|
|
|
|
|
|
|
2083
|
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
=item $object->slave() |
|
2085
|
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
Returns a filehandle to the slave part of the pty. Very useful in modifying |
|
2087
|
|
|
|
|
|
|
the terminal settings: |
|
2088
|
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
$object->slave->stty(qw(raw -echo)); |
|
2090
|
|
|
|
|
|
|
|
|
2091
|
|
|
|
|
|
|
Typical values are 'sane', 'raw', and 'raw -echo'. Note that I |
|
2092
|
|
|
|
|
|
|
recommend setting the terminal to 'raw' or 'raw -echo', as this avoids |
|
2093
|
|
|
|
|
|
|
a lot of hassle and gives pipe-like (i.e. transparent) behaviour |
|
2094
|
|
|
|
|
|
|
(without the buffering issue). |
|
2095
|
|
|
|
|
|
|
|
|
2096
|
|
|
|
|
|
|
|
|
2097
|
|
|
|
|
|
|
=item $object->print(@strings) I<or> |
|
2098
|
|
|
|
|
|
|
|
|
2099
|
|
|
|
|
|
|
=item $object->send(@strings) |
|
2100
|
|
|
|
|
|
|
|
|
2101
|
|
|
|
|
|
|
Sends the given strings to the spawned command. Note that the strings |
|
2102
|
|
|
|
|
|
|
are not logged in the logfile (see print_log_file) but will probably |
|
2103
|
|
|
|
|
|
|
be echoed back by the pty, depending on pty settings (default is echo) |
|
2104
|
|
|
|
|
|
|
and thus end up there anyway. This must also be taken into account |
|
2105
|
|
|
|
|
|
|
when expect()ing for an answer: the next string will be the command |
|
2106
|
|
|
|
|
|
|
just sent. I suggest setting the pty to raw, which disables echo and |
|
2107
|
|
|
|
|
|
|
makes the pty transparently act like a bidirectional pipe. |
|
2108
|
|
|
|
|
|
|
|
|
2109
|
|
|
|
|
|
|
|
|
2110
|
|
|
|
|
|
|
=item $object->expect($timeout, @match_patterns) |
|
2111
|
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
=over 4 |
|
2113
|
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
=item Simple interface |
|
2115
|
|
|
|
|
|
|
|
|
2116
|
|
|
|
|
|
|
Given $timeout in seconds Expect will wait for $object's handle to produce |
|
2117
|
|
|
|
|
|
|
one of the match_patterns, which are matched exactly by default. If you |
|
2118
|
|
|
|
|
|
|
want a regexp match, use a regexp object (C<qr//>) or prefix the pattern with '-re'. |
|
2119
|
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
$object->expect(15, 'match me exactly', qr/match\s+me\s+exactly/); |
|
2121
|
|
|
|
|
|
|
$object->expect(15, 'match me exactly','-re','match\s+me\s+exactly'); |
|
2122
|
|
|
|
|
|
|
|
|
2123
|
|
|
|
|
|
|
Due to o/s limitations $timeout should be a round number. If $timeout |
|
2124
|
|
|
|
|
|
|
is 0 Expect will check one time to see if $object's handle contains |
|
2125
|
|
|
|
|
|
|
any of the match_patterns. If $timeout is undef Expect |
|
2126
|
|
|
|
|
|
|
will wait forever for a pattern to match. If you don't want to |
|
2127
|
|
|
|
|
|
|
explicitly put the timeout on all calls to C<expect>, you can set |
|
2128
|
|
|
|
|
|
|
it via the C<timeout> method . If the first argument of C<expect> |
|
2129
|
|
|
|
|
|
|
doesn't look like a number, that value will be used. |
|
2130
|
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
$object->timeout(15); |
|
2132
|
|
|
|
|
|
|
$object->expect('match me exactly','-re','match\s+me\s+exactly'); |
|
2133
|
|
|
|
|
|
|
|
|
2134
|
|
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
If called in a scalar context, expect() will return the position of |
|
2136
|
|
|
|
|
|
|
the matched pattern within @matched_patterns, or undef if no pattern was |
|
2137
|
|
|
|
|
|
|
matched. This is a position starting from 1, so if you want to know |
|
2138
|
|
|
|
|
|
|
which of an array of @matched_patterns matched you should subtract one |
|
2139
|
|
|
|
|
|
|
from the return value. |
|
2140
|
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
If called in an array context expect() will return |
|
2142
|
|
|
|
|
|
|
($matched_pattern_position, $error, $successfully_matching_string, |
|
2143
|
|
|
|
|
|
|
$before_match, and $after_match). |
|
2144
|
|
|
|
|
|
|
|
|
2145
|
|
|
|
|
|
|
C<$matched_pattern_position> will contain the value that would have been |
|
2146
|
|
|
|
|
|
|
returned if expect() had been called in a scalar context. |
|
2147
|
|
|
|
|
|
|
|
|
2148
|
|
|
|
|
|
|
C<$error> is |
|
2149
|
|
|
|
|
|
|
the error that occurred that caused expect() to return. $error will |
|
2150
|
|
|
|
|
|
|
contain a number followed by a string equivalent expressing the nature |
|
2151
|
|
|
|
|
|
|
of the error. Possible values are undef, indicating no error, |
|
2152
|
|
|
|
|
|
|
'1:TIMEOUT' indicating that $timeout seconds had elapsed without a |
|
2153
|
|
|
|
|
|
|
match, '2:EOF' indicating an eof was read from $object, '3: spawn |
|
2154
|
|
|
|
|
|
|
id($fileno) died' indicating that the process exited before matching |
|
2155
|
|
|
|
|
|
|
and '4:$!' indicating whatever error was set in $ERRNO during the last |
|
2156
|
|
|
|
|
|
|
read on $object's handle or during select(). All handles indicated by |
|
2157
|
|
|
|
|
|
|
set_group plus STDOUT will have all data to come out of $object |
|
2158
|
|
|
|
|
|
|
printed to them during expect() if log_group and log_stdout are set. |
|
2159
|
|
|
|
|
|
|
|
|
2160
|
|
|
|
|
|
|
C<$successfully_matching_string> |
|
2161
|
|
|
|
|
|
|
C<$before_match> |
|
2162
|
|
|
|
|
|
|
C<$after_match> |
|
2163
|
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
Changed from older versions is the regular expression handling. By |
|
2165
|
|
|
|
|
|
|
default now all strings passed to expect() are treated as literals. To |
|
2166
|
|
|
|
|
|
|
match a regular expression pass '-re' as a parameter in front of the |
|
2167
|
|
|
|
|
|
|
pattern you want to match as a regexp. |
|
2168
|
|
|
|
|
|
|
|
|
2169
|
|
|
|
|
|
|
This change makes it possible to match literals and regular expressions |
|
2170
|
|
|
|
|
|
|
in the same expect() call. |
|
2171
|
|
|
|
|
|
|
|
|
2172
|
|
|
|
|
|
|
Also new is multiline matching. ^ will now match the beginning of |
|
2173
|
|
|
|
|
|
|
lines. Unfortunately, because perl doesn't use $/ in determining where |
|
2174
|
|
|
|
|
|
|
lines break using $ to find the end of a line frequently doesn't work. This |
|
2175
|
|
|
|
|
|
|
is because your terminal is returning "\r\n" at the end of every line. One |
|
2176
|
|
|
|
|
|
|
way to check for a pattern at the end of a line would be to use \r?$ instead |
|
2177
|
|
|
|
|
|
|
of $. |
|
2178
|
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
Example: Spawning telnet to a host, you might look for the escape |
|
2180
|
|
|
|
|
|
|
character. telnet would return to you "\r\nEscape character is |
|
2181
|
|
|
|
|
|
|
'^]'.\r\n". To find this you might use $match='^Escape char.*\.\r?$'; |
|
2182
|
|
|
|
|
|
|
|
|
2183
|
|
|
|
|
|
|
$telnet->expect(10,'-re',$match); |
|
2184
|
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
=item New more Tcl/Expect-like interface |
|
2186
|
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
expect($timeout, |
|
2188
|
|
|
|
|
|
|
'-i', [ $obj1, $obj2, ... ], |
|
2189
|
|
|
|
|
|
|
[ $re_pattern, sub { ...; exp_continue; }, @subparms, ], |
|
2190
|
|
|
|
|
|
|
[ 'eof', sub { ... } ], |
|
2191
|
|
|
|
|
|
|
[ 'timeout', sub { ... }, \$subparm1 ], |
|
2192
|
|
|
|
|
|
|
'-i', [ $objn, ...], |
|
2193
|
|
|
|
|
|
|
'-ex', $exact_pattern, sub { ... }, |
|
2194
|
|
|
|
|
|
|
$exact_pattern, sub { ...; exp_continue_timeout; }, |
|
2195
|
|
|
|
|
|
|
'-re', $re_pattern, sub { ... }, |
|
2196
|
|
|
|
|
|
|
'-i', \@object_list, @pattern_list, |
|
2197
|
|
|
|
|
|
|
...); |
|
2198
|
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
|
|
2200
|
|
|
|
|
|
|
It's now possible to expect on more than one connection at a time by |
|
2201
|
|
|
|
|
|
|
specifying 'C<-i>' and a single Expect object or a ref to an array |
|
2202
|
|
|
|
|
|
|
containing Expect objects, e.g. |
|
2203
|
|
|
|
|
|
|
|
|
2204
|
|
|
|
|
|
|
expect($timeout, |
|
2205
|
|
|
|
|
|
|
'-i', $exp1, @patterns_1, |
|
2206
|
|
|
|
|
|
|
'-i', [ $exp2, $exp3 ], @patterns_2_3, |
|
2207
|
|
|
|
|
|
|
) |
|
2208
|
|
|
|
|
|
|
|
|
2209
|
|
|
|
|
|
|
Furthermore, patterns can now be specified as array refs containing |
|
2210
|
|
|
|
|
|
|
[$regexp, sub { ...}, @optional_subprams] . When the pattern matches, |
|
2211
|
|
|
|
|
|
|
the subroutine is called with parameters ($matched_expect_obj, |
|
2212
|
|
|
|
|
|
|
@optional_subparms). The subroutine can return the symbol |
|
2213
|
|
|
|
|
|
|
`exp_continue' to continue the expect matching with timeout starting |
|
2214
|
|
|
|
|
|
|
anew or return the symbol `exp_continue_timeout' for continuing expect |
|
2215
|
|
|
|
|
|
|
without resetting the timeout count. |
|
2216
|
|
|
|
|
|
|
|
|
2217
|
|
|
|
|
|
|
$exp->expect($timeout, |
|
2218
|
|
|
|
|
|
|
[ qr/username: /i, sub { my $self = shift; |
|
2219
|
|
|
|
|
|
|
$self->send("$username\n"); |
|
2220
|
|
|
|
|
|
|
exp_continue; }], |
|
2221
|
|
|
|
|
|
|
[ qr/password: /i, sub { my $self = shift; |
|
2222
|
|
|
|
|
|
|
$self->send("$password\n"); |
|
2223
|
|
|
|
|
|
|
exp_continue; }], |
|
2224
|
|
|
|
|
|
|
$shell_prompt); |
|
2225
|
|
|
|
|
|
|
|
|
2226
|
|
|
|
|
|
|
|
|
2227
|
|
|
|
|
|
|
`expect' is now exported by default. |
|
2228
|
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
=back |
|
2230
|
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
=item $object->exp_before() I<or> |
|
2232
|
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
=item $object->before() |
|
2234
|
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
before() returns the 'before' part of the last expect() call. If the last |
|
2236
|
|
|
|
|
|
|
expect() call didn't match anything, exp_before() will return the entire |
|
2237
|
|
|
|
|
|
|
output of the object accumulated before the expect() call finished. |
|
2238
|
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
Note that this is something different than Tcl Expects before()!! |
|
2240
|
|
|
|
|
|
|
|
|
2241
|
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
=item $object->exp_after() I<or> |
|
2243
|
|
|
|
|
|
|
|
|
2244
|
|
|
|
|
|
|
=item $object->after() |
|
2245
|
|
|
|
|
|
|
|
|
2246
|
|
|
|
|
|
|
returns the 'after' part of the last expect() call. If the last |
|
2247
|
|
|
|
|
|
|
expect() call didn't match anything, exp_after() will return undef(). |
|
2248
|
|
|
|
|
|
|
|
|
2249
|
|
|
|
|
|
|
|
|
2250
|
|
|
|
|
|
|
=item $object->exp_match() I<or> |
|
2251
|
|
|
|
|
|
|
|
|
2252
|
|
|
|
|
|
|
=item $object->match() |
|
2253
|
|
|
|
|
|
|
|
|
2254
|
|
|
|
|
|
|
returns the string matched by the last expect() call, undef if |
|
2255
|
|
|
|
|
|
|
no string was matched. |
|
2256
|
|
|
|
|
|
|
|
|
2257
|
|
|
|
|
|
|
|
|
2258
|
|
|
|
|
|
|
=item $object->exp_match_number() I<or> |
|
2259
|
|
|
|
|
|
|
|
|
2260
|
|
|
|
|
|
|
=item $object->match_number() |
|
2261
|
|
|
|
|
|
|
|
|
2262
|
|
|
|
|
|
|
exp_match_number() returns the number of the pattern matched by the last |
|
2263
|
|
|
|
|
|
|
expect() call. Keep in mind that the first pattern in a list of patterns is 1, |
|
2264
|
|
|
|
|
|
|
not 0. Returns undef if no pattern was matched. |
|
2265
|
|
|
|
|
|
|
|
|
2266
|
|
|
|
|
|
|
|
|
2267
|
|
|
|
|
|
|
=item $object->exp_matchlist() I<or> |
|
2268
|
|
|
|
|
|
|
|
|
2269
|
|
|
|
|
|
|
=item $object->matchlist() |
|
2270
|
|
|
|
|
|
|
|
|
2271
|
|
|
|
|
|
|
exp_matchlist() returns a list of matched substrings from the brackets |
|
2272
|
|
|
|
|
|
|
() inside the regexp that last matched. ($object->matchlist)[0] |
|
2273
|
|
|
|
|
|
|
thus corresponds to $1, ($object->matchlist)[1] to $2, etc. |
|
2274
|
|
|
|
|
|
|
|
|
2275
|
|
|
|
|
|
|
|
|
2276
|
|
|
|
|
|
|
=item $object->exp_error() I<or> |
|
2277
|
|
|
|
|
|
|
|
|
2278
|
|
|
|
|
|
|
=item $object->error() |
|
2279
|
|
|
|
|
|
|
|
|
2280
|
|
|
|
|
|
|
exp_error() returns the error generated by the last expect() call if |
|
2281
|
|
|
|
|
|
|
no pattern was matched. It is typically useful to examine the value returned by |
|
2282
|
|
|
|
|
|
|
before() to find out what the output of the object was in determining |
|
2283
|
|
|
|
|
|
|
why it didn't match any of the patterns. |
|
2284
|
|
|
|
|
|
|
|
|
2285
|
|
|
|
|
|
|
|
|
2286
|
|
|
|
|
|
|
=item $object->clear_accum() |
|
2287
|
|
|
|
|
|
|
|
|
2288
|
|
|
|
|
|
|
Clear the contents of the accumulator for $object. This gets rid of |
|
2289
|
|
|
|
|
|
|
any residual contents of a handle after expect() or send_slow() such |
|
2290
|
|
|
|
|
|
|
that the next expect() call will only see new data from $object. The |
|
2291
|
|
|
|
|
|
|
contents of the accumulator are returned. |
|
2292
|
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
|
|
2294
|
|
|
|
|
|
|
=item $object->set_accum($value) |
|
2295
|
|
|
|
|
|
|
|
|
2296
|
|
|
|
|
|
|
Sets the content of the accumulator for $object to $value. The |
|
2297
|
|
|
|
|
|
|
previous content of the accumulator is returned. |
|
2298
|
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
|
|
2300
|
|
|
|
|
|
|
=item $object->exp_command() I<or> |
|
2301
|
|
|
|
|
|
|
|
|
2302
|
|
|
|
|
|
|
=item $object->command() |
|
2303
|
|
|
|
|
|
|
|
|
2304
|
|
|
|
|
|
|
exp_command() returns the string that was used to spawn the command. Helpful |
|
2305
|
|
|
|
|
|
|
for debugging and for reused patternmatch subroutines. |
|
2306
|
|
|
|
|
|
|
|
|
2307
|
|
|
|
|
|
|
|
|
2308
|
|
|
|
|
|
|
=item $object->exp_exitstatus() I<or> |
|
2309
|
|
|
|
|
|
|
|
|
2310
|
|
|
|
|
|
|
=item $object->exitstatus() |
|
2311
|
|
|
|
|
|
|
|
|
2312
|
|
|
|
|
|
|
Returns the exit status of $object (if it already exited). |
|
2313
|
|
|
|
|
|
|
|
|
2314
|
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
=item $object->exp_pty_handle() I<or> |
|
2316
|
|
|
|
|
|
|
|
|
2317
|
|
|
|
|
|
|
=item $object->pty_handle() |
|
2318
|
|
|
|
|
|
|
|
|
2319
|
|
|
|
|
|
|
Returns a string representation of the attached pty, for example: |
|
2320
|
|
|
|
|
|
|
`spawn id(5)' (pty has fileno 5), `handle id(7)' (pty was initialized |
|
2321
|
|
|
|
|
|
|
from fileno 7) or `STDIN'. Useful for debugging. |
|
2322
|
|
|
|
|
|
|
|
|
2323
|
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
=item $object->restart_timeout_upon_receive(0 | 1) |
|
2325
|
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
If this is set to 1, the expect timeout is retriggered whenever something |
|
2327
|
|
|
|
|
|
|
is received from the spawned command. This allows to perform some |
|
2328
|
|
|
|
|
|
|
aliveness testing and still expect for patterns. |
|
2329
|
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
$exp->restart_timeout_upon_receive(1); |
|
2331
|
|
|
|
|
|
|
$exp->expect($timeout, |
|
2332
|
|
|
|
|
|
|
[ timeout => \&report_timeout ], |
|
2333
|
|
|
|
|
|
|
[ qr/pattern/ => \&handle_pattern], |
|
2334
|
|
|
|
|
|
|
); |
|
2335
|
|
|
|
|
|
|
|
|
2336
|
|
|
|
|
|
|
Now the timeout isn't triggered if the command produces any kind of output, |
|
2337
|
|
|
|
|
|
|
i.e. is still alive, but you can act upon patterns in the output. |
|
2338
|
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
|
|
2340
|
|
|
|
|
|
|
=item $object->notransfer(1 | 0) |
|
2341
|
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
Do not truncate the content of the accumulator after a match. |
|
2343
|
|
|
|
|
|
|
Normally, the accumulator is set to the remains that come after the |
|
2344
|
|
|
|
|
|
|
matched string. Note that this setting is per object and not per |
|
2345
|
|
|
|
|
|
|
pattern, so if you want to have normal acting patterns that truncate |
|
2346
|
|
|
|
|
|
|
the accumulator, you have to add a |
|
2347
|
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
$exp->set_accum($exp->after); |
|
2349
|
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
to their callback, e.g. |
|
2351
|
|
|
|
|
|
|
|
|
2352
|
|
|
|
|
|
|
$exp->notransfer(1); |
|
2353
|
|
|
|
|
|
|
$exp->expect($timeout, |
|
2354
|
|
|
|
|
|
|
# accumulator not truncated, pattern1 will match again |
|
2355
|
|
|
|
|
|
|
[ "pattern1" => sub { my $self = shift; |
|
2356
|
|
|
|
|
|
|
... |
|
2357
|
|
|
|
|
|
|
} ], |
|
2358
|
|
|
|
|
|
|
# accumulator truncated, pattern2 will not match again |
|
2359
|
|
|
|
|
|
|
[ "pattern2" => sub { my $self = shift; |
|
2360
|
|
|
|
|
|
|
... |
|
2361
|
|
|
|
|
|
|
$self->set_accum($self->after()); |
|
2362
|
|
|
|
|
|
|
} ], |
|
2363
|
|
|
|
|
|
|
); |
|
2364
|
|
|
|
|
|
|
|
|
2365
|
|
|
|
|
|
|
This is only a temporary fix until I can rewrite the pattern matching |
|
2366
|
|
|
|
|
|
|
part so it can take that additional -notransfer argument. |
|
2367
|
|
|
|
|
|
|
|
|
2368
|
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
=item Expect::interconnect(@objects); |
|
2370
|
|
|
|
|
|
|
|
|
2371
|
|
|
|
|
|
|
Read from @objects and print to their @listen_groups until an escape sequence |
|
2372
|
|
|
|
|
|
|
is matched from one of @objects and the associated function returns 0 or undef. |
|
2373
|
|
|
|
|
|
|
The special escape sequence 'EOF' is matched when an object's handle returns |
|
2374
|
|
|
|
|
|
|
an end of file. Note that it is not necessary to include objects that only |
|
2375
|
|
|
|
|
|
|
accept data in @objects since the escape sequence is _read_ from an object. |
|
2376
|
|
|
|
|
|
|
Further note that the listen_group for a write-only object is always empty. |
|
2377
|
|
|
|
|
|
|
Why would you want to have objects listening to STDOUT (for example)? |
|
2378
|
|
|
|
|
|
|
By default every member of @objects _as well as every member of its listen |
|
2379
|
|
|
|
|
|
|
group_ will be set to 'raw -echo' for the duration of interconnection. |
|
2380
|
|
|
|
|
|
|
Setting $object->manual_stty() will stop this behavior per object. |
|
2381
|
|
|
|
|
|
|
The original tty settings will be restored as interconnect exits. |
|
2382
|
|
|
|
|
|
|
|
|
2383
|
|
|
|
|
|
|
For a generic way to interconnect processes, take a look at L<IPC::Run>. |
|
2384
|
|
|
|
|
|
|
|
|
2385
|
|
|
|
|
|
|
|
|
2386
|
|
|
|
|
|
|
=item Expect::test_handles(@objects) |
|
2387
|
|
|
|
|
|
|
|
|
2388
|
|
|
|
|
|
|
Given a set of objects determines which objects' handles have data ready |
|
2389
|
|
|
|
|
|
|
to be read. B<Returns an array> who's members are positions in @objects that |
|
2390
|
|
|
|
|
|
|
have ready handles. Returns undef if there are no such handles ready. |
|
2391
|
|
|
|
|
|
|
|
|
2392
|
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
=item Expect::version($version_requested or undef); |
|
2394
|
|
|
|
|
|
|
|
|
2395
|
|
|
|
|
|
|
Returns current version of Expect. As of .99 earlier versions are not |
|
2396
|
|
|
|
|
|
|
supported. Too many things were changed to make versioning possible. |
|
2397
|
|
|
|
|
|
|
|
|
2398
|
|
|
|
|
|
|
|
|
2399
|
|
|
|
|
|
|
=item $object->interact( C<\*FILEHANDLE, $escape_sequence>) |
|
2400
|
|
|
|
|
|
|
|
|
2401
|
|
|
|
|
|
|
interact() is essentially a macro for calling interconnect() for |
|
2402
|
|
|
|
|
|
|
connecting 2 processes together. \*FILEHANDLE defaults to \*STDIN and |
|
2403
|
|
|
|
|
|
|
$escape_sequence defaults to undef. Interaction ceases when $escape_sequence |
|
2404
|
|
|
|
|
|
|
is read from B<FILEHANDLE>, not $object. $object's listen group will |
|
2405
|
|
|
|
|
|
|
consist solely of \*FILEHANDLE for the duration of the interaction. |
|
2406
|
|
|
|
|
|
|
\*FILEHANDLE will not be echoed on STDOUT. |
|
2407
|
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
|
|
2409
|
|
|
|
|
|
|
=item $object->log_group(0 | 1 | undef) |
|
2410
|
|
|
|
|
|
|
|
|
2411
|
|
|
|
|
|
|
Set/unset logging of $object to its 'listen group'. If set all objects |
|
2412
|
|
|
|
|
|
|
in the listen group will have output from $object printed to them during |
|
2413
|
|
|
|
|
|
|
$object->expect(), $object->send_slow(), and C<Expect::interconnect($object |
|
2414
|
|
|
|
|
|
|
, ...)>. Default value is on. During creation of $object the setting will |
|
2415
|
|
|
|
|
|
|
match the value of $Expect::Log_Group, normally 1. |
|
2416
|
|
|
|
|
|
|
|
|
2417
|
|
|
|
|
|
|
|
|
2418
|
|
|
|
|
|
|
=item $object->log_user(0 | 1 | undef) I<or> |
|
2419
|
|
|
|
|
|
|
|
|
2420
|
|
|
|
|
|
|
=item $object->log_stdout(0 | 1 | undef) |
|
2421
|
|
|
|
|
|
|
|
|
2422
|
|
|
|
|
|
|
Set/unset logging of object's handle to STDOUT. This corresponds to Tcl's |
|
2423
|
|
|
|
|
|
|
log_user variable. Returns current setting if called without parameters. |
|
2424
|
|
|
|
|
|
|
Default setting is off for initialized handles. When a process object is |
|
2425
|
|
|
|
|
|
|
created (not a filehandle initialized with exp_init) the log_stdout setting |
|
2426
|
|
|
|
|
|
|
will match the value of $Expect::Log_Stdout variable, normally 1. |
|
2427
|
|
|
|
|
|
|
If/when you initialize STDIN it is usually associated with a tty which |
|
2428
|
|
|
|
|
|
|
will by default echo to STDOUT anyway, so be careful or you will have |
|
2429
|
|
|
|
|
|
|
multiple echoes. |
|
2430
|
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
|
|
2432
|
|
|
|
|
|
|
=item $object->log_file("filename" | $filehandle | \&coderef | undef) |
|
2433
|
|
|
|
|
|
|
|
|
2434
|
|
|
|
|
|
|
Log session to a file. All characters send to or received from the |
|
2435
|
|
|
|
|
|
|
spawned process are written to the file. Normally appends to the |
|
2436
|
|
|
|
|
|
|
logfile, but you can pass an additional mode of "w" to truncate the |
|
2437
|
|
|
|
|
|
|
file upon open(): |
|
2438
|
|
|
|
|
|
|
|
|
2439
|
|
|
|
|
|
|
$object->log_file("filename", "w"); |
|
2440
|
|
|
|
|
|
|
|
|
2441
|
|
|
|
|
|
|
Returns the logfilehandle. |
|
2442
|
|
|
|
|
|
|
|
|
2443
|
|
|
|
|
|
|
If called with an undef value, stops logging and closes logfile: |
|
2444
|
|
|
|
|
|
|
|
|
2445
|
|
|
|
|
|
|
$object->log_file(undef); |
|
2446
|
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
If called without argument, returns the logfilehandle: |
|
2448
|
|
|
|
|
|
|
|
|
2449
|
|
|
|
|
|
|
$fh = $object->log_file(); |
|
2450
|
|
|
|
|
|
|
|
|
2451
|
|
|
|
|
|
|
Can be set to a code ref, which will be called instead of printing |
|
2452
|
|
|
|
|
|
|
to the logfile: |
|
2453
|
|
|
|
|
|
|
|
|
2454
|
|
|
|
|
|
|
$object->log_file(\&myloggerfunc); |
|
2455
|
|
|
|
|
|
|
|
|
2456
|
|
|
|
|
|
|
|
|
2457
|
|
|
|
|
|
|
=item $object->print_log_file(@strings) |
|
2458
|
|
|
|
|
|
|
|
|
2459
|
|
|
|
|
|
|
Prints to logfile (if opened) or calls the logfile hook function. |
|
2460
|
|
|
|
|
|
|
This allows the user to add arbitrary text to the logfile. Note that |
|
2461
|
|
|
|
|
|
|
this could also be done as $object->log_file->print() but would only |
|
2462
|
|
|
|
|
|
|
work for log files, not code hooks. |
|
2463
|
|
|
|
|
|
|
|
|
2464
|
|
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
=item $object->set_seq($sequence, \&function, \@function_parameters) |
|
2466
|
|
|
|
|
|
|
|
|
2467
|
|
|
|
|
|
|
During Expect->interconnect() if $sequence is read from $object &function |
|
2468
|
|
|
|
|
|
|
will be executed with parameters @function_parameters. It is B<_highly |
|
2469
|
|
|
|
|
|
|
recommended_> that the escape sequence be a single character since the |
|
2470
|
|
|
|
|
|
|
likelihood is great that the sequence will be broken into to separate reads |
|
2471
|
|
|
|
|
|
|
from the $object's handle, making it impossible to strip $sequence from |
|
2472
|
|
|
|
|
|
|
getting printed to $object's listen group. \&function should be something |
|
2473
|
|
|
|
|
|
|
like 'main::control_w_function' and @function_parameters should be an |
|
2474
|
|
|
|
|
|
|
array defined by the caller, passed by reference to set_seq(). |
|
2475
|
|
|
|
|
|
|
Your function should return a non-zero value if execution of interconnect() |
|
2476
|
|
|
|
|
|
|
is to resume after the function returns, zero or undefined if interconnect() |
|
2477
|
|
|
|
|
|
|
should return after your function returns. |
|
2478
|
|
|
|
|
|
|
The special sequence 'EOF' matches the end of file being reached by $object. |
|
2479
|
|
|
|
|
|
|
See interconnect() for details. |
|
2480
|
|
|
|
|
|
|
|
|
2481
|
|
|
|
|
|
|
|
|
2482
|
|
|
|
|
|
|
=item $object->set_group(@listener_objects) |
|
2483
|
|
|
|
|
|
|
|
|
2484
|
|
|
|
|
|
|
@listener_objects is the list of objects that should have their handles |
|
2485
|
|
|
|
|
|
|
printed to by $object when Expect::interconnect, $object->expect() or |
|
2486
|
|
|
|
|
|
|
$object->send_slow() are called. Calling w/out parameters will return |
|
2487
|
|
|
|
|
|
|
the current list of the listener objects. |
|
2488
|
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
|
|
2490
|
|
|
|
|
|
|
=item $object->manual_stty(0 | 1 | undef) |
|
2491
|
|
|
|
|
|
|
|
|
2492
|
|
|
|
|
|
|
Sets/unsets whether or not Expect should make reasonable guesses as to |
|
2493
|
|
|
|
|
|
|
when and how to set tty parameters for $object. Will match |
|
2494
|
|
|
|
|
|
|
$Expect::Manual_Stty value (normally 0) when $object is created. If called |
|
2495
|
|
|
|
|
|
|
without parameters manual_stty() will return the current manual_stty setting. |
|
2496
|
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
=item $object->match_max($maximum_buffer_length | undef) I<or> |
|
2499
|
|
|
|
|
|
|
|
|
2500
|
|
|
|
|
|
|
=item $object->max_accum($maximum_buffer_length | undef) |
|
2501
|
|
|
|
|
|
|
|
|
2502
|
|
|
|
|
|
|
Set the maximum accumulator size for object. This is useful if you think |
|
2503
|
|
|
|
|
|
|
that the accumulator will grow out of hand during expect() calls. Since |
|
2504
|
|
|
|
|
|
|
the buffer will be matched by every match_pattern it may get slow if the |
|
2505
|
|
|
|
|
|
|
buffer gets too large. Returns current value if called without parameters. |
|
2506
|
|
|
|
|
|
|
Not defined by default. |
|
2507
|
|
|
|
|
|
|
|
|
2508
|
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
=item $object->notransfer(0 | 1) |
|
2510
|
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
If set, matched strings will not be deleted from the accumulator. |
|
2512
|
|
|
|
|
|
|
Returns current value if called without parameters. False by default. |
|
2513
|
|
|
|
|
|
|
|
|
2514
|
|
|
|
|
|
|
|
|
2515
|
|
|
|
|
|
|
=item $object->exp_pid() I<or> |
|
2516
|
|
|
|
|
|
|
|
|
2517
|
|
|
|
|
|
|
=item $object->pid() |
|
2518
|
|
|
|
|
|
|
|
|
2519
|
|
|
|
|
|
|
Return pid of $object, if one exists. Initialized filehandles will not have |
|
2520
|
|
|
|
|
|
|
pids (of course). |
|
2521
|
|
|
|
|
|
|
|
|
2522
|
|
|
|
|
|
|
|
|
2523
|
|
|
|
|
|
|
=item $object->send_slow($delay, @strings); |
|
2524
|
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
print each character from each string of @strings one at a time with $delay |
|
2526
|
|
|
|
|
|
|
seconds before each character. This is handy for devices such as modems |
|
2527
|
|
|
|
|
|
|
that can be annoying if you send them data too fast. After each character |
|
2528
|
|
|
|
|
|
|
$object will be checked to determine whether or not it has any new data ready |
|
2529
|
|
|
|
|
|
|
and if so update the accumulator for future expect() calls and print the |
|
2530
|
|
|
|
|
|
|
output to STDOUT and @listen_group if log_stdout and log_group are |
|
2531
|
|
|
|
|
|
|
appropriately set. |
|
2532
|
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
=back |
|
2534
|
|
|
|
|
|
|
|
|
2535
|
|
|
|
|
|
|
=head2 Configurable Package Variables: |
|
2536
|
|
|
|
|
|
|
|
|
2537
|
|
|
|
|
|
|
=over 4 |
|
2538
|
|
|
|
|
|
|
|
|
2539
|
|
|
|
|
|
|
=item $Expect::Debug |
|
2540
|
|
|
|
|
|
|
|
|
2541
|
|
|
|
|
|
|
Defaults to 0. Newly created objects have a $object->debug() value |
|
2542
|
|
|
|
|
|
|
of $Expect::Debug. See $object->debug(); |
|
2543
|
|
|
|
|
|
|
|
|
2544
|
|
|
|
|
|
|
=item $Expect::Do_Soft_Close |
|
2545
|
|
|
|
|
|
|
|
|
2546
|
|
|
|
|
|
|
Defaults to 0. When destroying objects, soft_close may take up to half |
|
2547
|
|
|
|
|
|
|
a minute to shut everything down. From now on, only hard_close will |
|
2548
|
|
|
|
|
|
|
be called, which is less polite but still gives the process a chance |
|
2549
|
|
|
|
|
|
|
to terminate properly. Set this to '1' for old behaviour. |
|
2550
|
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
=item $Expect::Exp_Internal |
|
2552
|
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
Defaults to 0. Newly created objects have a $object->exp_internal() |
|
2554
|
|
|
|
|
|
|
value of $Expect::Exp_Internal. See $object->exp_internal(). |
|
2555
|
|
|
|
|
|
|
|
|
2556
|
|
|
|
|
|
|
=item $Expect::IgnoreEintr |
|
2557
|
|
|
|
|
|
|
|
|
2558
|
|
|
|
|
|
|
Defaults to 0. If set to 1, when waiting for new data, Expect will |
|
2559
|
|
|
|
|
|
|
ignore EINTR errors and restart the select() call instead. |
|
2560
|
|
|
|
|
|
|
|
|
2561
|
|
|
|
|
|
|
=item $Expect::Log_Group |
|
2562
|
|
|
|
|
|
|
|
|
2563
|
|
|
|
|
|
|
Defaults to 1. Newly created objects have a $object->log_group() |
|
2564
|
|
|
|
|
|
|
value of $Expect::Log_Group. See $object->log_group(). |
|
2565
|
|
|
|
|
|
|
|
|
2566
|
|
|
|
|
|
|
=item $Expect::Log_Stdout |
|
2567
|
|
|
|
|
|
|
|
|
2568
|
|
|
|
|
|
|
Defaults to 1 for spawned commands, 0 for file handles |
|
2569
|
|
|
|
|
|
|
attached with exp_init(). Newly created objects have a |
|
2570
|
|
|
|
|
|
|
$object->log_stdout() value of $Expect::Log_Stdout. See |
|
2571
|
|
|
|
|
|
|
$object->log_stdout(). |
|
2572
|
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
=item $Expect::Manual_Stty |
|
2574
|
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
Defaults to 0. Newly created objects have a $object->manual_stty() |
|
2576
|
|
|
|
|
|
|
value of $Expect::Manual_Stty. See $object->manual_stty(). |
|
2577
|
|
|
|
|
|
|
|
|
2578
|
|
|
|
|
|
|
=item $Expect::Multiline_Matching |
|
2579
|
|
|
|
|
|
|
|
|
2580
|
|
|
|
|
|
|
Defaults to 1. Affects whether or not expect() uses the /m flag for |
|
2581
|
|
|
|
|
|
|
doing regular expression matching. If set to 1 /m is used. |
|
2582
|
|
|
|
|
|
|
|
|
2583
|
|
|
|
|
|
|
This makes a difference when you are trying to match ^ and $. If |
|
2584
|
|
|
|
|
|
|
you have this on you can match lines in the middle of a page of output |
|
2585
|
|
|
|
|
|
|
using ^ and $ instead of it matching the beginning and end of the entire |
|
2586
|
|
|
|
|
|
|
expression. I think this is handy. |
|
2587
|
|
|
|
|
|
|
|
|
2588
|
|
|
|
|
|
|
The $Expect::Multiline_Matching turns on and off Expect's multi-line |
|
2589
|
|
|
|
|
|
|
matching mode. But this only has an effect if you pass in a string, and |
|
2590
|
|
|
|
|
|
|
then use '-re' mode. If you pass in a regular expression value (via |
|
2591
|
|
|
|
|
|
|
qr//), then the qr//'s own flags are preserved irrespective of what it |
|
2592
|
|
|
|
|
|
|
gets interpolated into. There was a bug in Perl 5.8.x where interpolating |
|
2593
|
|
|
|
|
|
|
a regex without /m into a match with /m would incorrectly apply the /m |
|
2594
|
|
|
|
|
|
|
to the inner regex too, but this was fixed in Perl 5.10. The correct |
|
2595
|
|
|
|
|
|
|
behavior, as seen in Perl 5.10, is that if you pass in a regex (via |
|
2596
|
|
|
|
|
|
|
qr//), then $Expect::Multiline_Matching has no effect. |
|
2597
|
|
|
|
|
|
|
So if you pass in a regex, then you must use the qr's flags |
|
2598
|
|
|
|
|
|
|
to control whether it is multiline (which by default it is not, opposite |
|
2599
|
|
|
|
|
|
|
of the default behavior of Expect). |
|
2600
|
|
|
|
|
|
|
|
|
2601
|
|
|
|
|
|
|
=back |
|
2602
|
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
=head1 CONTRIBUTIONS |
|
2604
|
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
Lee Eakin <leakin@japh.itg.ti.com> has ported the kibitz script |
|
2606
|
|
|
|
|
|
|
from Tcl/Expect to Perl/Expect. |
|
2607
|
|
|
|
|
|
|
|
|
2608
|
|
|
|
|
|
|
Jeff Carr <jcarr@linuxmachines.com> provided a simple example of how |
|
2609
|
|
|
|
|
|
|
handle terminal window resize events (transmitted via the WINCH |
|
2610
|
|
|
|
|
|
|
signal) in a ssh session. |
|
2611
|
|
|
|
|
|
|
|
|
2612
|
|
|
|
|
|
|
You can find both scripts in the examples/ subdir. Thanks to both! |
|
2613
|
|
|
|
|
|
|
|
|
2614
|
|
|
|
|
|
|
Historical notes: |
|
2615
|
|
|
|
|
|
|
|
|
2616
|
|
|
|
|
|
|
There are still a few lines of code dating back to the inspirational |
|
2617
|
|
|
|
|
|
|
Comm.pl and Chat.pl modules without which this would not have been possible. |
|
2618
|
|
|
|
|
|
|
Kudos to Eric Arnold <Eric.Arnold@Sun.com> and Randal 'Nuke your NT box with |
|
2619
|
|
|
|
|
|
|
one line of perl code' Schwartz<merlyn@stonehenge.com> for making these |
|
2620
|
|
|
|
|
|
|
available to the perl public. |
|
2621
|
|
|
|
|
|
|
|
|
2622
|
|
|
|
|
|
|
As of .98 I think all the old code is toast. No way could this have been done |
|
2623
|
|
|
|
|
|
|
without it though. Special thanks to Graham Barr for helping make sense of |
|
2624
|
|
|
|
|
|
|
the IO::Handle stuff as well as providing the highly recommended IO::Tty |
|
2625
|
|
|
|
|
|
|
module. |
|
2626
|
|
|
|
|
|
|
|
|
2627
|
|
|
|
|
|
|
|
|
2628
|
|
|
|
|
|
|
=head1 REFERENCES |
|
2629
|
|
|
|
|
|
|
|
|
2630
|
|
|
|
|
|
|
Mark Rogaski <rogaski@att.com> wrote: |
|
2631
|
|
|
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
"I figured that you'd like to know that Expect.pm has been very |
|
2633
|
|
|
|
|
|
|
useful to AT&T Labs over the past couple of years (since I first talked to |
|
2634
|
|
|
|
|
|
|
Austin about design decisions). We use Expect.pm for managing |
|
2635
|
|
|
|
|
|
|
the switches in our network via the telnet interface, and such automation |
|
2636
|
|
|
|
|
|
|
has significantly increased our reliability. So, you can honestly say that |
|
2637
|
|
|
|
|
|
|
one of the largest digital networks in existence (AT&T Frame Relay) uses |
|
2638
|
|
|
|
|
|
|
Expect.pm quite extensively." |
|
2639
|
|
|
|
|
|
|
|
|
2640
|
|
|
|
|
|
|
|
|
2641
|
|
|
|
|
|
|
=head1 FAQ - Frequently Asked Questions |
|
2642
|
|
|
|
|
|
|
|
|
2643
|
|
|
|
|
|
|
This is a growing collection of things that might help. |
|
2644
|
|
|
|
|
|
|
Please send you questions that are not answered here to |
|
2645
|
|
|
|
|
|
|
RGiersig@cpan.org |
|
2646
|
|
|
|
|
|
|
|
|
2647
|
|
|
|
|
|
|
|
|
2648
|
|
|
|
|
|
|
=head2 What systems does Expect run on? |
|
2649
|
|
|
|
|
|
|
|
|
2650
|
|
|
|
|
|
|
Expect itself doesn't have real system dependencies, but the underlying |
|
2651
|
|
|
|
|
|
|
IO::Tty needs pseudoterminals. IO::Stty uses POSIX.pm and Fcntl.pm. |
|
2652
|
|
|
|
|
|
|
|
|
2653
|
|
|
|
|
|
|
I have used it on Solaris, Linux and AIX, others report *BSD and OSF |
|
2654
|
|
|
|
|
|
|
as working. Generally, any modern POSIX Unix should do, but there |
|
2655
|
|
|
|
|
|
|
are exceptions to every rule. Feedback is appreciated. |
|
2656
|
|
|
|
|
|
|
|
|
2657
|
|
|
|
|
|
|
See L<IO::Tty> for a list of verified systems. |
|
2658
|
|
|
|
|
|
|
|
|
2659
|
|
|
|
|
|
|
|
|
2660
|
|
|
|
|
|
|
=head2 Can I use this module with ActivePerl on Windows? |
|
2661
|
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
Up to now, the answer was 'No', but this has changed. |
|
2663
|
|
|
|
|
|
|
|
|
2664
|
|
|
|
|
|
|
You still cannot use ActivePerl, but if you use the Cygwin environment |
|
2665
|
|
|
|
|
|
|
(http://sources.redhat.com), which brings its own perl, and have |
|
2666
|
|
|
|
|
|
|
the latest IO::Tty (v0.05 or later) installed, it should work (feedback |
|
2667
|
|
|
|
|
|
|
appreciated). |
|
2668
|
|
|
|
|
|
|
|
|
2669
|
|
|
|
|
|
|
|
|
2670
|
|
|
|
|
|
|
=head2 The examples in the tutorial don't work! |
|
2671
|
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
The tutorial is hopelessly out of date and needs a serious overhaul. |
|
2673
|
|
|
|
|
|
|
I apologize for this, I have concentrated my efforts mainly on the |
|
2674
|
|
|
|
|
|
|
functionality. Volunteers welcomed. |
|
2675
|
|
|
|
|
|
|
|
|
2676
|
|
|
|
|
|
|
|
|
2677
|
|
|
|
|
|
|
=head2 How can I find out what Expect is doing? |
|
2678
|
|
|
|
|
|
|
|
|
2679
|
|
|
|
|
|
|
If you set |
|
2680
|
|
|
|
|
|
|
|
|
2681
|
|
|
|
|
|
|
$Expect::Exp_Internal = 1; |
|
2682
|
|
|
|
|
|
|
|
|
2683
|
|
|
|
|
|
|
Expect will tell you very verbosely what it is receiving and sending, |
|
2684
|
|
|
|
|
|
|
what matching it is trying and what it found. You can do this on a |
|
2685
|
|
|
|
|
|
|
per-command base with |
|
2686
|
|
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
$exp->exp_internal(1); |
|
2688
|
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
You can also set |
|
2690
|
|
|
|
|
|
|
|
|
2691
|
|
|
|
|
|
|
$Expect::Debug = 1; # or 2, 3 for more verbose output |
|
2692
|
|
|
|
|
|
|
|
|
2693
|
|
|
|
|
|
|
or |
|
2694
|
|
|
|
|
|
|
|
|
2695
|
|
|
|
|
|
|
$exp->debug(1); |
|
2696
|
|
|
|
|
|
|
|
|
2697
|
|
|
|
|
|
|
which gives you even more output. |
|
2698
|
|
|
|
|
|
|
|
|
2699
|
|
|
|
|
|
|
|
|
2700
|
|
|
|
|
|
|
=head2 I am seeing the output of the command I spawned. Can I turn that off? |
|
2701
|
|
|
|
|
|
|
|
|
2702
|
|
|
|
|
|
|
Yes, just set |
|
2703
|
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
$Expect::Log_Stdout = 0; |
|
2705
|
|
|
|
|
|
|
|
|
2706
|
|
|
|
|
|
|
to globally disable it or |
|
2707
|
|
|
|
|
|
|
|
|
2708
|
|
|
|
|
|
|
$exp->log_stdout(0); |
|
2709
|
|
|
|
|
|
|
|
|
2710
|
|
|
|
|
|
|
for just that command. 'log_user' is provided as an alias so |
|
2711
|
|
|
|
|
|
|
Tcl/Expect user get a DWIM experience... :-) |
|
2712
|
|
|
|
|
|
|
|
|
2713
|
|
|
|
|
|
|
|
|
2714
|
|
|
|
|
|
|
=head2 No, I mean that when I send some text to the spawned process, it gets echoed back and I have to deal with it in the next expect. |
|
2715
|
|
|
|
|
|
|
|
|
2716
|
|
|
|
|
|
|
This is caused by the pty, which has probably 'echo' enabled. A |
|
2717
|
|
|
|
|
|
|
solution would be to set the pty to raw mode, which in general is |
|
2718
|
|
|
|
|
|
|
cleaner for communication between two programs (no more unexpected |
|
2719
|
|
|
|
|
|
|
character translations). Unfortunately this would break a lot of old |
|
2720
|
|
|
|
|
|
|
code that sends "\r" to the program instead of "\n" (translating this |
|
2721
|
|
|
|
|
|
|
is also handled by the pty), so I won't add this to Expect just like that. |
|
2722
|
|
|
|
|
|
|
But feel free to experiment with C<$exp-E<gt>raw_pty(1)>. |
|
2723
|
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
|
|
2725
|
|
|
|
|
|
|
=head2 How do I send control characters to a process? |
|
2726
|
|
|
|
|
|
|
|
|
2727
|
|
|
|
|
|
|
A: You can send any characters to a process with the print command. To |
|
2728
|
|
|
|
|
|
|
represent a control character in Perl, use \c followed by the letter. For |
|
2729
|
|
|
|
|
|
|
example, control-G can be represented with "\cG" . Note that this will not |
|
2730
|
|
|
|
|
|
|
work if you single-quote your string. So, to send control-C to a process in |
|
2731
|
|
|
|
|
|
|
$exp, do: |
|
2732
|
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
print $exp "\cC"; |
|
2734
|
|
|
|
|
|
|
|
|
2735
|
|
|
|
|
|
|
Or, if you prefer: |
|
2736
|
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
$exp->send("\cC"); |
|
2738
|
|
|
|
|
|
|
|
|
2739
|
|
|
|
|
|
|
The ability to include control characters in a string like this is provided |
|
2740
|
|
|
|
|
|
|
by Perl, not by Expect.pm . Trying to learn Expect.pm without a thorough |
|
2741
|
|
|
|
|
|
|
grounding in Perl can be very daunting. We suggest you look into some of |
|
2742
|
|
|
|
|
|
|
the excellent Perl learning material, such as the books _Programming Perl_ |
|
2743
|
|
|
|
|
|
|
and _Learning Perl_ by O'Reilly, as well as the extensive online Perl |
|
2744
|
|
|
|
|
|
|
documentation available through the perldoc command. |
|
2745
|
|
|
|
|
|
|
|
|
2746
|
|
|
|
|
|
|
|
|
2747
|
|
|
|
|
|
|
=head2 My script fails from time to time without any obvious reason. It seems that I am sometimes loosing output from the spawned program. |
|
2748
|
|
|
|
|
|
|
|
|
2749
|
|
|
|
|
|
|
You could be exiting too fast without giving the spawned program |
|
2750
|
|
|
|
|
|
|
enough time to finish. Try adding $exp->soft_close() to terminate the |
|
2751
|
|
|
|
|
|
|
program gracefully or do an expect() for 'eof'. |
|
2752
|
|
|
|
|
|
|
|
|
2753
|
|
|
|
|
|
|
Alternatively, try adding a 'sleep 1' after you spawn() the program. |
|
2754
|
|
|
|
|
|
|
It could be that pty creation on your system is just slow (but this is |
|
2755
|
|
|
|
|
|
|
rather improbable if you are using the latest IO-Tty). |
|
2756
|
|
|
|
|
|
|
|
|
2757
|
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
=head2 I want to automate password entry for su/ssh/scp/rsh/... |
|
2759
|
|
|
|
|
|
|
|
|
2760
|
|
|
|
|
|
|
You shouldn't use Expect for this. Putting passwords, especially |
|
2761
|
|
|
|
|
|
|
root passwords, into scripts in clear text can mean severe security |
|
2762
|
|
|
|
|
|
|
problems. I strongly recommend using other means. For 'su', consider |
|
2763
|
|
|
|
|
|
|
switching to 'sudo', which gives you root access on a per-command and |
|
2764
|
|
|
|
|
|
|
per-user basis without the need to enter passwords. 'ssh'/'scp' can be |
|
2765
|
|
|
|
|
|
|
set up with RSA authentication without passwords. 'rsh' can use |
|
2766
|
|
|
|
|
|
|
the .rhost mechanism, but I'd strongly suggest to switch to 'ssh'; to |
|
2767
|
|
|
|
|
|
|
mention 'rsh' and 'security' in the same sentence makes an oxymoron. |
|
2768
|
|
|
|
|
|
|
|
|
2769
|
|
|
|
|
|
|
It will work for 'telnet', though, and there are valid uses for it, |
|
2770
|
|
|
|
|
|
|
but you still might want to consider using 'ssh', as keeping cleartext |
|
2771
|
|
|
|
|
|
|
passwords around is very insecure. |
|
2772
|
|
|
|
|
|
|
|
|
2773
|
|
|
|
|
|
|
|
|
2774
|
|
|
|
|
|
|
=head2 I want to use Expect to automate [anything with a buzzword]... |
|
2775
|
|
|
|
|
|
|
|
|
2776
|
|
|
|
|
|
|
Are you sure there is no other, easier way? As a rule of thumb, |
|
2777
|
|
|
|
|
|
|
Expect is useful for automating things that expect to talk to a human, |
|
2778
|
|
|
|
|
|
|
where no formal standard applies. For other tasks that do follow a |
|
2779
|
|
|
|
|
|
|
well-defined protocol, there are often better-suited modules that |
|
2780
|
|
|
|
|
|
|
already can handle those protocols. Don't try to do HTTP requests by |
|
2781
|
|
|
|
|
|
|
spawning telnet to port 80, use LWP instead. To automate FTP, take a |
|
2782
|
|
|
|
|
|
|
look at L<Net::FTP> or C<ncftp> (http://www.ncftp.org). You don't use |
|
2783
|
|
|
|
|
|
|
a screwdriver to hammer in your nails either, or do you? |
|
2784
|
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
|
|
2786
|
|
|
|
|
|
|
=head2 Is it possible to use threads with Expect? |
|
2787
|
|
|
|
|
|
|
|
|
2788
|
|
|
|
|
|
|
Basically yes, with one restriction: you must spawn() your programs in |
|
2789
|
|
|
|
|
|
|
the main thread and then pass the Expect objects to the handling |
|
2790
|
|
|
|
|
|
|
threads. The reason is that spawn() uses fork(), and L<perlthrtut>: |
|
2791
|
|
|
|
|
|
|
|
|
2792
|
|
|
|
|
|
|
"Thinking of mixing fork() and threads? Please lie down and wait until the feeling passes." |
|
2793
|
|
|
|
|
|
|
|
|
2794
|
|
|
|
|
|
|
|
|
2795
|
|
|
|
|
|
|
=head2 I want to log the whole session to a file. |
|
2796
|
|
|
|
|
|
|
|
|
2797
|
|
|
|
|
|
|
Use |
|
2798
|
|
|
|
|
|
|
|
|
2799
|
|
|
|
|
|
|
$exp->log_file("filename"); |
|
2800
|
|
|
|
|
|
|
|
|
2801
|
|
|
|
|
|
|
or |
|
2802
|
|
|
|
|
|
|
|
|
2803
|
|
|
|
|
|
|
$exp->log_file($filehandle); |
|
2804
|
|
|
|
|
|
|
|
|
2805
|
|
|
|
|
|
|
or even |
|
2806
|
|
|
|
|
|
|
|
|
2807
|
|
|
|
|
|
|
$exp->log_file(\&log_procedure); |
|
2808
|
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
for maximum flexibility. |
|
2810
|
|
|
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
Note that the logfile is appended to by default, but you can |
|
2812
|
|
|
|
|
|
|
specify an optional mode "w" to truncate the logfile: |
|
2813
|
|
|
|
|
|
|
|
|
2814
|
|
|
|
|
|
|
$exp->log_file("filename", "w"); |
|
2815
|
|
|
|
|
|
|
|
|
2816
|
|
|
|
|
|
|
To stop logging, just call it with a false argument: |
|
2817
|
|
|
|
|
|
|
|
|
2818
|
|
|
|
|
|
|
$exp->log_file(undef); |
|
2819
|
|
|
|
|
|
|
|
|
2820
|
|
|
|
|
|
|
|
|
2821
|
|
|
|
|
|
|
=head2 How can I turn off multi-line matching for my regexps? |
|
2822
|
|
|
|
|
|
|
|
|
2823
|
|
|
|
|
|
|
To globally unset multi-line matching for all regexps: |
|
2824
|
|
|
|
|
|
|
|
|
2825
|
|
|
|
|
|
|
$Expect::Multiline_Matching = 0; |
|
2826
|
|
|
|
|
|
|
|
|
2827
|
|
|
|
|
|
|
You can do that on a per-regexp basis by stating C<(?-m)> inside the regexp |
|
2828
|
|
|
|
|
|
|
(you need perl5.00503 or later for that). |
|
2829
|
|
|
|
|
|
|
|
|
2830
|
|
|
|
|
|
|
|
|
2831
|
|
|
|
|
|
|
=head2 How can I expect on multiple spawned commands? |
|
2832
|
|
|
|
|
|
|
|
|
2833
|
|
|
|
|
|
|
You can use the B<-i> parameter to specify a single object or a list |
|
2834
|
|
|
|
|
|
|
of Expect objects. All following patterns will be evaluated against |
|
2835
|
|
|
|
|
|
|
that list. |
|
2836
|
|
|
|
|
|
|
|
|
2837
|
|
|
|
|
|
|
You can specify B<-i> multiple times to create groups of objects |
|
2838
|
|
|
|
|
|
|
and patterns to match against within the same expect statement. |
|
2839
|
|
|
|
|
|
|
|
|
2840
|
|
|
|
|
|
|
This works just like in Tcl/Expect. |
|
2841
|
|
|
|
|
|
|
|
|
2842
|
|
|
|
|
|
|
See the source example below. |
|
2843
|
|
|
|
|
|
|
|
|
2844
|
|
|
|
|
|
|
|
|
2845
|
|
|
|
|
|
|
=head2 I seem to have problems with ptys! |
|
2846
|
|
|
|
|
|
|
|
|
2847
|
|
|
|
|
|
|
Well, pty handling is really a black magic, as it is extremely system |
|
2848
|
|
|
|
|
|
|
dependent. I have extensively revised IO-Tty, so these problems |
|
2849
|
|
|
|
|
|
|
should be gone. |
|
2850
|
|
|
|
|
|
|
|
|
2851
|
|
|
|
|
|
|
If your system is listed in the "verified" list of IO::Tty, you |
|
2852
|
|
|
|
|
|
|
probably have some non-standard setup, e.g. you compiled your |
|
2853
|
|
|
|
|
|
|
Linux-kernel yourself and disabled ptys. Please ask your friendly |
|
2854
|
|
|
|
|
|
|
sysadmin for help. |
|
2855
|
|
|
|
|
|
|
|
|
2856
|
|
|
|
|
|
|
If your system is not listed, unpack the latest version of IO::Tty, |
|
2857
|
|
|
|
|
|
|
do a 'perl Makefile.PL; make; make test; uname C<-a>' and send me the |
|
2858
|
|
|
|
|
|
|
results and I'll see what I can deduce from that. |
|
2859
|
|
|
|
|
|
|
|
|
2860
|
|
|
|
|
|
|
|
|
2861
|
|
|
|
|
|
|
=head2 I just want to read the output of a process without expect()ing anything. How can I do this? |
|
2862
|
|
|
|
|
|
|
|
|
2863
|
|
|
|
|
|
|
[ Are you sure you need Expect for this? How about qx() or open("prog|")? ] |
|
2864
|
|
|
|
|
|
|
|
|
2865
|
|
|
|
|
|
|
By using expect without any patterns to match. |
|
2866
|
|
|
|
|
|
|
|
|
2867
|
|
|
|
|
|
|
$process->expect(undef); # Forever until EOF |
|
2868
|
|
|
|
|
|
|
$process->expect($timeout); # For a few seconds |
|
2869
|
|
|
|
|
|
|
$process->expect(0); # Is there anything ready on the handle now? |
|
2870
|
|
|
|
|
|
|
|
|
2871
|
|
|
|
|
|
|
|
|
2872
|
|
|
|
|
|
|
=head2 Ok, so now how do I get what was read on the handle? |
|
2873
|
|
|
|
|
|
|
|
|
2874
|
|
|
|
|
|
|
$read = $process->before(); |
|
2875
|
|
|
|
|
|
|
|
|
2876
|
|
|
|
|
|
|
|
|
2877
|
|
|
|
|
|
|
=head2 Where's IO::Pty? |
|
2878
|
|
|
|
|
|
|
|
|
2879
|
|
|
|
|
|
|
Find it on CPAN as IO-Tty, which provides both. |
|
2880
|
|
|
|
|
|
|
|
|
2881
|
|
|
|
|
|
|
|
|
2882
|
|
|
|
|
|
|
=head2 How come when I automate the passwd program to change passwords for me passwd dies before changing the password sometimes/every time? |
|
2883
|
|
|
|
|
|
|
|
|
2884
|
|
|
|
|
|
|
What's happening is you are closing the handle before passwd exits. |
|
2885
|
|
|
|
|
|
|
When you close the handle to a process, it is sent a signal (SIGPIPE?) |
|
2886
|
|
|
|
|
|
|
telling it that STDOUT has gone away. The default behavior for |
|
2887
|
|
|
|
|
|
|
processes is to die in this circumstance. Two ways you can make this |
|
2888
|
|
|
|
|
|
|
not happen are: |
|
2889
|
|
|
|
|
|
|
|
|
2890
|
|
|
|
|
|
|
$process->soft_close(); |
|
2891
|
|
|
|
|
|
|
|
|
2892
|
|
|
|
|
|
|
This will wait 15 seconds for a process to come up with an EOF by |
|
2893
|
|
|
|
|
|
|
itself before killing it. |
|
2894
|
|
|
|
|
|
|
|
|
2895
|
|
|
|
|
|
|
$process->expect(undef); |
|
2896
|
|
|
|
|
|
|
|
|
2897
|
|
|
|
|
|
|
This will wait forever for the process to match an empty set of |
|
2898
|
|
|
|
|
|
|
patterns. It will return when the process hits an EOF. |
|
2899
|
|
|
|
|
|
|
|
|
2900
|
|
|
|
|
|
|
As a rule, you should always expect() the result of your transaction |
|
2901
|
|
|
|
|
|
|
before you continue with processing. |
|
2902
|
|
|
|
|
|
|
|
|
2903
|
|
|
|
|
|
|
|
|
2904
|
|
|
|
|
|
|
=head2 How come when I try to make a logfile with log_file() or set_group() it doesn't print anything after the last time I run expect()? |
|
2905
|
|
|
|
|
|
|
|
|
2906
|
|
|
|
|
|
|
Output is only printed to the logfile/group when Expect reads from the |
|
2907
|
|
|
|
|
|
|
process, during expect(), send_slow() and interconnect(). |
|
2908
|
|
|
|
|
|
|
One way you can force this is to make use of |
|
2909
|
|
|
|
|
|
|
|
|
2910
|
|
|
|
|
|
|
$process->expect(undef); |
|
2911
|
|
|
|
|
|
|
|
|
2912
|
|
|
|
|
|
|
and |
|
2913
|
|
|
|
|
|
|
|
|
2914
|
|
|
|
|
|
|
$process->expect(0); |
|
2915
|
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
which will make expect() run with an empty pattern set forever or just |
|
2917
|
|
|
|
|
|
|
for an instant to capture the output of $process. The output is |
|
2918
|
|
|
|
|
|
|
available in the accumulator, so you can grab it using |
|
2919
|
|
|
|
|
|
|
$process->before(). |
|
2920
|
|
|
|
|
|
|
|
|
2921
|
|
|
|
|
|
|
|
|
2922
|
|
|
|
|
|
|
=head2 I seem to have problems with terminal settings, double echoing, etc. |
|
2923
|
|
|
|
|
|
|
|
|
2924
|
|
|
|
|
|
|
Tty settings are a major pain to keep track of. If you find unexpected |
|
2925
|
|
|
|
|
|
|
behavior such as double-echoing or a frozen session, doublecheck the |
|
2926
|
|
|
|
|
|
|
documentation for default settings. When in doubt, handle them |
|
2927
|
|
|
|
|
|
|
yourself using $exp->stty() and manual_stty() functions. As of .98 |
|
2928
|
|
|
|
|
|
|
you shouldn't have to worry about stty settings getting fouled unless |
|
2929
|
|
|
|
|
|
|
you use interconnect or intentionally change them (like doing -echo to |
|
2930
|
|
|
|
|
|
|
get a password). |
|
2931
|
|
|
|
|
|
|
|
|
2932
|
|
|
|
|
|
|
If you foul up your terminal's tty settings, kill any hung processes |
|
2933
|
|
|
|
|
|
|
and enter 'stty sane' at a shell prompt. This should make your |
|
2934
|
|
|
|
|
|
|
terminal manageable again. |
|
2935
|
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
Note that IO::Tty returns ptys with your systems default setting |
|
2937
|
|
|
|
|
|
|
regarding echoing, CRLF translation etc. and Expect does not change |
|
2938
|
|
|
|
|
|
|
them. I have considered setting the ptys to 'raw' without any |
|
2939
|
|
|
|
|
|
|
translation whatsoever, but this would break a lot of existing things, |
|
2940
|
|
|
|
|
|
|
as '\r' translation would not work anymore. On the other hand, a raw |
|
2941
|
|
|
|
|
|
|
pty works much like a pipe and is more WYGIWYE (what you get is what |
|
2942
|
|
|
|
|
|
|
you expect), so I suggest you set it to 'raw' by yourself: |
|
2943
|
|
|
|
|
|
|
|
|
2944
|
|
|
|
|
|
|
$exp = Expect->new; |
|
2945
|
|
|
|
|
|
|
$exp->raw_pty(1); |
|
2946
|
|
|
|
|
|
|
$exp->spawn(...); |
|
2947
|
|
|
|
|
|
|
|
|
2948
|
|
|
|
|
|
|
To disable echo: |
|
2949
|
|
|
|
|
|
|
|
|
2950
|
|
|
|
|
|
|
$exp->slave->stty(qw(-echo)); |
|
2951
|
|
|
|
|
|
|
|
|
2952
|
|
|
|
|
|
|
|
|
2953
|
|
|
|
|
|
|
=head2 I'm spawning a telnet/ssh session and then let the user interact with it. But screen-oriented applications on the other side don't work properly. |
|
2954
|
|
|
|
|
|
|
|
|
2955
|
|
|
|
|
|
|
You have to set the terminal screen size for that. Luckily, IO::Pty |
|
2956
|
|
|
|
|
|
|
already has a method for that, so modify your code to look like this: |
|
2957
|
|
|
|
|
|
|
|
|
2958
|
|
|
|
|
|
|
my $exp = Expect->new; |
|
2959
|
|
|
|
|
|
|
$exp->slave->clone_winsize_from(\*STDIN); |
|
2960
|
|
|
|
|
|
|
$exp->spawn("telnet somehost); |
|
2961
|
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
Also, some applications need the TERM shell variable set so they know |
|
2963
|
|
|
|
|
|
|
how to move the cursor across the screen. When logging in, the remote |
|
2964
|
|
|
|
|
|
|
shell sends a query (Ctrl-Z I think) and expects the terminal to |
|
2965
|
|
|
|
|
|
|
answer with a string, e.g. 'xterm'. If you really want to go that way |
|
2966
|
|
|
|
|
|
|
(be aware, madness lies at its end), you can handle that and send back |
|
2967
|
|
|
|
|
|
|
the value in $ENV{TERM}. This is only a hand-waving explanation, |
|
2968
|
|
|
|
|
|
|
please figure out the details by yourself. |
|
2969
|
|
|
|
|
|
|
|
|
2970
|
|
|
|
|
|
|
|
|
2971
|
|
|
|
|
|
|
=head2 I set the terminal size as explained above, but if I resize the window, the application does not notice this. |
|
2972
|
|
|
|
|
|
|
|
|
2973
|
|
|
|
|
|
|
You have to catch the signal WINCH ("window size changed"), change the |
|
2974
|
|
|
|
|
|
|
terminal size and propagate the signal to the spawned application: |
|
2975
|
|
|
|
|
|
|
|
|
2976
|
|
|
|
|
|
|
my $exp = Expect->new; |
|
2977
|
|
|
|
|
|
|
$exp->slave->clone_winsize_from(\*STDIN); |
|
2978
|
|
|
|
|
|
|
$exp->spawn("ssh somehost); |
|
2979
|
|
|
|
|
|
|
$SIG{WINCH} = \&winch; |
|
2980
|
|
|
|
|
|
|
|
|
2981
|
|
|
|
|
|
|
sub winch { |
|
2982
|
|
|
|
|
|
|
$exp->slave->clone_winsize_from(\*STDIN); |
|
2983
|
|
|
|
|
|
|
kill WINCH => $exp->pid if $exp->pid; |
|
2984
|
|
|
|
|
|
|
$SIG{WINCH} = \&winch; |
|
2985
|
|
|
|
|
|
|
} |
|
2986
|
|
|
|
|
|
|
|
|
2987
|
|
|
|
|
|
|
$exp->interact(); |
|
2988
|
|
|
|
|
|
|
|
|
2989
|
|
|
|
|
|
|
There is an example file ssh.pl in the examples/ subdir that shows how |
|
2990
|
|
|
|
|
|
|
this works with ssh. Please note that I do strongly object against |
|
2991
|
|
|
|
|
|
|
using Expect to automate ssh login, as there are better way to do that |
|
2992
|
|
|
|
|
|
|
(see L<ssh-keygen>). |
|
2993
|
|
|
|
|
|
|
|
|
2994
|
|
|
|
|
|
|
=head2 I noticed that the test uses a string that resembles, but not exactly matches, a well-known sentence that contains every character. What does that mean? |
|
2995
|
|
|
|
|
|
|
|
|
2996
|
|
|
|
|
|
|
That means you are anal-retentive. :-) [Gotcha there!] |
|
2997
|
|
|
|
|
|
|
|
|
2998
|
|
|
|
|
|
|
|
|
2999
|
|
|
|
|
|
|
=head2 I get a "Could not assign a pty" error when running as a non-root user on an IRIX box? |
|
3000
|
|
|
|
|
|
|
|
|
3001
|
|
|
|
|
|
|
The OS may not be configured to grant additional pty's (pseudo terminals) |
|
3002
|
|
|
|
|
|
|
to non-root users. /usr/sbin/mkpts should be 4755, not 700 for this |
|
3003
|
|
|
|
|
|
|
to work. I don't know about security implications if you do this. |
|
3004
|
|
|
|
|
|
|
|
|
3005
|
|
|
|
|
|
|
|
|
3006
|
|
|
|
|
|
|
=head2 How come I don't notice when the spawned process closes its stdin/out/err?? |
|
3007
|
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
You are probably on one of the systems where the master doesn't get an |
|
3009
|
|
|
|
|
|
|
EOF when the slave closes stdin/out/err. |
|
3010
|
|
|
|
|
|
|
|
|
3011
|
|
|
|
|
|
|
One possible solution is when you spawn a process, follow it with a |
|
3012
|
|
|
|
|
|
|
unique string that would indicate the process is finished. |
|
3013
|
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
$process = Expect->spawn('telnet somehost; echo ____END____'); |
|
3015
|
|
|
|
|
|
|
|
|
3016
|
|
|
|
|
|
|
And then $process->expect($timeout,'____END____','other','patterns'); |
|
3017
|
|
|
|
|
|
|
|
|
3018
|
|
|
|
|
|
|
|
|
3019
|
|
|
|
|
|
|
=head1 Source Examples |
|
3020
|
|
|
|
|
|
|
|
|
3021
|
|
|
|
|
|
|
|
|
3022
|
|
|
|
|
|
|
=head2 How to automate login |
|
3023
|
|
|
|
|
|
|
|
|
3024
|
|
|
|
|
|
|
my $telnet = Net::Telnet->new("remotehost") # see Net::Telnet |
|
3025
|
|
|
|
|
|
|
or die "Cannot telnet to remotehost: $!\n";; |
|
3026
|
|
|
|
|
|
|
my $exp = Expect->exp_init($telnet); |
|
3027
|
|
|
|
|
|
|
|
|
3028
|
|
|
|
|
|
|
# deprecated use of spawned telnet command |
|
3029
|
|
|
|
|
|
|
# my $exp = Expect->spawn("telnet localhost") |
|
3030
|
|
|
|
|
|
|
# or die "Cannot spawn telnet: $!\n";; |
|
3031
|
|
|
|
|
|
|
|
|
3032
|
|
|
|
|
|
|
my $spawn_ok; |
|
3033
|
|
|
|
|
|
|
$exp->expect($timeout, |
|
3034
|
|
|
|
|
|
|
[ |
|
3035
|
|
|
|
|
|
|
qr'login: $', |
|
3036
|
|
|
|
|
|
|
sub { |
|
3037
|
|
|
|
|
|
|
$spawn_ok = 1; |
|
3038
|
|
|
|
|
|
|
my $fh = shift; |
|
3039
|
|
|
|
|
|
|
$fh->send("$username\n"); |
|
3040
|
|
|
|
|
|
|
exp_continue; |
|
3041
|
|
|
|
|
|
|
} |
|
3042
|
|
|
|
|
|
|
], |
|
3043
|
|
|
|
|
|
|
[ |
|
3044
|
|
|
|
|
|
|
'Password: $', |
|
3045
|
|
|
|
|
|
|
sub { |
|
3046
|
|
|
|
|
|
|
my $fh = shift; |
|
3047
|
|
|
|
|
|
|
print $fh "$password\n"; |
|
3048
|
|
|
|
|
|
|
exp_continue; |
|
3049
|
|
|
|
|
|
|
} |
|
3050
|
|
|
|
|
|
|
], |
|
3051
|
|
|
|
|
|
|
[ |
|
3052
|
|
|
|
|
|
|
eof => |
|
3053
|
|
|
|
|
|
|
sub { |
|
3054
|
|
|
|
|
|
|
if ($spawn_ok) { |
|
3055
|
|
|
|
|
|
|
die "ERROR: premature EOF in login.\n"; |
|
3056
|
|
|
|
|
|
|
} else { |
|
3057
|
|
|
|
|
|
|
die "ERROR: could not spawn telnet.\n"; |
|
3058
|
|
|
|
|
|
|
} |
|
3059
|
|
|
|
|
|
|
} |
|
3060
|
|
|
|
|
|
|
], |
|
3061
|
|
|
|
|
|
|
[ |
|
3062
|
|
|
|
|
|
|
timeout => |
|
3063
|
|
|
|
|
|
|
sub { |
|
3064
|
|
|
|
|
|
|
die "No login.\n"; |
|
3065
|
|
|
|
|
|
|
} |
|
3066
|
|
|
|
|
|
|
], |
|
3067
|
|
|
|
|
|
|
'-re', qr'[#>:] $', #' wait for shell prompt, then exit expect |
|
3068
|
|
|
|
|
|
|
); |
|
3069
|
|
|
|
|
|
|
|
|
3070
|
|
|
|
|
|
|
|
|
3071
|
|
|
|
|
|
|
=head2 How to expect on multiple spawned commands |
|
3072
|
|
|
|
|
|
|
|
|
3073
|
|
|
|
|
|
|
foreach my $cmd (@list_of_commands) { |
|
3074
|
|
|
|
|
|
|
push @commands, Expect->spawn($cmd); |
|
3075
|
|
|
|
|
|
|
} |
|
3076
|
|
|
|
|
|
|
|
|
3077
|
|
|
|
|
|
|
expect($timeout, |
|
3078
|
|
|
|
|
|
|
'-i', \@commands, |
|
3079
|
|
|
|
|
|
|
[ |
|
3080
|
|
|
|
|
|
|
qr"pattern", # find this pattern in output of all commands |
|
3081
|
|
|
|
|
|
|
sub { |
|
3082
|
|
|
|
|
|
|
my $obj = shift; # object that matched |
|
3083
|
|
|
|
|
|
|
print $obj "something\n"; |
|
3084
|
|
|
|
|
|
|
exp_continue; # we don't want to terminate the expect call |
|
3085
|
|
|
|
|
|
|
} |
|
3086
|
|
|
|
|
|
|
], |
|
3087
|
|
|
|
|
|
|
'-i', $some_other_command, |
|
3088
|
|
|
|
|
|
|
[ |
|
3089
|
|
|
|
|
|
|
"some other pattern", |
|
3090
|
|
|
|
|
|
|
sub { |
|
3091
|
|
|
|
|
|
|
my ($obj, $parmref) = @_; |
|
3092
|
|
|
|
|
|
|
# ... |
|
3093
|
|
|
|
|
|
|
|
|
3094
|
|
|
|
|
|
|
# now we exit the expect command |
|
3095
|
|
|
|
|
|
|
}, |
|
3096
|
|
|
|
|
|
|
\$parm |
|
3097
|
|
|
|
|
|
|
], |
|
3098
|
|
|
|
|
|
|
); |
|
3099
|
|
|
|
|
|
|
|
|
3100
|
|
|
|
|
|
|
|
|
3101
|
|
|
|
|
|
|
=head2 How to propagate terminal sizes |
|
3102
|
|
|
|
|
|
|
|
|
3103
|
|
|
|
|
|
|
my $exp = Expect->new; |
|
3104
|
|
|
|
|
|
|
$exp->slave->clone_winsize_from(\*STDIN); |
|
3105
|
|
|
|
|
|
|
$exp->spawn("ssh somehost); |
|
3106
|
|
|
|
|
|
|
$SIG{WINCH} = \&winch; |
|
3107
|
|
|
|
|
|
|
|
|
3108
|
|
|
|
|
|
|
sub winch { |
|
3109
|
|
|
|
|
|
|
$exp->slave->clone_winsize_from(\*STDIN); |
|
3110
|
|
|
|
|
|
|
kill WINCH => $exp->pid if $exp->pid; |
|
3111
|
|
|
|
|
|
|
$SIG{WINCH} = \&winch; |
|
3112
|
|
|
|
|
|
|
} |
|
3113
|
|
|
|
|
|
|
|
|
3114
|
|
|
|
|
|
|
$exp->interact(); |
|
3115
|
|
|
|
|
|
|
|
|
3116
|
|
|
|
|
|
|
=head1 HOMEPAGE |
|
3117
|
|
|
|
|
|
|
|
|
3118
|
|
|
|
|
|
|
L<http://sourceforge.net/projects/expectperl/> though the source code is now in GitHub: L<https://github.com/jacoby/expect.pm> |
|
3119
|
|
|
|
|
|
|
|
|
3120
|
|
|
|
|
|
|
|
|
3121
|
|
|
|
|
|
|
=head1 MAILING LISTS |
|
3122
|
|
|
|
|
|
|
|
|
3123
|
|
|
|
|
|
|
There are two mailing lists available, expectperl-announce and |
|
3124
|
|
|
|
|
|
|
expectperl-discuss, at |
|
3125
|
|
|
|
|
|
|
|
|
3126
|
|
|
|
|
|
|
http://lists.sourceforge.net/lists/listinfo/expectperl-announce |
|
3127
|
|
|
|
|
|
|
|
|
3128
|
|
|
|
|
|
|
and |
|
3129
|
|
|
|
|
|
|
|
|
3130
|
|
|
|
|
|
|
http://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
|
3131
|
|
|
|
|
|
|
|
|
3132
|
|
|
|
|
|
|
|
|
3133
|
|
|
|
|
|
|
=head1 BUG TRACKING |
|
3134
|
|
|
|
|
|
|
|
|
3135
|
|
|
|
|
|
|
You can use the CPAN Request Tracker http://rt.cpan.org/ and submit |
|
3136
|
|
|
|
|
|
|
new bugs under |
|
3137
|
|
|
|
|
|
|
|
|
3138
|
|
|
|
|
|
|
http://rt.cpan.org/Ticket/Create.html?Queue=Expect |
|
3139
|
|
|
|
|
|
|
|
|
3140
|
|
|
|
|
|
|
|
|
3141
|
|
|
|
|
|
|
=head1 AUTHORS |
|
3142
|
|
|
|
|
|
|
|
|
3143
|
|
|
|
|
|
|
(c) 1997 Austin Schutz E<lt>F<ASchutz@users.sourceforge.net>E<gt> (retired) |
|
3144
|
|
|
|
|
|
|
|
|
3145
|
|
|
|
|
|
|
expect() interface & functionality enhancements (c) 1999-2006 Roland Giersig. |
|
3146
|
|
|
|
|
|
|
|
|
3147
|
|
|
|
|
|
|
This module is now maintained by Dave Jacoby E<lt>F<jacoby@cpan.org>E<gt> |
|
3148
|
|
|
|
|
|
|
|
|
3149
|
|
|
|
|
|
|
=head1 LICENSE |
|
3150
|
|
|
|
|
|
|
|
|
3151
|
|
|
|
|
|
|
This module can be used under the same terms as Perl. |
|
3152
|
|
|
|
|
|
|
|
|
3153
|
|
|
|
|
|
|
|
|
3154
|
|
|
|
|
|
|
=head1 DISCLAIMER |
|
3155
|
|
|
|
|
|
|
|
|
3156
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
|
3157
|
|
|
|
|
|
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
3158
|
|
|
|
|
|
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
3159
|
|
|
|
|
|
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
3160
|
|
|
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
3161
|
|
|
|
|
|
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|
3162
|
|
|
|
|
|
|
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
3163
|
|
|
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |
|
3164
|
|
|
|
|
|
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
|
3165
|
|
|
|
|
|
|
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
|
3166
|
|
|
|
|
|
|
DAMAGE. |
|
3167
|
|
|
|
|
|
|
|
|
3168
|
|
|
|
|
|
|
In other words: Use at your own risk. Provided as is. Your mileage |
|
3169
|
|
|
|
|
|
|
may vary. Read the source, Luke! |
|
3170
|
|
|
|
|
|
|
|
|
3171
|
|
|
|
|
|
|
And finally, just to be sure: |
|
3172
|
|
|
|
|
|
|
|
|
3173
|
|
|
|
|
|
|
Any Use of This Product, in Any Manner Whatsoever, Will Increase the |
|
3174
|
|
|
|
|
|
|
Amount of Disorder in the Universe. Although No Liability Is Implied |
|
3175
|
|
|
|
|
|
|
Herein, the Consumer Is Warned That This Process Will Ultimately Lead |
|
3176
|
|
|
|
|
|
|
to the Heat Death of the Universe. |
|
3177
|
|
|
|
|
|
|
|
|
3178
|
|
|
|
|
|
|
=cut |