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;