home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / Perl_WWW_Utilities / daemon.pl < prev    next >
Encoding:
Perl Script  |  1996-04-24  |  3.4 KB  |  93 lines

  1. ##---------------------------------------------------------------------------##
  2. ##  File:
  3. ##    daemon.pl
  4. ##  Author:
  5. ##    Earl Hood    ehood@convex.com
  6. ##  Description:
  7. ##    This package contains the routine "daemon_init" which
  8. ##    can be called by a perl program to initialize itself as a
  9. ##    daemon.  The routine achieves this by the following:
  10. ##
  11. ##        1. Forks a child and exits the parent process.
  12. ##        2. Becomes a seesion leader (which detaches the program from
  13. ##           the controlling terminal).
  14. ##        3. Changes the current working directory to "/".
  15. ##        4. Clears the file creation mask.
  16. ##
  17. ##    The calling program is responible for closing unnecessary open
  18. ##    file handles.
  19. ##
  20. ##    If an error occurs in daemon_init so it cannot perform the above
  21. ##    steps, than it calls "die" with an error message.  One can
  22. ##    prevent program termination by using "eval" to capture any
  23. ##    error messages.
  24. ##
  25. ##  Implementation Notes:
  26. ##    Perl does not have direct support for the setsid(2) system call.
  27. ##    This call is needed to perform step 2 above.  Therefore,
  28. ##    syscall() is used to call setsid.  However, there existed a
  29. ##    problem with calling setsid.
  30. ##
  31. ##    I work in a heterogenous environment.  I noticed that the file
  32. ##    syscall.ph did not always define the assembly language
  33. ##    interface number for setsid (plus, on one of the Sparc 2s,
  34. ##    syscall.ph was called syscall.h, BUT it wasn't the C header).
  35. ##    Therefore, to avoid the dependency of administrators installing
  36. ##    perl correctly, I access the syscall.h file in /usr/include/sys
  37. ##    to determine the value I need for syscall().  If for some
  38. ##    reason, syscall.h is not /usr/include/sys, you can change the
  39. ##    $syscall_h variable.
  40. ##---------------------------------------------------------------------------##
  41. ##  Copyright (C) 1994  Earl Hood, ehood@convex.com
  42. ##
  43. ##  This program is free software; you can redistribute it and/or modify
  44. ##  it under the terms of the GNU General Public License as published by
  45. ##  the Free Software Foundation; either version 2 of the License, or
  46. ##  (at your option) any later version.
  47. ##  
  48. ##  This program is distributed in the hope that it will be useful,
  49. ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  51. ##  GNU General Public License for more details.
  52. ##  
  53. ##  You should have received a copy of the GNU General Public License
  54. ##  along with this program; if not, write to the Free Software
  55. ##  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  56. ##---------------------------------------------------------------------------##
  57.  
  58. package daemon;
  59.  
  60. $syscall_h = "/usr/include/sys/syscall.h";
  61.  
  62. sub main'daemon_init {
  63.     ## Fork and exit parent ##
  64.     FORK: {
  65.     if ($pid = fork) {         ## parent process
  66.         exit 0;
  67.     } elsif (defined $pid) {    ## child process
  68.         last FORK;
  69.     } elsif ($! =~ /No more process/) {
  70.         sleep 5;
  71.         redo FORK;
  72.     } else {
  73.         die "Can't fork: $!\n";
  74.     }
  75.     }
  76.     ## Detach ourselves from the terminal ##
  77.     if (open(SYSCALL_H, "< $syscall_h")) {
  78.     while (<SYSCALL_H>) {
  79.         next unless /^\s*#define\s+SYS_setsid\s+(\d*)\s+.*$/;
  80.         $setsid = $1;  last;
  81.     }
  82.     close(SYSCALL_H);
  83.     if ($setsid) { syscall($setsid); }
  84.     else { die "Cannot detach from controlling terminal\n"; }
  85.     }
  86.     else { die "Unable to access $syscall_h\n",
  87.            "Cannot detach from controlling terminal\n"; }
  88.     
  89.     chdir "/";        ## Change working directory
  90.     umask 0;        ## Clear file creation mask
  91. }
  92. 1;
  93.