On Thu, May 16, 2002 at 12:16:58PM -0700, Matt Simonsen wrote:
> 
> My best guess is I should have the script immediately fork a copy of itself
> then die while the forked copy still runs, but I haven't been able to figure
> out how to make that work. Any suggestions would be helpful, especially a
> sample loop like this that just forks a daemon to do something stupid like
> print "foo" ; forever.

Ok, here's what we need to do to completely detach from our parent
process - speak when we want to become a daemon:

1. get out of the parent's (in that case your shell's) process group.
We'll have PPID 1 after this call.  The only error that setsid can throw
is EPERM which means that we already are process group leader.

2. move up to the root directory, so that we're not blocking filesystems
that one might want to unmount (e.g. /opt)

3. close all those rotten filehandles who's output nobody will see
anyways...

    ---------- daemonify ----------
    #!/usr/bin/perl -w

    use strict;
    use POSIX qw/setsid/;

    my $child = shift;
    die "Path to $child must be absolute\n"
        unless $child =~ /^\//;

    unless (fork) {
        setsid();
        chdir '/';
        close STDIN;
        close STDOUT;
        close STDERR;

        exec $child;    # or write your code here...

        die "Mustn't happen: exec failed: $!\n";
    }

    # No need to reap since we detached...
    exit;
    ---------- daemonify ----------

and

    ---------- daemonified ----------
    #!/usr/bin/perl

    use strict;
    use warnings;
    use Sys::Syslog;

    while (1) {
        syslog 'INFO', "$0 ($$): %s", scalar localtime;
        sleep 1;
    }
    ---------- daemonified ----------

Test it like this:

    ---------- snip ----------
    nijushiho:/tmp/try$ ls
    daemonified*  daemonify*
    nijushiho:/tmp/try$ 
    nijushiho:/tmp/try$ ssh localhost "cd /tmp/try && ./daemonify $PWD/daemonified"
    nijushiho:/tmp/try$ tail -3 /var/log/messages
    May 17 00:18:01 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:01 2002 
    May 17 00:18:02 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:02 2002 
    May 17 00:18:03 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:03 2002 
    nijushiho:/tmp/try$ ps -aef | egrep 'PID|daemonified'
    UID        PID  PPID  C STIME TTY          TIME CMD
    mlamertz 14462     1  1 00:19 ?        00:00:00 /usr/bin/perl /tmp/try/daemonified
    mlamertz 14483 13904  0 00:19 pts/2    00:00:00 grep daemonified
    nijushiho:/tmp/try$ kill 14462
    nijushiho:/tmp/try$ !ps
    ps -aef | egrep 'PID|daemonified'
    UID        PID  PPID  C STIME TTY          TIME CMD
    mlamertz 14510 13904  0 00:20 pts/2    00:00:00 egrep PID|daemonified
    nijushiho:/tmp/try$ 
    ---------- snip ----------

As you see, the process was running and logging to syslog although the
ssh immediately returned.  The 'ps' told us that our PPID was 1 which is
'init'.

That should be it, but I may have forgotten something since it's been a
while that I needed that stuff frequently.

To learn more about this kind of stuff, go and buy the late Richard
Stevens "Advanced Programming in the Unix(R) Environment".

-- 
                       If we fail, we will lose the war.

Michael Lamertz                        |      +49 221 445420 / +49 171 6900 310
Nordstr. 49                            |                       [EMAIL PROTECTED]
50733 Cologne                          |                 http://www.lamertz.net
Germany                                |               http://www.perl-ronin.de 

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to