home *** CD-ROM | disk | FTP | other *** search
- package PPM::Installer::Local;
- @PPM::Installer::Local::ISA = qw(PPM::Installer);
-
- use strict;
- use Data::Dumper;
- use PPM::PPD;
- use PPM::Result qw(Ok Warning Error List);
-
- sub new {
- my $class = shift;
- my $targ = shift;
- my $name = shift;
- my $inst = bless {
- name => $name,
- path => $targ->{path},
- type => $targ->{type},
- port => $targ->{port},
- }, $class;
- return $inst;
- }
-
- sub init {
- my $inst = shift;
-
- # First, check if the process is already running. If so, use that.
- my $ok = $inst->connect_to('localhost', $inst->{port});
-
- # If it isn't, try to launch it ourselves, _then_ connect. Because
- # spawning a process is fairly slow, we have to try to connect for a
- # little while, to give the child time to set up the server.
- do {
- $inst->spawn;
- for (1 .. 10) {
- $ok = $inst->connect_to('localhost', $inst->{port});
- last if $ok->ok;
- # let the CPU swap out to the child process.
- defined &Win32::Sleep ? Win32::Sleep(250) : sleep 1;
- }
- die $ok->msg unless $ok->ok;
- } unless $ok->ok;
- $ok;
- }
-
- sub fini {
- my $o = shift;
- $o->sendmsg('STOP');
- }
-
- sub spawn {
- my $inst = shift;
-
- $ENV{PPM_PORT} = $inst->port;
-
- # Note: $inst->{path} must be an executable, but Windows
- # does not support an executable permission bit, checking
- # for .bat or .exe files instead. This isn't suitable
- # for scripts, so we only make this check on non-Windows boxes
- die "$0: error: '$inst->{path}' is not executable"
- unless ((-x $inst->{path}) or ($^O eq 'MSWin32'));
- if ($^O eq 'MSWin32') {
- $inst->{path} =~ s,/,\\,g;
-
- # We don't want the child to inherit our STDOUT because that
- # would break things like `ppm query * > modlist`.
- # XXX Unfortunately this also silences all output from
- # XXX post-install scripts. :( Disabled for now...
- #open(MYSTDOUT, ">&STDOUT") or die $!;
- #close(STDOUT);
- #open(STDOUT, ">nul") or die $!;
-
- $inst->{pid} = system(1, $inst->{path});
-
- #open(STDOUT, ">&MYSTDOUT") or die $!;
- #close(MYSTDOUT);
- }
- else {
- $inst->{pid} = fork();
- if (defined $inst->{pid} and $inst->{pid} == 0) {
- exec $inst->{path};
- exit 1;
- }
- }
- }
-
- sub ckeys {
- my $o = shift;
- ($o->SUPER::ckeys,
- qw(path),
- );
- }
-
- sub path {
- my $o = shift;
- $o->{path};
- }
-
- 1;
-