FCGI local-lib-built_debian_i386
Tomas Doran [Fri, 28 May 2010 10:47:48 +0000 (11:47 +0100)]
local-lib5/lib/perl5/FCGI/ProcManager.pm [new file with mode: 0644]
local-lib5/lib/perl5/i486-linux-gnu-thread-multi/FCGI.pm [new file with mode: 0644]
local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/.packlist [new file with mode: 0644]
local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.bs [new file with mode: 0644]
local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.so [new file with mode: 0755]
local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/ProcManager/.packlist [new file with mode: 0644]
local-lib5/man/man3/FCGI.3pm [new file with mode: 0644]
local-lib5/man/man3/FCGI::ProcManager.3pm [new file with mode: 0644]

diff --git a/local-lib5/lib/perl5/FCGI/ProcManager.pm b/local-lib5/lib/perl5/FCGI/ProcManager.pm
new file mode 100644 (file)
index 0000000..f8e0797
--- /dev/null
@@ -0,0 +1,736 @@
+package FCGI::ProcManager;
+
+# Copyright (c) 2000, FundsXpress Financial Network, Inc.
+# This library is free software released under the GNU Lesser General
+# Public License, Version 2.1.  Please read the important licensing and
+# disclaimer information included below.
+
+# $Id: ProcManager.pm,v 1.23 2001/04/23 16:10:11 muaddie Exp $
+
+use strict;
+use Exporter;
+use POSIX qw(:signal_h);
+
+use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS $Q $SIG_CODEREF);
+BEGIN {
+  $VERSION = '0.19'; 
+  @ISA = qw(Exporter);
+  @EXPORT_OK = qw(pm_manage pm_die pm_wait
+                 pm_write_pid_file pm_remove_pid_file
+                 pm_pre_dispatch pm_post_dispatch
+                 pm_change_process_name pm_received_signal pm_parameter 
+                 pm_warn pm_notify pm_abort pm_exit
+                 $SIG_CODEREF);
+  $EXPORT_TAGS{all} = \@EXPORT_OK;
+  $FCGI::ProcManager::Default = 'FCGI::ProcManager';
+}
+
+=head1 NAME
+
+ FCGI::ProcManager - functions for managing FastCGI applications.
+
+=head1 SYNOPSIS
+
+{
+ # In Object-oriented style.
+ use CGI::Fast;
+ use FCGI::ProcManager;
+ my $proc_manager = FCGI::ProcManager->new({
+       n_processes => 10 
+ });
+ $proc_manager->pm_manage();
+ while (my $cgi = CGI::Fast->new()) {
+   $proc_manager->pm_pre_dispatch();
+   # ... handle the request here ...
+   $proc_manager->pm_post_dispatch();
+ }
+
+ # This style is also supported:
+ use CGI::Fast;
+ use FCGI::ProcManager qw(pm_manage pm_pre_dispatch 
+                         pm_post_dispatch);
+ pm_manage( n_processes => 10 );
+ while (my $cgi = CGI::Fast->new()) {
+   pm_pre_dispatch();
+   #...
+   pm_post_dispatch();
+ }
+
+=head1 DESCRIPTION
+
+FCGI::ProcManager is used to serve as a FastCGI process manager.  By
+re-implementing it in perl, developers can more finely tune performance in
+their web applications, and can take advantage of copy-on-write semantics
+prevalent in UNIX kernel process management.  The process manager should
+be invoked before the caller''s request loop
+
+The primary routine, C<pm_manage>, enters a loop in which it maintains a
+number of FastCGI servers (via fork(2)), and which reaps those servers
+when they die (via wait(2)).
+
+C<pm_manage> provides too hooks:
+
+ C<managing_init> - called just before the manager enters the manager loop.
+ C<handling_init> - called just before a server is returns from C<pm_manage>
+
+It is necessary for the caller, when implementing its request loop, to
+insert a call to C<pm_pre_dispatch> at the top of the loop, and then
+7C<pm_post_dispatch> at the end of the loop.
+
+=head2 Signal Handling
+
+FCGI::ProcManager attempts to do the right thing for proper shutdowns now.
+
+When it receives a SIGHUP, it sends a SIGTERM to each of its children, and
+then resumes its normal operations.   
+
+When it receives a SIGTERM, it sends a SIGTERM to each of its children, sets
+an alarm(3) "die timeout" handler, and waits for each of its children to
+die.  If all children die before this timeout, process manager exits with
+return status 0.  If all children do not die by the time the "die timeout"
+occurs, the process manager sends a SIGKILL to each of the remaining
+children, and exists with return status 1.
+
+In order to get FastCGI servers to exit upon receiving a signal, it is
+necessary to use its FAIL_ACCEPT_ON_INTR.  See FCGI.pm's description of
+FAIL_ACCEPT_ON_INTR.  Unfortunately, if you want/need to use CGI::Fast, it
+appears currently necessary to modify your installation of FCGI.pm, with
+something like the following:
+
+ -*- patch -*-
+ --- FCGI.pm     2001/03/09 01:44:00     1.1.1.3
+ +++ FCGI.pm     2001/03/09 01:47:32     1.2
+ @@ -24,7 +24,7 @@
+  *FAIL_ACCEPT_ON_INTR = sub() { 1 };
+  
+  sub Request(;***$$$) {
+ -    my @defaults = (\*STDIN, \*STDOUT, \*STDERR, \%ENV, 0, 0);
+ +    my @defaults = (\*STDIN, \*STDOUT, \*STDERR, \%ENV, 0, FAIL_ACCEPT_ON_INTR());
+      splice @defaults,0,@_,@_;
+      RequestX(@defaults);
+  }   
+ -*- end patch -*-
+
+Otherwise, if you don't, there is a loop around accept(2) which prevents
+os_unix.c OS_Accept() from returning the necessary error when FastCGI
+servers blocking on accept(2) receive the SIGTERM or SIGHUP.
+
+FCGI::ProcManager uses POSIX::sigaction() to override the default SA_RESTART
+policy used for perl's %SIG behavior.  Specifically, the process manager
+never uses SA_RESTART, while the child FastCGI servers turn off SA_RESTART
+around the accept(2) loop, but re-enstate it otherwise.
+
+The desired (and implemented) effect is to give a request as big a chance as
+possible to succeed and to delay their exits until after their request,
+while allowing the FastCGI servers waiting for new requests to die right
+away. 
+
+=head1 METHODS
+
+=head2 new
+
+ class or instance
+ (ProcManager) new([hash parameters])
+
+Constructs a new process manager.  Takes an option has of initial parameter
+values, and assigns these to the constructed object HASH, overriding any
+default values.  The default parameter values currently are:
+
+ role         => manager
+ start_delay  => 0
+ die_timeout  => 60
+ pm_title => 'perl-fcgi-pm'
+
+=cut
+
+sub new {
+  my ($proto,$init) = @_;
+  $init ||= {};
+
+  my $this = { 
+             role => "manager",
+             start_delay => 0,
+             die_timeout => 60,
+        pm_title => 'perl-fcgi-pm',
+             %$init
+            };
+  bless $this, ref($proto)||$proto;
+
+  $this->{PIDS} = {};
+
+  # initialize signal constructions.
+  unless ($this->no_signals()) {
+    $this->{sigaction_no_sa_restart} =
+       POSIX::SigAction->new('FCGI::ProcManager::sig_sub');
+    $this->{sigaction_sa_restart} =
+       POSIX::SigAction->new('FCGI::ProcManager::sig_sub',undef,POSIX::SA_RESTART);
+  }
+
+  return $this;
+}
+
+=head1 Manager methods
+
+=head2 pm_manage
+
+ instance or export
+ (int) pm_manage([hash parameters])
+
+DESCRIPTION:
+
+When this is called by a FastCGI script to manage application servers.  It
+defines a sequence of instructions for a process to enter this method and
+begin forking off and managing those handlers, and it defines a sequence of
+instructions to intialize those handlers.
+
+If n_processes < 1, the managing section is subverted, and only the
+handling sequence is executed.
+
+Either returns the return value of pm_die() and/or pm_abort() (which will
+not ever return in general), or returns 1 to the calling script to begin
+handling requests.
+
+=cut
+
+sub pm_manage {
+  my ($this,%values) = self_or_default(@_);
+  map { $this->pm_parameter($_,$values{$_}) } keys %values;
+
+  # skip to handling now if we won't be managing any processes.
+  $this->n_processes() or return;
+
+  # call the (possibly overloaded) management initialization hook.
+  $this->role("manager");
+  $this->managing_init();
+  $this->pm_notify("initialized");
+
+  my $manager_pid = $$;
+
+ MANAGING_LOOP: while (1) {
+
+    $this->n_processes() > 0 or
+      return $this->pm_die();
+
+    # while we have fewer servers than we want.
+  PIDS: while (keys(%{$this->{PIDS}}) < $this->n_processes()) {
+
+      if (my $pid = fork()) {
+       # the manager remembers the server.
+       $this->{PIDS}->{$pid} = { pid=>$pid };
+        $this->pm_notify("server (pid $pid) started");
+
+      } elsif (! defined $pid) {
+       return $this->pm_abort("fork: $!");
+
+      } else {
+       $this->{MANAGER_PID} = $manager_pid;
+       # the server exits the managing loop.
+       last MANAGING_LOOP;
+      }
+
+      for (my $s = $this->start_delay(); $s; $s = sleep $s) {};
+    }
+
+    # this should block until the next server dies.
+    $this->pm_wait();
+
+  }# while 1
+
+HANDLING:
+
+  # forget any children we had been collecting.
+  delete $this->{PIDS};
+
+  # call the (possibly overloaded) handling init hook
+  $this->role("server");
+  $this->handling_init();
+  $this->pm_notify("initialized");
+
+  # server returns 
+  return 1;
+}
+
+=head2 managing_init
+
+ instance
+ () managing_init()
+
+DESCRIPTION:
+
+Overrideable method which initializes a process manager.  In order to
+handle signals, manage the PID file, and change the process name properly,
+any method which overrides this should call SUPER::managing_init().
+
+=cut
+
+sub managing_init {
+  my ($this) = @_;
+
+  # begin to handle signals.
+  # We do NOT want SA_RESTART in the process manager.
+  # -- we want start the shutdown sequence immediately upon SIGTERM.
+  unless ($this->no_signals()) {
+    sigaction(SIGTERM, $this->{sigaction_no_sa_restart}) or
+       $this->pm_warn("sigaction: SIGTERM: $!");
+    sigaction(SIGHUP,  $this->{sigaction_no_sa_restart}) or
+       $this->pm_warn("sigaction: SIGHUP: $!");
+    $SIG_CODEREF = sub { $this->sig_manager(@_) };
+  }
+
+  # change the name of this process as it appears in ps(1) output.
+  $this->pm_change_process_name($this->pm_parameter('pm_title'));
+
+  $this->pm_write_pid_file();
+}
+
+=head2 pm_die
+
+ instance or export
+ () pm_die(string msg[, int exit_status])
+
+DESCRIPTION:
+
+This method is called when a process manager receives a notification to
+shut itself down.  pm_die() attempts to shutdown the process manager
+gently, sending a SIGTERM to each managed process, waiting die_timeout()
+seconds to reap each process, and then exit gracefully once all children
+are reaped, or to abort if all children are not reaped.
+
+=cut
+
+sub pm_die {
+  my ($this,$msg,$n) = self_or_default(@_);
+
+  # stop handling signals.
+  undef $SIG_CODEREF;
+  $SIG{HUP}  = 'DEFAULT';
+  $SIG{TERM} = 'DEFAULT';
+
+  $this->pm_remove_pid_file();
+
+  # prepare to die no matter what.
+  if (defined $this->die_timeout()) {
+    $SIG{ALRM} = sub { $this->pm_abort("wait timeout") };
+    alarm $this->die_timeout();
+  }
+
+  # send a TERM to each of the servers.
+  if (my @pids = keys %{$this->{PIDS}}) {
+    $this->pm_notify("sending TERM to PIDs, @pids");
+    kill "TERM", @pids;
+  }
+
+  # wait for the servers to die.
+  while (%{$this->{PIDS}}) {
+    $this->pm_wait();
+  }
+
+  # die already.
+  $this->pm_exit("dying: ".$msg,$n);
+}
+
+=head2 pm_wait
+
+ instance or export
+ (int pid) pm_wait()
+
+DESCRIPTION:
+
+This calls wait() which suspends execution until a child has exited.
+If the process ID returned by wait corresponds to a managed process,
+pm_notify() is called with the exit status of that process.
+pm_wait() returns with the return value of wait().
+
+=cut
+
+sub pm_wait {
+  my ($this) = self_or_default(@_);
+
+  # wait for the next server to die.
+  next if (my $pid = wait()) < 0;
+
+  # notify when one of our servers have died.
+  delete $this->{PIDS}->{$pid} and
+    $this->pm_notify("server (pid $pid) exited with status $?");
+
+  return $pid;
+}
+
+=head2 pm_write_pid_file
+
+ instance or export
+ () pm_write_pid_file([string filename])
+
+DESCRIPTION:
+
+Writes current process ID to optionally specified file.  If no filename is
+specified, it uses the value of the C<pid_fname> parameter.
+
+=cut
+
+sub pm_write_pid_file {
+  my ($this,$fname) = self_or_default(@_);
+  $fname ||= $this->pid_fname() or return;
+  if (!open PIDFILE, ">$fname") {
+    $this->pm_warn("open: $fname: $!");
+    return;
+  }
+  print PIDFILE "$$\n";
+  close PIDFILE;
+}
+
+=head2 pm_remove_pid_file
+
+ instance or export
+ () pm_remove_pid_file()
+
+DESCRIPTION:
+
+Removes optionally specified file.  If no filename is specified, it uses
+the value of the C<pid_fname> parameter.
+
+=cut
+
+sub pm_remove_pid_file {
+  my ($this,$fname) = self_or_default(@_);
+  $fname ||= $this->pid_fname() or return;
+  my $ret = unlink($fname) or $this->pm_warn("unlink: $fname: $!");
+  return $ret;
+}
+
+=head2 sig_sub
+
+ instance
+ () sig_sub(string name)
+
+DESCRIPTION:
+
+The name of this method is passed to POSIX::sigaction(), and handles signals
+for the process manager.  If $SIG_CODEREF is set, then the input arguments
+to this are passed to a call to that.
+
+=cut
+
+sub sig_sub {
+  $SIG_CODEREF->(@_) if ref $SIG_CODEREF;
+}
+
+=head2 sig_manager
+
+ instance
+ () sig_manager(string name)
+
+DESCRIPTION:
+
+Handles signals of the process manager.  Takes as input the name of signal
+being handled.
+
+=cut
+
+sub sig_manager {
+  my ($this,$name) = @_;
+  if ($name eq "TERM") {
+    $this->pm_notify("received signal $name");
+    $this->pm_die("safe exit from signal $name");
+  } elsif ($name eq "HUP") {
+    # send a TERM to each of the servers, and pretend like nothing happened..
+    if (my @pids = keys %{$this->{PIDS}}) {
+      $this->pm_notify("sending TERM to PIDs, @pids");
+      kill "TERM", @pids;
+    }
+  } else {
+    $this->pm_notify("ignoring signal $name");
+  }
+}
+
+=head1 Handler methods
+
+=head2 handling_init
+
+ instance or export
+ () handling_init()
+
+DESCRIPTION:
+
+=cut
+
+sub handling_init {
+  my ($this) = @_;
+
+  # begin to handle signals.
+  # We'll want accept(2) to return -1(EINTR) on caught signal..
+  unless ($this->no_signals()) {
+    sigaction(SIGTERM, $this->{sigaction_no_sa_restart}) or $this->pm_warn("sigaction: SIGTERM: $!");
+    sigaction(SIGHUP,  $this->{sigaction_no_sa_restart}) or $this->pm_warn("sigaction: SIGHUP: $!");
+    $SIG_CODEREF = sub { $this->sig_handler(@_) };
+  }
+
+  # change the name of this process as it appears in ps(1) output.
+  $this->pm_change_process_name("perl-fcgi");
+}
+
+=head2 pm_pre_dispatch
+
+ instance or export
+ () pm_pre_dispatch()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_pre_dispatch {
+  my ($this) = self_or_default(@_);
+
+  # Now, we want the request to continue unhindered..
+  unless ($this->no_signals()) {
+    sigaction(SIGTERM, $this->{sigaction_sa_restart}) or $this->pm_warn("sigaction: SIGTERM: $!");
+    sigaction(SIGHUP,  $this->{sigaction_sa_restart}) or $this->pm_warn("sigaction: SIGHUP: $!");
+  }
+}
+
+=head2 pm_post_dispatch
+
+ instance or export
+ () pm_post_dispatch()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_post_dispatch {
+  my ($this) = self_or_default(@_);
+  if ($this->pm_received_signal("TERM")) {
+    $this->pm_exit("safe exit after SIGTERM");
+  }
+  if ($this->pm_received_signal("HUP")) {
+    $this->pm_exit("safe exit after SIGHUP");
+  }
+  if ($this->{MANAGER_PID} and getppid() != $this->{MANAGER_PID}) {
+    $this->pm_exit("safe exit: manager has died");
+  }
+  # We'll want accept(2) to return -1(EINTR) on caught signal..
+  unless ($this->no_signals()) {
+    sigaction(SIGTERM, $this->{sigaction_no_sa_restart}) or $this->pm_warn("sigaction: SIGTERM: $!");
+    sigaction(SIGHUP,  $this->{sigaction_no_sa_restart}) or $this->pm_warn("sigaction: SIGHUP: $!");
+  }
+}
+
+=head2 sig_handler
+
+ instance or export
+ () sig_handler()
+
+DESCRIPTION:
+
+=cut
+
+sub sig_handler {
+  my ($this,$name) = @_;
+  $this->pm_received_signal($name,1);
+}
+
+=head1 Common methods and routines
+
+=head2 self_or_default
+
+ private global
+ (ProcManager, @args) self_or_default([ ProcManager, ] @args);
+
+DESCRIPTION:
+
+This is a helper subroutine to acquire or otherwise create a singleton
+default object if one is not passed in, e.g., a method call.
+
+=cut
+
+sub self_or_default {
+  return @_ if defined $_[0] and !ref $_[0] and $_[0] eq 'FCGI::ProcManager';
+  if (!defined $_[0] or (ref($_[0]) ne 'FCGI::ProcManager' and
+                        !UNIVERSAL::isa($_[0],'FCGI::ProcManager'))) {
+    $Q or $Q = $FCGI::ProcManager::Default->new;
+    unshift @_, $Q;
+  }
+  return wantarray ? @_ : $Q;
+}
+
+=head2 pm_change_process_name
+
+ instance or export
+ () pm_change_process_name()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_change_process_name {
+  my ($this,$name) = self_or_default(@_);
+  $0 = $name;
+}
+
+=head2 pm_received_signal
+
+ instance or export
+ () pm_received signal()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_received_signal {
+  my ($this,$sig,$received) = self_or_default(@_);
+  $sig or return $this->{SIG_RECEIVED};
+  $received and $this->{SIG_RECEIVED}->{$sig}++;
+  return $this->{SIG_RECEIVED}->{$sig};
+}
+
+=head1 parameters
+
+=head2 pm_parameter
+
+ instance or export
+ () pm_parameter()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_parameter {
+  my ($this,$key,$value) = self_or_default(@_);
+  defined $value and $this->{$key} = $value;
+  return $this->{$key};
+}
+
+=head2 n_processes
+
+=head2 no_signals
+
+=head2 pid_fname
+
+=head2 die_timeout
+
+=head2 role
+
+=head2 start_delay
+
+DESCRIPTION:
+
+=cut
+
+sub n_processes     { shift->pm_parameter("n_processes",     @_); }
+sub pid_fname       { shift->pm_parameter("pid_fname",       @_); }
+sub no_signals      { shift->pm_parameter("no_signals",      @_); }
+sub die_timeout     { shift->pm_parameter("die_timeout",     @_); }
+sub role            { shift->pm_parameter("role",            @_); }
+sub start_delay     { shift->pm_parameter("start_delay",     @_); }
+
+=head1 notification and death
+
+=head2 pm_warn
+
+ instance or export
+ () pm_warn()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_warn {
+  my ($this,$msg) = self_or_default(@_);
+  $this->pm_notify($msg);
+}
+
+=head2 pm_notify
+
+ instance or export
+ () pm_notify()
+
+DESCRIPTION:
+
+=cut
+
+sub pm_notify {
+  my ($this,$msg) = self_or_default(@_);
+  $msg =~ s/\s*$/\n/;
+  print STDERR "FastCGI: ".$this->role()." (pid $$): ".$msg;
+}
+
+=head2 pm_exit
+
+ instance or export
+ () pm_exit(string msg[, int exit_status])
+
+DESCRIPTION:
+
+=cut
+
+sub pm_exit {
+  my ($this,$msg,$n) = self_or_default(@_);
+  $n ||= 0;
+
+  # if we still have children at this point, something went wrong.
+  # SIGKILL them now.
+  kill "KILL", keys %{$this->{PIDS}} if $this->{PIDS};
+
+  $this->pm_warn($msg);
+  $@ = $msg;
+  exit $n;
+}
+
+=head2 pm_abort
+
+ instance or export
+ () pm_abort(string msg[, int exit_status])
+
+DESCRIPTION:
+
+=cut
+
+sub pm_abort {
+  my ($this,$msg,$n) = self_or_default(@_);
+  $n ||= 1;
+  $this->pm_exit($msg,1);
+}
+
+1;
+__END__
+
+=head1 BUGS
+
+No known bugs, but this does not mean no bugs exist.
+
+=head1 SEE ALSO
+
+L<FCGI>.
+
+=head1 MAINTAINER
+
+Gareth Kirwan <gbjk@thermeon.com>
+
+=head1 AUTHOR
+
+James E Jurach Jr.
+
+=head1 COPYRIGHT
+
+ FCGI-ProcManager - A Perl FCGI Process Manager
+ Copyright (c) 2000, FundsXpress Financial Network, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ BECAUSE THIS LIBRARY IS LICENSED FREE OF CHARGE, THIS LIBRARY IS
+ BEING PROVIDED "AS IS WITH ALL FAULTS," WITHOUT ANY WARRANTIES
+ OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT
+ LIMITATION, ANY IMPLIED WARRANTIES OF TITLE, NONINFRINGEMENT,
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, AND THE
+ ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY,
+ AND EFFORT IS WITH THE YOU.  See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+
+=cut
diff --git a/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/FCGI.pm b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/FCGI.pm
new file mode 100644 (file)
index 0000000..eecf13a
--- /dev/null
@@ -0,0 +1,312 @@
+# $Id: FCGI.PL,v 1.37 2002/12/15 20:02:48 skimo Exp $
+
+package FCGI;
+
+require Exporter;
+require DynaLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT = qw(
+
+);
+
+$VERSION = q{0.71};
+
+bootstrap FCGI;
+$VERSION = eval $VERSION;
+# Preloaded methods go here.
+
+# Autoload methods go after __END__, and are processed by the autosplit program.
+
+*FAIL_ACCEPT_ON_INTR = sub() { 1 };
+
+sub Request(;***$*$) {
+    my @defaults = (\*STDIN, \*STDOUT, \*STDERR, \%ENV, 0, 0);
+    $_[4] = fileno($_[4]) if defined($_[4]) && defined(fileno($_[4]));
+    splice @defaults,0,@_,@_;
+    RequestX(@defaults);
+}
+
+sub accept() {
+    warn "accept called as a method; you probably wanted to call Accept" if @_;
+    if (%FCGI::ENV) {
+       %ENV = %FCGI::ENV;
+    } else {
+       %FCGI::ENV = %ENV;
+    }
+    my $rc = Accept($global_request);
+    for (keys %FCGI::ENV) {
+       $ENV{$_} = $FCGI::ENV{$_} unless exists $ENV{$_};
+    }
+
+    # not SFIO
+    $SIG{__WARN__} = $warn_handler if (tied (*STDIN));
+    $SIG{__DIE__} = $die_handler if (tied (*STDIN));
+
+    return $rc;
+}
+
+sub finish() {
+    warn "finish called as a method; you probably wanted to call Finish" if @_;
+    %ENV = %FCGI::ENV if %FCGI::ENV;
+
+    # not SFIO
+    if (tied (*STDIN)) {
+       delete $SIG{__WARN__} if ($SIG{__WARN__} == $warn_handler);
+       delete $SIG{__DIE__} if ($SIG{__DIE__} == $die_handler);
+    }
+
+    Finish ($global_request);
+}
+
+sub flush() {
+    warn "flush called as a method; you probably wanted to call Flush" if @_;
+    Flush($global_request);
+}
+
+sub detach() {
+    warn "detach called as a method; you probably wanted to call Detach" if @_;
+    Detach($global_request);
+}
+
+sub attach() {
+    warn "attach called as a method; you probably wanted to call Attach" if @_;
+    Attach($global_request);
+}
+
+# deprecated
+sub set_exit_status {
+}
+
+sub start_filter_data() {
+    StartFilterData($global_request);
+}
+
+$global_request = Request();
+$warn_handler = sub { print STDERR @_ };
+$die_handler = sub { print STDERR @_ unless $^S };
+
+package FCGI::Stream;
+
+sub PRINTF {
+  shift->PRINT(sprintf(shift, @_));
+}
+
+sub BINMODE {
+}
+
+sub READLINE {
+    my $stream = shift;
+    my ($s, $c);
+    my $rs = $/ eq '' ? "\n\n" : $/;
+    my $l = substr $rs, -1;
+    my $len = length $rs;
+
+    $c = $stream->GETC();
+    if ($/ eq '') {
+       while ($c eq "\n") {
+           $c = $stream->GETC();
+       }
+    }
+    while (defined $c) {
+       $s .= $c;
+       last if $c eq $l and substr($s, -$len) eq $rs;
+       $c = $stream->GETC();
+    }
+    $s;
+}
+
+sub OPEN {
+    $_[0]->CLOSE;
+    if (@_ == 2) {
+       return open($_[0], $_[1]);
+    } else {
+       my $rc;
+       eval("$rc = open($_[0], $_[1], $_[2])");
+       die $@ if $@;
+       return $rc;
+    }
+}
+
+# Some things (e.g. IPC::Run) use fileno to determine if a filehandle is open,
+# so we return a defined, but meaningless value. (-1 being the error return
+# value from the syscall in c, meaning it can never be a valid fd no)
+# Probably a better alternative would be to return the fcgi stream fd.
+sub FILENO { -1 }
+
+1;
+
+=pod
+
+=head1 NAME
+
+FCGI - Fast CGI module
+
+=head1 SYNOPSIS
+
+    use FCGI;
+
+    my $count = 0;
+    my $request = FCGI::Request();
+
+    while($request->Accept() >= 0) {
+       print("Content-type: text/html\r\n\r\n", ++$count);
+    }
+
+=head1 DESCRIPTION
+
+Functions:
+
+=over 4
+
+=item FCGI::Request
+
+Creates a request handle. It has the following optional parameters:
+
+=over 8
+
+=item input perl file handle (default: \*STDIN)
+
+=item output perl file handle (default: \*STDOUT)
+
+=item error perl file handle (default: \*STDERR)
+
+These filehandles will be setup to act as input/output/error
+on succesful Accept.
+
+=item environment hash reference (default: \%ENV)
+
+The hash will be populated with the environment.
+
+=item socket (default: 0)
+
+Socket to communicate with the server.
+Can be the result of the OpenSocket function.
+For the moment, it's the file descriptor of the socket
+that should be passed. This may change in the future.
+
+You should only use your own socket if your program
+is not started by a process manager such as mod_fastcgi
+(except for the FastCgiExternalServer case) or cgi-fcgi.
+If you use the option, you have to let your FastCGI
+server know which port (and possibly server) your program
+is listening on.
+See remote.pl for an example.
+
+=item flags (default: 0)
+
+Possible values:
+
+=over 12
+
+=item FCGI::FAIL_ACCEPT_ON_INTR
+
+If set, Accept will fail if interrupted.
+It not set, it will just keep on waiting.
+
+=back
+
+=back
+
+Example usage:
+    my $req = FCGI::Request;
+
+or:
+    my %env;
+    my $in = new IO::Handle;
+    my $out = new IO::Handle;
+    my $err = new IO::Handle;
+    my $req = FCGI::Request($in, $out, $err, \%env);
+
+=item FCGI::OpenSocket(path, backlog)
+
+Creates a socket suitable to use as an argument to Request.
+
+=over 8
+
+=item path
+
+Pathname of socket or colon followed by local tcp port.
+Note that some systems take file permissions into account
+on Unix domain sockets, so you'll have to make sure that
+the server can write to the created file, by changing
+the umask before the call and/or changing permissions and/or
+group of the file afterwards.
+
+=item backlog
+
+Maximum length of the queue of pending connections.
+If a connection
+request arrives with the queue full the client may receive
+an  error  with  an  indication of ECONNREFUSED.
+
+=back
+
+=item FCGI::CloseSocket(socket)
+
+Close a socket opened with OpenSocket.
+
+=item $req->Accept()
+
+Accepts a connection on $req, attaching the filehandles and
+populating the environment hash.
+Returns 0 on success.
+If a connection has been accepted before, the old
+one will be finished first.
+
+Note that unlike with the old interface, no die and warn
+handlers are installed by default. This means that if
+you are not running an sfio enabled perl, any warn or
+die message will not end up in the server's log by default.
+It is advised you set up die and warn handlers yourself.
+FCGI.pm contains an example of die and warn handlers.
+
+=item $req->Finish()
+
+Finishes accepted connection.
+Also detaches filehandles.
+
+=item $req->Flush()
+
+Flushes accepted connection.
+
+=item $req->Detach()
+
+Temporarily detaches filehandles on an accepted connection.
+
+=item $req->Attach()
+
+Re-attaches filehandles on an accepted connection.
+
+=item $req->LastCall()
+
+Tells the library not to accept any more requests on this handle.
+It should be safe to call this method from signal handlers.
+
+Note that this method is still experimental and everything
+about it, including its name, is subject to change.
+
+=item $env = $req->GetEnvironment()
+
+Returns the environment parameter passed to FCGI::Request.
+
+=item ($in, $out, $err) = $req->GetHandles()
+
+Returns the file handle parameters passed to FCGI::Request.
+
+=item $isfcgi = $req->IsFastCGI()
+
+Returns whether or not the program was run as a FastCGI.
+
+=back
+
+=head1 AUTHOR
+
+Sven Verdoolaege <skimo@kotnet.org>
+
+=cut
+
+__END__
diff --git a/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/.packlist b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/.packlist
new file mode 100644 (file)
index 0000000..e1ebf1e
--- /dev/null
@@ -0,0 +1,4 @@
+/home/t0m/Gitalist/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/FCGI.pm
+/home/t0m/Gitalist/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.bs
+/home/t0m/Gitalist/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.so
+/home/t0m/Gitalist/local-lib5/man/man3/FCGI.3pm
diff --git a/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.bs b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.bs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.so b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.so
new file mode 100755 (executable)
index 0000000..b060e2c
Binary files /dev/null and b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/FCGI.so differ
diff --git a/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/ProcManager/.packlist b/local-lib5/lib/perl5/i486-linux-gnu-thread-multi/auto/FCGI/ProcManager/.packlist
new file mode 100644 (file)
index 0000000..f6e62b8
--- /dev/null
@@ -0,0 +1,2 @@
+/home/t0m/Gitalist/local-lib5/lib/perl5/FCGI/ProcManager.pm
+/home/t0m/Gitalist/local-lib5/man/man3/FCGI::ProcManager.3pm
diff --git a/local-lib5/man/man3/FCGI.3pm b/local-lib5/man/man3/FCGI.3pm
new file mode 100644 (file)
index 0000000..196fe7b
--- /dev/null
@@ -0,0 +1,282 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.el \{\
+.    de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "FCGI 3"
+.TH FCGI 3 "2010-05-28" "perl v5.8.8" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+FCGI \- Fast CGI module
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 1
+\&    use FCGI;
+\&
+\&    my $count = 0;
+\&    my $request = FCGI::Request();
+\&
+\&    while($request\->Accept() >= 0) {
+\&        print("Content\-type: text/html\er\en\er\en", ++$count);
+\&    }
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+Functions:
+.IP "FCGI::Request" 4
+.IX Item "FCGI::Request"
+Creates a request handle. It has the following optional parameters:
+.RS 4
+.IP "input perl file handle (default: \e*STDIN)" 8
+.IX Item "input perl file handle (default: *STDIN)"
+.PD 0
+.IP "output perl file handle (default: \e*STDOUT)" 8
+.IX Item "output perl file handle (default: *STDOUT)"
+.IP "error perl file handle (default: \e*STDERR)" 8
+.IX Item "error perl file handle (default: *STDERR)"
+.PD
+These filehandles will be setup to act as input/output/error
+on succesful Accept.
+.IP "environment hash reference (default: \e%ENV)" 8
+.IX Item "environment hash reference (default: %ENV)"
+The hash will be populated with the environment.
+.IP "socket (default: 0)" 8
+.IX Item "socket (default: 0)"
+Socket to communicate with the server.
+Can be the result of the OpenSocket function.
+For the moment, it's the file descriptor of the socket
+that should be passed. This may change in the future.
+.Sp
+You should only use your own socket if your program
+is not started by a process manager such as mod_fastcgi
+(except for the FastCgiExternalServer case) or cgi-fcgi.
+If you use the option, you have to let your FastCGI
+server know which port (and possibly server) your program
+is listening on.
+See remote.pl for an example.
+.IP "flags (default: 0)" 8
+.IX Item "flags (default: 0)"
+Possible values:
+.RS 8
+.IP "\s-1FCGI::FAIL_ACCEPT_ON_INTR\s0" 12
+.IX Item "FCGI::FAIL_ACCEPT_ON_INTR"
+If set, Accept will fail if interrupted.
+It not set, it will just keep on waiting.
+.RE
+.RS 8
+.RE
+.RE
+.RS 4
+.Sp
+Example usage:
+    my \f(CW$req\fR = FCGI::Request;
+.Sp
+or:
+    my \f(CW%env\fR;
+    my \f(CW$in\fR = new IO::Handle;
+    my \f(CW$out\fR = new IO::Handle;
+    my \f(CW$err\fR = new IO::Handle;
+    my \f(CW$req\fR = FCGI::Request($in, \f(CW$out\fR, \f(CW$err\fR, \e%env);
+.RE
+.IP "FCGI::OpenSocket(path, backlog)" 4
+.IX Item "FCGI::OpenSocket(path, backlog)"
+Creates a socket suitable to use as an argument to Request.
+.RS 4
+.IP "path" 8
+.IX Item "path"
+Pathname of socket or colon followed by local tcp port.
+Note that some systems take file permissions into account
+on Unix domain sockets, so you'll have to make sure that
+the server can write to the created file, by changing
+the umask before the call and/or changing permissions and/or
+group of the file afterwards.
+.IP "backlog" 8
+.IX Item "backlog"
+Maximum length of the queue of pending connections.
+If a connection
+request arrives with the queue full the client may receive
+an  error  with  an  indication of \s-1ECONNREFUSED\s0.
+.RE
+.RS 4
+.RE
+.IP "FCGI::CloseSocket(socket)" 4
+.IX Item "FCGI::CloseSocket(socket)"
+Close a socket opened with OpenSocket.
+.ie n .IP "$req\->\fIAccept()\fR" 4
+.el .IP "\f(CW$req\fR\->\fIAccept()\fR" 4
+.IX Item "$req->Accept()"
+Accepts a connection on \f(CW$req\fR, attaching the filehandles and
+populating the environment hash.
+Returns 0 on success.
+If a connection has been accepted before, the old
+one will be finished first.
+.Sp
+Note that unlike with the old interface, no die and warn
+handlers are installed by default. This means that if
+you are not running an sfio enabled perl, any warn or
+die message will not end up in the server's log by default.
+It is advised you set up die and warn handlers yourself.
+\&\s-1FCGI\s0.pm contains an example of die and warn handlers.
+.ie n .IP "$req\->\fIFinish()\fR" 4
+.el .IP "\f(CW$req\fR\->\fIFinish()\fR" 4
+.IX Item "$req->Finish()"
+Finishes accepted connection.
+Also detaches filehandles.
+.ie n .IP "$req\->\fIFlush()\fR" 4
+.el .IP "\f(CW$req\fR\->\fIFlush()\fR" 4
+.IX Item "$req->Flush()"
+Flushes accepted connection.
+.ie n .IP "$req\->\fIDetach()\fR" 4
+.el .IP "\f(CW$req\fR\->\fIDetach()\fR" 4
+.IX Item "$req->Detach()"
+Temporarily detaches filehandles on an accepted connection.
+.ie n .IP "$req\->\fIAttach()\fR" 4
+.el .IP "\f(CW$req\fR\->\fIAttach()\fR" 4
+.IX Item "$req->Attach()"
+Re-attaches filehandles on an accepted connection.
+.ie n .IP "$req\->\fILastCall()\fR" 4
+.el .IP "\f(CW$req\fR\->\fILastCall()\fR" 4
+.IX Item "$req->LastCall()"
+Tells the library not to accept any more requests on this handle.
+It should be safe to call this method from signal handlers.
+.Sp
+Note that this method is still experimental and everything
+about it, including its name, is subject to change.
+.ie n .IP "$env = $req\->\fIGetEnvironment()\fR" 4
+.el .IP "\f(CW$env\fR = \f(CW$req\fR\->\fIGetEnvironment()\fR" 4
+.IX Item "$env = $req->GetEnvironment()"
+Returns the environment parameter passed to FCGI::Request.
+.ie n .IP "($in, $out, $err) = $req\->\fIGetHandles()\fR" 4
+.el .IP "($in, \f(CW$out\fR, \f(CW$err\fR) = \f(CW$req\fR\->\fIGetHandles()\fR" 4
+.IX Item "($in, $out, $err) = $req->GetHandles()"
+Returns the file handle parameters passed to FCGI::Request.
+.ie n .IP "$isfcgi = $req\->\fIIsFastCGI()\fR" 4
+.el .IP "\f(CW$isfcgi\fR = \f(CW$req\fR\->\fIIsFastCGI()\fR" 4
+.IX Item "$isfcgi = $req->IsFastCGI()"
+Returns whether or not the program was run as a FastCGI.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Sven Verdoolaege <skimo@kotnet.org>
diff --git a/local-lib5/man/man3/FCGI::ProcManager.3pm b/local-lib5/man/man3/FCGI::ProcManager.3pm
new file mode 100644 (file)
index 0000000..73db592
--- /dev/null
@@ -0,0 +1,515 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.el \{\
+.    de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "ProcManager 3"
+.TH ProcManager 3 "2009-07-22" "perl v5.8.8" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+.Vb 1
+\& FCGI::ProcManager \- functions for managing FastCGI applications.
+.Ve
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+{
+ # In Object-oriented style.
+ use CGI::Fast;
+ use FCGI::ProcManager;
+ my \f(CW$proc_manager\fR = FCGI::ProcManager\->new({
+       n_processes => 10 
+ });
+ \f(CW$proc_manager\fR\->\fIpm_manage()\fR;
+ while (my \f(CW$cgi\fR = CGI::Fast\->\fInew()\fR) {
+   \f(CW$proc_manager\fR\->\fIpm_pre_dispatch()\fR;
+   # ... handle the request here ...
+   \f(CW$proc_manager\fR\->\fIpm_post_dispatch()\fR;
+ }
+.PP
+.Vb 10
+\& # This style is also supported:
+\& use CGI::Fast;
+\& use FCGI::ProcManager qw(pm_manage pm_pre_dispatch 
+\&                          pm_post_dispatch);
+\& pm_manage( n_processes => 10 );
+\& while (my $cgi = CGI::Fast\->new()) {
+\&   pm_pre_dispatch();
+\&   #...
+\&   pm_post_dispatch();
+\& }
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+FCGI::ProcManager is used to serve as a FastCGI process manager.  By
+re-implementing it in perl, developers can more finely tune performance in
+their web applications, and can take advantage of copy-on-write semantics
+prevalent in \s-1UNIX\s0 kernel process management.  The process manager should
+be invoked before the caller''s request loop
+.PP
+The primary routine, \f(CW\*(C`pm_manage\*(C'\fR, enters a loop in which it maintains a
+number of FastCGI servers (via \fIfork\fR\|(2)), and which reaps those servers
+when they die (via \fIwait\fR\|(2)).
+.PP
+\&\f(CW\*(C`pm_manage\*(C'\fR provides too hooks:
+.PP
+.Vb 2
+\& C<managing_init> \- called just before the manager enters the manager loop.
+\& C<handling_init> \- called just before a server is returns from C<pm_manage>
+.Ve
+.PP
+It is necessary for the caller, when implementing its request loop, to
+insert a call to \f(CW\*(C`pm_pre_dispatch\*(C'\fR at the top of the loop, and then
+7\f(CW\*(C`pm_post_dispatch\*(C'\fR at the end of the loop.
+.SS "Signal Handling"
+.IX Subsection "Signal Handling"
+FCGI::ProcManager attempts to do the right thing for proper shutdowns now.
+.PP
+When it receives a \s-1SIGHUP\s0, it sends a \s-1SIGTERM\s0 to each of its children, and
+then resumes its normal operations.
+.PP
+When it receives a \s-1SIGTERM\s0, it sends a \s-1SIGTERM\s0 to each of its children, sets
+an \fIalarm\fR\|(3) \*(L"die timeout\*(R" handler, and waits for each of its children to
+die.  If all children die before this timeout, process manager exits with
+return status 0.  If all children do not die by the time the \*(L"die timeout\*(R"
+occurs, the process manager sends a \s-1SIGKILL\s0 to each of the remaining
+children, and exists with return status 1.
+.PP
+In order to get FastCGI servers to exit upon receiving a signal, it is
+necessary to use its \s-1FAIL_ACCEPT_ON_INTR\s0.  See \s-1FCGI\s0.pm's description of
+\&\s-1FAIL_ACCEPT_ON_INTR\s0.  Unfortunately, if you want/need to use CGI::Fast, it
+appears currently necessary to modify your installation of \s-1FCGI\s0.pm, with
+something like the following:
+.PP
+.Vb 5
+\& \-*\- patch \-*\-
+\& \-\-\- FCGI.pm     2001/03/09 01:44:00     1.1.1.3
+\& +++ FCGI.pm     2001/03/09 01:47:32     1.2
+\& @@ \-24,7 +24,7 @@
+\&  *FAIL_ACCEPT_ON_INTR = sub() { 1 };
+\&  
+\&  sub Request(;***$$$) {
+\& \-    my @defaults = (\e*STDIN, \e*STDOUT, \e*STDERR, \e%ENV, 0, 0);
+\& +    my @defaults = (\e*STDIN, \e*STDOUT, \e*STDERR, \e%ENV, 0, FAIL_ACCEPT_ON_INTR());
+\&      splice @defaults,0,@_,@_;
+\&      RequestX(@defaults);
+\&  }   
+\& \-*\- end patch \-*\-
+.Ve
+.PP
+Otherwise, if you don't, there is a loop around \fIaccept\fR\|(2) which prevents
+os_unix.c \fIOS_Accept()\fR from returning the necessary error when FastCGI
+servers blocking on \fIaccept\fR\|(2) receive the \s-1SIGTERM\s0 or \s-1SIGHUP\s0.
+.PP
+FCGI::ProcManager uses \fIPOSIX::sigaction()\fR to override the default \s-1SA_RESTART\s0
+policy used for perl's \f(CW%SIG\fR behavior.  Specifically, the process manager
+never uses \s-1SA_RESTART\s0, while the child FastCGI servers turn off \s-1SA_RESTART\s0
+around the \fIaccept\fR\|(2) loop, but re-enstate it otherwise.
+.PP
+The desired (and implemented) effect is to give a request as big a chance as
+possible to succeed and to delay their exits until after their request,
+while allowing the FastCGI servers waiting for new requests to die right
+away.
+.SH "METHODS"
+.IX Header "METHODS"
+.SS "new"
+.IX Subsection "new"
+.Vb 2
+\& class or instance
+\& (ProcManager) new([hash parameters])
+.Ve
+.PP
+Constructs a new process manager.  Takes an option has of initial parameter
+values, and assigns these to the constructed object \s-1HASH\s0, overriding any
+default values.  The default parameter values currently are:
+.PP
+.Vb 4
+\& role         => manager
+\& start_delay  => 0
+\& die_timeout  => 60
+\& pm_title => \*(Aqperl\-fcgi\-pm\*(Aq
+.Ve
+.SH "Manager methods"
+.IX Header "Manager methods"
+.SS "pm_manage"
+.IX Subsection "pm_manage"
+.Vb 2
+\& instance or export
+\& (int) pm_manage([hash parameters])
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+When this is called by a FastCGI script to manage application servers.  It
+defines a sequence of instructions for a process to enter this method and
+begin forking off and managing those handlers, and it defines a sequence of
+instructions to intialize those handlers.
+.PP
+If n_processes < 1, the managing section is subverted, and only the
+handling sequence is executed.
+.PP
+Either returns the return value of \fIpm_die()\fR and/or \fIpm_abort()\fR (which will
+not ever return in general), or returns 1 to the calling script to begin
+handling requests.
+.SS "managing_init"
+.IX Subsection "managing_init"
+.Vb 2
+\& instance
+\& () managing_init()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+Overrideable method which initializes a process manager.  In order to
+handle signals, manage the \s-1PID\s0 file, and change the process name properly,
+any method which overrides this should call \fISUPER::managing_init()\fR.
+.SS "pm_die"
+.IX Subsection "pm_die"
+.Vb 2
+\& instance or export
+\& () pm_die(string msg[, int exit_status])
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+This method is called when a process manager receives a notification to
+shut itself down.  \fIpm_die()\fR attempts to shutdown the process manager
+gently, sending a \s-1SIGTERM\s0 to each managed process, waiting \fIdie_timeout()\fR
+seconds to reap each process, and then exit gracefully once all children
+are reaped, or to abort if all children are not reaped.
+.SS "pm_wait"
+.IX Subsection "pm_wait"
+.Vb 2
+\& instance or export
+\& (int pid) pm_wait()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+This calls \fIwait()\fR which suspends execution until a child has exited.
+If the process \s-1ID\s0 returned by wait corresponds to a managed process,
+\&\fIpm_notify()\fR is called with the exit status of that process.
+\&\fIpm_wait()\fR returns with the return value of \fIwait()\fR.
+.SS "pm_write_pid_file"
+.IX Subsection "pm_write_pid_file"
+.Vb 2
+\& instance or export
+\& () pm_write_pid_file([string filename])
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+Writes current process \s-1ID\s0 to optionally specified file.  If no filename is
+specified, it uses the value of the \f(CW\*(C`pid_fname\*(C'\fR parameter.
+.SS "pm_remove_pid_file"
+.IX Subsection "pm_remove_pid_file"
+.Vb 2
+\& instance or export
+\& () pm_remove_pid_file()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+Removes optionally specified file.  If no filename is specified, it uses
+the value of the \f(CW\*(C`pid_fname\*(C'\fR parameter.
+.SS "sig_sub"
+.IX Subsection "sig_sub"
+.Vb 2
+\& instance
+\& () sig_sub(string name)
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+The name of this method is passed to \fIPOSIX::sigaction()\fR, and handles signals
+for the process manager.  If \f(CW$SIG_CODEREF\fR is set, then the input arguments
+to this are passed to a call to that.
+.SS "sig_manager"
+.IX Subsection "sig_manager"
+.Vb 2
+\& instance
+\& () sig_manager(string name)
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+Handles signals of the process manager.  Takes as input the name of signal
+being handled.
+.SH "Handler methods"
+.IX Header "Handler methods"
+.SS "handling_init"
+.IX Subsection "handling_init"
+.Vb 2
+\& instance or export
+\& () handling_init()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_pre_dispatch"
+.IX Subsection "pm_pre_dispatch"
+.Vb 2
+\& instance or export
+\& () pm_pre_dispatch()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_post_dispatch"
+.IX Subsection "pm_post_dispatch"
+.Vb 2
+\& instance or export
+\& () pm_post_dispatch()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "sig_handler"
+.IX Subsection "sig_handler"
+.Vb 2
+\& instance or export
+\& () sig_handler()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SH "Common methods and routines"
+.IX Header "Common methods and routines"
+.SS "self_or_default"
+.IX Subsection "self_or_default"
+.Vb 2
+\& private global
+\& (ProcManager, @args) self_or_default([ ProcManager, ] @args);
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.PP
+This is a helper subroutine to acquire or otherwise create a singleton
+default object if one is not passed in, e.g., a method call.
+.SS "pm_change_process_name"
+.IX Subsection "pm_change_process_name"
+.Vb 2
+\& instance or export
+\& () pm_change_process_name()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_received_signal"
+.IX Subsection "pm_received_signal"
+.Vb 2
+\& instance or export
+\& () pm_received signal()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SH "parameters"
+.IX Header "parameters"
+.SS "pm_parameter"
+.IX Subsection "pm_parameter"
+.Vb 2
+\& instance or export
+\& () pm_parameter()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "n_processes"
+.IX Subsection "n_processes"
+.SS "no_signals"
+.IX Subsection "no_signals"
+.SS "pid_fname"
+.IX Subsection "pid_fname"
+.SS "die_timeout"
+.IX Subsection "die_timeout"
+.SS "role"
+.IX Subsection "role"
+.SS "start_delay"
+.IX Subsection "start_delay"
+\&\s-1DESCRIPTION:\s0
+.SH "notification and death"
+.IX Header "notification and death"
+.SS "pm_warn"
+.IX Subsection "pm_warn"
+.Vb 2
+\& instance or export
+\& () pm_warn()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_notify"
+.IX Subsection "pm_notify"
+.Vb 2
+\& instance or export
+\& () pm_notify()
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_exit"
+.IX Subsection "pm_exit"
+.Vb 2
+\& instance or export
+\& () pm_exit(string msg[, int exit_status])
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SS "pm_abort"
+.IX Subsection "pm_abort"
+.Vb 2
+\& instance or export
+\& () pm_abort(string msg[, int exit_status])
+.Ve
+.PP
+\&\s-1DESCRIPTION:\s0
+.SH "BUGS"
+.IX Header "BUGS"
+No known bugs, but this does not mean no bugs exist.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\s-1FCGI\s0.
+.SH "MAINTAINER"
+.IX Header "MAINTAINER"
+Gareth Kirwan <gbjk@thermeon.com>
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+James E Jurach Jr.
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+.Vb 2
+\& FCGI\-ProcManager \- A Perl FCGI Process Manager
+\& Copyright (c) 2000, FundsXpress Financial Network, Inc.
+\&
+\& This library is free software; you can redistribute it and/or
+\& modify it under the terms of the GNU Lesser General Public
+\& License as published by the Free Software Foundation; either
+\& version 2 of the License, or (at your option) any later version.
+\&
+\& BECAUSE THIS LIBRARY IS LICENSED FREE OF CHARGE, THIS LIBRARY IS
+\& BEING PROVIDED "AS IS WITH ALL FAULTS," WITHOUT ANY WARRANTIES
+\& OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT
+\& LIMITATION, ANY IMPLIED WARRANTIES OF TITLE, NONINFRINGEMENT,
+\& MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, AND THE
+\& ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY,
+\& AND EFFORT IS WITH THE YOU.  See the GNU Lesser General Public
+\& License for more details.
+\&
+\& You should have received a copy of the GNU Lesser General Public
+\& License along with this library; if not, write to the Free Software
+\& Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111\-1307  USA
+.Ve