Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Perl Daemons and SIGHUP

by explodec14 (Novice)
on Feb 24, 2010 at 12:24 UTC ( #825062=perlquestion: print w/ replies, xml ) Need Help??
explodec14 has asked for the wisdom of the Perl Monks concerning the following question:

Hello -

I have posted my problems in the chatterbox but i didn't get replies satisfying.

I have written a daemon (using Proc::Daemon:Init) which listens to port 9000 and forks whenever a client connects. So far so good. I have added signal handler in order to handle SIGHUP in case the user changes the configuration file and wants to reload the daemon. In this case, the daemon should restart itself in order to listen on the new configured port. The daemon traps the signal and when it tries to restart itself (using the exec call) it vanishes ...

I suspect it has to do with the daemonizing because otherwise I checked and it works fine.

(a) Why is that ?
(b) What is the proper way to reload a daemon ?
(c) I have encountered in CPAN the package Daemon::Generic, which suggest somekind of solution, does anyonen know this package ?

10x in advance

Comment on Perl Daemons and SIGHUP
Replies are listed 'Best First'.
Re: Perl Daemons and SIGHUP
by moritz (Cardinal) on Feb 24, 2010 at 12:36 UTC
    (a) Why is that ?

    Because the default action for SIGHUP is to terminate the process

    (b) What is the proper way to reload a daemon ?

    As you've mentioned yourself on the chatterbox, exec is a possibility. As I've also told you on the chatterbox, installing a signal handler for SIGHUP and doing the exec in that handle might be a solution

    (c) I have encountered in CPAN the package Daemon::Generic, which suggest somekind of solution, does anyonen know this package ?

    Since three people have written reviews for it, I'd assume that at least 4 people know this package. Probably a lot more.

      Hi -

      I have installed the signal handler as you advised me. but still the exec call terminates the process and i don't know why.

      Here is the code:
      #!/usr/bin/perl -w use strict; use Socket; use Carp; use MTS; use MTS qw(prepare_transaction); use Proc::Daemon; use File::Temp qw(tempfile); use Data::Dumper; use Logger::Syslog; use JSON; use File::Find; use File::Basename; use Cwd 'realpath'; use POSIX (); #use FindBin(); use File::Spec::Functions qw(rel2abs catfile); no warnings 'File::Find'; my $SELF = rel2abs($0); my @argv = @ARGV; # Daemonizing Proc::Daemon::Init unless defined($ENV{"DEBUG"}); use vars qw($mts $qtime $qattr $qsender $qempty $qxtra $qend @template + $PORT @rcpts $pid $lock_dir @children $cfg $CONFIG_FILE); $CONFIG_FILE = '/etc/mts/mts.conf'; # # Forward Declarations # sub spawn; sub _dispatcher; sub _check_spam; sub _process_request; sub _build_msg; sub _enqueue_messages; sub _prepare_message; sub _notify; sub _signal_handler; sub _recover_transactions; sub _lock_maildrop_dir; sub _read_config; sub _reload_config; $SIG{CHLD} = \&REAPER; $SIG{HUP} = \&sigHUP_handler; #$SIG{__DIE__} = 'IGNORE'; $SIG{ABRT} = \&_signal_handler; $SIG{TERM} = \&_signal_handler; $SIG{INT} = \&_signal_handler; _read_config; #print Dumper $cfg; sub sigHUP_handler { #_reload_config; debug("Restarting daemon with: \$SELF=$SELF and \@argv=@argv "); exec($SELF,@argv); } # POSIX unmasks the sigprocmask properly #my $sigset = POSIX::SigSet->new(); #my $action = POSIX::SigAction->new('sigHUP_handler', $sigset, &POSIX: +:SA_NODEFER); #POSIX::sigaction(&POSIX::SIGHUP, $action); #$action = POSIX::SigAction->new('_signal_handler', $sigset, &POSIX::S +A_NODEFER); #POSIX::sigaction(&POSIX::SIGTERM, $action); #POSIX::sigaction(&POSIX::SIGINT, $action); #POSIX::sigaction(&POSIX::SIGABRT, $action);

      pay attention to the commented code block which uses POSIX. This does the same problem too

        Is the debug()-line executed at all?
        Perl 6 - links to (nearly) everything that is Perl 6.
Re: Perl Daemons and SIGHUP
by cdarke (Prior) on Feb 24, 2010 at 13:56 UTC
    Like me you probably found Can't catch signals after an exec? which recommends using the POSIX routines. Unfortunately you have an error in your SigAction->new, you should supply a reference to the handler, not its name:
    my $sigset = POSIX::SigSet->new(); my $action = POSIX::SigAction->new( \&sigHUP_handler, $sigset, &POSIX::SA_NODEFER ); POSIX::sigaction(&POSIX::SIGHUP, $action);
    I reproduced a simplified version of your problem using $SIG{HUP} and this fixed it.

      well i tried what you've fixed. but still, after the doing the exec call, the process dies.

      It happens also when i use the Daemon::Generic package.

        Might I suggest that you try this without any Daemon modules? Just get it running as an ordinary background job using &, because that did not work previously. Even if it still does not work then at least you would have eliminated a chunk of software and we might be able to tie down a simplified version.
        If it does work without the Daemon modules then we know where to look next.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://825062]
Approved by moritz
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2016-02-06 09:20 GMT
Find Nodes?
    Voting Booth?

    How many photographs, souvenirs, artworks, trophies or other decorative objects are displayed in your home?

    Results (222 votes), past polls