in reply to How to get a persistent daemons after exiting the session?
i have an almost what you want. i'm still stuck in a couple of places. Proc::PID::File has some issues (at least the way i want to use it) in that it will delete your pidfile when it shouldn't. i started on a patch/replacement but haven't finished. (can't figure a good way to hold the pidfile locked while i daemonize since Proc::Daemon closes open files (losing the locks).
#!/usr/bin/perl use strict; use warnings; $|++; my $base = '/home/me/testing'; my $name = 'simpledaemon'; my $default_configfile = join '/', $base, $name . ".conf"; =head1 NAME B<simpledaemon> -- A daemon to ... =head1 SYNOPSIS simpledaemon [--start|--stop|--check] [--configfile <file>] Options: --help Display help --man Display man page --start Start the daemon (default) --stop Stop the daemon --check Check the daemon --configfile <file> Specify alternate configuration file (default: simpledaemon.conf) =cut # # handle command line options # use Getopt::Long; use Pod::Usage; my %opt = ( help => 0, man => 0, configfile => $default_configfile, check => 0, stop => 0, start => 1, fork => 1, ); GetOptions(\%opt, 'help', 'man', 'configfile=s', 'check', 'stop', 'start!', 'fork!', ); # # handy dandy help and man options # pod2usage(-verbose => 1), exit if $opt{help}; pod2usage(-verbose => 2), exit if $opt{man}; # # load the config file # use Config::General; my $conf; # the object my %conf; # the handy hash # we eval this just to give pretty error messages... eval { $conf = Config::General->new( -ConfigFile => $opt{configfile}, -InterPolateVars => 1, ); }; if (local $_ = $@) { s/\n.*//; chomp; die "load config failed with: $_\n"; } # and voila! here's our conf %conf = $conf->getall; if (0) { # debugging use Data::Dumper; print Data::Dumper->Dump([\%conf],['conf']); } my $myname = $conf{Simpledaemon}{name}; # save some typing late +r on # # now we start the real work... handling --start, --stop, --check # use Proc::PID::File; my $pidfile; $pidfile = Proc::PID::File->new( # dir => $conf{Simpledaemon}{base}, # default: /var/run # name => 'simpledaemon', # default: prognam +e (.pid g ets added) ); # only one of --check, --stop, --start will be performed. # handle --check if ($opt{check}) { if ($pidfile->alive) { print "$myname appears to be alive (pid ",$pidfile->re +ad,").$/"; } else { print "$myname appears to be dead.$/"; } $pidfile = undef; exit 0; } # handle --stop if ($opt{stop}) { if ($pidfile->alive) { my $pid = $pidfile->read; kill TERM => $pid; sleep 2; if (kill 0, $pid) { print "$myname is hard to kill!$/"; exit 1; } else { print "$myname appears to be dead now.$/"; exit 0; } } else { print "$myname wasn't alive.$/"; exit 1; } } # handle --start sub logfailsafe { open(F, '>>', $conf{Simpledaemon}{logfailsafe}) and print(F @_) and close(F); die "@_"; } use Proc::Daemon; if ($opt{start}) { die "$myname already running!$/" if $pidfile->alive; # # fork if needed # we get a new pidfile here, Proc::Daemon::Init closes the open files +(losing lo cks) # if ($opt{fork}) { $pidfile = undef; Proc::Daemon::Init; # become a dae +mon $pidfile = Proc::PID::File->new( # dir => '$conf{Simpledaemon}{base}', # default: + /var/run # name => 'simpledaemon', # default: + progname (.pid is added) ); } $pidfile->write; # # start our logging, try and fail gracefully # use Log::Log4perl qw(get_logger); eval { # Log::Log4perl::init(\$conf{logconfig}); Log::Log4perl::init_and_watch($conf{Simpledaemon}{logc +onfigfile} , 10); }; if (local $_ = $@) { s/ at .*//; chomp; logfailsafe("logging config failed with: $_\n"); } my $log = get_logger($conf{Simpledaemon}{logger}) or logfailsafe("get_logger failed!\n"); # # safeish death, pidfile is picky # $SIG{INT} = $SIG{TERM} = sub { $log->info("stopping"); $pidfile = undef; exit 0; }; $log->info("starting"); # # here's our loop # while (1) { no strict 'refs'; sleep 20; for my $i (qw/ debug info warn error fatal /) { $log->$i("log $i"); } } # # end of our loop # } # start __END__ =head1 DESCRIPTION This program will... =cut
i never found a CPAN module that did all of the stuff i wanted (like you, stop/start/check). my plan is to eventually get this finished up as a module that i can use for all of my daemons to provide common functionality.
package MyDaemon; use base qw(SimpleDaemon); sub MainLoop { #do work here }
or something similar. i'm open for ideas/comments/pointers to modules etc.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: How to get a persistent daemons after exiting the session?
by rob_au (Abbot) on Mar 11, 2003 at 22:21 UTC | |
by zengargoyle (Deacon) on Mar 11, 2003 at 23:16 UTC |