#!/usr/bin/perl
##################################################
# pc [-d dir] [-l logdir] [-s signal] [-q] 
#    start|stop proc
##################################################

use Getopt::Std;
use File::Spec;

sub usage($);

getopts('d:l:s:q', \%opts);

usage "Wrong argument count" if @ARGV < 2;
usage "No action" unless $ARGV[0] eq "start" ||
                         $ARGV[0] eq "stop";

chdir($d) or usage "Cannot chdir to $d" if 
    exists $opts{d};

my $pidf = "$ARGV[1].pid";
$pidf = File::Spec->catfile($opts{l}, 
                            $pidf) if $opts{l};
if($ARGV[0] eq "start") {
    start_proc($pidf, @ARGV[1..$#ARGV]);
} else {
    stop_proc($pidf);
}

##################################################
sub start_proc {
##################################################
    my ($pidf, @proc) = @_;
    local $| = 1;

    print "Starting @proc ... " unless $opts{q};

    if(-f $pidf) {
        print "Already running\n";
        exit 0;
    }

    defined(my $pid = fork()) or die "Fork failed";

    if($pid != 0) {                      # Father
        open LOG, ">$pidf" or 
            usage "Cannot open $pidf";
        print LOG "$pid\n";
        close LOG;
    } else {                             # Son
        exec @proc;
        usage "Cannot start \"$proc[0]\"";
    }

    print "started\n" unless $opts{q};
}

##################################################
sub stop_proc {
##################################################
    my $pidf = shift;
    local $| = 1;
    
    print "Stopping ... " unless $opts{q};

    if(! open LOG, "<$pidf") {
        print "No instance running\n";
        exit 0;
    }

    my $pid = <LOG>;
    close LOG;

    if(! kill 0, $pid) {
        print "Already Stopped\n";
        unlink $pidf or die "Cannot unlink $pidf";
        return;
    }

    foreach (1..10) {
        kill $opts{s} || "TERM", $pid;
        if(! kill 0, $pid) {
            print "stopped\n" unless $opts{q};
            unlink $pidf or 
                         die "Cannot unlink $pidf";
            return;
        }
        sleep(1);
    }
    
    print "Can't stop it - giving up.\n";
}

##################################################
sub usage($) {
##################################################
    (my $prog = $0) =~ s#.*/##g;
    print "$prog: $_[0].\n";
    print "usage: $prog [-d dir] [-l logdir] " .
          "proc start|stop\n";
    exit 1;
}
