—##---------------------------------------------------------------------------##
## File:
## @(#) Daemon.pm 1.2 99/04/17 01:02:34
## Author:
## Earl Hood earlhood@usa.net
##---------------------------------------------------------------------------##
## Copyright (C) 1997-1999 Earl Hood, earlhood@usa.net
## All rights reserved.
##
## This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself.
##---------------------------------------------------------------------------##
package
Proc::Daemon;
use
strict;
use
Exporter;
@ISA
=
qw( Exporter )
;
$VERSION
=
"0.02"
;
@EXPORT_OK
=
qw( Fork OpenMax )
;
##---------------------------------------------------------------------------##
use
Carp;
use
POSIX;
##---------------------------------------------------------------------------##
## Fork(): Try to fork if at all possible. Function will croak
## if unable to fork.
##
sub
Fork {
my
(
$pid
);
FORK: {
if
(
defined
(
$pid
=
fork
)) {
return
$pid
;
}
elsif
($! =~ /No more process/) {
sleep
5;
redo
FORK;
}
else
{
croak
"Can't fork: $!"
;
}
}
}
##---------------------------------------------------------------------------##
## OpenMax(): Return the maximum number of possible file descriptors.
## If sysconf() does not give us value, we punt with our own value.
##
sub
OpenMax {
my
$openmax
= POSIX::sysconf(
&POSIX::_SC_OPEN_MAX
);
(!
defined
(
$openmax
) ||
$openmax
< 0) ? 64 :
$openmax
;
}
##---------------------------------------------------------------------------##
## Init(): Become a daemon.
##
sub
Init {
my
$oldmode
=
shift
|| 0;
my
(
$pid
,
$sess_id
,
$i
);
## Fork and exit parent
if
(
$pid
= Fork) {
exit
0; }
## Detach ourselves from the terminal
croak
"Cannot detach from controlling terminal"
unless
$sess_id
= POSIX::setsid();
## Prevent possibility of acquiring a controling terminal
if
(!
$oldmode
) {
$SIG
{
'HUP'
} =
'IGNORE'
;
if
(
$pid
= Fork) {
exit
0; }
}
## Change working directory
chdir
"/"
;
## Clear file creation mask
umask
0;
## Close open file descriptors
foreach
$i
(0 .. OpenMax) { POSIX::
close
(
$i
); }
## Reopen stderr, stdout, stdin to /dev/null
open
(STDIN,
"+>/dev/null"
);
open
(STDOUT,
"+>&STDIN"
);
open
(STDERR,
"+>&STDIN"
);
$oldmode
?
$sess_id
: 0;
}
*init
= \
&Init
;
##---------------------------------------------------------------------------##
1;
__END__
=head1 NAME
Proc::Daemon - Run Perl program as a daemon process
=head1 SYNOPSIS
use Proc::Daemon;
Proc::Daemon::Init;
=head1 DESCRIPTION
This module contains the routine B<Init> which can be called by
a perl program to initialize itself as a daemon. A daemon is a
process that runs in the background with no controlling terminal.
Generally servers (like FTP and HTTP servers) run as daemon processes.
However, do not make the mistake that a daemon == server.
The B<Proc::Daemon::Init> function does the following:
=over 4
=item 1
Forks a child and exits the parent process.
=item 2
Becomes a session leader (which detaches the program from
the controlling terminal).
=item 3
Forks another child process and exits first child. This prevents
the potential of acquiring a controlling terminal.
=item 4
Changes the current working directory to "/".
=item 5
Clears the file creation mask.
=item 6
Closes all open file descriptors.
=back
You will notice that no logging facility, or other functionality
is performed. B<Proc::Daemon::Init> just performs the main steps
to initialize a program as daemon. Since other funtionality can vary
depending on the nature of the program, B<Proc::Daemon> leaves
the implementation of other desired functionality to the
caller, or other module/library (like B<Sys::Syslog>).
There is no meaningful return value B<Proc::Daemon::Init>. If an
error occurs in B<Init> so it cannot perform the above steps, than
it croaks with an error message. One can prevent program termination
by using eval.
=head1 OTHER FUNCTIONS
B<Proc::Daemon> also defines some other functions. These functions
can be imported into the callers name space if the function names
are specified during the B<use> declaration:
=head2 Fork
B<Fork> is like the built-in B<fork>, but will try to fork if at all
possible, retrying if necessary. If not possible, B<Fork> will
croak.
=head2 OpenMax
B<OpenMax> returns the maximum file descriptor number.
If undetermined, 64 will be returned.
=head1 NOTES
=over 4
=item *
B<Proc::Daemon::init> is still available for backwards capatibilty.
However, it will not perform the double fork, and will return the
session ID.
=back
=head1 AUTHOR
Earl Hood, earlhood@usa.net
=head1 CREDITS
Implementation of B<Proc::Daemon> derived from the following sources:
=over 4
=item *
B<Advanced Programming in the UNIX Environment>, by W. Richard Stevens.
Addison-Wesley, Copyright 1992.
=item *
B<UNIX Network Progamming>, Vol 1, by W. Richard Stevens.
Prentice-Hall PTR, Copyright 1998.
=back
=head1 DEPENDENCIES
B<Proc::Daemon> depends on the following modules: B<Carp>, B<POSIX>.
=head1 SEE ALSO
L<POSIX>,
L<Sys::Syslog>
=cut