Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / bin / PerlACE / ProcessWinCE_Unix.pm
blobaf82496e35201c08bac6c210984180480f9ac1a1
1 #!/usr/bin/env perl
3 package PerlACE::ProcessVX;
5 use strict;
6 use POSIX "sys_wait_h";
7 use File::Basename;
8 use File::Spec;
9 use Config;
10 use FileHandle;
11 use Cwd;
13 eval { require Net::Telnet; };
15 ###############################################################################
17 ### Grab signal names
19 my @signame;
21 if (defined $Config{sig_name}) {
22 my $i = 0;
23 foreach my $name (split (' ', $Config{sig_name})) {
24 $signame[$i] = $name;
25 $i++;
28 else {
29 my $i;
30 for ($i = 0; $i < 255; ++$i) {
31 $signame[$i] = $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
44 sub new
46 my $proto = shift;
47 my $class = ref ($proto) || $proto;
48 my $self = {};
50 $self->{RUNNING} = 0;
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);
64 return $self;
67 sub DESTROY
69 my $self = shift;
71 if ($self->{RUNNING} == 1) {
72 print STDERR "ERROR: <", $self->{EXECUTABLE},
73 "> still running upon object destruction\n";
74 $self->Kill ();
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.
87 sub Spawn ()
89 my $self = shift;
91 if ($self->{RUNNING} == 1) {
92 print STDERR "ERROR: Cannot Spawn: <", $self->Executable (),
93 "> already running\n";
94 return -1;
97 if (!defined $self->{EXECUTABLE}) {
98 print STDERR "ERROR: Cannot Spawn: No executable specified\n";
99 return -1;
102 if ($self->{IGNOREEXESUBDIR} == 0) {
103 if (!-f $self->Executable ()) {
104 print STDERR "ERROR: Cannot Spawn: <", $self->Executable (),
105 "> not found\n";
106 return -1;
110 my $status = 0;
112 my $cmdline;
114 # Reboot the target if necessery
115 $self->reboot();
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 );
123 else {
124 $cwdrel = File::Spec->abs2rel( $cwdrel, $prjroot );
126 $program = basename($program, $PerlACE::ProcessVX::ExeExt);
128 my @cmds;
129 my $cmdnr = 0;
130 my $arguments = "";
131 my $prompt = '';
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'};
160 my(@load_commands);
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;
166 } else {
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'};
178 } else {
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 = '[\\\\].*>[\ ]$';
188 FORK: {
189 if ($self->{PROCESS} = fork) {
190 #parent here
191 bless $self;
193 elsif (defined $self->{PROCESS}) {
194 #child here
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) {
201 $telnet_port = 23;
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);
207 if (!defined $t) {
208 die "ERROR: Telnet failed to <" . $telnet_host . ":". $telnet_port . ">";
210 my $retries = 10;
211 while ($retries--) {
212 if (!$t->open()) {
213 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
214 print "Couldn't open telnet connection; sleeping then retrying\n";
216 if ($retries == 0) {
217 die "ERROR: Telnet open to <" . $telnet_host . ":". $telnet_port . "> " . $t->errmsg;
219 sleep(5);
220 } else {
221 last;
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");
238 my $buf = '';
239 # wait for the prompt
240 while (1) {
241 my $blk = $t->get;
242 print $blk;
243 $buf .= $blk;
244 if ($buf =~ /$prompt/) {
245 last;
248 if ($buf !~ /$prompt/) {
249 die "ERROR: Didn't got prompt but got <$buf>";
251 my $i = 0;
252 my @lines;
253 while($i < $cmdnr) {
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
259 my $buf = '';
260 while (1) {
261 my $blk = $t->get;
262 print $blk;
263 $buf .= $blk;
264 if ($buf =~ /$prompt/) {
265 last;
268 } else {
269 print $t->errmsg;
272 $t->close();
273 sleep(2);
274 exit;
276 elsif ($! =~ /No more process/) {
277 #EAGAIN, supposedly recoverable fork error
278 sleep 5;
279 redo FORK;
281 else {
282 # weird fork error
283 print STDERR "ERROR: Can't fork <" . $cmdline . ">: $!\n";
286 $self->{RUNNING} = 1;
287 return 0;
291 # Terminate the process and wait for it to finish
293 sub TerminateWaitKill ($)
295 my $self = shift;
296 my $timeout = shift;
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 ($)
311 my $self = shift;
312 my $rc = shift;
314 my $CC_MASK = 0xff00;
316 # Exit code processing
317 if ($rc == 0) {
318 return 0;
320 elsif ($rc == $CC_MASK) {
321 print STDERR "ERROR: <", $self->{EXECUTABLE},
322 "> failed: $!\n";
324 $PerlACE::ProcessVX::DoVxInit = 1; # force reboot on next run
326 return ($rc >> 8);
328 elsif (($rc & 0xff) == 0) {
329 $rc >>= 8;
330 return $rc;
333 # Remember Core dump flag
334 my $dump = 0;
336 if ($rc & 0x80) {
337 $rc &= ~0x80;
338 $dump = 1;
341 # check for ABRT, KILL or TERM
342 if ($rc == 6 || $rc == 9 || $rc == 15) {
343 return 0;
346 print STDERR "ERROR: <", $self->{EXECUTABLE},
347 "> exited with ";
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
355 return 0;
358 sub Kill ()
360 my $self = shift;
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.
373 sub Wait ($)
375 my $self = shift;
376 my $timeout = shift;
377 if (!defined $timeout || $timeout < 0) {
378 waitpid ($self->{PROCESS}, 0);
379 } else {
380 return TimedWait($self, $timeout);
385 sub TimedWait ($)
387 my $self = shift;
388 my $timeout = shift;
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 ($?);
399 sleep 1;
402 $PerlACE::ProcessVX::DoVxInit = 1; # force reboot on next run
404 return -1;
407 sub handle_vxtest_file
409 my $self = shift;
410 my $vxtestfile = shift;
411 my $vx_ref = 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)) {
424 my $line1 = <$fh>;
425 chomp $line1;
426 while(<$fh>) {
427 $line1 = $_;
428 chomp $line1;
429 push @$vx_ref, "copy " . $ENV{'ACE_RUN_VX_TGTSVR_ROOT'} . "/lib/$line1" . ".dll .";
430 unshift @$unld_ref, "del $line1" . ".dll";
432 close $fh;
433 } else {
434 return 0;
437 return 1;