mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 20:36:06 +08:00
e45fb91b64
Then there's the cleanup to do to make this all much easier to do in the future to more boards...
158 lines
4.1 KiB
Perl
158 lines
4.1 KiB
Perl
# Proc::Background::Win32 Windows interface to background process management.
|
|
#
|
|
# Copyright (C) 1998-2005 Blair Zajac. All rights reserved.
|
|
|
|
package Proc::Background::Win32;
|
|
|
|
require 5.004_04;
|
|
|
|
use strict;
|
|
use Exporter;
|
|
use Carp;
|
|
|
|
use vars qw(@ISA $VERSION);
|
|
@ISA = qw(Exporter);
|
|
$VERSION = sprintf '%d.%02d', '$Revision: 1.10 $' =~ /(\d+)\.(\d+)/;
|
|
|
|
BEGIN {
|
|
eval "use Win32";
|
|
$@ and die "Proc::Background::Win32 needs Win32 from libwin32-?.??.zip to run.\n";
|
|
eval "use Win32::Process";
|
|
$@ and die "Proc::Background::Win32 needs Win32::Process from libwin32-?.??.zip to run.\n";
|
|
}
|
|
|
|
sub _new {
|
|
my $class = shift;
|
|
|
|
unless (@_ > 0) {
|
|
confess "Proc::Background::Win32::_new called with insufficient number of arguments";
|
|
}
|
|
|
|
return unless defined $_[0];
|
|
|
|
# If there is only one element in the @_ array, then just split the
|
|
# argument by whitespace. If there is more than one element in @_,
|
|
# then assume that each argument should be properly protected from
|
|
# the shell so that whitespace and special characters are passed
|
|
# properly to the program, just as it would be in a Unix
|
|
# environment. This will ensure that a single argument with
|
|
# whitespace will not be split into multiple arguments by the time
|
|
# the program is run. Make sure that any arguments that are already
|
|
# protected stay protected. Then convert unquoted "'s into \"'s.
|
|
# Finally, check for whitespace and protect it.
|
|
my @args;
|
|
if (@_ == 1) {
|
|
@args = split(' ', $_[0]);
|
|
} else {
|
|
@args = @_;
|
|
for (my $i=1; $i<@args; ++$i) {
|
|
my $arg = $args[$i];
|
|
$arg =~ s#\\\\#\200#g;
|
|
$arg =~ s#\\"#\201#g;
|
|
$arg =~ s#"#\\"#g;
|
|
$arg =~ s#\200#\\\\#g;
|
|
$arg =~ s#\201#\\"#g;
|
|
if (length($arg) == 0 or $arg =~ /\s/) {
|
|
$arg = "\"$arg\"";
|
|
}
|
|
$args[$i] = $arg;
|
|
}
|
|
}
|
|
|
|
# Find the absolute path to the program. If it cannot be found,
|
|
# then return. To work around a problem where
|
|
# Win32::Process::Create cannot start a process when the full
|
|
# pathname has a space in it, convert the full pathname to the
|
|
# Windows short 8.3 format which contains no spaces.
|
|
$args[0] = Proc::Background::_resolve_path($args[0]) or return;
|
|
$args[0] = Win32::GetShortPathName($args[0]);
|
|
|
|
my $self = bless {}, $class;
|
|
|
|
# Perl 5.004_04 cannot run Win32::Process::Create on a nonexistant
|
|
# hash key.
|
|
my $os_obj = 0;
|
|
|
|
# Create the process.
|
|
if (Win32::Process::Create($os_obj,
|
|
$args[0],
|
|
"@args",
|
|
0,
|
|
NORMAL_PRIORITY_CLASS,
|
|
'.')) {
|
|
$self->{_pid} = $os_obj->GetProcessID;
|
|
$self->{_os_obj} = $os_obj;
|
|
return $self;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
# Reap the child.
|
|
sub _waitpid {
|
|
my ($self, $timeout) = @_;
|
|
|
|
# Try to wait on the process.
|
|
my $result = $self->{_os_obj}->Wait($timeout ? INFINITE : 0);
|
|
# Process finished. Grab the exit value.
|
|
if ($result == 1) {
|
|
my $_exit_status;
|
|
$self->{_os_obj}->GetExitCode($_exit_status);
|
|
return (0, $_exit_status<<8);
|
|
}
|
|
# Process still running.
|
|
elsif ($result == 0) {
|
|
return (2, 0);
|
|
}
|
|
# If we reach here, then something odd happened.
|
|
return (0, 1<<8);
|
|
}
|
|
|
|
sub _die {
|
|
my $self = shift;
|
|
|
|
# Try the kill the process several times. Calling alive() will
|
|
# collect the exit status of the program.
|
|
my $count = 5;
|
|
while ($count and $self->alive) {
|
|
--$count;
|
|
$self->{_os_obj}->Kill(1<<8);
|
|
last unless $self->alive;
|
|
sleep 1;
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Proc::Background::Win32 - Interface to process mangement on Win32 systems
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
Do not use this module directly.
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This is a process management class designed specifically for Win32
|
|
operating systems. It is not meant used except through the
|
|
I<Proc::Background> class. See L<Proc::Background> for more information.
|
|
|
|
=head1 IMPLEMENTATION
|
|
|
|
This package uses the Win32::Process class to manage the objects.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Blair Zajac <blair@orcaware.com>
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (C) 1998-2005 Blair Zajac. All rights reserved. This
|
|
package is free software; you can redistribute it and/or modify it
|
|
under the same terms as Perl itself.
|
|
|
|
=cut
|