3 package PerlACE
::ProcessVX
;
6 use POSIX
"sys_wait_h";
13 eval { require Net
::Telnet
; };
15 ###############################################################################
21 if (defined $Config{sig_name
}) {
23 foreach my $name (split (' ', $Config{sig_name
})) {
30 for ($i = 0; $i < 255; ++$i) {
35 ###############################################################################
37 # This is what GetExitCode will return if the process is still running.
38 my $STILL_ACTIVE = 259;
40 ###############################################################################
42 ### Constructor and Destructor
47 my $class = ref ($proto) || $proto;
51 $self->{IGNOREEXESUBDIR
} = 1;
52 $self->{IGNOREHOSTROOT
} = 0;
53 $self->{PROCESS
} = undef;
54 $self->{EXECUTABLE
} = shift;
55 $self->{ARGUMENTS
} = shift;
56 $self->{TARGET
} = shift;
57 if (!defined $PerlACE::ProcessVX
::WAIT_DELAY_FACTOR
) {
58 $PerlACE::ProcessVX
::WAIT_DELAY_FACTOR
= 2;
60 if (!defined $PerlACE::ProcessVX
::RebootCmd
) {
61 $PerlACE::ProcessVX
::RebootCmd
= "reboot 0x02";
63 bless ($self, $class);
71 if ($self->{RUNNING
} == 1) {
72 print STDERR
"ERROR: <", $self->{EXECUTABLE
},
73 "> still running upon object destruction\n";
77 if (defined $ENV{'ACE_RUN_VX_IBOOT'} && !defined $ENV{'ACE_RUN_VX_NO_SHUTDOWN'}) {
78 # Shutdown the target to save power
79 $self->iboot_cycle_power(1);
83 ###############################################################################
85 # Spawn the process and continue.
91 if ($self->{RUNNING
} == 1) {
92 print STDERR
"ERROR: Cannot Spawn: <", $self->Executable (),
93 "> already running\n";
97 if (!defined $self->{EXECUTABLE
}) {
98 print STDERR
"ERROR: Cannot Spawn: No executable specified\n";
102 if ($self->{IGNOREEXESUBDIR
} == 0) {
103 if (!-f
$self->Executable ()) {
104 print STDERR
"ERROR: Cannot Spawn: <", $self->Executable (),
114 # Reboot the target if necessery
117 my $program = $self->Executable ();
118 my $cwdrel = dirname
($program);
119 my $prjroot = defined $ENV{'ACE_RUN_VX_PRJ_ROOT'} ?
$ENV{'ACE_RUN_VX_PRJ_ROOT'} : $ENV{'ACE_ROOT'};
120 if (length ($cwdrel) > 0) {
121 $cwdrel = File
::Spec
->abs2rel( cwd
(), $prjroot );
124 $cwdrel = File
::Spec
->abs2rel( $cwdrel, $prjroot );
126 $program = basename
($program, $PerlACE::ProcessVX
::ExeExt
);
132 my $exesubdir = defined $ENV{'ACE_RUN_VX_EXE_SUBDIR'} ?
$ENV{'ACE_RUN_VX_EXE_SUBDIR'} : "";
134 if (defined $ENV{'ACE_RUN_VX_STARTUP_SCRIPT'}) {
135 if (defined $ENV{'ACE_RUN_VX_STARTUP_SCRIPT_ROOT'}) {
136 $cmds[$cmdnr++] = 'cd "' . $ENV{'ACE_RUN_VX_STARTUP_SCRIPT_ROOT'} . '"';
138 $cmds[$cmdnr++] = '< ' . $ENV{'ACE_RUN_VX_STARTUP_SCRIPT'};
141 if (defined $ENV{'ACE_RUN_VX_STARTUP_COMMAND'}) {
142 $cmds[$cmdnr++] = $ENV{'ACE_RUN_VX_STARTUP_COMMAND'};
145 $cmds[$cmdnr++] = 'cd ' . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/" . $cwdrel . "/" . $exesubdir;
146 $cmds[$cmdnr++] = 'set TMPDIR=' . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/" . $cwdrel;
148 if (defined $ENV{'ACE_RUN_ACE_DEBUG'}) {
149 $cmds[$cmdnr++] = 'set ACE_DEBUG=' . $ENV{'ACE_RUN_ACE_DEBUG'};
152 if (defined $ENV{'ACE_RUN_TAO_ORB_DEBUG'}) {
153 $cmds[$cmdnr++] = 'set TAO_ORB_DEBUG=' . $ENV{'ACE_RUN_TAO_ORB_DEBUG'};
156 if (defined $ENV{'ACE_RUN_ACE_LD_SEARCH_PATH'}) {
157 $cmds[$cmdnr++] = 'set ACE_LD_SEARCH_PATH=' . $ENV{'ACE_RUN_ACE_LD_SEARCH_PATH'};
161 my(@unload_commands);
162 my $vxtest_file = $program . '.vxtest';
163 if (handle_vxtest_file
($self, $vxtest_file, \
@load_commands, \
@unload_commands)) {
164 push @cmds, @load_commands;
165 $cmdnr += scalar @load_commands;
167 print STDERR
"ERROR: Cannot find <", $vxtest_file, ">\n";
170 if (defined $self->{ARGUMENTS
}) {
171 ($arguments = $self->{ARGUMENTS
})=~ s/\"/\\\"/g;
172 ($arguments = $self->{ARGUMENTS
})=~ s/\'/\\\'/g;
175 $cmdline = $program . ' ' . $arguments;
176 if (defined $ENV{'ACE_RUN_VX_TGTSRV_WORKINGDIR'}) {
177 $cmds[$cmdnr++] = 'cd ' . $ENV{'ACE_RUN_VX_TGTSRV_WORKINGDIR'};
179 $cmds[$cmdnr++] = 'cd ' . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/" . $cwdrel;
181 $cmds[$cmdnr++] = $cmdline;
182 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
183 push @cmds, @unload_commands;
184 $cmdnr += scalar @unload_commands;
186 $prompt = '[\\\\].*>[\ ]$';
189 if ($self->{PROCESS
} = fork) {
193 elsif (defined $self->{PROCESS
}) {
195 my $telnet_port = $ENV{'ACE_RUN_VX_TGT_TELNET_PORT'};
196 my $telnet_host = $ENV{'ACE_RUN_VX_TGT_TELNET_HOST'};
197 if (!defined $telnet_host) {
198 $telnet_host = $ENV{'ACE_RUN_VX_TGTHOST'};
200 if (!defined $telnet_port) {
203 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
204 print "Opening telnet connection <" . $telnet_host . ":". $telnet_port . ">\n";
206 my $t = new Net
::Telnet
(Timeout
=> 600, Errmode
=> 'return', Host
=> $telnet_host, Port
=> $telnet_port);
208 die "ERROR: Telnet failed to <" . $telnet_host . ":". $telnet_port . ">";
213 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
214 print "Couldn't open telnet connection; sleeping then retrying\n";
217 die "ERROR: Telnet open to <" . $telnet_host . ":". $telnet_port . "> " . $t->errmsg;
225 my $target_login = $ENV{'ACE_RUN_VX_LOGIN'};
226 my $target_password = $ENV{'ACE_RUN_VX_PASSWORD'};
228 if (defined $target_login) {
229 $t->waitfor('/VxWorks login: $/');
230 $t->print("$target_login");
233 if (defined $target_password) {
234 $t->waitfor('/Password: $/');
235 $t->print("$target_password");
239 # wait for the prompt
244 if ($buf =~ /$prompt/) {
248 if ($buf !~ /$prompt/) {
249 die "ERROR: Didn't got prompt but got <$buf>";
254 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
255 print $cmds[$i]."\n";
257 if ($t->print ($cmds[$i++])) {
258 # After each command wait for the prompt
264 if ($buf =~ /$prompt/) {
276 elsif ($! =~ /No more process/) {
277 #EAGAIN, supposedly recoverable fork error
283 print STDERR
"ERROR: Can't fork <" . $cmdline . ">: $!\n";
286 $self->{RUNNING
} = 1;
291 # Terminate the process and wait for it to finish
293 sub TerminateWaitKill
($)
298 if ($self->{RUNNING
}) {
299 print STDERR
"INFO: $self->{EXECUTABLE} being killed.\n";
300 kill ('TERM', $self->{PROCESS
});
302 $PerlACE::ProcessVX
::DoVxInit
= 1; # force reboot on next run
305 return $self->WaitKill ($timeout);
308 # really only for internal use
309 sub check_return_value
($)
314 my $CC_MASK = 0xff00;
316 # Exit code processing
320 elsif ($rc == $CC_MASK) {
321 print STDERR
"ERROR: <", $self->{EXECUTABLE
},
324 $PerlACE::ProcessVX
::DoVxInit
= 1; # force reboot on next run
328 elsif (($rc & 0xff) == 0) {
333 # Remember Core dump flag
341 # check for ABRT, KILL or TERM
342 if ($rc == 6 || $rc == 9 || $rc == 15) {
346 print STDERR
"ERROR: <", $self->{EXECUTABLE
},
349 print STDERR
"coredump from " if ($dump == 1);
351 print STDERR
"signal $rc : ", $signame[$rc], "\n";
353 $PerlACE::ProcessVX
::DoVxInit
= 1; # force reboot on next run
362 if ($self->{RUNNING
} && !defined $ENV{'ACE_TEST_WINDOW'}) {
363 kill ('KILL', $self->{PROCESS
});
364 waitpid ($self->{PROCESS
}, 0);
365 $self->check_return_value ($?
);
368 $self->{RUNNING
} = 0;
371 # Wait until a process exits.
372 # return -1 if the process is still alive.
377 if (!defined $timeout || $timeout < 0) {
378 waitpid ($self->{PROCESS
}, 0);
380 return TimedWait
($self, $timeout);
390 if ($PerlACE::Process
::WAIT_DELAY_FACTOR
> 0) {
391 $timeout *= $PerlACE::Process
::WAIT_DELAY_FACTOR
;
394 while ($timeout-- != 0) {
395 my $pid = waitpid ($self->{PROCESS
}, &WNOHANG
);
396 if ($pid != 0 && $?
!= -1) {
397 return $self->check_return_value ($?
);
402 $PerlACE::ProcessVX
::DoVxInit
= 1; # force reboot on next run
407 sub handle_vxtest_file
410 my $vxtestfile = shift;
412 my $unld_ref = shift;
413 my $fh = new FileHandle
;
415 if (defined $self->{TARGET
} && $self->{TARGET
}->SystemLibs()) {
416 my @tokens = split(/;/, $self->{TARGET
}->SystemLibs());
417 foreach my $token (@tokens) {
418 push @
$vx_ref, "copy " . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/lib/" . $token . " .";
419 unshift @
$unld_ref, "del " . $token;
422 if (!$PerlACE::Static
) {
423 if (open ($fh, $vxtestfile)) {
429 push @
$vx_ref, "copy " . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/lib/$line1" . ".dll .";
430 unshift @
$unld_ref, "del $line1" . ".dll";