Applied FastCGI daemon patch from mugwump
Andy Grundman [Thu, 17 Nov 2005 21:22:23 +0000 (21:22 +0000)]
Changes
lib/Catalyst.pm
lib/Catalyst/Engine/FastCGI.pm
lib/Catalyst/Helper.pm

diff --git a/Changes b/Changes
index b4b23e4..0c2174b 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,7 +3,8 @@ This file documents the revision history for Perl extension Catalyst.
 5.57
         - Added PAR support
         - Added keep-alive support and bug fixes to HTTP engine.
-          (Sascha Kiefer) 
+          (Sascha Kiefer)
+        - Added daemonize option to FastCGI engine. (Sam Vilain)
 
 5.56   2005-11-16 10:33:00
         - Fixed FastCGI engine to not clobber the global %ENV on each
index 7231383..b7dd179 100644 (file)
@@ -56,7 +56,7 @@ our $DETACH    = "catalyst_detach\n";
 require Module::Pluggable::Fast;
 
 # Helper script generation
-our $CATALYST_SCRIPT_GEN = 17;
+our $CATALYST_SCRIPT_GEN = 18;
 
 __PACKAGE__->mk_classdata($_)
   for qw/components arguments dispatcher engine log dispatcher_class
index 2eb34cd..9ebe51b 100644 (file)
@@ -39,6 +39,8 @@ Options may also be specified;
   nproc           Specify a number of processes for
                   FCGI::ProcManager
   pidfile         Specify a filename for the pid file
+  manager         Specify a FCGI::ProcManager sub-class
+  detach          Detach from console
 
 =cut
 
@@ -74,17 +76,28 @@ sub run {
     my $proc_manager;
 
     if ($listen) {
-        require FCGI::ProcManager;
-        $options->{nproc} ||= 1;
-
-        $proc_manager =
-          FCGI::ProcManager->new( { n_processes => $options->{nproc} } );
-
-        if ( $options->{pidfile} ) {
-            $proc_manager->pm_write_pid_file( $options->{pidfile} );
+        $options->{manager} ||= "FCGI::ProcManager";
+        $options->{nproc}   ||= 1;
+        
+        $self->daemon_fork() if $options->{detach};
+        
+        if ( $options->{manager} ) {
+            eval "use $options->{manager}; 1" or die $@;
+
+            $proc_manager
+                = $options->{manager}->new( {
+                    n_processes => $options->{nproc},
+                    pid_fname   => $options->{pidfile},
+                } );
+                
+            # detach *before* the ProcManager inits
+            $self->daemon_detach() if $options->{detach};
+
+            $proc_manager->pm_manage();
         }
-
-        $proc_manager->pm_manage();
+        elsif ( $options->{detach} ) {
+            $self->daemon_detach();
+        }            
     }
 
     while ( $request->Accept >= 0 ) {
@@ -111,6 +124,39 @@ sub write {
     *STDOUT->syswrite($buffer);
 }
 
+=item $self->daemon_fork()
+
+Performs the first part of daemon initialisation.  Specifically,
+forking.  STDERR, etc are still connected to a terminal.
+
+=cut
+
+sub daemon_fork {
+    require POSIX;
+    fork && exit;
+}
+
+=item $self->daemon_detach( )
+
+Performs the second part of daemon initialisation.  Specifically,
+disassociates from the terminal.
+
+However, this does B<not> change the current working directory to "/",
+as normal daemons do.  It also does not close all open file
+descriptors (except STDIN, STDOUT and STDERR, which are re-opened from
+F</dev/null>).
+
+=cut
+
+sub daemon_detach {
+    my $self = shift;
+    print "FastCGI daemon started (pid $$)\n";
+    open STDIN, "+</dev/null" or die $!;
+    open STDOUT, ">&STDIN" or die $!;
+    open STDERR, ">&STDIN" or die $!;
+    POSIX::setsid();
+}
+
 1;
 __END__
 
index f26b811..2c63481 100644 (file)
@@ -701,13 +701,15 @@ use lib "$FindBin::Bin/../lib";
 use [% name %];
 
 my $help = 0;
-my ( $listen, $nproc, $pidfile );
+my ( $listen, $nproc, $pidfile, $manager, $detach );
  
 GetOptions(
     'help|?'      => \$help,
     'listen|l=s'  => \$listen,
     'nproc|n=i'   => \$nproc,
     'pidfile|p=s' => \$pidfile,
+    'manager|M=s' => \$manager,
+    'daemon|d'    => \$detach,
 );
 
 pod2usage(1) if $help;
@@ -716,6 +718,8 @@ pod2usage(1) if $help;
     $listen, 
     {   nproc   => $nproc,
         pidfile => $pidfile, 
+        manager => $manager,
+        detach  => $detach,
     }
 );
 
@@ -740,6 +744,10 @@ pod2usage(1) if $help;
                  requires -listen)
    -p -pidfile   specify filename for pid file
                  (requires -listen)
+   -d -daemon    daemonize (requires -listen)
+   -M -manager   specify alternate process manager
+                 (FCGI::ProcessManager sub-class)
+                 or empty string to disable
 
 =head1 DESCRIPTION