home *** CD-ROM | disk | FTP | other *** search
- ##---------------------------------------------------------------------------##
- ## File:
- ## daemon.pl
- ## Author:
- ## Earl Hood ehood@convex.com
- ## Description:
- ## This package contains the routine "daemon_init" which
- ## can be called by a perl program to initialize itself as a
- ## daemon. The routine achieves this by the following:
- ##
- ## 1. Forks a child and exits the parent process.
- ## 2. Becomes a seesion leader (which detaches the program from
- ## the controlling terminal).
- ## 3. Changes the current working directory to "/".
- ## 4. Clears the file creation mask.
- ##
- ## The calling program is responible for closing unnecessary open
- ## file handles.
- ##
- ## If an error occurs in daemon_init so it cannot perform the above
- ## steps, than it calls "die" with an error message. One can
- ## prevent program termination by using "eval" to capture any
- ## error messages.
- ##
- ## Implementation Notes:
- ## Perl does not have direct support for the setsid(2) system call.
- ## This call is needed to perform step 2 above. Therefore,
- ## syscall() is used to call setsid. However, there existed a
- ## problem with calling setsid.
- ##
- ## I work in a heterogenous environment. I noticed that the file
- ## syscall.ph did not always define the assembly language
- ## interface number for setsid (plus, on one of the Sparc 2s,
- ## syscall.ph was called syscall.h, BUT it wasn't the C header).
- ## Therefore, to avoid the dependency of administrators installing
- ## perl correctly, I access the syscall.h file in /usr/include/sys
- ## to determine the value I need for syscall(). If for some
- ## reason, syscall.h is not /usr/include/sys, you can change the
- ## $syscall_h variable.
- ##---------------------------------------------------------------------------##
- ## Copyright (C) 1994 Earl Hood, ehood@convex.com
- ##
- ## This program is free software; you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation; either version 2 of the License, or
- ## (at your option) any later version.
- ##
- ## This program is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with this program; if not, write to the Free Software
- ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ##---------------------------------------------------------------------------##
-
- package daemon;
-
- $syscall_h = "/usr/include/sys/syscall.h";
-
- sub main'daemon_init {
- ## Fork and exit parent ##
- FORK: {
- if ($pid = fork) { ## parent process
- exit 0;
- } elsif (defined $pid) { ## child process
- last FORK;
- } elsif ($! =~ /No more process/) {
- sleep 5;
- redo FORK;
- } else {
- die "Can't fork: $!\n";
- }
- }
- ## Detach ourselves from the terminal ##
- if (open(SYSCALL_H, "< $syscall_h")) {
- while (<SYSCALL_H>) {
- next unless /^\s*#define\s+SYS_setsid\s+(\d*)\s+.*$/;
- $setsid = $1; last;
- }
- close(SYSCALL_H);
- if ($setsid) { syscall($setsid); }
- else { die "Cannot detach from controlling terminal\n"; }
- }
- else { die "Unable to access $syscall_h\n",
- "Cannot detach from controlling terminal\n"; }
-
- chdir "/"; ## Change working directory
- umask 0; ## Clear file creation mask
- }
- 1;
-