http://qs321.pair.com?node_id=374409

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks, so sorry to disturby but i need help I am currently developing a proxy server all in perl and I have tested it and seems to be greate. But there is a problem, I want to meke it run as a daemon service I a Red hat Linux system but I dont know how. The proxy handls its own multi threading and spawns a new instance each time a new connection is made to it. I tried using xinetd superserver to start it but I keep getting this error messagees

04/7/14@19:55:56: DEBUG: 3298 {main_loop} select returned 1
04/7/14@19:55:56: DEBUG: 3298 {server_start} Starting service webcache
04/7/14@19:55:56: DEBUG: 3313 {exec_server} duping 7
04/7/14@19:55:56: DEBUG: 3298 {main_loop} active_services = 1
04/7/14@19:55:57: DEBUG: 3298 {main_loop} active_services = 1
04/7/14@19:55:57: DEBUG: 3298 {main_loop} select returned 1
04/7/14@19:55:57: DEBUG: 3298 {check_pipe} Got signal 17 (Child exited)
04/7/14@19:55:57: DEBUG: 3298 {child_exit} waitpid returned

really i would like it to be started ad a daemon program when booting the system, i.e, I get to initialize it in the /etc/rc... directories. pleasse can you provide me with a solution. thanks

Replies are listed 'Best First'.
Re: Creating a perl daemon
by Zaxo (Archbishop) on Jul 14, 2004 at 21:34 UTC

    TStanley++ suggests Proc::Daemon, which is likely to be just what you want.

    It's a Good Thing to go through the details of exactly what to do, and why, to run as a daemon. A daemon process is one which runs forever without a controlling terminal or parent process. There are some housekeeping issues to be taken care of in launching a daemon. Stevens' Advanced Programming in the UNIX Environment provides a a list of coding rules and a C function for that which is readily translated to perl.

    We'll need the POSIX system call setsid() and we'll also import Cwd's chdir to get $ENV{PWD} reset when we change directory. We define a function daemon_init() which does all the daemonic housekeeping.

    use POSIX 'setsid'; use Cwd 'chdir'; sub daemon_init {
    First, we fork and exit the parent. That makes the launching process think we're done and also makes sure we're not a process group leader - a necessary condition for the next step to succeed.
    my $pid = fork; exit 0 if $pid; exit 1 if not defined $pid;
    Second, we call setsid() which does three things. We become leader of a new session, group leader of a new process group, and become detached from any terminal. To satisfy SVR4, we do the fork dance again to shuck session leadership, which guarantees we never get a controlling terminal.
    setsid(); $pid = fork; exit 0 if $pid; exit 1 if not defined $pid;
    Third, we change directory to the root of all. That is a courtesy to the system, which without it would be prevented from unmounting the filesystem we started in.     chdir '/' or die $!; Fourth, we clear the permissions mask for file creation. That frees our daemon to manage its files as it sees fit.     umask 0; Finally, we close unwanted filehandles we have inherited from the parent process. That is another courtesy to the system, as well as being sparing of our own process resources. I'll take them from arguments passed to daemon_init(), just to be different from Proc::Daemon.
    close $_ for @_; }
    The only reason to do this by hand, as written, instead of through Proc::Daemon is if you do have file handles already open which the daemon will use. Proc::Daemon closes 'em all.

    It is conventional to rewire the SIGHUP handler of a daemon to reinitialize and reload configuration files. If you set $SIG{HUP} = \&_init; for some suitably defined _init() before you fork, the initialization will be done automatically. You can repeat initialization at any time ( like after editing configuration files) with kill HUP, pid.

    After Compline,
    Zaxo

      !OFFTOPIC!

      There should really be some option for giving more than one ++ to a post.

      This one would deserve something like 10 :-)

      please can you expansiate a bit, i actuall still am confused. i don't know how to use this code that you pasted here, though i think it owuld be very helpful. Please can yo tell me how to use this code??


      the program i want to daemonizs is already an executable and it will run in a terminal window as an application. do i edit this program and add the code you sudgrested to it or do i pass the program to your sudgestio as an argument??. thanks

        Ok, your program also runs in a terminal and you don't want to lose that capacity. We'll define a boolean command line option, -d, which means "run as daemon". This is a modification to your existing program. It is also possible to exec another program after daemon_init is called, so a daemonizing wrapper is just as easy.

        #!/usr/bin/perl use warnings; use strict; use Getopt::Std; our $opt_d, %config; getopt('d');
        Now, $opt_d will be true if the -d option appears in the command line. If it does we want to set up our new SIGHUP handler, call daemon_init(), drop root priviledge, and open our new I/O streams.
        use POSIX qw/setuid setsid/; if ($opt_d) { $SIG{'HUP'} = sub { %config = %{ +do '/etc/mydaemon/config' } }; daemon_init( *STDERR, *STDOUT, *STDIN); setuid( scalar getpwnam $config{'run_as'} ) unless $<; open STDIN, '<', '/dev/null' or die $!; open STDOUT, '>', '/dev/null' or die $!; open STDERR, '>>', '/var/log/mydaemon.log'; } # Be sure to define sub daemon_init # On with the program . . .
        You'll need to look closely at your requirements to see if this does what you want. I made all kinds of simplifying assumptions in writing that. For instance, if you already have option option handling, you should modify this to fit what you already have.

        This is just an outline, there are lots of choices and this is not cast in stone. You'll need to pay close attention to the suid part. It is there to drop privilege when the daemon is run by root. You'll need to make sure the real log path is writable by the daemon user.

        This setup is nearly the same if you use Proc::Daemon. Tho only difference is that the call to &Proc::Daemon::Init takes no arguments.

        After Compline,
        Zaxo

Re: Creating a perl daemon
by TStanley (Canon) on Jul 14, 2004 at 19:49 UTC
    I'm not sure if this is what you would be looking for, but have you looked at Proc::Daemon?

    TStanley
    --------
    The only thing necessary for the triumph of evil is for good men to do nothing -- Edmund Burke
      thanks for the lead, i will try it out and report the results