perl-modperl-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sbek...@locus.apache.org
Subject cvs commit: modperl-site/guide CHANGES advocacy.html browserbugs.html config.html control.html correct_headers.html databases.html dbm.html debug.html download.html frequent.html hardware.html help.html index.html install.html intro.html mod_perl_guide.pdf.gz modules.html multiuser.html performance.html perl.html porting.html scenario.html snippets.html strategy.html troubleshooting.html
Date Sun, 09 Apr 2000 14:19:47 GMT
sbekman     00/04/09 07:19:46

  Modified:    guide    CHANGES advocacy.html browserbugs.html config.html
                        control.html correct_headers.html databases.html
                        dbm.html debug.html download.html frequent.html
                        hardware.html help.html index.html install.html
                        intro.html mod_perl_guide.pdf.gz modules.html
                        multiuser.html performance.html perl.html
                        porting.html scenario.html snippets.html
                        strategy.html troubleshooting.html
  Log:
  * intro: updated the long due credits section
  
  * snippets: new: "Authentication Snippets" (Michael Finke, Eric
    Cholet)
  
  * debug: new: "Apache::DumpHeaders" (Ask Bjoern Hansen)
  
  * debug: new: "Apache::DebugInfo" (Geoffrey Young)
  
  * config: updated: "PerlFreshRestart" with DSO notes (Doug, Vivek
    Khera)
  
  * troubleshooting: new: "Can't upgrade that kind of scalar ..." (Doug)
  
  * performance: new: "Bloatware" (Tom Christiansen)
  
  * performance: new: "CGI.pm versus Apache::Request" (Doug)
  
  * performance: new: "Apache::Registry versus pure PerlHandler" (Doug)
  
  * performance: new: "TMTOWTDI: Convenience and Performance"
  
  * install: "Is it possible to run mod_perl enabled Apache as suExec?"
    (Randal L. Schwartz, Matt Sergeant)
  
  * performance: updated: "Benchmarking PerlHandlers"
  
  * performance: new: "Keeping the Shared Memory Limit"
  
  * porting: new: "File tests operators"
  
  * performance: updated "PerlSetupEnv Off" with a test script
  
  * snippets: new: "Getting the Front-end Server's Name in the Back-end
    Server" (Sean Dague)
  
  * porting: extended "Taint mode" -- a suggestion for services that
    move to mod_perl and have part of the scripts that won't run under
    enabled Taint mode (Gunther Birznieks, Ken Williams)
  
  * modules: new: "Apache::OutputChain -- Chain Stacked Perl Handlers"
    (Honza Pazdziora, Eric Cholet)
  
  * snippets: new: "SSI and Embperl -- Doing Both" (Michael Schout)
  
  * performance: new: "-Dusemymalloc Perl Build Option" (Doug, Jeffrey
    W. Baker)
  
  * strategy: added unedited answer for the question "Multithreading or
    not Multithreading" (Shane shane@isupportlive.com)
  
  * install: updated "Automating installation" (James G Smith)
  
  * performance: added a workaround for limiting memory usage under
    Linux to "Limiting the Resources Used by httpd Children" (Kevin
    Murphy)
  
  * debug: added clarification fd leakage in "Safe Resource Locking"
    (Bill Moseley)
  
  * multiuser: extended the scenario for multi-user/multi-webserver on
    one machine option, how to enforce port and similar settings without
    forbidding user to modify his httpd.conf. (inspired by Greg Cope)
  
  * scenario: new: "Caching in mod_proxy" (Ilya Obshadko)
  
  * porting: new: "Accessing Request Object in non-Perl*Handler Modules"
    (Doug)
  
  * config: new: "Adding Custom Configuration Directives" (Doug)
  
  * snippets: new: "Convert a POST Request into a GET Request" (Doug)
  
  * scenario: extended the "Getting the Remote Server IP in the Back-end
    server in the Proxy Setup" section with notes about the modules
    configuration precedence problem and its solution. (Ilya Obshadko,
    Ewan Edwards)
  
  * strategy: new "Pros and Cons of Building mod_perl as DSO" (based on
    http://www.apache.org/docs/dso.html by Ralf S. Engelschall)
  
  * strategy: new: "mod_perl and mod_ssl" (Tom Mornini, Vivek Khera, Mads
    Toftum)
  
  * snippets: added a "PerlTransHandler example" (Randal L. Schwartz,
    Ajay Shah)
  
  * config: extended examples for "<Perl> sections", added the package
    declaration caveat, Apache::ReadConfig namespace and more.
  
  * performance: extended the "Reducing the Number of stat() Calls"
    section, with examples of PerlTransHandler and reducing stat()s for
    .htaccess look-ups
  
  * help: added the perlmonth.com and Gerald Richter's article reference
  
  * porting: updated the "Right headers generation": OS with EBCDIC as
    character set and sending proper headers. (Doug)
  
  * porting: added: "Apache::print() and CORE::print()" (Doug)
  
  * debug: updated: Sys::Signal, SIGALRM and perl5.6 issue (Doug and Bill
    Moseley)
  
  * config: $Apache::Server::StrictPerlSections (Doug)
  
  * scenario: more practical mod_rewrite examples by Geoffrey Young.
  
  * minor corrections: download.pod by Ron Pool, scenario.pod by Terry
    West and Eric Cholet, config.pod by Richard More, performance.pod by
    Stephen Judd and Steve Reppucci, frequent.pod by Andreas Piesk.
  
  * review: Mark Summerfield has joined the group of the kind people who
    review and correct the Guide. He has reviewed these chapters:
    advocacy, config, control, databases, dbm, debug, download,
    frequent, hardware, help, install.
  
  * review: Ged W. Haywood was very kind to review and correct the
    debug chapter.
  
  Revision  Changes    Path
  1.22      +129 -4    modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/CHANGES,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- CHANGES	2000/03/04 20:31:44	1.21
  +++ CHANGES	2000/04/09 14:19:37	1.22
  @@ -2,6 +2,131 @@
   		### mod_perl Guide CHANGES file ###
   		###################################
   
  +04.10.2000 ver 1.22
  +
  +* updated the long due credits section
  +
  +* snippets: new: "Authentication Snippets" (Michael Finke, Eric
  +  Cholet)
  +
  +* debug: new: "Apache::DumpHeaders" (Ask Bjoern Hansen)
  +
  +* debug: new: "Apache::DebugInfo" (Geoffrey Young)
  +
  +* config: updated: "PerlFreshRestart" with DSO notes (Doug, Vivek
  +  Khera)
  +
  +* troubleshooting: new: "Can't upgrade that kind of scalar ..." (Doug)
  +
  +* performance: new: "Bloatware" (Tom Christiansen)
  +
  +* performance: new: "CGI.pm versus Apache::Request" (Doug)
  +
  +* performance: new: "Apache::Registry versus pure PerlHandler" (Doug)
  +
  +* performance: new: "TMTOWTDI: Convenience and Performance"
  +
  +* install: "Is it possible to run mod_perl enabled Apache as suExec?"
  +  (Randal L. Schwartz, Matt Sergeant)
  +
  +* performance: updated: "Benchmarking PerlHandlers"
  +
  +* performance: new: "Keeping the Shared Memory Limit"
  +
  +* porting: new: "File tests operators"
  +
  +* performance: updated "PerlSetupEnv Off" with a test script
  +
  +* snippets: new: "Getting the Front-end Server's Name in the Back-end
  +  Server" (Sean Dague)
  +
  +* porting: extended "Taint mode" -- a suggestion for services that
  +  move to mod_perl and have part of the scripts that won't run under
  +  enabled Taint mode (Gunther Birznieks, Ken Williams)
  +
  +* modules: new: "Apache::OutputChain -- Chain Stacked Perl Handlers"
  +  (Honza Pazdziora, Eric Cholet)
  +
  +* snippets: new: "SSI and Embperl -- Doing Both" (Michael Schout)
  +
  +* performance: new: "-Dusemymalloc Perl Build Option" (Doug, Jeffrey
  +  W. Baker)
  +
  +* strategy: added unedited answer for the question "Multithreading or
  +  not Multithreading" (Shane shane@isupportlive.com)
  +
  +* install: updated "Automating installation" (James G Smith)
  +
  +* performance: added a workaround for limiting memory usage under
  +  Linux to "Limiting the Resources Used by httpd Children" (Kevin
  +  Murphy)
  +
  +* debug: added clarification fd leakage in "Safe Resource Locking"
  +  (Bill Moseley)
  +
  +* multiuser: extended the scenario for multi-user/multi-webserver on
  +  one machine option, how to enforce port and similar settings without
  +  forbidding user to modify his httpd.conf. (inspired by Greg Cope)
  +
  +* scenario: new: "Caching in mod_proxy" (Ilya Obshadko)
  +
  +* porting: new: "Accessing Request Object in non-Perl*Handler Modules"
  +  (Doug)
  +
  +* config: new: "Adding Custom Configuration Directives" (Doug)
  +
  +* snippets: new: "Convert a POST Request into a GET Request" (Doug)
  +
  +* scenario: extended the "Getting the Remote Server IP in the Back-end
  +  server in the Proxy Setup" section with notes about the modules
  +  configuration precedence problem and its solution. (Ilya Obshadko,
  +  Ewan Edwards)
  +
  +* strategy: new "Pros and Cons of Building mod_perl as DSO" (based on
  +  http://www.apache.org/docs/dso.html by Ralf S. Engelschall)
  +
  +* strategy: new: "mod_perl and mod_ssl" (Tom Mornini, Vivek Khera, Mads
  +  Toftum)
  +
  +* snippets: added a "PerlTransHandler example" (Randal L. Schwartz,
  +  Ajay Shah)
  +
  +* config: extended examples for "<Perl> sections", added the package
  +  declaration caveat, Apache::ReadConfig namespace and more.
  +
  +* performance: extended the "Reducing the Number of stat() Calls"
  +  section, with examples of PerlTransHandler and reducing stat()s for
  +  .htaccess look-ups
  +
  +* help: added the perlmonth.com and Gerald Richter's article reference
  +
  +* porting: updated the "Right headers generation": OS with EBCDIC as
  +  character set and sending proper headers. (Doug)
  +
  +* porting: added: "Apache::print() and CORE::print()" (Doug)
  +
  +* debug: updated: Sys::Signal, SIGALRM and perl5.6 issue (Doug and Bill
  +  Moseley)
  +
  +* config: $Apache::Server::StrictPerlSections (Doug)
  +
  +* scenario: more practical mod_rewrite examples by Geoffrey Young.
  +
  +* minor corrections: download.pod by Ron Pool, scenario.pod by Terry
  +  West and Eric Cholet, config.pod by Richard More, performance.pod by
  +  Stephen Judd and Steve Reppucci, frequent.pod by Andreas Piesk.
  +
  +* review: Mark Summerfield has joined the group of the kind people who
  +  review and correct the Guide. He has reviewed these chapters:
  +  advocacy, config, control, databases, dbm, debug, download,
  +  frequent, hardware, help, install.
  +
  +* review: Ged W. Haywood was very kind to review and correct the
  +  debug chapter.
  +
  +
  +
  +
   03.04.2000 ver 1.21
   
   * help: updated the mod_perl list subscription info, added the
  @@ -13,7 +138,7 @@
     SQL DB and mod_perl" (Vivek Khera, Jeffrey W. Baker, John Armstrong,
     Mike Miller, Leslie Mikesell, Tom Brown, Ed Phillips, Marko van der
     Puil) Special thanks to Jeffrey for working on the this section
  -  before it went into the Gude.
  +  before it went into the Guide.
   
   * perfomance: added the section "Memory Swapping is Considered Bad"
   
  @@ -129,7 +254,7 @@
     Apache Modules" (David Harris)
   
   * snippets: added "mod_rewrite Based On Query String and URI
  -  Implemented in Perl" (darren chamberlain)
  +  Implemented in Perl" (Darren Chamberlain)
   
   * config: added "Knowing the proxy_pass'ed Connection Type" (Geoff
     Crawshaw)
  @@ -219,7 +344,7 @@
   
   * performance: added "Upload/Download of Big Files" (Ken Williams)
   
  -* install: added a reference to "Static debian package" (by David
  +* install: added a reference to "Static debian package" (David
     Huggins-Daines)
   
   * troubleshooting: added Windows: "Apache::DBI and
  @@ -423,7 +548,7 @@
   * snippets: added "Terminating a child process on Request Completion"
     (Doug)
   
  -* troubleshooting": added "Apache.pm failed to load!" (Doug)
  +* troubleshooting: added "Apache.pm failed to load!" (Doug)
   
   * snippets: added "Reading POST Data, then Redirecting" (Doug)
   
  
  
  
  1.7       +34 -31    modperl-site/guide/advocacy.html
  
  Index: advocacy.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/advocacy.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- advocacy.html	1999/12/19 19:51:46	1.6
  +++ advocacy.html	2000/04/09 14:19:38	1.7
  @@ -57,26 +57,28 @@
   <P>
   <CENTER><H1><A NAME="Thoughts_about_scalability_and_f">Thoughts about scalability and flexibility</A></H1></CENTER>
   <P>
  -Your need for scalability and flexibility depends on your needs from the
  -web. If you want only a simple guest book or database gateway with no
  -feature headroom, you can get away with any EASY_AND_FAST_TO_DEVELOP_TOOL
  -(Exchange, MS IIS, Lotus Notes, etc).
  +Your need for scalability and flexibility depends on what you need from
  +your web site. If you only want a simple guest book or database gateway
  +with no feature headroom, you can get away with any
  +EASY_AND_FAST_TO_DEVELOP_TOOL (Exchange, MS IIS, Lotus Notes, etc).
   
   <P>
  -Experience shows that you will soon want more functionality, that's the
  -point you'll discover the limitations of these ``easy'' tools. Gradually,
  -your boss will ask for increasing functionality and at some point you'll
  -realize that the tool lacks flexibility and/or scalability. Then your boss
  -will either buy another EASY_AND_FAST_TO_DEVELOP_TOOL and repeat the
  -process (with different unforseen problems), or you'll start investing time
  +Experience shows that you will soon want more functionality, at which point
  +you'll discover the limitations of these ``easy'' tools. Gradually, your
  +boss will ask for increasing functionality and at some point you'll realize
  +that the tool lacks flexibility and/or scalability. Then your boss will
  +either buy another EASY_AND_FAST_TO_DEVELOP_TOOL and repeat the process
  +(with different unforseen problems), or you'll start investing time
   learning how to use a powerful, flexible tool to make the long-term
   development cycle easier.
   
   <P>
   If you and your company are serious about delivering flexible Internet
   functionality, do your homework. Then urge your boss to invest a little
  -extra time and resources to choose the right tool for the job. Your
  -long-term Internet site will prove the results.
  +extra time and resource into choosing the right tool for the job. The extra
  +quality and manageability of your site along with your ability to deliver
  +new and improved functionality of high quality and in good time will prove
  +the superiority of using solid flexible tools.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -87,23 +89,23 @@
   media and associates before handing down large decisions. Of course,
   results count! A sales brochure makes very little impact compared to a
   working demonstration, and demonstrations of company-specific and
  -developer-specific results count big!
  +developer-specific results count for a lot!
   
   <P>
   Personally, when I discovered mod_perl I did a lot of testing and coding at
   home and at work. Once I had a working heavy application, I came to my boss
  -with 2 URLs - one for the plain CGI server and the other for the
  +with two URLs - one for the plain CGI server and the other for the
   mod_perl-enabled server. It took about 30 secs for my boss to say: `Go with
  -it''. Of course the moment I did it, I have had to provide all the support
  -for other developers, that is why I took time to learn it in first place
  -(that is how this guide was born!).
  +it'. Of course since the moment I did it, I have had to provide all the
  +support for other developers, which is why I took time to learn it in first
  +place (and why this guide was created!).
   
   <P>
  -Chances are that if you've done your homework, you've learned the tools and
  -can deliver results, you'll have a successful project. If you convince your
  +Chances are that if you've done your homework, learnt the tools and can
  +deliver results, you'll have a successful project. If you convince your
   boss to try a tool that you don't know very well, your results may suffer.
   If your boss follows your development process closely and sees much worse
  -than expected progress, he might say ``forget it'' and wish never to give
  +than expected progress, you might be told to ``forget it'' and never give
   mod_perl a second chance.
   
   <P>
  @@ -147,31 +149,32 @@
   
   <P><LI>
   <P>
  -Math intensive code and other stuff which is faster in C/C++, plugged in
  -into Perl with XS/SWIG and transparent to perl user of the modules.
  +Math intensive code and other stuff which is faster in C/C++, can be
  +plugged into Perl with XS/SWIG and may be used transparently by Perl
  +programmers.
   
   <P><LI>
   <P>
  -Most CGI apps do text processing, where perl excels at
  +Most CGI apps do text processing, which perl excels at
   
   <P><LI>
   <P>
  -Forking and loading (unless code is shared) a C/C++ optimized CGI produces
  -an overhead
  +Forking and loading (unless code is shared) of C/C++ optimized CGI programs
  +produces an overhead
   
   <P><LI>
   <P>
  -Bandwidth is a bigger bottleneck than perl performance (vs C/C++) (not true
  -for Intranets, and might change for Internet in a number of years)
  +Bandwidth is a bigger bottleneck than perl performance (vs C/C++) (except
  +for Intranets, although this might change in a number of years)
   
   <P><LI>
   <P>
  -For database driven apps, db itself is a bottleneck. lots of posts talk
  -about latency vs throughput.
  +For database driven applications, the database itself is a bottleneck. Lots
  +of posts talk about latency vs throughput.
   
   <P><LI>
   <P>
  -mod_perl, FastCGI, velocigen and perlexec are good solutions for plain
  +mod_perl, FastCGI, Velocigen and PerlEx are good replacements for plain
   mod_cgi slowness
   
   <P><LI>
  @@ -222,7 +225,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 11/13/1999
  +	     <BR>Last Modified at 04/01/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.8       +2 -4      modperl-site/guide/browserbugs.html
  
  Index: browserbugs.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/browserbugs.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- browserbugs.html	2000/02/09 21:11:39	1.7
  +++ browserbugs.html	2000/04/09 14:19:38	1.8
  @@ -77,10 +77,8 @@
   designator and uses port 80 anyway.
   
   <P>
  -See <A HREF="././config.html#Publishing_Port_Numbers_Differen">Publishing Port Numbers Different from 80</A>
  +See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
  -
  -
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -114,7 +112,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/05/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.24      +543 -291  modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- config.html	2000/03/04 20:31:44	1.23
  +++ config.html	2000/04/09 14:19:38	1.24
  @@ -59,26 +59,28 @@
   		<LI><A HREF="#The_Sample_Start_up_File">The Sample Start-up File</A>
   		<LI><A HREF="#What_Modules_Should_You_Add_to_t">What Modules Should You Add to the Start-up File and Why</A>
   		<LI><A HREF="#The_Confusion_with_use_at_the_">The Confusion with use() at the Server Start-up File</A>
  -		<LI><A HREF="#The_Confusion_with_Global_Variab">The Confusion with Global Variables in Start-up File</A>
  +		<LI><A HREF="#The_Confusion_with_Global_Variab">The Confusion with Global Variables in the Start-up File</A>
   	</UL>
   
  -	<LI><A HREF="#_Perl_Perl_Sections">&lt;Perl&gt;...&lt;/Perl&gt; Sections</A>
  +	<LI><A HREF="#Apache_Configuration_in_Perl">Apache Configuration in Perl</A>
   	<UL>
   
   		<LI><A HREF="#Usage">Usage</A>
   		<LI><A HREF="#Enabling">Enabling</A>
  +		<LI><A HREF="#Caveats">Caveats</A>
   		<LI><A HREF="#Verifying">Verifying</A>
  +		<LI><A HREF="#Strict_Perl_Sections">Strict &lt;Perl&gt; Sections</A>
   		<LI><A HREF="#Debugging">Debugging</A>
   	</UL>
   
   	<LI><A HREF="#Validating_the_Configuration_Syn">Validating the Configuration Syntax</A>
   	<LI><A HREF="#Enabling_Remote_Server_Configura">Enabling Remote Server Configuration Reports</A>
  -	<LI><A HREF="#Publishing_Port_Numbers_Differen">Publishing Port Numbers Different from 80</A>
  +	<LI><A HREF="#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>
   	<LI><A HREF="#Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A>
   	<LI><A HREF="#General_Pitfalls">General Pitfalls</A>
   	<UL>
   
  -		<LI><A HREF="#My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as a Plain Text Instead of Being Executed by the Webserver</A>
  +		<LI><A HREF="#My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A>
   		<LI><A HREF="#My_Script_Works_under_mod_cgi_b">My Script Works under mod_cgi, but when Called via mod_perl I Get a 'Save-As' Prompt</A>
   		<LI><A HREF="#Is_There_a_Way_to_Provide_a_Diff">Is There a Way to Provide a Different startup.pl File for Each Individual Virtual Host</A>
   		<LI><A HREF="#Is_There_a_Way_to_Modify_INC_on">Is There a Way to Modify @INC on a Per-Virtual-Host or Per-Location Basis.</A>
  @@ -89,6 +91,7 @@
   	<LI><A HREF="#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="#Apache_Restarts_Twice_On_Start">Apache Restarts Twice On Start</A>
   	<LI><A HREF="#Knowing_the_proxy_pass_ed_Connec">Knowing the proxy_pass'ed Connection Type</A>
  +	<LI><A HREF="#Adding_Custom_Configuration_Dire">Adding Custom Configuration Directives </A>
   </UL>
   <!-- INDEX END -->
   
  @@ -125,34 +128,33 @@
   <P>
   Prior to version 1.3.4, the default Apache install used three configuration
   files -- <EM>httpd.conf</EM>, <EM>srm.conf</EM>, and <EM>access.conf</EM>. The 1.3.4 version began distributing the configuration directives in a
  -single file -- <EM>httpd.conf</EM>. The Guide uses the <EM>httpd.conf</EM> in its examples.
  +single file -- <EM>httpd.conf</EM>. This Guide uses the <EM>httpd.conf</EM> in its examples.
   
   <P>
  -So as you have already understood, the only file that you should edit is <EM>httpd.conf</EM> that by default is put into a <EM>conf</EM> directory under the document root. The document root is the directory that
  -you choose for Apache installation or the default one, which is
  -<EM>/usr/local/apache/</EM> on many UNIX platforms.
  +So the only file that you should need to edit is <EM>httpd.conf</EM> that by default is put into a <EM>conf</EM> directory under the document root. The document root is the directory that
  +you choose for Apache installation or the default one, which is <EM>/usr/local/apache/</EM> on many UNIX platforms.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Apache_Configuration">Apache Configuration</A></H1></CENTER>
   <P>
   To minimize the number of things that can go wrong, it can be a good idea
  -to configure the Apache itself first (like there is no mod_perl at all) and
  -make sure that it works.
  +to configure Apache itself first (without mod_perl) and make sure that it
  +works.
   
   <P>
  -Apache distibution comes with an extensive configuration manual and in
  +The Apache distibution comes with an extensive configuration manual and in
   addition each section of the configuration file includes helpful comments
  -explaining how every directive should be configured and what are the
  -defaults values.
  +explaining how every directive should be configured and what the defaults
  +values are.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Configuration_Directives">Configuration Directives</A></H2></CENTER>
   <P>
  -If you didn't move Apache directories around, the installation program
  -already has configured everything for you. Just start the server and test
  -it working. To start the server use the <CODE>apachectl</CODE> utility which comes bundled with Apache distribution and resides in the
  +If you didn't move Apache's directories around, the installation program
  +will have configured everything for you. Just start the server and test it
  +working. To start the server use the <CODE>apachectl</CODE> utility which comes bundled with Apache distribution and resides in the
   same directory with <CODE>httpd</CODE> (the Apache server itself). Execute:
   
   <P>
  @@ -164,16 +166,16 @@
   
   <P>
   For a basic setup there are just a few things to configure. If you have
  -moved directories you have to update them in <EM>httpd.conf</EM>. There are many of them, listing just a few of them:
  +moved directories you have to update them in <EM>httpd.conf</EM>. There are many of them, here are just a few of them:
   
   <P>
   <PRE>  ServerRoot   &quot;/usr/local/apache&quot;
     DocumentRoot &quot;/home/httpd/docs&quot;
   </PRE>
   <P>
  -You should set a name of your machine as it's known to the external world
  -if it's not a testing machine and referring to it as
  -<CODE>localhost</CODE> isn't good enough for you.
  +You should set a name for your machine as it's to be known to the external
  +world if it's not a testing machine and referring to it as
  +<CODE>localhost</CODE> isn't what you want.
   
   <P>
   <PRE>  ServerName www.example.com
  @@ -196,22 +198,22 @@
     Group nobody
   </PRE>
   <P>
  -There are other directives that you might need to cinfigure as well, as
  +There are other directives that you might need to configure as well, as
   mentioned earlier you will find them all in <EM>httpd.conf</EM>.
   
   <P>
   After single valued directives come the <CODE>Directory</CODE> and <CODE>Location</CODE>
   sections of configuration. That's the place where for each directory and
  -location you supply its unique behaviour, that applies to every request
  -that happens to fall into its domain.
  +location you can determine its unique behaviour, which will apply to every
  +request that happens to fall into its domain.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="_Directory_Location_and_Fil">&lt;Directory&gt;, &lt;Location&gt; and &lt;Files&gt;</A></H2></CENTER>
   <P>
  -I'll explain partially the <CODE>&lt;Directory</CODE>&gt;, <CODE>&lt;Location</CODE>&gt; and
  +I'll explain the basics of the <CODE>&lt;Directory</CODE>&gt;, <CODE>&lt;Location</CODE>&gt; and
   <CODE>&lt;Files</CODE>&gt; sections configuration. Remember that there is more to know and the
  -rest of the information you can read at Apache documentations. The
  +rest of the information is available in the Apache documentation. The
   information I'll present here is important for understanding the mod_perl
   configuration section.
   
  @@ -228,8 +230,8 @@
   <P>
   <CODE>Directory</CODE> is either the full path to a directory, or a wild-card string. In a
   wild-card string, <CODE>?</CODE> matches any single character, <CODE>*</CODE>
  -matches any sequences of characters, and <CODE>[]</CODE> character ranges like in the shell. None of the wildcards match a `/'
  -character. For example:
  +matches any sequences of characters, and <CODE>[]</CODE> character ranges. (This is similar to the shell's file globs.) None of the
  +wildcards will match a <EM>`/'</EM> character. For example:
   
   <P>
   <PRE>   &lt;Directory /home/httpd/docs&gt;
  @@ -237,7 +239,7 @@
      &lt;/Directory&gt;
   </PRE>
   <P>
  -If wanted a regex matching a <CODE>&lt;DirectoryMatch regex</CODE>&gt; ... <CODE>&lt;/DirectoryMatch</CODE>&gt; syntax should be used.
  +If you want to use a regex to match then the <CODE>&lt;DirectoryMatch regex</CODE>&gt; ... <CODE>&lt;/DirectoryMatch</CODE>&gt; syntax should be used.
   
   <P>
   If multiple (non-regular expression) directory sections match the directory
  @@ -269,11 +271,11 @@
   <P><LI><STRONG><A NAME="item_C">C&lt;&lt;Files filename&gt;&gt; ... C&lt;&lt;/Files&gt;&gt;</A></STRONG>
   <P>
   Can appear in server and virtual host configurations, and <EM>.htaccess</EM>
  -as well.
  +files as well.
   
   <P>
   The <CODE>&lt;Files</CODE>&gt; directive provides for access control by filename. It is comparable to
  -the <CODE>&lt;Directory</CODE>&gt; directive and <CODE>&lt;Location</CODE>&gt; directives. It should be matched with a <CODE>&lt;/Files</CODE>&gt; directive. The directives given within this section will be applied to
  +the <CODE>&lt;Directory</CODE>&gt; directive and <CODE>&lt;Location</CODE>&gt; directives. It should be closed with a <CODE>&lt;/Files</CODE>&gt; directive. The directives given within this section will be applied to
   any object with a basename (last component of filename) matching the
   specified filename.
   
  @@ -292,7 +294,8 @@
   <PRE>   &lt;Files ~ &quot;\.(gif|jpe?g|png)$&quot;&gt;
   </PRE>
   <P>
  -would match most common Internet graphics formats. Another alternative is a <CODE>&lt;FilesMatch regex</CODE>&gt; ... <CODE>&lt;/FilesMatch</CODE>&gt; syntax.
  +would match most common Internet graphics formats. Another alternative is
  +the <CODE>&lt;FilesMatch regex</CODE>&gt; ... <CODE>&lt;/FilesMatch</CODE>&gt; syntax.
   
   <P><LI><STRONG><A NAME="item__Location_URL_Location_">&lt;Location URL&gt; ... &lt;/Location&gt;</A></STRONG>
   <P>
  @@ -307,14 +310,14 @@
   files are read, and after the <CODE>&lt;Files</CODE>&gt; sections.
   
   <P>
  -This is the directive that most often used with mod_perl.
  +This is the directive that is most often used with mod_perl.
   
   <P>
  -URLs do not have to line up with the filesystem at all, it should be
  -emphasized that <CODE>&lt;Location</CODE>&gt; operates completely outside the filesystem.
  +URLs <EM>do not</EM> have to refer to real directories or files within the filesystem at all, <CODE>&lt;Location</CODE>&gt; operates completely outside the filesystem. Indeed it may be wise to
  +ensure that <CODE>&lt;Location</CODE>&gt;s do not match real paths to avoid confusion.
   
   <P>
  -The URL may use wildcards. In a wild-card string, <CODE>?</CODE> matches any single character, and <CODE>*</CODE> matches any sequences of characters. For regex macthes use a similar <CODE>&lt;LocationMatch regex</CODE>&gt; ... <CODE>&lt;/LocationMatch</CODE>&gt; syntax.
  +The URL may use wildcards. In a wild-card string, <CODE>?</CODE> matches any single character, and <CODE>*</CODE> matches any sequences of characters. For regex matches use the <CODE>&lt;LocationMatch regex</CODE>&gt; ... <CODE>&lt;/LocationMatch</CODE>&gt; syntax.
   
   <P>
   The <CODE>Location</CODE> functionality is especially useful when combined with the <CODE>SetHandler</CODE> directive. For example, to enable status requests, but allow them only from
  @@ -333,16 +336,17 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="How_Directory_Location_and_File">How Directory, Location and Files Sections are Merged</A></H2></CENTER>
   <P>
  -When configuring the server, it's important to understand an order rules of
  -each section are being applied to request. The order of merging is:
  +When configuring the server, it's important to understand the order in
  +which the rules of each section apply to requests. The order of merging is:
   
   <OL>
   <P><LI><STRONG><A NAME="item_C_Directory_except_regular_e">C&lt;&lt;Directory&gt;&gt; (except regular expressions) and .htaccess
  -done simultaneously (with .htaccess overriding C&lt;&lt;Directory&gt;&gt;)</A></STRONG>
  +are processed simultaneously (with .htaccess overriding
  +C&lt;&lt;Directory&gt;&gt;)</A></STRONG>
   <P><LI><STRONG><A NAME="item_C_DirectoryMatch_and_C_Dire">C&lt;&lt;DirectoryMatch&gt;&gt;, and C&lt;&lt;Directory&gt;&gt; with regular
   expressions</A></STRONG>
  -<P><LI><STRONG><A NAME="item_C_Files_and_C_FilesMatch_d">C&lt;&lt;Files&gt;&gt; and C&lt;&lt;FilesMatch&gt;&gt; done simultaneously</A></STRONG>
  -<P><LI><STRONG><A NAME="item_C_Location_and_C_LocationMat">C&lt;&lt;Location&gt;&gt; and C&lt;&lt;LocationMatch&gt;&gt; done simultaneously</A></STRONG>
  +<P><LI><STRONG><A NAME="item_C_Files_and_C_FilesMatch_a">C&lt;&lt;Files&gt;&gt; and C&lt;&lt;FilesMatch&gt;&gt; are processed simultaneously</A></STRONG>
  +<P><LI><STRONG><A NAME="item_C_Location_and_C_LocationMat">C&lt;&lt;Location&gt;&gt; and C&lt;&lt;LocationMatch&gt;&gt; are processed simultaneously</A></STRONG>
   </OL>
   <P>
   Apart from <CODE>&lt;Directory</CODE>&gt;, each group is processed in the order that they appear in the
  @@ -359,8 +363,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Sub_Grouping_of_Location_Dir">Sub-Grouping of &lt;Location&gt;, &lt;Directory&gt; and &lt;Files&gt; Sections</A></H2></CENTER>
   <P>
  -Let's say that you want all, but a few of files in a specific directory and
  -below it to be handled in the same way. For example if we want all files in <EM>/home/http/docs</EM> to be served as plain files, but file with ending <EM>.html</EM> and <EM>.txt</EM> to be processed by the content handler of <CODE>Apache::MyFilter</CODE> module.
  +Let's say that you want all files, except for a few of files in a specific
  +directory and below, to be handled in the same way. For example if we want
  +all files in <EM>/home/http/docs</EM> to be served as plain files, but files with ending <EM>.html</EM> and <EM>.txt</EM> to be processed by the content handler of our <CODE>Apache::MyFilter</CODE> module.
   
   <P>
   <PRE>  &lt;Directory /home/httpd/docs&gt;
  @@ -371,12 +376,11 @@
     &lt;/Directory&gt;
   </PRE>
   <P>
  -As you see, it's possible to embed sections inside sections to create
  -subgroups with slightly different behavior. Alternatively you can use
  -<CODE>&lt;Files</CODE>&gt; inside an <CODE>.htaccess</CODE> file.
  +Thus, it is possible to embed sections inside sections to create subgroups
  +which have their own distinct behavior. Alternatively you can use <CODE>&lt;Files</CODE>&gt; inside an <CODE>.htaccess</CODE> file.
   
   <P>
  -Note that you can't have the <CODE>&lt;Files</CODE>&gt; and <CODE>&lt;FilesMatch</CODE>&gt; sub-sections inside the <CODE>&lt;Location</CODE>&gt; section, but you can inside
  +Note that you can't have the <CODE>&lt;Files</CODE>&gt; and <CODE>&lt;FilesMatch</CODE>&gt; sub-sections inside the <CODE>&lt;Location</CODE>&gt; section, but you can inside a
   <CODE>&lt;Directory</CODE>&gt; section.
   
   <P>
  @@ -385,7 +389,7 @@
   <P>
   Normally, if multiple <CODE>Options</CODE> directives could apply to a directory, then the most specific one is taken
   complete; the options are not merged. However if all the options on the <CODE>Options</CODE>
  -directive are preceded by a <CODE>+</CODE> or <CODE>-</CODE> symbol, the options are merged. Any options preceded by <CODE>+</CODE> are added to the options currently in force, and any options preceded by <CODE>-</CODE> are getting removed.
  +directive are preceded by a <CODE>+</CODE> or <CODE>-</CODE> symbol, the options are merged. Any options preceded by <CODE>+</CODE> are added to the options currently in force, and any options preceded by <CODE>-</CODE> are removed.
   
   <P>
   For example, without any <CODE>+</CODE> and <CODE>-</CODE> symbols:
  @@ -412,21 +416,20 @@
     &lt;/Directory&gt;
   </PRE>
   <P>
  -then the options <CODE>FollowSymLinks</CODE> and <CODE>Includes</CODE> are set for the
  +then the options <CODE>FollowSymLinks</CODE> and <CODE>Includes</CODE> are also set for the
   <EM>/home/httpd/docs/shtml</EM> directory.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="mod_perl_Configuration">mod_perl Configuration</A></H1></CENTER>
   <P>
  -When you have tested that the Apache server works on your machine, it's a
  -time to step forward and configure the mod_perl side. Part of the
  -configuration directives are already familiar to you, however mod_perl
  -introduces a few new ones.
  +When you have tested that the Apache server works on your machine, it's
  +time to configure mod_perl. Part of the configuration directives are
  +already familiar to you, but mod_perl introduces a few new ones.
   
   <P>
  -It can be a good idea to keep all the mod_perl stuff at the end of the
  -file, after the native Apache configurations.
  +It can be a good idea to keep all the mod_perl related configuration at the
  +end of the configuration file, after the native Apache configurations.
   
   <P>
   META: explain Include file directive to load mod_perl side configuration.
  @@ -435,11 +438,12 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Alias_Configurations">Alias Configurations</A></H2></CENTER>
   <P>
  -First, you need to specify the locations on a file-system for the scripts
  -to be found.
  +First, you need to specify the locations on a file-system where the scripts
  +will be found.
   
   <P>
  -Add the following configuration directives:
  +Add configuration directives like these but reflecting your own
  +file-system:
   
   <P>
   <PRE>    # for plain cgi-bin:
  @@ -452,30 +456,31 @@
     Alias /cgi-perl/ /usr/local/myproject/cgi/
   </PRE>
   <P>
  -<CODE>Alias</CODE> provides a mapping of URL to file system object under
  +<CODE>Alias</CODE> provides a mapping of a URL to a file system object under
   <A HREF="#item_mod_perl">mod_perl</A>. <CODE>ScriptAlias</CODE> is being used for <CODE>mod_cgi</CODE>.
   
   <P>
   Alias defines the start of the URL path to the script you are referencing.
   For example, using the above configuration, fetching
  -<EM>http://www.example.com/perl/test.pl</EM>, will cause the server to look for the file <EM>test.pl</EM> at <EM>/usr/local/myproject/cgi</EM>, and execute it as an <CODE>Apache::Registry</CODE> script if we define <CODE>Apache::Registry</CODE> to be the handler of <EM>/perl</EM> location (see below).
  +<EM>http://www.example.com/perl/test.pl</EM>, will cause the server to look for the file <EM>test.pl</EM> at <EM>/usr/local/myproject/cgi</EM>, and execute it as an <CODE>Apache::Registry</CODE> script if we define <CODE>Apache::Registry</CODE> to be the handler for the <EM>/perl</EM> location (see below).
   
   <P>
  -The URL <EM>http://www.example.com/perl/test.pl</EM> will be mapped to
  -<EM>/usr/local/myproject/cgi/test.pl</EM>. This means that you can have all your CGIs located at the same place in
  -the file-system, and call the script in any of three modes simply by
  -changing the directory name component of the URL (<EM>cgi-bin|perl|cgi-perl</EM>) - is not this neat? (That is the configuration you see above - all three
  -Aliases point to the same directory within your file system, but of course
  -they can be different).
  +The URL <EM>http://www.example.com/perl/test.pl</EM> will also be mapped to
  +<EM>/usr/local/myproject/cgi/test.pl</EM>. This means that you can have all your CGI scripts located at the same
  +place in the file-system, and call the script in any of three modes simply
  +by changing the directory name component of the URL (<EM>cgi-bin|perl|cgi-perl</EM>). This makes it easy to migrate your scripts to mod_perl. (Although this
  +is the configuration we have used above, i.e. all three Aliases pointing to
  +the same directory within your file system, you can of course have them
  +point to different directories if you prefer.)
   
   <P>
   If your script does not seem to be working while running under mod_perl,
   you can easily call the script in straight mod_cgi mode without making any
  -script changes (in most cases), but rather by changing the URL you invoke
  -it by.
  +script changes (in most cases), simply by changing the URL you invoke it
  +with.
   
   <P>
  -<CODE>ScriptAlias</CODE> is actually:
  +<CODE>ScriptAlias</CODE> is actually the same as:
   
   <P>
   <PRE>  Alias /foo/ /path/to/foo/
  @@ -492,14 +497,14 @@
   configuration). All three modes or part of them can be used. But you should
   remember that it is undesirable to run scripts in plain mod_cgi from a
   mod_perl-enabled server--the price is too high, it is better to run these
  -on plain Apache server. (See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>)
  +on a plain Apache server. (See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>)
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="_Location_Configuration">&lt;Location&gt; Configuration</A></H2></CENTER>
   <P>
  -As we know <CODE>&lt;Location</CODE>&gt; section assigns a number of rules the server should follow when the
  -request's URI matches the Location domain. It's widely accepted to use <EM>/perl</EM> as a base URI of the perl scripts running under mod_perl, like <EM>/cgi-bin</EM> for mod_cgi. Let's explain the following very widely used <CODE>&lt;Location</CODE>&gt; section:
  +The <CODE>&lt;Location</CODE>&gt; section assigns a number of rules which the server should follow when
  +the request's URI matches the Location domain. It's widely accepted to use <EM>/perl</EM> as a base URI of the perl scripts running under mod_perl, like <EM>/cgi-bin</EM> for mod_cgi. Let's review the following very widely used <CODE>&lt;Location</CODE>&gt; section:
   
   <P>
   <PRE>  &lt;Location /perl&gt;
  @@ -511,51 +516,49 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -This configuration causes all requests' URI starting with <EM>/perl</EM> to be handled by mod_perl Apache module with handler from the
  -<CODE>Apache::Registry</CODE> Perl module. Let's go through the directives inside the <CODE>&lt;Location</CODE>&gt; section in the example:
  +This configuration causes all requests' URI starting with <EM>/perl</EM> to be handled by the mod_perl Apache module with the handler from the
  +<CODE>Apache::Registry</CODE> Perl module. Let's review the directives inside the <CODE>&lt;Location</CODE>&gt; section in the example:
   
   <P>
   <PRE>  &lt;Location /perl&gt;
   </PRE>
   <P>
   Remember the <STRONG>Alias</STRONG> from the above section? We use the same <CODE>Alias</CODE>
  -here, if you use <CODE>Location</CODE> that does not have the same <CODE>Alias</CODE>, the server will fail to locate the script in the file system. You needed
  +here; if you were to use a <CODE>Location</CODE> that does not have the same <CODE>Alias</CODE>, the server will fail to locate the script in the file system. You needed
   the <CODE>Alias</CODE> setting only if the code that should be executed is located in the file. So <CODE>Alias</CODE> just provides the URI to filepath translation rule. 
   
   <P>
   Sometimes there is no script to be executed. Instead there is some module
  -that its method is being executed, similar to <EM>/perl-status</EM>, where the code is stored in Apache module. If this is the case, we don't
  -need <CODE>Alias</CODE> settings for such a <CODE>&lt;Location</CODE>&gt;.
  +whose method is being executed, similar to <EM>/perl-status</EM>, where the code is stored in an Apache module. In such cases we don't need <CODE>Alias</CODE> settings for those <CODE>&lt;Location</CODE>&gt;s.
   
   <P>
   <PRE>  SetHandler perl-script
   </PRE>
   <P>
  -assigns mod_perl Apache module to handle the content generation phase.
  +This assigns the mod_perl Apache module to handle the content generation
  +phase.
   
   <P>
   <PRE>  PerlHandler Apache::Registry
   </PRE>
   <P>
  -tells Apache to use <CODE>Apache::Registry</CODE> Perl module for the actual content generation.
  +Here we tell Apache to use the <CODE>Apache::Registry</CODE> Perl module for the actual content generation.
   
   <P>
   <PRE>  Options ExecCGI
   </PRE>
   <P>
  -<CODE>Options</CODE> directive accepts a few different parameters (options), the
  -<CODE>ExecCGI</CODE> option tells the server that the file is a program and should be executed,
  -instead of just displayed like plain html file. If you omit this option
  -depending on clients configuration, the script will either be rendered as a
  -plain text or trigger a <EM>Save-As</EM>
  -dialog.
  +The <CODE>Options</CODE> directive accepts various parameters (options), one of which is the <CODE>ExecCGI</CODE> option that tells the server that the file is a program and should be
  +executed, instead of just displayed like a plain html file. If you omit
  +this option then depending on the clients configuration, the script will
  +either be rendered as plain text or trigger a <EM>Save-As</EM> dialog.
   
   <P>
   <PRE>  allow from all
   </PRE>
   <P>
  -This directive is in charge of access control based on domain. The above
  -settings allows to run the script for client from any domain.
  +This directive is used to set access control based on domain. The above
  +settings allows any client to run the script from any domain.
   
   <P>
   <PRE>  PerlSendHeader On
  @@ -566,19 +569,19 @@
   scripts.
   
   <P>
  -<CODE>PerlSendHeader On</CODE> setting invokes <CODE>ap_send_http_header()</CODE> after parsing your script headers. It is only meant for CGI emulation, it's
  -always better to use <CODE>CGI-&gt;header</CODE> from <CODE>CGI.pm</CODE> module or
  +The <CODE>PerlSendHeader On</CODE> setting invokes <CODE>ap_send_http_header()</CODE> after parsing your script headers. It is only meant for CGI emulation, and
  +it's always better to use <CODE>CGI-&gt;header</CODE> from the <CODE>CGI.pm</CODE> module or
   <CODE>$r-&gt;send_http_header</CODE> directly to send the HTTP header.
   
   <P>
   <PRE>  &lt;/Location&gt;
   </PRE>
   <P>
  -closes the <CODE>&lt;Location</CODE>&gt; section definition.
  +Closes the <CODE>&lt;Location</CODE>&gt; section definition.
   
   <P>
   Note that sometimes you will have to preload the module before using it in
  -the <CODE>&lt;Location</CODE>&gt; section, in case of <CODE>Apache::Registry</CODE> the configuration will look like this:
  +the <CODE>&lt;Location</CODE>&gt; section. In the case of <CODE>Apache::Registry</CODE> the configuration will look like this:
   
   <P>
   <PRE>  PerlModule Apache::Registry
  @@ -594,10 +597,10 @@
   <CODE>PerlModule</CODE> is equal to Perl's native <CODE>use()</CODE> function call.
   
   <P>
  -You have nothing to do about <CODE>/cgi-bin</CODE> location (mod_cgi), since it has nothing to do with mod_perl.
  +No changes are required to the <EM>/cgi-bin</EM> location (mod_cgi), since it has nothing to do with mod_perl.
   
   <P>
  -Let's see another very similar example with <CODE>Apache::PerlRun</CODE> (More about <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>):
  +Here is another very similar example this time using <CODE>Apache::PerlRun</CODE> (More about <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>):
   
   <P>
   <PRE>  &lt;Location /cgi-perl&gt;
  @@ -609,25 +612,26 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -The only difference from the <CODE>Apache::Registry</CODE> configuration id the argument of the <CODE>PerlHandler</CODE> directive, where <CODE>Apache::Registry</CODE>
  -was replaced by <CODE>Apache::PerlRun</CODE>.
  +The only difference from the <CODE>Apache::Registry</CODE> configuration is the argument of the <CODE>PerlHandler</CODE> directive, where <CODE>Apache::Registry</CODE>
  +has been replaced with <CODE>Apache::PerlRun</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="PerlModule_and_PerlRequire_Direc">PerlModule and PerlRequire Directives</A></H2></CENTER>
   <P>
  -As we saw earlier the module should be loaded before allowed to be used, <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are the two mod_perl directives equivalent to the Perl's <CODE>use()</CODE>
  +As we saw earlier the module should be loaded before it is used. <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are the two mod_perl directives equivalent to the Perl's <CODE>use()</CODE>
   and <CODE>require()</CODE> respectively. Since they are equivalent, the
  -same rules apply to their arguments. You pass <CODE>Apache::DBI</CODE> as an argument for <CODE>PerlModule</CODE>, and <CODE>Apache/DBI.pm</CODE> for <CODE>PerlRequire</CODE>.
  +same rules apply to their arguments. Thus you would pass <CODE>Apache::DBI</CODE> as an argument for <CODE>PerlModule</CODE>, and
  +<CODE>Apache/DBI.pm</CODE> for <CODE>PerlRequire</CODE>.
   
   <P>
  -You may load modules from the config file at server startup via:
  +You may load modules from the configuration file at server startup e.g.:
   
   <P>
   <PRE>    PerlModule Apache::DBI CGI DBD::Mysql
   </PRE>
   <P>
  -Generally the modules are preloaded from the startup script, usually named <EM>startup.pl</EM>. This is a file with plain perl code which is executed through the <CODE>PerlRequire</CODE> directive. For example:
  +Generally the modules are preloaded from the startup script, usually called <EM>startup.pl</EM>. This is a file with plain perl code which is executed through the <CODE>PerlRequire</CODE> directive. For example:
   
   <P>
   <PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
  @@ -641,12 +645,13 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Perl_Handlers">Perl*Handlers</A></H2></CENTER>
   <P>
  -As you know Apache specifies about 11 phases of the request loop, namely in
  -that order: Post-Read-Request, URI Translation, Header Parsing, Access
  -Control, Authentication, Authorization, MIME type checking, FixUp, Response
  -(Content phase). Logging and finally Cleanup. These are the stages of a
  -request where the Apache API allows a module to step in and do something.
  -There is a dedicated PerlHandler for each of these stages. Namely:
  +As you know Apache specifies about eleven phases of the request loop,
  +namely (and in order): Post-Read-Request, URI Translation, Header Parsing,
  +Access Control, Authentication, Authorization, MIME type checking, FixUp,
  +Response (Content phase), Logging and finally Cleanup. These are the stages
  +of a request where the Apache API allows a module to step in and do
  +something. There is a dedicated PerlHandler for each of these stages,
  +specifically:
   
   <P>
   <PRE>    PerlChildInitHandler
  @@ -665,62 +670,59 @@
       PerlChildExitHandler
   </PRE>
   <P>
  -The first 4 handlers cannot be used in the <CODE>&lt;Location</CODE>&gt;,
  -<CODE>&lt;Directory</CODE>&gt;, <CODE>&lt;Files</CODE>&gt; and <CODE>.htaccess</CODE> file, the main reason is all the above require a known path to the file in
  -order to bind a requested path with one or more of the identifiers above.
  -Starting from <CODE>PerlHeaderParserHandler</CODE> (5th) URI is allready being mapped to a physical pathname, thus can be used
  -to match the <CODE>&lt;Location</CODE>&gt;,
  -<CODE>&lt;Directory</CODE>&gt; or <CODE>&lt;Files</CODE>&gt; configuration section, or to look at
  -<CODE>.htaccess</CODE> file if exists at the specified directory in the translated path.
  +The first four handlers cannot be used in <CODE>&lt;Location</CODE>&gt;,
  +<CODE>&lt;Directory</CODE>&gt; or <CODE>&lt;Files</CODE>&gt; sections nor in <CODE>.htaccess</CODE> files; this is mainly because all of them require a known path to the file
  +in order to bind a requested path with one or more of the identifiers
  +above. Starting from <CODE>PerlHeaderParserHandler</CODE> (5th) the URI is already being mapped to a physical pathname, and thus can
  +be used to match the <CODE>&lt;Location</CODE>&gt;, <CODE>&lt;Directory</CODE>&gt; or <CODE>&lt;Files</CODE>&gt; configuration section, or to look in a <CODE>.htaccess</CODE> file if exists at the specified directory in the translated path.
   
   <P>
   The Apache documentation (or even better -- the ``Writing Apache Modules
   with Perl and C'' book by Doug MacEachern and Lincoln Stein) will tell you
   all about those stages and what your modules can do. By default, these
   hooks are disabled at compile time, see the INSTALL document for
  -information on enabling these hooks.
  +information on enabling them.
   
   <P>
  -Note that by default Perl API expects a subrotine called <CODE>handler</CODE> to handle the request in the registered PerlHandler module. Thus if your
  -module implements this subrotine, you can register the handler as simple as
  -writing:
  +Note that by default the Perl API expects a subroutine called
  +<CODE>handler</CODE> to handle the request in the registered PerlHandler module. Thus if your
  +module implements this subroutine, you can register the handler like this:
   
   <P>
   <PRE>  Perl*Handler Apache::SomeModule
   </PRE>
   <P>
  -replace <EM>Perl*Handler</EM> with a wanted name of the handler. mod_perl will preload the specified
  -module for you. But if you decide to give the handler code a different
  -name, like <CODE>my_handler</CODE>, you must preload the module and to write explicitly the chosen name.
  +Replace <EM>Perl*Handler</EM> with the name of a specific handler from the list given above. mod_perl
  +will preload the specified module for you. But if you decide to give the
  +handler routine a different name, like <CODE>my_handler</CODE>, you must preload the module and explicitly write the chosen name:
   
   <P>
   <PRE>  PerlModule Apache::SomeModule
     Perl*Handler Apache::SomeModule::my_handler
   </PRE>
   <P>
  -Please note that the former approach will not preload the module at the
  -startup, so either explicitly preload it with <CODE>PerlModule</CODE>
  -directive, add it to the startup file or use a nice shortcut the
  -<CODE>Perl*Handler</CODE> syntax suggests:
  +Please note that the former approach will not preload the module at
  +startup, so you should either explicitly preload it with the
  +<CODE>PerlModule</CODE> directive, or add it to the startup file, or use a nice shortcut the <CODE>Perl*Handler</CODE> syntax provides:
   
   <P>
   <PRE>  Perl*Handler +Apache::SomeModule
   </PRE>
   <P>
  -Notice the leading <CODE>+</CODE> character. It's equal to:
  +Notice the leading <CODE>+</CODE> character. It's equivalent to:
   
   <P>
   <PRE>  PerlModule Apache::SomeModule
     Perl*Handler Apache::SomeModule
   </PRE>
   <P>
  -If a module wishes to know what handler is currently being run, it can find
  -out with the <EM>current_callback</EM> method. This method is most useful to <EM>PerlDispatchHandlers</EM> who wish to only take action for certain phases.
  +If a module needs to know which handler is currently being run, it can find
  +out with the <EM>current_callback</EM> method. This method is most useful to <EM>PerlDispatchHandlers</EM> which wish to take action for certain phases only.
   
   <P>
  -<PRE> if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
  -     $r-&gt;warn(&quot;Logging request&quot;);
  - }
  +<PRE>  if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
  +      $r-&gt;warn(&quot;Logging request&quot;);
  +  }
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -731,7 +733,7 @@
   
   <P>
   Perl*Handler directives can define any number of subroutines, e.g. (in
  -config files)
  +configuration files)
   
   <P>
   <PRE> PerlTransHandler OneTrans TwoTrans RedTrans BlueTrans
  @@ -788,22 +790,22 @@
   <PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;purge);
   </PRE>
   <P>
  -Persistent database connection modules such as <CODE>Apache::DBI</CODE> could push a <CODE>PerlCleanupHandler</CODE> handler that iterates over <CODE>%Connected</CODE>, refreshing connections or just checking that ones have not gone stale.
  -Remember, by the time we get to <CODE>PerlCleanupHandler</CODE>, the client has what it wants and has gone away, we can spend as much time
  -as we want here without slowing down response time to the client (but the
  -process is unavailable for serving new request befor the operation is
  -completed).
  +Persistent database connection modules such as <CODE>Apache::DBI</CODE> could push a <CODE>PerlCleanupHandler</CODE> handler that iterates over <CODE>%Connected</CODE>, refreshing connections or just checking that connections have not gone
  +stale. Remember, by the time we get to <CODE>PerlCleanupHandler</CODE>, the client has what it wants and has gone away, so we can spend as much
  +time as we want here without slowing down response time to the client
  +(although the process itself is unavailable for serving new requests before
  +the operation is completed).
   
   <P>
  -<CODE>PerlTransHandlers</CODE> may decide, based on URI or other condition, whether or not to handle a
  -request, e.g. <CODE>Apache::MsqlProxy</CODE>. Without stacked handlers, users must configure:
  +<CODE>PerlTransHandlers</CODE> may decide, based on URI or some other condition, whether or not to handle
  +a request, e.g. <CODE>Apache::MsqlProxy</CODE>. Without stacked handlers, users must configure it themselves:
   
   <P>
   <PRE> PerlTransHandler Apache::MsqlProxy::translate
    PerlHandler      Apache::MsqlProxy
   </PRE>
   <P>
  -<CODE>PerlHandler</CODE> is never actually invoked unless <CODE>translate()</CODE> sees the request is a proxy request (<CODE>$r-&gt;proxyreq</CODE>), if it is a proxy request, <CODE>translate()</CODE> sets <CODE>$r-&gt;handler("perl-script")</CODE>, only then will <CODE>PerlHandler</CODE> handle the request. Now, users do not have to specify <CODE>PerlHandler Apache::MsqlProxy</CODE>, the <CODE>translate()</CODE>
  +<CODE>PerlHandler</CODE> is never actually invoked unless <CODE>translate()</CODE> sees the request is a proxy request (<CODE>$r-&gt;proxyreq</CODE>), if it is a proxy request, <CODE>translate()</CODE> sets <CODE>$r-&gt;handler("perl-script")</CODE>, and only then will <CODE>PerlHandler</CODE> handle the request. Now, users do not have to specify <CODE>PerlHandler Apache::MsqlProxy</CODE>, the <CODE>translate()</CODE>
   function can set it with <CODE>push_handlers()</CODE>.
   
   <P>
  @@ -814,45 +816,44 @@
   <PRE> PerlHandler My::Header Some::Body A::Footer
   </PRE>
   <P>
  -A little test:
  +A small example:
   
   <P>
  -<PRE> #My.pm
  - package My;
  -</PRE>
  -<P>
  -<PRE> sub header {
  +<PRE>  # My.pm
  +  package My;
  +  
  +  sub header {
        my $r = shift;
        $r-&gt;content_type(&quot;text/plain&quot;);
        $r-&gt;send_http_header;
        $r-&gt;print(&quot;header text\n&quot;);
  - }
  - sub body   { shift-&gt;print(&quot;body text\n&quot;)   }
  - sub footer { shift-&gt;print(&quot;footer text\n&quot;) }
  - 1;
  - __END__
  +  }
  +  sub body   { shift-&gt;print(&quot;body text\n&quot;)   }
  +  sub footer { shift-&gt;print(&quot;footer text\n&quot;) }
  +  1;
  +  __END__
   </PRE>
   <P>
  -<PRE> #in config
  - &lt;Location /foo&gt;
  - SetHandler &quot;perl-script&quot;
  - PerlHandler My::header My::body My::footer   
  - &lt;/Location&gt;
  +<PRE>  # in httpd.conf or perl.conf
  +  &lt;Location /foo&gt;
  +     SetHandler &quot;perl-script&quot;
  +     PerlHandler My::header My::body My::footer   
  +   &lt;/Location&gt;
   </PRE>
   <P>
  -Parsing the output of another PerlHandler? this is a little more tricky,
  +Parsing the output of another PerlHandler? This is a little more tricky,
   but consider:
   
   <P>
  -<PRE> &lt;Location /foo&gt;
  -   SetHandler &quot;perl-script&quot;
  -   PerlHandler OutputParser SomeApp
  - &lt;/Location&gt;
  - 
  - &lt;Location /bar&gt;
  -   SetHandler &quot;perl-script&quot;
  -   PerlHandler OutputParser AnotherApp
  - &lt;/Location&gt;
  +<PRE>  &lt;Location /foo&gt;
  +    SetHandler &quot;perl-script&quot;
  +    PerlHandler OutputParser SomeApp
  +  &lt;/Location&gt;
  +  
  +  &lt;Location /bar&gt;
  +    SetHandler &quot;perl-script&quot;
  +    PerlHandler OutputParser AnotherApp
  +  &lt;/Location&gt;
   </PRE>
   <P>
   Now, OutputParser goes first, but it <CODE>untie()'s</CODE> <CODE>*STDOUT</CODE> and re-tie()'s to its own package like so:
  @@ -897,7 +898,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Perl_Method_Handlers">Perl Method Handlers</A></H2></CENTER>
   <P>
  -If a Perl*Handler is prototyped with <CODE>$$</CODE>, this handler will be invoked as method. e.g.
  +If a <CODE>Perl*Handler</CODE> is prototyped with <CODE>$$</CODE>, this handler will be invoked as method. e.g.
   
   <P>
   <PRE> package My;
  @@ -952,10 +953,25 @@
   
   <P>
   <PRE>  PerlFreshRestart On
  -Make sure you read L&lt;Evil things might happen when using
  -PerlFreshRestart|warnings/Evil_things_might_happen_when_us&gt;.
   </PRE>
   <P>
  +Make sure you read <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
  +
  +<P>
  +Starting from mod_perl version 1.22 <CODE>PerlFreshRestart</CODE> is ignored when mod_perl is DSO. But it almost doesn't matter, since
  +mod_perl DSO will do a full tear-down (perl_destruct()) so it's still a
  +<EM>FreshRestart</EM>, just fresher than static (non-DSO) mod_perl :)
  +
  +<P>
  +But if you have:
  +
  +<P>
  +<PRE>  PerlFreshRestart No
  +</PRE>
  +<P>
  +and mod_perl DSO--you will still get a <EM>FreshRestart</EM>.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A></H2></CENTER>
   <P>
  @@ -966,23 +982,45 @@
   <CODE>PerlPassEnv</CODE> passes, <CODE>PerlSetEnv</CODE> sets and passes the
   <EM>ENVironment</EM> variables to your scripts. you can access them in your scripts through <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
   
  +<P>
  +Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in <EM>httpd.conf</EM>: if you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset).
  +
   <P>
  -Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in <EM>httpd.conf</EM> If you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset).
  +<CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. 
   
  +<P>
  +<PRE>  PerlSetVar key val
  +</PRE>
   <P>
  -<CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
  +or
   
   <P>
  -<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ 'FOO' =&gt; BAR ];
  +<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; 'val' ];
   </PRE>
   <P>
   and in the code you read it with:
   
   <P>
   <PRE>  my $r = Apache-&gt;request;
  -  print $r-&gt;dir_config('FOO');
  +  print $r-&gt;dir_config('key');
   </PRE>
   <P>
  +The above prints: 
  +
  +<P>
  +<PRE>  val
  +</PRE>
  +<P>
  +Note that you cannot do this:
  +
  +<P>
  +<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; \%hash ];
  +</PRE>
  +<P>
  +All values are treated as strings, so you will get a stringified reference
  +to a string as a value, which cannot be revivified upon retrieval.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="PerlSetupEnv">PerlSetupEnv</A></H2></CENTER>
   <P>
  @@ -999,7 +1037,7 @@
   <CENTER><H2><A NAME="MinSpareServers_MaxSpareServers_">MinSpareServers MaxSpareServers StartServers MaxClients MaxRequestsPerChild</A></H2></CENTER>
   <P>
   <CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>, <CODE>StartServers</CODE> and
  -<CODE>MaxClients</CODE> are plain Apache configuration directives that control the number of
  +<CODE>MaxClients</CODE> are standard Apache configuration directives that control the number of
   servers that can be launched at the server startup and kept alive through
   the server's work duration.
   
  @@ -1016,19 +1054,24 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Start_up_File">Start-up File</A></H1></CENTER>
   <P>
  -There is more to do at the server startup, than just preloading files. You
  -might want to initialize RDMS connections, tie read-only dbm files and etc.
  -Startup file is an ideal place to put the code that should be executed when
  -the server starts. Once you prepared the code, load it before the rest of
  -the mod_perl configuration directives with:
  +There is more that can be done at server startup, other than just
  +preloading files, before child processes are spawned to receive incoming
  +requests. You might want to register code that will initialize a database
  +connection for each child when this gets forked, tie read-only dbm files,
  +etc.
   
   <P>
  +The startup file is an ideal place to put the code that should be executed
  +when the server starts. Once you have prepared the code, load it before the
  +rest of the mod_perl configuration directives like this:
  +
  +<P>
   <PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
   </PRE>
   <P>
   I must stress that all the code that is run at the server initialization
   time is run with root priveleges if you are executing it as a root user
  -(you have to, unless you choose to run the server on an unpriveledged port,
  +(you have to, unless you choose to run the server on an unpriviledged port,
   above 1024). This means that anyone who has write access to a script or
   module that is loaded by <CODE>PerlModule</CODE> or
   <CODE>PerlRequire</CODE>, effectively has root access to the system. You might want to take a look
  @@ -1091,25 +1134,23 @@
     );
   </PRE>
   <P>
  -Let's go and explain the reasons of my decision to include this specific
  -code in the startup file.
  +Now we'll review the code explaining why each line is used.
   
   <P>
   <PRE>  use strict;
   </PRE>
   <P>
  -As with every script longer than five lines I have a habit to use this
  -pragma, which saves me from a lot for troubles in a long run. The startup
  -file is not different from any other perl code that I write.
  +This pragma is worth using in every script longer than half a dozen lines.
  +It will save a lot of time and debugging later on.
   
   <P>
   <PRE>  use lib qw(/dir/foo /dir/bar);
   </PRE>
   <P>
  -The only chance to permanently modify the <CODE>@INC</CODE> before the server was started is with this command. Later the running code
  +The only chance to permanently modify the <CODE>@INC</CODE> before the server is started is with this command. Later the running code
   can modify
  -<CODE>@INC</CODE> just for a moment it <CODE>requre()'s</CODE> some file, and than its value
  -gets reset to the previous one.
  +<CODE>@INC</CODE> just for the a moment it <CODE>requre()'s</CODE> some file, and than
  +<CODE>@INC</CODE>s value gets reset to the previous one.
   
   <P>
   <PRE>  $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/
  @@ -1128,9 +1169,9 @@
   <P>
   Preload the modules that get used by our Perl code serving the requests.
   Unless you need the symbols (variables and subroutines) exported by the
  -modules you preload to do accomplish something within the startup file,
  -don't import them, since it's just a waste of startup time. Instead use
  -empty list <CODE>()</CODE> to tell the <CODE>import()</CODE> function not to import a thing.
  +modules you preload to accomplish something within the startup file, don't
  +import them, since it's just a waste of startup time. Instead use the empty
  +list <CODE>()</CODE> to tell the <CODE>import()</CODE> function not to import anything.
   
   <P>
   <PRE>  use Carp ();
  @@ -1138,10 +1179,9 @@
   </PRE>
   <P>
   This is a useful snippet to enable extended warnings logged in the
  -error_log file. In addition to same basic warning, a trace of calls would
  -be added which makes the tracking of the potential problem a much easier
  -task, since you know who called whom. For example, with normal warnings you
  -might see:
  +error_log file. In addition to basic warnings, a trace of calls is added
  +which makes the tracking of the potential problem a much easier task, since
  +you know who called whom. For example, with normal warnings you might see:
   
   <P>
   <PRE>  Use of uninitialized value at
  @@ -1177,17 +1217,17 @@
     CGI-&gt;compile(':all');
   </PRE>
   <P>
  -Some modules get their subroutines created at the run time to improve the
  -loading time. This helps when the module includes many subroutines, but
  -only a few are actually get used. <CODE>CGI.pm</CODE> falls into this category. Since with mod_perl the module is loaded only
  +Some modules create their subroutines at run time to improve their load
  +time. This helps when the module includes many subroutines, but only a few
  +are actually used. <CODE>CGI.pm</CODE> falls into this category. Since with mod_perl the module is loaded only
   once, it might be a good idea to precompile all or a part of its methods.
   
   <P>
   <CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method performs this task. Notice that this is a
   propietary function of this module, other modules can implement this
  -feature or not and use this other name for the subroutine. As with all
  -module we preloaded in the startup file, we don't import symbols from them
  -as they are all get lost when they go out of the file's scope.
  +feature or not and use this or some other name for this functionality. As
  +with all modules we preload in the startup file, we don't import symbols
  +from them as they will be lost when they go out of the file's scope.
   
   <P>
   Note that starting with <CODE>$CGI::VERSION</CODE> 2.46, the recommended method to precompile the code in <CODE>CGI.pm</CODE> is:
  @@ -1199,38 +1239,47 @@
   But the old method is still available for backward compatibility.
   
   <P>
  -See also the '<A HREF="././debug.html#Apache_Status_Embedded_inter">Apache::Status -- Embedded interpreter status information</A>' section.
  +See also the '<A HREF="././debug.html#Apache_Status_Embedded_Inter">Apache::Status -- Embedded interpreter status information</A>' section.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="What_Modules_Should_You_Add_to_t">What Modules Should You Add to the Start-up File and Why</A></H2></CENTER>
   <P>
   Every module loaded at the server startup will be shared among server
  -children, saving a lot of RAM for you. Usually I put most of the code I
  -develop into modules and preload them.
  +children, saving a lot of RAM on your machine. Usually I put most of the
  +code I develop into modules and preload them.
   
   <P>
   You can even preload your CGI script with <CODE>Apache::RegistryLoader</CODE>
  -and preopen the DB connections with <CODE>Apache::DBI</CODE>. (See <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A>).
  +and preopen the database connections with <CODE>Apache::DBI</CODE>. (See
  +<A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A>).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="The_Confusion_with_use_at_the_">The Confusion with use() at the Server Start-up File</A></H2></CENTER>
   <P>
  -Some people wonder, why there is a need for a duplication of <CODE>use()</CODE>
  -clause in startup file and in the script itself. The confusion rises from
  -misunderstanding of the <CODE>use()</CODE> function. <CODE>use()</CODE> consists of two other functions, namely <CODE>require()</CODE> and <CODE>import()</CODE>, called within a
  -<CODE>BEGIN</CODE> block. See the section ``<A HREF="././perl.html#use_">use()</A>'' a detailed explanation of <CODE>use(),</CODE> <CODE>require()</CODE> and
  -<CODE>import()</CODE> methods.
  +Some people wonder, why you need to duplicate the <CODE>use()</CODE> clause in startup file and in the script itself. The confusion arises due
  +to misunderstanding the <CODE>use()</CODE> function. <CODE>use()</CODE> normally performs two operations, namely <CODE>require()</CODE> and <CODE>import()</CODE>, called within a
  +<CODE>BEGIN</CODE> block. See the section ``<A HREF="././perl.html#use_">use()</A>'' for a detailed explanation of the <CODE>use(),</CODE>
  +<CODE>require()</CODE> and <CODE>import()</CODE> functions.
  +
  +<P>
  +In the startup file we don't want to import any symbols since they will be
  +lost when we leave the scope of the startup file anyway, i.e. they won't be
  +visible to any of child process in which our mod_perl scripts run. Instead
  +we want to preload the module in the startup file and then import any
  +symbols that we actually need in each script individually. 
  +
  +<P>
  +Normally when we write <CODE>use MyModule;</CODE>, <CODE>use</CODE> will both load the module and import its symbols; so for the startup file
  +we write <CODE>use
  +MyModule ();</CODE> and the empty parantheses will ensure that the module is loaded but that no
  +symbols are imported. Then in the actual mod_perl script that we write we
  +use <CODE>use()</CODE> in the standard way, e.g. <CODE>use
  +MyModule;</CODE>, and since the module has already been preloaded the only action taken is
  +to import the symbols. For example in the startup file you write:
   
   <P>
  -So, if the module in question imports some symbols into your code's
  -namespace, you have to write the <CODE>use()</CODE> statement once again in
  -your code. The module will not be loaded once again, only the
  -<CODE>import()</CODE> call will be called. For example in the startup file
  -you write:
  -
  -<P>
   <PRE>  use CGI ();
   </PRE>
   <P>
  @@ -1241,10 +1290,7 @@
   <PRE>  use CGI qw(:html);
   </PRE>
   <P>
  -Since the symbols that you might import into a startup's script namespace
  -will be visible by none of the children, scripts that need a
  -<CODE>Foo</CODE>'s module exported tags have to pull it in like if you did not preload <CODE>Foo</CODE> at the startup file. For example, just because you have
  -<CODE>use()'d</CODE>  <CODE>Apache::Constants</CODE> in the startup file, does not mean you can have the following handler:
  +For example, just because you have <CODE>use()'d</CODE>  <CODE>Apache::Constants</CODE> in the startup file, does not mean you can have the following handler:
   
   <P>
   <PRE>  package MyModule;
  @@ -1262,59 +1308,65 @@
   <PRE>  use Apache::Constants qw( OK );
   </PRE>
   <P>
  -Or use a fully qualified notation:
  +Or use the fully qualified name:
   
   <P>
   <PRE>  return Apache::Constants::OK;
   </PRE>
   <P>
   If you want to use the function interface without exporting the symbols,
  -use a fully qualified functions, e.g. <CODE>CGI::param</CODE>. The same rule applies to variables, you can import variables and you can
  +use fully qualified function names, e.g. <CODE>CGI::param</CODE>. The same rule applies to variables, you can import variables and you can
   access them by their full name. e g. <CODE>$My::Module::bar</CODE>. When you use the object oriented (methods) interface you don't need to
   export the method symbols as well.
   
   <P>
  -In both later cases technically you aren't required to return on
  -<CODE>use()</CODE> statement in your code, if it was already loaded at the
  -startup. But you do have to write your code like id there is no code
  -preloaded. Because you or someone else will read your code at some point
  -and will not understand how can you use this or that method, without first
  -loading the module containing it.
  +Technically, you aren't required to supply the <CODE>use()</CODE> statement
  +in your (handler?) code if it was already loaded at server
  +initialization/startup (i.e. PerlRequire/startup.pl ). When writing your
  +code, you should not assume the module code has been preloaded. In the
  +future, you or someone else will revist this code and will not understand
  +how it is possible you used a module's method without first loading the
  +module itself.
   
   <P>
   Read the <CODE>Exporter</CODE> and <CODE>perlmod</CODE> manpages for more information about <CODE>import()</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_Confusion_with_Global_Variab">The Confusion with Global Variables in Start-up File</A></H2></CENTER>
  +<CENTER><H2><A NAME="The_Confusion_with_Global_Variab">The Confusion with Global Variables in the Start-up File</A></H2></CENTER>
   <P>
  -<CODE>PerlRequire</CODE> allows you to execute code that preloads modules and does more things.
  -Imported or defined variables are visible in the scope of the startup file.
  -It is a wrong assumption that global variables that were defined in the
  -startup file, will be accessible by child processes.
  +<CODE>PerlRequire</CODE> allows you to execute code that preloads modules and performs other
  +functions. Imported or defined variables are visible in the scope of the
  +startup file. It is wrong to assume that global variables that were defined
  +in the startup file will be visible to child processes.
   
   <P>
  -You do have to define/import variables in your scripts and they will be
  -visible inside a child process who run this script. They will be not shared
  -between siblings. Remember that every script is running in a specially
  -(uniquely) named package - so it cannot access variables from other
  -packages unless it inherits from them or <CODE>use()</CODE>'s them.
  +If you define or import variables in your scripts they will be visible
  +inside the child process which is running the script: but they will not be
  +shared between siblings. Remember that every script is running in a
  +specially (uniquely) named package - so it cannot access variables from
  +other packages unless it inherits from them or
  +<CODE>use()</CODE>'s them.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="_Perl_Perl_Sections">&lt;Perl&gt;...&lt;/Perl&gt; Sections</A></H1></CENTER>
  +<CENTER><H1><A NAME="Apache_Configuration_in_Perl">Apache Configuration in Perl</A></H1></CENTER>
  +<P>
  +With <CODE>&lt;Perl</CODE>&gt;...<CODE>&lt;/Perl</CODE>&gt; sections in <EM>httpd.conf</EM>, it is possible to configure your server entirely in Perl. 
  +
   <P>
  -With <CODE>&lt;Perl</CODE>&gt;...<CODE>&lt;/Perl</CODE>&gt; sections, it is possible to configure your server entirely in Perl.
  +Behind the scenes mod_perl defined a <CODE>Apache::ReadConfig</CODE> package where all the variables you define inside the <CODE>&lt;Perl</CODE>&gt; sections go to. Which means that you can create a module where you
  +should declare the package <CODE>Apache::ReadConfig</CODE>, to put the code inside it and then load it with <CODE>PerlModule</CODE>, <CODE>PerlRequire</CODE> or from within the startup file.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Usage">Usage</A></H2></CENTER>
   <P>
  -<CODE>&lt;Perl</CODE>&gt; sections can contain *any* and as much Perl code as you wish. These
  -sections are compiled into a special package whose symbol table mod_perl
  -can then walk and grind the names and values of Perl variables/structures
  -through the Apache core configuration gears. Most of the configurations
  -directives can be represented as scalars (<CODE>$scalar</CODE>) or lists (<CODE>@list</CODE>). A <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
  +<CODE>&lt;Perl</CODE>&gt; sections can contain <EM>any</EM> and as much Perl code as you wish. These sections are compiled into a
  +special package whose symbol table mod_perl can then walk and grind the
  +names and values of Perl variables/structures through the Apache core
  +configuration gears. Most of the configuration directives can be
  +represented as scalars (<CODE>$scalar</CODE>) or lists (<CODE>@list</CODE>). A <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
   you inside. Here is an example:
   
   <P>
  @@ -1341,15 +1393,15 @@
       AuthName =&gt; 'test',
       DirectoryIndex =&gt; [qw(index.html index.htm)],
       Limit =&gt; {
  -    METHODS =&gt; 'GET POST',
  -    require =&gt; 'user dougm',
  +      METHODS =&gt; 'GET POST',
  +      require =&gt; 'user dougm',
       },
     };
   </PRE>
   <P>
   If an Apache directive can take two or three arguments you may push strings
   and the lowest number of arguments will be shifted off the
  -<CODE>@List</CODE> or use array reference to handle any number greater than the minimum for
  +<CODE>@List</CODE> or use an array reference to handle any number greater than the minimum for
   that directive:
   
   <P>
  @@ -1380,25 +1432,39 @@
   <P>
   These are somewhat simple examples, but they should give you the basic
   idea. You can mix in any Perl code your heart desires. See
  -<EM>eg/httpd.conf.pl</EM> and <EM>eg/perl_sections.txt</EM> in mod_perl distribution for more examples.
  +<EM>eg/httpd.conf.pl</EM> and <EM>eg/perl_sections.txt</EM> in the mod_perl distribution for more examples.
  +
  +<P>
  +Assuming that you have a cluster of machines with similar homogeneous
  +configurations and only small distinctions between them. Ideally you would
  +want to maintain a single configuration file, but because the
  +configurations aren't <EM>exactly</EM> the same (i.e. <CODE>ServerName</CODE>
  +directive) it's not that simple. 
   
   <P>
  -A tip for syntax checking outside of httpd:
  +<CODE>&lt;Perl</CODE>&gt; sections are coming to rescue. Now you have a single configuration
  +file and the full power of Perl to make the local configuration tweaking.
  +For example to solve the uniqueness of the
  +<CODE>ServerName</CODE> directive you might want to have this <CODE>&lt;Perl</CODE>&gt; section:
   
   <P>
   <PRE>  &lt;Perl&gt;
  -  # !perl
  -  
  -  #... code here ...
  -  
  -  __END__
  +  $ServerName = `hostname`;
     &lt;/Perl&gt;
   </PRE>
   <P>
  -Now you may run:
  +For example if you want to allow personal directories on all machines but
  +the ones whose name is starting with <EM>secure</EM>:
   
   <P>
  -<PRE>  perl -cx httpd.conf
  +<PRE>  &lt;Perl&gt;
  +  $ServerName = `hostname`;
  +  if ( $ServerName !~ /^secure/) {
  +    $UserDir = &quot;public.html&quot;;
  +  } else {
  +    $UserDir = &quot;DISABLED&quot;;
  +  }
  +  &lt;/Perl&gt;
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -1409,14 +1475,84 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Caveats">Caveats</A></H2></CENTER>
  +<P>
  +Be careful when you declare package names inside the <CODE>&lt;Perl</CODE>&gt; sections, for example in this code:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;  
  +    package My::Trans;
  +    use Apache::Constants qw(:common);
  +    sub handler{ OK }
  +    
  +    $PerlTransHandler = &quot;My::Trans&quot;;
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +The <CODE>PerlTransHandler</CODE> you have tried to defined is actually undefined, because when you put the
  +code inside the <CODE>&lt;Perl</CODE>&gt; sections it's actually goes into the <CODE>Apache::ReadConfig</CODE> package, which is already declared for you. If you define a different
  +package name within <CODE>&lt;Perl</CODE>&gt; sections make sure to close the scope of the package and return to the <CODE>Apache::ReadConfig</CODE> package when you want to define the configuration parameters, like this:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;  
  +    package My::Trans;
  +    use Apache::Constants qw(:common);
  +    sub handler{ OK }
  +    
  +    package Apache::ReadConfig;  
  +    $PerlTransHandler = &quot;My::Trans&quot;;
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +The next section shows how to dump the configuration you have made with a
  +help of the <CODE>&lt;Perl</CODE>&gt; sections.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Verifying">Verifying</A></H2></CENTER>
   <P>
  -You can watch how have you configured the <CODE>&lt;Perl</CODE>&gt; sections through the <A HREF="././debug.html#Apache_Status_Embedded_inter">/perl-status</A> location, by choosing the <STRONG>Perl Sections</STRONG> from the menu.
  +To check the <CODE>&lt;Perl</CODE>&gt; section syntax outside of httpd, we make it look like a Perl script:
   
  +<P>
  +<PRE>  &lt;Perl&gt;
  +  # !perl
  +  # ... code here ...
  +  __END__
  +  &lt;/Perl&gt;
  +</PRE>
   <P>
  -You can dump the configuration by <CODE>&lt;Perl</CODE>&gt; sections configuration this way:
  +Now you may run:
  +
  +<P>
  +<PRE>  perl -cx httpd.conf
  +</PRE>
  +<P>
  +You can see how have you configured the <CODE>&lt;Perl</CODE>&gt; sections through the
  +<A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A> location, by choosing the <EM>Perl Section Configuration</EM> from the menu. In order to make this item show up in the menu you should
  +set
  +<CODE>$Apache::Server::SaveConfig</CODE> to a true value. When you do that the
  +<EM>Apache::ReadConfig</EM> namespace, the configuration data is stored in, will not be flushed, making
  +configuration data available to Perl modules at request time.
  +
  +<P>
  +Example:
  +
  +<P>
  +<PRE> &lt;Perl&gt;
  + $Apache::Server::SaveConfig = 1;
  +</PRE>
  +<P>
  +<PRE> $DocumentRoot = ...
  + ...
  + &lt;/Perl&gt;
  +</PRE>
  +<P>
  +At request time, the value of <STRONG>$DocumentRoot</STRONG> can be accessed with the fully qualified name <STRONG>$Apache::ReadConfig::DocumentRoot</STRONG>.
   
   <P>
  +You can dump the configuration of <CODE>&lt;Perl</CODE>&gt; sections like this:
  +
  +<P>
   <PRE>  &lt;Perl&gt;
     use Apache::PerlSections();
     ...
  @@ -1436,6 +1572,21 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Strict_Perl_Sections">Strict &lt;Perl&gt; Sections</A></H2></CENTER>
  +<P>
  +If the Perl code doesn't compile, the server won't start. If the generated
  +Apache config is invalid, <CODE>&lt;Perl</CODE>&gt; sections have always just logged an error and carried on, since there
  +might be globals in the section that are not intended for the config.
  +
  +<P>
  +<PRE>  $Apache::Server::StrictPerlSections = 1;
  +</PRE>
  +<P>
  +will not tolerate invalid Apache configuration syntax and croak (die) if
  +this is the case. At this time the default value is <CODE>0</CODE>. (This variable has been added in the mod_perl version 1.22).
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Debugging">Debugging</A></H2></CENTER>
   <P>
   If you compile modperl with <CODE>PERL_TRACE=1</CODE> and set the environment variable <A HREF="././debug.html#Debug_Tracing">MOD_PERL_TRACE</A> then you should see some useful diagnostics when mod_perl is processing
  @@ -1446,13 +1597,14 @@
   <CENTER><H1><A NAME="Validating_the_Configuration_Syn">Validating the Configuration Syntax</A></H1></CENTER>
   <P>
   <CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
  -modify the configuration file on your production server, if you run this
  -test before you restart the server. Of course it is not 100% error prone,
  -but it will reveal any syntax errors you might make while editing the file.
  +modify the configuration file on your production server, if you can
  +successfully run this test before you restart the server. Of course it is
  +not 100% perfect, but it will reveal any syntax errors you might have made
  +while editing the file.
   
   <P>
  -'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it actually executes the code in startup.pl, not just parses it. <CODE>&lt;Perl</CODE>&gt; configuration has always started Perl during the configuration read,
  -<CODE>Perl{Require,Module}</CODE> do so as well.
  +'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it doesn't just parse the code in startup.pl it actually executes it. <CODE>&lt;Perl</CODE>&gt; configuration has always started Perl during the configuration read,
  +and <CODE>Perl{Require,Module}</CODE> do so as well.
   
   <P>
   If you want your startup code to get a control over the <CODE>-t</CODE>
  @@ -1474,10 +1626,10 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Enabling_Remote_Server_Configura">Enabling Remote Server Configuration Reports</A></H1></CENTER>
   <P>
  -A nifty mod_info module displays a complete server configuration in the
  -browser. In order to use it you have compile it in or load as an object if
  -the server was compiled with DSO mode enabled. Then uncomment the already
  -prepared section in the <EM>httpd.conf</EM> file:
  +The nifty mod_info module displays the complete server configuration in
  +your browser. In order to use it you have compile it in or load as an
  +object if the server was compiled with DSO mode enabled. Then uncomment the
  +already prepared section in the <EM>httpd.conf</EM> file:
   
   <P>
   <PRE>  &lt;Location /server-info&gt;
  @@ -1495,9 +1647,9 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Publishing_Port_Numbers_Differen">Publishing Port Numbers Different from 80</A></H1></CENTER>
  +<CENTER><H1><A NAME="Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A></H1></CENTER>
   <P>
  -It is advised not to publish the 8080 (or alike) port number in URLs, but
  +It is advised not to publish the 8080 (or similar) port number in URLs, but
   rather using a proxying rewrite rule in the thin (httpd_docs) server:
   
   <P>
  @@ -1509,8 +1661,8 @@
   designator, and uses port 80 anyway.
   
   <P>
  -The other reason is that firewalls the users work from behind might have
  -all ports closed, but 80.
  +The other reason is that the firewalls the users work behind might have all
  +ports closed, except port 80.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -1520,8 +1672,8 @@
   and use macros in the Apache configuration file.
   
   <P>
  -mod_macro proved really useful when you have many virtual hosts, each
  -virtual host has a number of scripts/modules, most of them with a
  +mod_macro can be really useful when you have many virtual hosts, and where
  +each virtual host has a number of scripts/modules, most of them with a
   moderately complex configuration setup.
   
   <P>
  @@ -1646,9 +1798,9 @@
     Use vhost 10.1.1.2 example.net examplenet examplenet-admin
   </PRE>
   <P>
  -mod_macro also useful in a non vhost setting. Some sites for example have
  -lots of scripts where people use to view various statistics, email settings
  -and etc. It is much easier to read things like:
  +mod_macro is also useful in a non vhost setting. Some sites for example
  +have lots of scripts which people use to view various statistics, email
  +settings and etc. It is much easier to read things like:
   
   <P>
   <PRE>  use /forwards email/showforwards
  @@ -1659,7 +1811,7 @@
   <CENTER><H1><A NAME="General_Pitfalls">General Pitfalls</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as a Plain Text Instead of Being Executed by the Webserver</A></H2></CENTER>
  +<CENTER><H2><A NAME="My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A></H2></CENTER>
   <P>
   Check your configuration files and make sure that the ``ExecCGI'' is turned
   on in your configurations. 
  @@ -1710,12 +1862,12 @@
   <PRE>  $Apache::Registry::NameWithVirtualHost = 1;
   </PRE>
   <P>
  -But, as we know sometimes bug turns into a feature. If there is the same
  -script running for more than one Virtual host on the same machine, this can
  -be a waste, right? Set it to 0 in a startup script if you want to turn it
  -off and have this bug as a feature. (Only makes sense if you are sure that
  -there will be no <EM>other</EM> scripts named by the same path/name). It also saves you some memory on the
  -way.
  +But, as we know sometimes a bug turns out to be a feature. If the same
  +script is running for more than one Virtual host on the same machine, this
  +can be a waste, right? Set it to 0 in a startup script if you want to turn
  +it off and have this bug as a feature. (Only makes sense if you are sure
  +that there will be no <EM>other</EM> scripts named by the same path/name). It also saves you some memory as
  +well.
   
   <P>
   <PRE>  $Apache::Registry::NameWithVirtualHost = 0;
  @@ -1733,7 +1885,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Configuration_Security_Concerns">Configuration Security Concerns</A></H1></CENTER>
   <P>
  -It is better not to advertise the port mod_perl server running at to the
  +It is better not to advertise the port mod_perl server running to the
   outside world for it creates a potential security risk by revealing which
   <CODE>module(s)</CODE> and/or OS you are running your web server on.
   
  @@ -1754,10 +1906,8 @@
   if you are debugging.
   
   <P>
  -For more information see <A HREF="././config.html#Publishing_Port_Numbers_Differen">Publishing port numbers different from 80</A>
  +For more information see <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
  -
  -
   <P>
   Another approach is to modify httpd sources to reveal no unwanted
   information, so if you know the port the <CODE>HEAD</CODE> request will return an empty or phony <CODE>Server:</CODE> field.
  @@ -1789,19 +1939,121 @@
   Let's say that you have a frontend server running mod_ssl, mod_rewrite and
   mod_proxy. You want to make sure that user is using a secure connection for
   some specific actions like login information submission. You don't want to
  -let user login unless the request was submitted through secure port.
  +let the user login unless the request was submitted through a secure port.
   
   <P>
   Since you have to proxy_pass the request between front and backend servers,
  -you cannot know where the connection has come from. Neither using the HTTP
  -headers is reliable.
  +you cannot know where the connection has come from. Neither is using the
  +HTTP headers reliable.
   
   <P>
   A possible solution for this problem is to have the the mod_perl server
   listen on two different ports (.i.e 8000 and 8001) and have the mod_rewrite
   proxy rule in the regular server redirect to port 8000 and the mod_rewrite
   proxy rule in the SSL virtual host redirect to port 8001. In the mod_perl
  -server then just check the <CODE>PORT</CODE> variable to tell if the connect is encrypted or not.
  +server just check the <CODE>PORT</CODE> variable to tell if the connection is encrypted or not.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Adding_Custom_Configuration_Dire">Adding Custom Configuration Directives</A></H1></CENTER>
  +<P>
  +Well this is all covered in the Eagle Book in a great details. This is just
  +a simple example, showing how to add your own Configuration directive.
  +
  +<P>
  +<PRE>  Makefile.PL
  +  -----------
  +  package Apache::TestDirective;
  +  
  +  use ExtUtils::MakeMaker;
  +  
  +  use Apache::ExtUtils qw(command_table);
  +  use Apache::src ();
  +  
  +  my @directives = (
  +                  {   name        =&gt;  'Directive4',
  +                      errmsg      =&gt;  'Anything',
  +                      args_how    =&gt;  'RAW_ARGS',
  +                      req_override=&gt;  'OR_ALL',
  +                  },
  +                 );
  +    
  +  command_table(\@directives);
  +  
  +  WriteMakefile(
  +    'NAME'      =&gt; 'Apache::TestDirective',
  +    'VERSION_FROM' =&gt; 'TestDirective.pm',
  +    'INC'       =&gt; Apache::src-&gt;new-&gt;inc,
  +  );
  +</PRE>
  +<P>
  +<PRE>  TestDirective.pm
  +  ----------------
  +  package Apache::TestDirective;
  +  
  +  use strict;
  +  use strict;
  +  use Apache::ModuleConfig ();
  +  use DynaLoader ();
  +   
  +  if($ENV{MOD_PERL}) {
  +    no strict;
  +    $VERSION = '0.01';
  +    @ISA = qw(DynaLoader);
  +     __PACKAGE__-&gt;bootstrap($VERSION); #command table, etc.
  +  }
  +  
  +  sub Directive4 {
  +    warn &quot;Directive4 @_\n&quot;;
  +  }
  +  
  +  1;
  +  __END__
  +</PRE>
  +<P>
  +In the mod_perl source tree, add this to <EM>t/docs/startup.pl</EM>:
  +
  +<P>
  +<PRE>  use blib qw(/home/dougm/test/Apache/TestDirective);
  +</PRE>
  +<P>
  +and at the bottom of &lt;It/conf/httpd.conf&gt;:
  +
  +<P>
  +<PRE>  PerlModule Apache::TestDirective
  +  Directive4 hi
  +</PRE>
  +<P>
  +Test it:
  +
  +<P>
  +<PRE>  % make start_httpd
  +  % make kill_httpd
  +</PRE>
  +<P>
  +You should see:
  +
  +<P>
  +<PRE>  Directive4 Apache::TestDirective=HASH(0x83379d0)
  +  Apache::CmdParms=SCALAR(0x862b80c) hi
  +</PRE>
  +<P>
  +And in the error log file:
  +
  +<P>
  +<PRE>  % grep Directive4 t/logs/error_log 
  +  Directive4 Apache::TestDirective=HASH(0x83119dc)
  +  Apache::CmdParms=SCALAR(0x8326878) hi
  +</PRE>
  +<P>
  +If it didn't work as expected try building mod_perl with PERL_TRACE=1, then
  +do:
  +
  +<P>
  +<PRE>  setenv MOD_PERL_TRACE all
  +</PRE>
  +<P>
  +before starting the server. Now you should get some useful diagnostics.
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -1836,7 +2088,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/26/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.24      +174 -162  modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- control.html	2000/03/04 20:31:45	1.23
  +++ control.html	2000/04/09 14:19:38	1.24
  @@ -69,7 +69,7 @@
   <P>
   All of these techniques require that you know the server PID (Process ID).
   The easiest way to find the PID is to look it up in the
  -<CODE>httpd.pid</CODE> file. It's easy to discover where to look at, by checking out the <EM>httpd.conf</EM> file. Open the file and locate the entry
  +<CODE>httpd.pid</CODE> file. It's easy to discover where to look, by looking in the <EM>httpd.conf</EM> file. Open the file and locate the entry
   <CODE>PidFile</CODE>. Here is the line from one of my own <EM>httpd.conf</EM> files:
   
   <P>
  @@ -80,7 +80,7 @@
   <CODE>/usr/local/var/httpd_perl/run/httpd.pid</CODE>.
   
   <P>
  -Another way is to use the <CODE>ps</CODE> and <CODE>grep</CODE> utilities. Assuuming that the binary is called <EM>httpd_perl</EM>, we would do:
  +Another way is to use the <CODE>ps</CODE> and <CODE>grep</CODE> utilities. Assuming that the binary is called <EM>httpd_perl</EM>, we would do:
   
   <P>
   <PRE>  % ps auxc | grep httpd_perl
  @@ -94,7 +94,7 @@
   <P>
   This will produce a list of all the <CODE>httpd_perl</CODE> (parent and children) processes. You are looking for the parent process. If
   you run your server as root, you will easily locate it since it belongs to
  -root. If you run the server as some other user (when you <A HREF="././install.html#Installation_Without_Superuser_P">don't have root access</A>, the processes will belong to that user unless defined differently in <EM>httpd.conf</EM>. It's still easy to find which is the parent - it's the smallest one.
  +root. If you run the server as some other user (when you <A HREF="././install.html#Installation_Without_Superuser_P">don't have root access</A>, the processes will belong to that user unless defined differently in <EM>httpd.conf</EM>. It's still easy to find which is the parent--it's the smallest one.
   
   <P>
   You will see many <CODE>httpd</CODE> executables running on your system, but you should never need to send
  @@ -112,8 +112,8 @@
     #define SIGUSR1   30    /* user defined signal 1 */
   </PRE>
   <P>
  -Note that to send these signals from the command line the <CODE>SIG</CODE>
  -prefix must be omitted.
  +Note that to send these signals from the command line the <CODE>SIG</CODE> prefix must be omitted and under some operating systems they will need to
  +be preceeded by a minus sign, e.g. <CODE>kill -15</CODE> or <CODE>kill -TERM</CODE> followed by the PID.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -128,18 +128,17 @@
   <DL>
   <P><DT><STRONG><A NAME="item_TERM">TERM Signal: Stop Now</A></STRONG><DD>
   <P>
  -Sending the <A HREF="#item_TERM">TERM</A> signal to the parent causes it immediately to attempt to kill off all its
  +Sending the <A HREF="#item_TERM">TERM</A> signal to the parent causes it to immediately attempt to kill off all its
   children. Any requests in progress are terminated, and no further requests
   are served. This process may take quite a few seconds to complete. To stop
  -a child, the parent sends
  -<CODE>SIGHUP</CODE> signal. If that fails it sends another. If that fails it sends <CODE>SIGTERM</CODE> signal, and as a last resort it sends <CODE>SIGKILL</CODE>
  -signal. For each failed attempt to kill a child it makes an entry in the <EM>error_log</EM>.
  +a child, the parent sends it a <CODE>SIGHUP</CODE> signal. If that fails it sends another. If that fails it sends the <CODE>SIGTERM</CODE> signal, and as a last resort it sends the
  +<CODE>SIGKILL</CODE> signal. For each failed attempt to kill a child it makes an entry in the <EM>error_log</EM>.
   
   <P>
   Finally the parent itself exits and any open log files are closed. This is
  -when all the accumulated <CODE>END</CODE> blocks, but the ones from
  -<CODE>Apache::Registry</CODE> or <CODE>Apache::PerlRun</CODE> scripts, will be executed. The latter gets executed after each request is
  -served.
  +when all the accumulated <CODE>END</CODE> blocks, apart from the ones in
  +<CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE> scripts, will be executed. <CODE>END</CODE> blocks are executed after each request is served for
  +<CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE> scripts.
   
   <P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
   <P>
  @@ -153,22 +152,25 @@
   
   <P>
   Note: If your configuration files have errors when you issue a restart then
  -the parent not restart but will exit with an error and your sever will be
  -stopped. See below for a way of avoiding this.
  +the parent will not restart but instead it will exit with an error and your
  +sever will be stopped. See below for how to avoid this.
   
   <P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
   <P>
   The <A HREF="#item_USR1">USR1</A> signal causes the parent process to advise the children to exit after
  -serving the current request, or to exit immediately if they're not serving
  -a request. The parent re-reads its configuration files and re-opens its log
  -files. As each child dies off the parent replaces it with a child from the
  -new generation (the new children use the new configuration) and it begins
  -serving new requests immediately.
  +serving their current requests, or to exit immediately if they're not
  +serving a request. The parent re-reads its configuration files and re-opens
  +its log files. As each child dies off the parent replaces it with a child
  +from the new generation (the new children use the new configuration) and it
  +begins serving new requests immediately.
   
   <P>
   The only difference between <A HREF="#item_USR1">USR1</A> and <A HREF="#item_HUP">HUP</A> is that <A HREF="#item_USR1">USR1</A> allows the children to complete any current requests prior to killing them
  -off.
  +off and there is no interruption in the services compared to the killing
  +with <A HREF="#item_HUP">HUP</A> signal, where it might take a few seconds for a restart to get completed
  +and there is no real service at this time.
   
  +</DL>
   <P>
   By default, if a server is restarted (using <CODE>kill -USR1 `cat
   logs/httpd.pid`</CODE> or with the <A HREF="#item_HUP">HUP</A> signal), Perl scripts and modules are not reloaded. To reload <CODE>PerlRequire</CODE>'s, <CODE>PerlModule</CODE>'s, other
  @@ -180,10 +182,10 @@
   <P>
   Make sure you read <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
  -</DL>
   <P>
   We've already mentioned that restart or termination can sometimes take
  -quite a long time for a mod_perl server. You have an option to set the <A HREF="././debug.html#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A> during the <CODE>perl
  +quite a long time, (e.g. tens of seconds), for a mod_perl server. You have
  +an option to set the <A HREF="././debug.html#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A> during the <CODE>perl
   Makefile.PL</CODE> stage. You can also simply set it to <EM>-1</EM> directly. This can speed things up, and can lead to more robust operation
   in the face of problems such as running out of memory.
   
  @@ -191,8 +193,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Using_apachectl_to_control_the_s">Using apachectl to control the server</A></H1></CENTER>
   <P>
  -Apache's distribution provides a script to control the server. It's called <EM>apachectl</EM> and it is installed into the same location as the httpd executable. Let's
  -say in our scenario it's in
  +The Apache distribution comes with a script to control the server. It's
  +called <EM>apachectl</EM> and it is installed into the same location as the httpd executable. We will
  +assume for the sake of our examples that it's in
   <CODE>/usr/local/sbin/httpd_perl/apachectl</CODE>:
   
   <P>
  @@ -242,7 +245,7 @@
   Either copy the <EM>apachectl</EM> file to the appropriate location (<CODE>/etc/rc.d/rc3.d/S99apache</CODE> works on my RedHat Linux system) or create a symlink with that name
   pointing to the canonical location. (If you do this, make certain that the
   script is writable only by root! The startup scripts have root privileges
  -during initialisation, and you don't want to open any security holes.)
  +during initialisation, and you don't want to open up any security holes.)
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -254,7 +257,7 @@
   code.
   
   <P>
  -It's quite easy to prevent it, just don't overwrite the previous good
  +It's quite easy to prevent it, just don't overwrite the previous working
   files!
   
   <P>
  @@ -270,12 +273,12 @@
     % mv rel old &amp;&amp; mv beta rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err
   </PRE>
   <P>
  -Let me explain what I'm doing.
  +Let me explain what this does.
   
   <P>
   Firstly, note that I put all the commands on one line, separated by
  -<CODE>&amp;&amp;</CODE>, and only then press the <CODE>Enter</CODE> key. As I am working remotely, this ensures that if I suddenly get a lost
  -connection (sadly that happens sometimes) I won't leave the server down if
  +<CODE>&amp;&amp;</CODE>, and only then press the <CODE>Enter</CODE> key. As I am working remotely, this ensures that if I suddenly lose my
  +connection (sadly this happens sometimes) I won't leave the server down if
   only the
   <CODE>stop</CODE> command squeezed in.  <CODE>&amp;&amp;</CODE> also ensures that if any command fails, the rest won't be executed. I am
   using aliases (which I have already defined) to make the typing easier:
  @@ -296,50 +299,51 @@
   Taking the line apart piece by piece:
   
   <P>
  -mv rel old &amp;&amp;
  -
  -<P>
  -<PRE>  back up the working directory to C&lt;old&gt;
  +<PRE>  mv rel old &amp;&amp;
   </PRE>
   <P>
  -mv beta rel &amp;&amp;
  +back up the working directory to <CODE>old</CODE>
  +
   
  +
   <P>
  -<PRE>  put the new one in its place
  +<PRE>  mv beta rel &amp;&amp;
   </PRE>
   <P>
  -stop &amp;&amp;
  +put the new one in its place
   
   <P>
  -<PRE>  stop the server
  +<PRE>  stop &amp;&amp;
   </PRE>
   <P>
  -sleep 3 &amp;&amp;
  +stop the server
   
   <P>
  -<PRE>  give it a few seconds to shut down (it might take even longer)
  +<PRE>  sleep 3 &amp;&amp;
   </PRE>
   <P>
  -restart &amp;&amp;
  +give it a few seconds to shut down (it might take even longer)
   
   <P>
  -<PRE>  C&lt;restart&gt; the server
  +<PRE>  restart &amp;&amp;
   </PRE>
   <P>
  -err
  +<CODE>restart</CODE> the server
   
   <P>
  -<PRE>  view of the tail of the C&lt;error_log&gt; file in order to see that
  -  everything is OK
  +<PRE>  err
   </PRE>
   <P>
  +view of the tail of the <CODE>error_log</CODE> file in order to see that everything is OK
  +
  +<P>
   <CODE>apachectl</CODE> generates the status messages a little too early (e.g. when you issue <CODE>apachectl stop</CODE> it says the server has been stopped, while in fact it's still running) so
   don't rely on it, rely on the <CODE>error_log</CODE> file instead.
   
   <P>
  -Also you have noticed that I use <CODE>restart</CODE> and not just <CODE>start</CODE>. I do this because of Apache's potentially long stopping times (it depends
  -on what you do with it of course!). If you use <CODE>start</CODE> and Apache hasn't yet releases the port it's listening to, the start would
  -fail and <CODE>error_log</CODE> would tell you that port is in use, e.g.:
  +Also notice that I use <CODE>restart</CODE> and not just <CODE>start</CODE>. I do this because of Apache's potentially long stopping times (it depends
  +on what you do with it of course!). If you use <CODE>start</CODE> and Apache hasn't yet released the port it's listening to, the start would
  +fail and <CODE>error_log</CODE> would tell you that the port is in use, e.g.:
   
   <P>
   <PRE>  Address already in use: make_sock: could not bind to port 8080
  @@ -351,7 +355,7 @@
   Now what happens if the new modules are broken? First of all, I see
   immediately an indication of the problems reported in the <CODE>error_log</CODE>
   file, which I <CODE>tail -f</CODE> immediately after a restart command. If there's a problem, I just put
  -everything as it was before:
  +everything back as it was before:
   
   <P>
   <PRE>  % mv rel bad &amp;&amp; mv old rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err
  @@ -366,8 +370,8 @@
   <P>
   What happens if you really must take down the server or disable the
   scripts? This situation might happen when you need to do some maintenance
  -work on your database server. If you have to take it down the scripts using
  -this database server will fail.
  +work on your database server. If you have to take your database down then
  +any scripts that use it will fail.
   
   <P>
   If you do nothing, the user will see either the grey <CODE>An Error has
  @@ -375,10 +379,10 @@
   trap and customize the errors. See <A HREF="././snippets.html#Redirecting_Errors_to_the_Client">Redirecting Errors to the Client instead of to the error_log</A> for the latter case.
   
   <P>
  -A much more friendlier approach is to confess to your users that you are
  -doing some maintenance work and plead for patience, promising (keep the
  -promise!) that the service will become fully functional in X minutes. There
  -are a few ways to do this:
  +A much friendlier approach is to confess to your users that you are doing
  +some maintenance work and plead for patience, promising (keep the promise!)
  +that the service will become fully functional in X minutes. There are a few
  +ways to do this:
   
   <P>
   The first doesn't require messing with the server. It works when you have
  @@ -388,19 +392,20 @@
   <P>
   <PRE>  /home/http/perl/construction.pl
     ----------------------------
  -  #!/usr/bin/perl -wT
  +  #!/usr/bin/perl -Tw
     
     use strict;
     use CGI;
     my $q = new CGI;
  -  print $q-&gt;header,
  +  print $q-&gt;header, $q-&gt;p(
     &quot;Sorry, the service is temporarily down for maintenance. 
      It will be back in ten to fifteen minutes.
      Please, bear with us.
  -   Thank you!&quot;;
  +   Thank you!&quot;);
   </PRE>
   <P>
  -And if now you have to disable a script at <CODE>/home/http/perl/chat.pl</CODE>, just do this:
  +So if you now have to disable a script for example
  +<CODE>/home/http/perl/chat.pl</CODE>, just do this:
   
   <P>
   <PRE>  % mv /home/http/perl/chat.pl /home/http/perl/chat.pl.orig
  @@ -445,19 +450,19 @@
     ---------------
     use strict;
     use CGI;
  -  use Apache::Constants;
  -  sub handler{
  +  use Apache::Constants qw(:common);
  +  sub handler {
       my $q = new CGI;
  -    print $q-&gt;header,
  +    print $q-&gt;header, $q-&gt;p(
     &quot;Sorry, the service is temporarily down for maintenance. 
      It will be back in ten to fifteen minutes.
      Please, bear with us.
  -   Thank you!&quot;;
  +   Thank you!&quot;);
       return OK;
     }
   </PRE>
   <P>
  -and put it in a directory that in the server's <CODE>@INC</CODE>, to disable all the scripts in Location <CODE>/perl</CODE> you would replace:
  +and put it in a directory that is in the server's <CODE>@INC</CODE>, to disable all the scripts in Location <CODE>/perl</CODE> you would replace:
   
   <P>
   <PRE>  &lt;Location /perl&gt;
  @@ -477,9 +482,9 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -Now restart the server. Your user will be happy to go and read slashdot.org
  -for ten minutes, knowing that you are working on a much better version of
  -the service.
  +Now restart the server. Your users will be happy to go and read
  +slashdot.org for ten minutes, knowing that you are working on a much better
  +version of the service.
   
   <P>
   If you need to disable a location handled by some module, the second
  @@ -490,68 +495,68 @@
   <CENTER><H1><A NAME="SUID_Start_up_Scripts">SUID Start-up Scripts</A></H1></CENTER>
   <P>
   For those who want to use SUID startup scripts, here is an example. This
  -script is SUID <EM>root</EM>, and should be executable only by members of some special group at your
  -site. Note the tenth line, which fixes an obscure error when starting
  -apache/mod_perl by setting the real to the effective UID. As others have
  -pointed out, a mismatch between the real and the effective UIDs causes Perl
  -to croak on the -e switch.
  +script is <EM>SUID root</EM>, and should be executable only by members of some special group at your
  +site. Note the line marked
  +<CODE>WORKAROUND</CODE>, which fixes an obscure error when starting apache/mod_perl by setting the
  +real to the effective UID. Without this workaround, a mismatch between the
  +real and the effective UIDs causes Perl to croak on the -e switch.
   
   <P>
   Note that you must be using a version of Perl that recognizes and emulates
  -the suid bits in order for this to work. The script will do different
  +the suid bits in order for this to work. This script will do different
   things depending on whether it is named <CODE>start_http</CODE>,
   <CODE>stop_http</CODE> or <CODE>restart_http</CODE>. You can use symbolic links for this purpose.
   
   <P>
  -<PRE> #!/usr/bin/perl
  - 
  - # These constants will need to be adjusted.
  - $PID_FILE = '/home/www/logs/httpd.pid';
  - $HTTPD = '/home/www/httpd -d /home/www';
  - 
  - # These prevent taint warnings while running suid
  - $ENV{PATH}='/bin:/usr/bin';
  - $ENV{IFS}='';
  - 
  - # This sets the real to the effective ID, and prevents
  - # an obscure error when starting apache/mod_perl
  - $&lt; = $&gt;;
  - $( = $) = 0; # set the group to root too
  - 
  - # Do different things depending on our name
  - ($name) = $0 =~ m|([^/]+)$|;
  - 
  - if ($name eq 'start_http') {
  -     system $HTTPD and die &quot;Unable to start HTTP&quot;;
  -     print &quot;HTTP started.\n&quot;;
  -     exit 0;
  - }
  - 
  - # extract the process id and confirm that it is numeric
  - $pid = `cat $PID_FILE`;
  - $pid =~ /(\d+)/ or die &quot;PID $pid not numeric&quot;;
  - $pid = $1;
  - 
  - if ($name eq 'stop_http') {
  -     kill 'TERM',$pid or die &quot;Unable to signal HTTP&quot;;
  -     print &quot;HTTP stopped.\n&quot;;
  -     exit 0;
  - }
  - 
  - if ($name eq 'restart_http') {
  -     kill 'HUP',$pid or die &quot;Unable to signal HTTP&quot;;
  -     print &quot;HTTP restarted.\n&quot;;
  -     exit 0;
  - }
  - 
  - die &quot;Script must be named start_http, stop_http, or restart_http.\n&quot;;
  +<PRE>  #!/usr/bin/perl -T
  +   
  +  # These constants will need to be adjusted.
  +  $PID_FILE = '/home/www/logs/httpd.pid';
  +  $HTTPD = '/home/www/httpd -d /home/www';
  +  
  +  # These prevent taint warnings while running suid
  +  $ENV{PATH}='/bin:/usr/bin';
  +  $ENV{IFS}='';
  +  
  +  # This sets the real to the effective ID, and prevents
  +  # an obscure error when starting apache/mod_perl
  +  $&lt; = $&gt;; # WORKAROUND
  +  $( = $) = 0; # set the group to root too
  +  
  +  # Do different things depending on our name
  +  ($name) = $0 =~ m|([^/]+)$|;
  +  
  +  if ($name eq 'start_http') {
  +      system $HTTPD and die &quot;Unable to start HTTP&quot;;
  +      print &quot;HTTP started.\n&quot;;
  +      exit 0;
  +  }
  +  
  +  # extract the process id and confirm that it is numeric
  +  $pid = `cat $PID_FILE`;
  +  $pid =~ /(\d+)/ or die &quot;PID $pid not numeric&quot;;
  +  $pid = $1;
  +  
  +  if ($name eq 'stop_http') {
  +      kill 'TERM',$pid or die &quot;Unable to signal HTTP&quot;;
  +      print &quot;HTTP stopped.\n&quot;;
  +      exit 0;
  +  }
  +  
  +  if ($name eq 'restart_http') {
  +      kill 'HUP',$pid or die &quot;Unable to signal HTTP&quot;;
  +      print &quot;HTTP restarted.\n&quot;;
  +      exit 0;
  +  }
  +  
  +  die &quot;Script must be named start_http, stop_http, or restart_http.\n&quot;;
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Preparing_for_Machine_Reboot">Preparing for Machine Reboot</A></H1></CENTER>
   <P>
  -When you run your own development box, it's OK to start the webserver by
  -hand when you need it. On a production system, there is chance that the
  +When you run your own development box, it's okay to start the webserver by
  +hand when you need to. On a production system it is possible that the
   machine the server is running on will have to be rebooted. When the reboot
   is completed, who is going to rememeber to start the server? It's easy to
   forget this task, and what happens if you aren't around when the machine is
  @@ -560,7 +565,8 @@
   <P>
   After the server installation is complete, it's important not to forget
   that you need to put a script to perform the server startup and shutdown
  -into the standard system location, for example <CODE>/etc/rc.d</CODE>.
  +into the standard system location, for example <CODE>/etc/rc.d</CODE>
  +under RedHat Linux, or <CODE>/etc/init.d/apache</CODE> under Debian Slink Linux.
   
   <P>
   This is the directory which contains scripts to start and stop all the
  @@ -569,8 +575,9 @@
   
   <P>
   Generally the simplest solution is to copy the <CODE>apachectl</CODE> script to your startup directory. You will find <CODE>apachectl</CODE> in the same directory as the httpd executable after Apache installation. If
  -you have more than one Apache server you need a script for each one, and of
  -course you will have to rename them.
  +you have more than one Apache server you will need a script for each one,
  +and of course you will have to rename them so that they can co-exist in the
  +same directories.
   
   <P>
   For example on a RedHat Linux machine with two servers, I have the
  @@ -585,14 +592,14 @@
     /etc/rc.d/rc6.d/K87httpd_perl -&gt; ../init.d/httpd_perl
   </PRE>
   <P>
  -The scripts themselves reside in the <EM>init.d</EM> directory. There are symbolic links to these scripts in other directories,
  -the names are the same as the script names but they have numbers prepended,
  -which used for executing the scripts in a particular order: the lower
  +The scripts themselves reside in the <EM>init.d</EM> directory. There are symbolic links to these scripts in other directories.
  +The names are the same as the script names but they have numbers prepended,
  +which are used for executing the scripts in a particular order: the lower
   numbers are executed earlier.
   
   <P>
  -When a machine is booted and its runlevel set to 3 (multiuser+network),
  -Linux goes into <CODE>/etc/rc.d/rc3.d/</CODE> and executes the scripts the symbolic links point to with the <CODE>start</CODE> argument. When it sees <EM>S87httpd_perl</EM>, it executes:
  +Under RedHat Linux, when a machine is booted and its runlevel set to 3
  +(multiuser+network), Linux goes into <CODE>/etc/rc.d/rc3.d/</CODE> and executes the scripts the symbolic links point to with the <CODE>start</CODE> argument. When it sees <EM>S87httpd_perl</EM>, it executes:
   
   <P>
   <PRE>  /etc/rc.d/init.d/httpd_perl start
  @@ -605,8 +612,8 @@
   <PRE>  /etc/rc.d/init.d/httpd_perl stop
   </PRE>
   <P>
  -Most of the systems have GUI utilites to automate the creation of symbolic
  -links. For example RedHat Linux includes the
  +Most systems have GUI utilites to automate the creation of symbolic links.
  +For example RedHat Linux includes the
   <CODE>control-panel</CODE> utility, which amongst other things includes the
   <CODE>RunLevel Manager</CODE>. This will help you to create the proper symbolic links. Of course before
   you use it, you should put <CODE>apachectl</CODE> or similar scripts into the <EM>init.d</EM> or equivalent directory.
  @@ -689,10 +696,11 @@
   Again we put this script into the crontab to call it every 30 minutes.
   Personally I call it every minute, to fetch some very light script. Why so
   often? If your server starts to spin and trash your disk space with
  -multiple error messages, in five minutes you might run out of free disk
  -space which might bring your system to its knees. Chances are that no other
  -child will be able to serve requests, since the system will be too busy
  -writing to the <CODE>error_log</CODE> file. Think big -- if you are running a heavy service (which is very fast
  +multiple error messages filling the error log, in five minutes you might
  +run out of free disk space which might bring your system to its knees.
  +Chances are that no other child will be able to serve requests, since the
  +system will be too busy writing to the
  +<CODE>error_log</CODE> file. Think big -- if you are running a heavy service (which is very fast
   since you are running under mod_perl) adding one more request every minute
   will not be felt by the server at all.
   
  @@ -734,7 +742,7 @@
     #  $proxy=&quot;<A HREF="http://www-proxy.com&quot">http://www-proxy.com&quot</A>;;
     $ua-&gt;proxy('http', $proxy) if $proxy;
     
  -  # If returns '1' it's we are alive
  +  # If it returns '1' it means we are alive
     exit 1 if checkurl($test_script_url);
     
     # Houston, we have a problem.
  @@ -807,8 +815,7 @@
   shell, so you can kill it with <EM>Ctrl-C</EM>.
   
   <P>
  -Note that in <CODE>-X</CODE> (single-process) mode the server will run very slowly while fetching
  -images.
  +Note that in <CODE>-X</CODE> (single-process) mode the server will run very slowly when fetching images.
   
   <P>
   Note for Netscape users:
  @@ -873,7 +880,7 @@
     &lt;/IfDefine&gt;
     
     # Personal development Server for userfoo
  -  # userfoo use the server running on port 8001
  +  # userfoo uses the server running on port 8001
     &lt;IfDefine userfoo&gt;
     Port 8001
     PidFile /usr/local/var/httpd_perl/run/httpd.pid.userfoo
  @@ -888,10 +895,10 @@
     &lt;/IfDefine&gt;
   </PRE>
   <P>
  -With this technique we have achieved for each server full control over
  -start/stop, number of children, a separate error log file, and port
  -selection. This saves me from getting called every few minutes - ``Stas,
  -I'm going to restart the server''.
  +With this technique we have achieved full control over start/stop, number
  +of children, a separate error log file, and port selection for each server.
  +This saves me from getting called every few minutes - ``Stas, I'm going to
  +restart the server''.
   
   <P>
   In the above technique, you need to discover the PID of your parent
  @@ -908,8 +915,8 @@
   so simple.
   
   <P>
  -The last thing was to let developers an option to run in single process
  -mode by:
  +The last thing is to provide developers with an option to run in single
  +process mode by:
   
   <P>
   <PRE>  /usr/local/sbin/httpd_perl/httpd_perl -Dsbekman -X
  @@ -921,11 +928,11 @@
   simple, we use <CODE>mod_rewrite</CODE>.
   
   <P>
  -To use mod_rewrite you have to configure your <EM>httpd_docs</EM> server with <CODE>--enable-module=rewrite</CODE> and recompile, or use DSO and load the module in httpd.conf. In the <EM>access.conf</EM> of our <CODE>httpd_docs</CODE>
  +To use mod_rewrite you have to configure your <EM>httpd_docs</EM> server with <CODE>--enable-module=rewrite</CODE> and recompile, or use DSO and load the module in <EM>httpd.conf</EM>. In the <EM>access.conf</EM> of our <CODE>httpd_docs</CODE>
   server we have the following code:
   
   <P>
  -<PRE>  # sbekman' server
  +<PRE>  # sbekman's server
     # port = 8000
     RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
     RewriteCond  %{REMOTE_ADDR} 123.34.45.56
  @@ -948,7 +955,7 @@
   <CODE>REMOTE_USER</CODE> since we have all the users authenticated but it did not work for me.
   
   <P>
  -So if written in some <EM>file.html</EM> I have a relative URL like
  +So if I have a relative URL written in some <EM>file.html</EM> like
   <EM>/perl/test.pl</EM> or even <A
   HREF="http://www.nowhere.com/perl/test.pl">http://www.nowhere.com/perl/test.pl</A>
   (the user at the machine of <EM>sbekman</EM>) it will be redirected by httpd_docs to <A
  @@ -956,14 +963,14 @@
   
   
   <P>
  -You have another problem: the CGI script may generate some html which the
  -client may then use to request further action from the server. If the
  +There is another problem: the CGI script may generate some HTML code which
  +the client may then use to request further action from the server. If the
   script generates a URL with a hard coded PORT, the above scheme will not
   work. There two solutions:
   
   <P>
   First, generate relative URLs so it will reuse the technique above, with
  -redirect (which is transparent for the user). But this will not work if you
  +redirect (which is transparent to the user). But this will not work if you
   have something to <CODE>POST</CODE>, because the redirect loses all the data!
   
   <P>
  @@ -984,10 +991,10 @@
   <P>
   Often you will start off debugging your script by running it from your
   favorite shell. Sometimes you encounter a very weird situation when the
  -script runs from the shell but dies when called as a CGI. The real problem
  -often lies in the difference between the environment that is used by your
  -server and the one used by your shell. For example you may have a different
  -Perl path, a <CODE>PERL5LIB</CODE> environment variable which includes paths that are not in the <CODE>@INC</CODE> array of the copy of Perl which is linked into the mod_perl server and
  +script runs from the shell but dies when called as a CGI script. The real
  +problem often lies in the difference between the environment that is used
  +by your server and the one used by your shell. For example you may have a
  +different Perl path, a <CODE>PERL5LIB</CODE> environment variable which includes paths that are not in the <CODE>@INC</CODE> array of the copy of Perl which is linked into the mod_perl server and
   configured during startup.
   
   <P>
  @@ -999,7 +1006,7 @@
   skips it and the wrapper knows how to call the script.
   
   <P>
  -Below is the example of such a script. Note that we force the use of
  +Below is an example of such a script. Note that we force the use of
   <CODE>-Tw</CODE> when we call the real script. I have also added the ability to pass
   parameters, which will not happen when you call the CGI script from the
   Web.
  @@ -1017,7 +1024,7 @@
     # Usage: wrap.pl some_cgi.pl
     #
     
  -  BEGIN{
  +  BEGIN {
       use vars qw($basedir);
       $basedir = &quot;/usr/local&quot;;
     
  @@ -1048,7 +1055,7 @@
     
       # if the path includes the directory 
       # we extract it and chdir there
  -  if ($cgi =~ m|/|) {
  +  if (index($cgi,'/') &gt;= 0) {
       my $dirname = dirname($cgi);
       chdir $dirname or die &quot;Can't chdir to $dirname: $! \n&quot;;
       $cgi =~ m|$dirname/(.*)|;
  @@ -1121,6 +1128,12 @@
     }
   </PRE>
   <P>
  +Note: Setting <CODE>$^I</CODE> sets the in-place edit flag to a dot followed by the time. We copy the
  +names of the logfiles into <CODE>@ARGV</CODE>, and open each in turn and immediately close them without doing any
  +changes; but because the in-place edit flag is set they are effectively
  +renamed.
  +
  +<P>
   Randal L. Schwartz contributed this:
   
   <BLOCKQUOTE>
  @@ -1222,8 +1235,8 @@
   <CENTER><H1><A NAME="Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A></H1></CENTER>
   <P>
   Sometimes calling an undefined subroutine in a module can cause a tight
  -loop that consumes all memory. Here is a way to catch such errors. Define
  -an autoload subroutine:
  +loop that consumes all the available memory. Here is a way to catch such
  +errors. Define an autoload subroutine:
   
   <P>
   <PRE>  sub UNIVERSAL::AUTOLOAD {
  @@ -1237,11 +1250,10 @@
   
   <P>
   Sometimes an error happens and causes the server to write millions of lines
  -into your <EM>error_log</EM> file and in a few minutes to bring your server to its knees. For example
  -sometimes I get bursts of an error
  -<CODE>Callback called exit</CODE> showing up in my <EM>error_log</EM>. The file grows 300 Mbytes in a few minutes. You should run a cron job to
  -make sure this does not happen, and if it does to take care of it. Andreas
  -J. Koenig runs this shell script every minute:
  +into your <EM>error_log</EM> file and in a few minutes this will bring your server to its knees due to
  +lack of disk space. For example sometimes I get bursts of an error <CODE>Callback called exit</CODE> showing up in my <EM>error_log</EM>. The file grows to 300 Mbytes in a few minutes. You should run a cron job
  +to make sure this does not happen, and if it does to take care of it.
  +Andreas J. Koenig runs this shell script every minute:
   
   <P>
   <PRE>  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  @@ -1253,7 +1265,7 @@
   </PRE>
   <P>
   On my server I run a watchdog every five minutes which restarts the server
  -if it gets stuck it always works since when some mod_perl child process
  +if it gets stuck. It always works since when some mod_perl child process
   goes wild, the I/O it causes is so heavy that its sibling processes cannot
   serve requests. See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server</A> for more hints.
   
  @@ -1304,7 +1316,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/26/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.6       +0 -0      modperl-site/guide/correct_headers.html
  
  Index: correct_headers.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/correct_headers.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- correct_headers.html	2000/03/04 20:31:45	1.5
  +++ correct_headers.html	2000/04/09 14:19:38	1.6
  @@ -229,7 +229,7 @@
     use Date::Parse;
     # Date::Parse parses RCS format, Apache::Util::parsedate doesn't
     $Mtime ||=
  -    Date::Parse::str2time(substr q$Date: 2000/03/04 20:31:45 $, 6);
  +    Date::Parse::str2time(substr q$Date: 2000/04/09 14:19:38 $, 6);
     $r-&gt;set_last_modified($Mtime);
   </PRE>
   <P>
  @@ -777,8 +777,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="VERSION">VERSION</A></H1></CENTER>
   <P>
  -You're reading revision $Revision: 1.5 $ of this document, written on
  -$Date: 2000/03/04 20:31:45 $
  +You're reading revision $Revision: 1.6 $ of this document, written on
  +$Date: 2000/04/09 14:19:38 $
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  
  
  
  1.13      +35 -33    modperl-site/guide/databases.html
  
  Index: databases.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/databases.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- databases.html	2000/03/04 20:31:45	1.12
  +++ databases.html	2000/04/09 14:19:38	1.13
  @@ -89,7 +89,8 @@
   Terabytes of data lying around. To manipulate the data new smart techniques
   and technologies were invented. One of the major inventions was the
   relational database, which allows us to search and modify huge stores of
  -data in very little time. We use <STRONG>SQL</STRONG> (Structured Query Language) to manipulate the contents of these databases.
  +data very quickly. We use <STRONG>SQL</STRONG> (Structured Query Language) to access and manipulate the contents of these
  +databases.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -99,10 +100,14 @@
   web interfaces to their databases. CGI is the most widely used technology
   for building such interfaces. The main limitation of a CGI script driving a
   database is that its database connection is not persistent - on every
  -request the CGI script has to initiate a connection to the database, and
  -when the request is completed the connection is closed. <CODE>Apache::DBI</CODE> was written to remove this limitation. When you use it, you have a database
  +request the CGI script has to re-connect to the database, and when the
  +request is completed the connection is closed.
  +
  +<P>
  +<CODE>Apache::DBI</CODE> was written to remove this limitation. When you use it, you have a database
   connection which persists for the process' entire life. So when your
  -mod_perl script needs to use a database, <CODE>Apache::DBI</CODE> provides a valid connection immediately and your script starts work right
  +mod_perl script needs to use a database,
  +<CODE>Apache::DBI</CODE> provides a valid connection immediately and your script starts work right
   away without having to initiate a database connection first.
   
   <P>
  @@ -111,15 +116,14 @@
   been served.
   
   <P>
  -It's almost as straightforward as is it sounds, there are just a few things
  +It's almost as straightforward as is it sounds; there are just a few things
   to know about and we will cover them in this section.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Introduction">Introduction</A></H2></CENTER>
   <P>
  -The DBI module can make use of the Apache::DBI module. When it loads, the
  -DBI module tests if the environment variable
  +The DBI module can make use of the <CODE>Apache::DBI</CODE> module. When it loads, the DBI module tests if the environment variable
   <CODE>$ENV{GATEWAY_INTERFACE}</CODE> starts with <CODE>CGI-Perl</CODE>, and if the
   <CODE>Apache::DBI</CODE> module has already been loaded. If so, the DBI module will forward every
   <CODE>connect()</CODE> request to the <CODE>Apache::DBI</CODE>
  @@ -131,7 +135,8 @@
   <P>
   If there is no appropriate database handle or if the <CODE>ping()</CODE>
   method fails, <CODE>Apache::DBI</CODE> establishes a new connection and stores the handle for later re-use. When
  -the script is run again by a child that is still connected, <CODE>Apache::DBI</CODE> just checks the cache of open connections by matching <EM>host</EM>,<EM>username</EM> and <EM>password</EM> parameters against it. A matching connection is returned if available or a
  +the script is run again by a child that is still connected, <CODE>Apache::DBI</CODE> just checks the cache of open connections by matching the <EM>host</EM>, <EM>username</EM> and <EM>password</EM>
  +parameters against it. A matching connection is returned if available or a
   new one is initiated and then returned.
   
   <P>
  @@ -139,7 +144,7 @@
   your code. They won't do anything because the <CODE>Apache::DBI</CODE> module overloads the <CODE>disconnect()</CODE> method with an empty one.
   
   <P>
  -When this module should be used and when shouldn't?
  +When should this module be used and when shouldn't it be used?
   
   <P>
   You will want to use this module if you are opening several database
  @@ -151,10 +156,10 @@
   database traffic.
   
   <P>
  -You must NOT use this module if you are opening a special connection for
  -each of your users. Each connection will stay persistent and in a short
  -time the number of connections will be so big that your machine will scream
  -in agony and die.
  +You must <STRONG>not</STRONG> use this module if you are opening a special connection for each of your
  +users. Each connection will stay persistent and in a short time the number
  +of connections will be so big that your machine will scream in agony and
  +die.
   
   <P>
   If you want to use <CODE>Apache::DBI</CODE> but you have both situations on one machine, at the time of writing the
  @@ -174,7 +179,7 @@
   </PRE>
   <P>
   Note that it is important to load this module before any other
  -<CODE>Apache*DBI</CODE> module and <CODE>DBI</CODE> module itself!
  +<CODE>Apache*DBI</CODE> module and before the <CODE>DBI</CODE> module itself!
   
   <P>
   You can skip preloading <CODE>DBI</CODE>, since <CODE>Apache::DBI</CODE> does that. But there is no harm in leaving it in, as long as it is loaded
  @@ -202,9 +207,10 @@
     );
   </PRE>
   <P>
  -As noted above, use this method only if you only want all of apache to be
  -able to connect to the database server as one user (or as a very few
  -users).
  +As noted above, use this method only if you want all of apache to be able
  +to connect to the database server as one user (or as a very few users),
  +i.e. if your <CODE>user(s)</CODE> can effectively share the connection. Do
  +<STRONG>not</STRONG> use this method if you want for example one unique connection per user.
   
   <P>
   Be warned though, that if you call <CODE>connect_on_init()</CODE> and your database is down, Apache children will be delayed at server
  @@ -216,8 +222,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Debugging_Apache_DBI">Debugging Apache::DBI</A></H2></CENTER>
   <P>
  -If you are not sure this module is working as advertised, you should enable
  -Debug mode in the startup script by:
  +If you are not sure if this module is working as advertised, you should
  +enable Debug mode in the startup script by:
   
   <P>
   <PRE>  $Apache::DBI::DEBUG = 1;
  @@ -262,7 +268,7 @@
   <PRE>  nohup $ledir/mysqld [snipped other options] -O wait_timeout=172800
   </PRE>
   <P>
  -172800 seconds is equal to 48 hours. This change solves the problem.
  +(172800 seconds is equal to 48 hours. This change solves the problem.)
   
   <P>
   Note that as from version <CODE>0.82</CODE>, <CODE>Apache::DBI</CODE> implements <CODE>ping()</CODE> inside the <CODE>eval</CODE> block. This means that if the handle has timed out it should be reconnected
  @@ -272,8 +278,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Opening_connections_with_differe">Opening connections with different parameters</A></H3></CENTER>
   <P>
  -When it received a connection request, before it will decide to use an
  -existing cached connection, <CODE>Apache::DBI</CODE> insists that the new connection be opened in exactly the same way as the
  +When it receives a connection request, before it decides to use an existing
  +cached connection, <CODE>Apache::DBI</CODE> insists that the new connection be opened in exactly the same way as the
   cached connection. If I have one script that sets <CODE>LongReadLen</CODE> and one that does not, <CODE>Apache::DBI</CODE> will make two different connections. So instead of having a maximum of 40
   open connections, I can end up with 80.
   
  @@ -368,8 +374,8 @@
   the similar C&lt;$h-E&lt;gt&gt;trace&gt; method.
   </PRE>
   <P>
  -Using the handle trace option with a <CODE>$dbh</CODE> or <CODE>$sth</CODE> is handy for limiting the trace info to the specific bit of code you are
  -interested in.
  +Using the handle trace option with a <CODE>$dbh</CODE> or <CODE>$sth</CODE> is handy for limiting the trace info to the specific bit of code that you
  +are interested in.
   
   <P>
   Trace Levels:
  @@ -379,9 +385,9 @@
   <P><LI><STRONG><A NAME="item_1">1 - trace DBI method calls returning with results.</A></STRONG>
   <P><LI><STRONG><A NAME="item_2">2 - trace method entry with parameters and exit with results.</A></STRONG>
   <P><LI><STRONG><A NAME="item_3">3 - as above, adding some high-level information from the
  -driver also adds some internal information from the DBI.</A></STRONG>
  +driver and also adding some internal information from the DBI.</A></STRONG>
   <P><LI><STRONG><A NAME="item_4">4 - as above, adding more detailed information from the driver
  -also includes DBI mutex information when using threaded perl.</A></STRONG>
  +and also including DBI mutex information when using threaded perl.</A></STRONG>
   <P><LI><STRONG><A NAME="item_5">5 and above - as above but with more and more obscure
   information.</A></STRONG>
   </UL>
  @@ -464,10 +470,6 @@
   handles with mod_cgi.
   
   <P>
  -Notice the <CODE>DESTROY</CODE> block at the end of the module, which makes various cleanups and allows
  -this module to be used under <CODE>mod_cgi</CODE> as well.
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="The_My_DB_module">The My::DB module</A></H2></CENTER>
   
  @@ -489,8 +491,8 @@
     my $db_obj = new My::DB or croak &quot;Can't initialize My::DB object: $!\n&quot;;
   </PRE>
   <P>
  -Now you can use any of <CODE>My::DB</CODE>'s methods. Assume that we have a table called <EM>tracker</EM> where we store the names of the users and what they are doing in each and
  -every moment (think about online community program).
  +Now you can use any of <CODE>My::DB</CODE>'s methods. Assume that we have a table called <EM>tracker</EM> where we store the names of the users and what they are doing at each and
  +every moment (think about an online community program).
   
   <P>
   I will start with a very simple query--I want to know where the users are
  @@ -683,7 +685,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/16/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.13      +32 -33    modperl-site/guide/dbm.html
  
  Index: dbm.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/dbm.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- dbm.html	2000/03/04 20:31:45	1.12
  +++ dbm.html	2000/04/09 14:19:38	1.13
  @@ -65,12 +65,12 @@
   pairs to store and manipulate the records, this is a solution that should
   be amongst the first you consider. The maximum practical size of a dbm
   database depends on your hardware and the desired response times of course,
  -but as a rough guide consider 5000 to 10000 records to be reasonable.
  +but as a rough guide consider 5,000 to 10,000 records to be reasonable.
   
   <P>
   Some of the earliest databases implemented on Unix were dbm files, and many
   are still in use today. As of this writing the Berkeley DB is the most
  -powerful dbm implementation.
  +powerful dbm implementation (http://www.sleepycat.com).
   
   <P>
   With dbm, the whole database is rarely read into a memory. Combine this
  @@ -86,7 +86,7 @@
   <UL>
   <P><LI>
   <P>
  -The <CODE>HASH</CODE> algorithm gives a <CODE>0(1)</CODE> complexity of search and update, fast insert and delete, but a slow sort.
  +The <CODE>HASH</CODE> algorithm gives an <CODE>0(1)</CODE> complexity of search and update, fast insert and delete, but a slow sort.
   (You have to do it yourself.)
   
   <P><LI>
  @@ -109,7 +109,7 @@
   <P>
   <STRONG>dbm</STRONG> databases are not limited to storing key/value pairs. They can store more
   complicated data structures with the help of the <CODE>MLDBM</CODE>
  -module. This module can dump and restore the whole symbol table of your
  +module. This module can store and restore the whole symbol table of your
   script, including arrays, hashes and other complicated data structures.
   
   <P>
  @@ -122,16 +122,15 @@
   <PRE>  #!/usr/bin/perl -w
     
     #
  -  # This script gets as a parameter a Berkeley DB file(s) which is stored
  -  # with DB_BTREE algorithm, and will backup it with .bak and create
  -  # instead the db with the same records but stored with DB_HASH
  -  # algorithm
  +  # This script takes as its parameters a list of Berkeley DB file(s)
  +  # which are stored with DB_BTREE algorithm, and will back them up
  +  # using .bak extension and create instead dbms with the same records
  +  # but stored using the DB_HASH   # algorithm
     #
     # Usage: btree2hash.pl filename(s)
     
     use strict;
     use DB_File;
  -  use File::Copy;
     
       # Do checks 
     die &quot;Usage: btree2hash.pl filename(s))\n&quot; unless @ARGV;
  @@ -141,8 +140,8 @@
       die &quot;Can't find $filename: $!\n&quot; unless -e $filename and -r $filename;
     
         # First backup the file
  -    move(&quot;$filename&quot;,&quot;$filename.btree&quot;) 
  -      or die &quot;can't move $filename $filename.btree:$!\n&quot;;
  +    rename &quot;$filename&quot;, &quot;$filename.btree&quot; 
  +      or die &quot;can't rename $filename $filename.btree:$!\n&quot;;
     
       my %btree;
       my %hash;
  @@ -173,13 +172,13 @@
   
   <P>
   If you are using a read only dbm file you can have it work faster if you
  -keep it open (tied) all the time, so when your CGI script wants to access
  -the database it is already tied and ready to be used. It will work with
  -dynamic (read/write) databases as well but you need to use locking and data
  -flushing to avoid data corruption.
  +keep it open (tied) all the time, so that when your CGI script wants to
  +access the database it is already tied and ready to be used. It will work
  +with dynamic (read/write) databases as well but you need to use locking and
  +data flushing to avoid data corruption.
   
   <P>
  -Although mod_perl and dbm can give huge performance gains to your CGIs
  +Although mod_perl and dbm can give huge performance gains to your CGI
   scripts, you should be very careful. You need to consider locking, and the
   consequences of <CODE>die()</CODE> and unexpected process deaths.
   
  @@ -218,13 +217,12 @@
   The treatment of the <EM>WRITE</EM> lock request is most important.
   
   <P>
  -If the DB is <EM>READ</EM> locked, a process that makes a WRITE request will poll until there are no
  -reading or writing processes left. Lots of processes can successfully read
  -the file, since they do not block each other. This means that a process
  -that wants to write to the file (so first it needs to obtain an exclusive
  -lock) may never get a chance to squeeze in. The following diagram
  -represents a possible scenario where everybody can read but no one can
  -write:
  +If the DB is <EM>READ</EM> locked, a process that makes a <EM>WRITE</EM> request will poll until there are no reading or writing processes left.
  +Lots of processes can successfully read the file, since they do not block
  +each other. This means that a process that wants to write to the file (so
  +first it needs to obtain an exclusive lock) may never get a chance to
  +squeeze in. The following diagram represents a possible scenario where
  +everybody can read but no one can write:
   
   <P>
   <PRE>  [-p1-]                 [--p1--]
  @@ -241,7 +239,7 @@
   
   <P>
   Ken Williams solved the above problem with his
  -<CODE>&lt;A HREF=&quot;././dbm.html#Tie_DB_Lock&quot;&gt;Tie::DB_Lock&lt;/A&gt;</CODE> module, which I will present in on of the next sections.
  +<CODE>&lt;A HREF=&quot;././dbm.html#Tie_DB_Lock&quot;&gt;Tie::DB_Lock&lt;/A&gt;</CODE> module, which I will discuss in one of the following sections.
   
   <P>
   There are three locking wrappers for <CODE>DB_File</CODE> in CPAN right now. Each one implements locking differently and has
  @@ -260,9 +258,9 @@
   <P>
   You may not use a tied file's filehandle for locking, since you get the
   filehandle after the file has been already tied. It's too late to lock. The
  -problem is that the database file is locked <STRONG>after</STRONG> it is opened. When the database is opened, the first 4k (in my dbm library)
  -are read and then cached in memory. Therefore, a process can open the
  -database file, cache the first 4k, and then block while another process
  +problem is that the database file is locked <STRONG>after</STRONG> it is opened. When the database is opened, the first 4k (in Berkley dbm
  +library) is read and then cached in memory. Therefore, a process can open
  +the database file, cache the first 4k, and then block while another process
   writes to the file. If the second process modifies the first 4k of the
   file, when the original process gets the lock is now has an inconsistent
   view of the database. If it writes using this view it may easily corrupt
  @@ -304,12 +302,12 @@
   <CODE>DB_File::Lock</CODE> -- extremely lightweight <CODE>DB_File</CODE> wrapper that simply flocks a lockfile before tie-ing the database and drops
   the lock after the untie. Allows one to use the same lockfile for multiple
   databases to avoid deadlock problems, if desired. Use for databases where
  -updates are reads are quick and simple flock locking semantics are enough.
  +updates and reads are quick and simple flock locking semantics are enough.
   Refer to <CODE>DB_File::Lock</CODE> manpage for more information.
   
   <P><LI>
   <P>
  -<CODE>DB_File::Lock2</CODE> -- does the same thing as <CODE>DB_File::Lock</CODE>, but has a little different implementation, as I wrote it before David
  +<CODE>DB_File::Lock2</CODE> -- does the same thing as <CODE>DB_File::Lock</CODE>, but has a slightly different implementation, as I wrote it before David
   Harris has released his <CODE>DB_File::Lock</CODE> and I didn't want to kill mine, I'll keep it here for a while :).  <CODE>DB_File::Lock2</CODE> is covered
   <A HREF="././dbm.html#DB_File_Lock2">here</A>.
   
  @@ -368,7 +366,7 @@
   careful</STRONG> if you use it on a production machine.
   
   <P>
  -And you use it like this:
  +You use it like this:
   
   <P>
   <PRE>  use DB_File::Lock2 ();
  @@ -425,7 +423,8 @@
     }
     untie %mydb;
     
  -    # now, read them and printout (unsorted)
  +    # now, read them and printout (unsorted) 
  +    # notice that 'read' is a default lock mode
     tie %mydb, 'DB_File::Lock2', $dbfile;
     while (my($k,$v) = each %mydb) {
       print &quot;$k =&gt; $v\n&quot;;
  @@ -433,7 +432,7 @@
     untie %mydb;
   </PRE>
   <P>
  -If your CGI was interrupted in the middle, <CODE>DESTROY</CODE> block will take care of unlocking the dbm file and flush any changes. So
  +If your CGI script was interrupted in the middle, the <CODE>DESTROY</CODE> block will take care of unlocking the dbm file and flush any changes. So
   your DB will be safe against possible corruption because of unclean program
   termination.
   
  @@ -470,7 +469,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/16/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.22      +1516 -1310modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- debug.html	2000/03/04 20:31:45	1.21
  +++ debug.html	2000/04/09 14:19:38	1.22
  @@ -38,9 +38,14 @@
   	<LI><A HREF="#Hanging_processes_Detection_and">Hanging processes: Detection and Diagnostics</A>
   	<UL>
   
  -		<LI><A HREF="#An_Example_of_the_Code_that_Migh">An Example of the Code that Might Hang the Process</A>
  +		<LI><A HREF="#An_Example_of_Code_that_Might_Ha">An Example of Code that Might Hang a Process</A>
   		<LI><A HREF="#Detecting_hanging_processes">Detecting hanging processes</A>
   		<LI><A HREF="#Determination_of_the_reason">Determination of the reason</A>
  +		<UL>
  +
  +			<LI><A HREF="#Using_gdb">Using gdb</A>
  +		</UL>
  +
   	</UL>
   
   	<LI><A HREF="#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>
  @@ -57,11 +62,11 @@
   
   	</UL>
   
  -	<LI><A HREF="#Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A>
  +	<LI><A HREF="#Handling_Server_Timeout_Cases_an">Handling Server Timeout Cases and Working with $SIG{ALRM}</A>
   	<LI><A HREF="#Looking_inside_the_server">Looking inside the server</A>
   	<UL>
   
  -		<LI><A HREF="#Apache_Status_Embedded_inter">Apache::Status - Embedded interpreter status information</A>
  +		<LI><A HREF="#Apache_Status_Embedded_Inter">Apache::Status - Embedded Interpreter Status Information</A>
   		<UL>
   
   			<LI><A HREF="#Minimal_Configuration">Minimal Configuration</A>
  @@ -79,17 +84,17 @@
   
   	</UL>
   
  -	<LI><A HREF="#Sometimes_script_works_sometime">Sometimes script works, sometimes does not</A>
  +	<LI><A HREF="#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A>
   	<LI><A HREF="#Code_Debug">Code Debug</A>
   	<UL>
   
   		<LI><A HREF="#Locating_and_correcting_Syntax_E">Locating and correcting Syntax Errors</A>
   		<LI><A HREF="#Using_Apache_FakeRequest_to_Deb">Using Apache::FakeRequest to Debug Apache Perl Modules</A>
  -		<LI><A HREF="#Finding_the_Line_Number_the_Erro">Finding the Line Number the Error/Warning has been Triggered at</A>
  -		<LI><A HREF="#Using_print_Function_for_Debug">Using print() Function for Debugging</A>
  +		<LI><A HREF="#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A>
  +		<LI><A HREF="#Using_print_for_Debugging">Using print() for Debugging</A>
   		<LI><A HREF="#Using_print_and_Data_Dumper_f">Using print() and Data::Dumper for Debugging</A>
  -		<LI><A HREF="#The_Importance_of_Good_Coding_St">The Importance of Good Coding Style and Conciseness</A>
  -		<LI><A HREF="#Introduction_into_Perl_Debugger">Introduction into Perl Debugger</A>
  +		<LI><A HREF="#The_Importance_of_a_Good_Concise">The Importance of a Good Concise Coding Style</A>
  +		<LI><A HREF="#Introduction_to_the_Perl_Debugge">Introduction to the Perl Debugger</A>
   		<LI><A HREF="#Interactive_Perl_Debugging_under">Interactive Perl Debugging under mod_cgi</A>
   		<LI><A HREF="#Non_Interactive_Perl_Debugging_u">Non-Interactive Perl Debugging under mod_perl</A>
   		<LI><A HREF="#Interactive_mod_perl_Debugging">Interactive mod_perl Debugging</A>
  @@ -111,8 +116,10 @@
   	<LI><A HREF="#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
   	<LI><A HREF="#Code_Profiling">Code Profiling</A>
   	<LI><A HREF="#Devel_Peek">Devel::Peek</A>
  -	<LI><A HREF="#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  +	<LI><A HREF="#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A>
   	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
  +	<LI><A HREF="#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A>
  +	<LI><A HREF="#Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -143,40 +150,51 @@
   <P>
   You have just installed this new CGI script and when you try it out you see
   the grey screen of death saying ``Internal Server Error''... Or even worse
  -you have a script running on production server for a long time without
  -problems, when suddenly the same grey screen occasionally shows up.
  +you have a script running on a production server for a long time without
  +problems, when the same grey screen starts to show up occasionally for no
  +apparent reason.
   
   <P>
  -What are you going to do? How can find out what the problem is? You code in
  -Perl for years, and whenever an error was occuring you always saw it as it
  -was displayed in the same terminal window you've started the script from.
  -But when you work with webserver, there is no terminal to look for errors,
  -since the server in most cases has no terminal to send the error messages
  -to.
  +How can we find out what the problem is?
   
   <P>
  -Actually, the error messages don't disappear, there end up in the
  -<CODE>error_log</CODE> file, that located in the directory specified by an
  -<CODE>ErrorLog</CODE> directive in the <CODE>httpd.conf</CODE> file. The default setting is generally:
  +First problem:
   
   <P>
  +You have been coding in Perl for years, and whenever an error occurred in
  +the past it was displayed in the same terminal window that you started the
  +script from. But when you work with a webserver there is no terminal to
  +show you the errors, since the server in most cases has no terminal to send
  +the error messages to.
  +
  +<P>
  +Actually, the error messages don't disappear, they end up in the
  +<EM>error_log</EM> file. It is located in the directory specified by the
  +<CODE>ErrorLog</CODE> directive in <EM>httpd.conf</EM>. The default setting is generally:
  +
  +<P>
   <PRE>  ErrorLog /usr/local/apache/logs/error_log
   </PRE>
   <P>
  -So whenever you see the <EM>"Internal Server Error"</EM> it's a time to look at this file. We have solved the first problem, where
  -to look for error messages.
  +So whenever you see <EM>"Internal Server Error"</EM> it's time to look at this file.
   
   <P>
  -There is a chance that seeing the error message doesn't really help to spot
  -and fix the error. The error message can be of immediate help, but it might
  -not help at all. The usefulness of the error message depends solely on the
  -programmers coding style.
  +First problem solved!
   
   <P>
  -Let's take an example of the call to a function that opens a file passed as
  -a parameter and does nothing with it. The first version of the code:
  +Second problem:
   
   <P>
  +The usefulness of the error message depends to some extent on the
  +programmer's coding style. An uninformative message might not help you to
  +spot and fix the error.
  +
  +<P>
  +For example, let's take a function which opens a file passed to it as a
  +parameter. It does nothing else with the file. Here's our first version of
  +the code:
  +
  +<P>
   <PRE>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
  @@ -190,22 +208,22 @@
     open_file(&quot;/tmp/test.txt&quot;);
   </PRE>
   <P>
  -I assume that <CODE>/tmp/test.txt</CODE> doesn't exist so the <CODE>open()</CODE> would fail to open the file. When
  -we call this script from our browser, the browser returns an <EM>"internal error"</EM> message and we see the following error at at the end of <CODE>error_log</CODE> file:
  +Let's assume that <CODE>/tmp/test.txt</CODE> doesn't exist so the <CODE>open()</CODE> will fail to open the file. When
  +we call this script from our browser, the browser returns an <EM>"internal error"</EM> message and we see the following error appended to <EM>error_log</EM>:
   
   <P>
   <PRE>  Died at /home/httpd/perl/test.pl line 9.
   </PRE>
   <P>
  -So we use the hint, Perl kindly gave to us to find where in the code the
  -<CODE>die()</CODE> was called. What we still don't know is what filename
  -that was passed to this subroutine caused the program termination. When we
  -have only once function call like in the example above -- the task of
  -finding the problematic file is trivial.
  +We can use the hint Perl kindly gave to us to find where in the code the
  +<CODE>die()</CODE> was called. However, we still don't know what filename
  +was passed to this subroutine to cause the program termination.
   
   <P>
  -Now let's add two more <CODE>open_file()</CODE> function calls and assume
  -that among tree files only <CODE>/tmp/test2.txt</CODE> exists:
  +If we have only one function call as in the example above, the task of
  +finding the problematic filename will be trivial. Now let's add two more
  +<CODE>open_file()</CODE> function calls and assume that among the three
  +files only <EM>/tmp/test2.txt</EM> exists:
   
   <P>
   <PRE>  open_file(&quot;/tmp/test.txt&quot;);
  @@ -213,8 +231,7 @@
     open_file(&quot;/tmp/test3.txt&quot;);
   </PRE>
   <P>
  -When you execute the above call, you will see the same error message for
  -two times.
  +When you execute the above call, you will see the same error message twice:
   
   <P>
   <PRE>  Died at /home/httpd/perl/test.pl line 9.
  @@ -222,15 +239,14 @@
   </PRE>
   <P>
   Based on this error message, can you tell what files your program failed to
  -open? Probably not. Let's fix it by passing to <CODE>die()</CODE> the name
  -of the file is question.
  +open? Probably not. Let's fix it by passing the name of the file to
  +<CODE>die():</CODE>
   
   <P>
   <PRE>  sub open_file{
       my $filename = shift || '';
       die &quot;No filename passed!&quot; unless $filename;
  -  
  -    open FILE, $filename or die &quot;failed to open $filename&quot;;;
  +    open FILE, $filename or die &quot;failed to open $filename&quot;;
     }
     
     open_file(&quot;/tmp/test.txt&quot;);
  @@ -242,262 +258,283 @@
   <PRE>  failed to open /tmp/test.txt at /home/httpd/perl/test.pl line 9.
   </PRE>
   <P>
  -Which makes a big difference, since we know what file we should be checking
  -on.
  +which makes a big difference.
   
   <P>
  -By the way, if you append a newline at the end of the message you pass to
  -<CODE>die(),</CODE> perl wouldn't report the line number the error has
  +By the way, if you append a newline to the end of the message you pass to
  +<CODE>die(),</CODE> Perl won't report the line number the error has
   happened at, so if you code:
   
   <P>
   <PRE>  open FILE, $filename or die &quot;failed to open a file\n&quot;;
   </PRE>
   <P>
  -The error message in case of failure would be:
  +The error message will be:
   
   <P>
   <PRE>  failed to open a file
   </PRE>
   <P>
  -Which gives you no debug information at all. It's very hard to debug this
  -kind of code.
  +Which gives you very little to go on. It's very hard to debug with such
  +uninformative error messages.
   
   <P>
   The <CODE>warn()</CODE> function, a kinder sister of <CODE>die(),</CODE>
  -which logs the message but doesn't cause the program termination, behaves
  -in the same way -- if you don't add a newline at the end of the message,
  -the line number <CODE>warn()</CODE> was called at would be logged,
  -otherwise it wouldn't.
  +which logs the message but doesn't cause program termination, behaves in
  +the same way. If you add a newline to the end of the message, the line
  +number <CODE>warn()</CODE> was called at won't be logged, otherwise it
  +will.
   
   <P>
  -You might want to use <CODE>warn()</CODE> instead of <CODE>die(),</CODE> if
  -the file opening failure isn't critical, consider the following code:
  +You might want to use <CODE>warn()</CODE> instead of <CODE>die()</CODE> if
  +the failure isn't critical. Consider the following code:
   
   <P>
   <PRE>  if(open FILE, $filename){
       # do something with file
     } else {
  -    warn &quot;failed to open a $filename&quot;;
  +    warn &quot;failed to open $filename&quot;;
     } 
     # more code here...
   </PRE>
   <P>
  -So, we improved our code to report to us the names of the problematic
  -files, but we still don't know the reason for <CODE>open()'s</CODE>
  -failure. Let's try to improve the <CODE>warn()</CODE> example:
  +Now we've improved our code, by reporting the names of the problematic
  +files, but we still don't know the reason for the failure. Let's try to
  +improve the <CODE>warn()</CODE> example. The <CODE>-r</CODE> operator tests whether the file is readable:
   
   <P>
  -<PRE>  if(-r $filename){}
  +<PRE>  if(-r $filename){
       open FILE, $filename;
       # do something with file
     } else {
  -    warn &quot;$filename doesn't exist or is not readable&quot;;
  +    warn &quot;Couldn't open $filename - doesn't exist or is not readable&quot;;
     } 
   </PRE>
   <P>
  -We see the warning in the error_log file:
  +Now if we cannot read the file we do not even try to open it. But we still
  +see a warning in error_log:
   
   <P>
  -<PRE>  /tmp/test.txt doesn't exist or is not readable
  +<PRE>  Couldn't open /tmp/test.txt - doesn't exist or is not readable
     at /home/httpd/perl/test.pl line 9.
   </PRE>
   <P>
  -Since it tells us the reason for failure and we don't have to go to the
  -code and check what it was trying to do with a file: open it for writing,
  -reading or else. <CODE>-r</CODE> operator tests whether the file is readable.
  +The warning tells us the reason for the failure, so we don't have to go to
  +the code and check what it was trying to do with the file.
   
   <P>
  -It could by quite an overhead to explain the possible failure that way But
  -why reinvent the wheel, when we already have the reason of failure stored
  -in <CODE>$!</CODE> variable. Let's go back to the <CODE>open_file()</CODE> function:
  +It could be quite a coding overhead to explain all the possible failure
  +reasons that way, but why reinvent the wheel? We already have the reason
  +for the failure stored in the <CODE>$!</CODE> variable. Let's go back to the <CODE>open_file()</CODE> function:
   
   <P>
   <PRE>  sub open_file{
       my $filename = shift || '';
       die &quot;No filename passed!&quot; unless $filename;
  -  
       open FILE, $filename or die &quot;failed to open $filename: $!&quot;;
     }
     
     open_file(&quot;/tmp/test.txt&quot;);
   </PRE>
   <P>
  -We see:
  +This time, if <CODE>open()</CODE> fails we see:
   
   <P>
   <PRE>  failed to open /tmp/test.txt: No such file or directory
     at /home/httpd/perl/test.pl line 9.
   </PRE>
   <P>
  -Now we have all the information we ever need to debug this problems: we
  -know what line of code triggered <CODE>die(),</CODE> we know what file was
  -attempted to be opened and the last but not least -- the reason, which an
  -operational system gladly tells to us thru <CODE>$!</CODE> variable.
  +Now we have all the information we need to debug these problems: we know
  +what line of code triggered <CODE>die(),</CODE> we know what file we were
  +trying to open, and last but not least we know the reason, given to us
  +through Perl's <CODE>$!</CODE> variable.
   
   <P>
  -Now let's create the <CODE>/tmp/test.txt</CODE> file, so it would exist
  +Now let's create the file <EM>/tmp/test.txt</EM>.
   
   <P>
   <PRE>  % touch /tmp/test.txt
   </PRE>
   <P>
  -Now when we execute the latest version of the code, we see:
  +When we execute the latest version of the code, we see:
   
   <P>
  -<PRE>  failed to open a /tmp/test.txt: Permission denied
  +<PRE>  failed to open /tmp/test.txt: Permission denied
     at /home/httpd/perl/test.pl line 9.
   </PRE>
   <P>
  -We see a different reason: I've created the file that doesn't belong to
  -user <EM>nobody</EM>, the server runs as. So it has no permission to read the file.
  +Here we see a different reason: we created a file that doesn't belong to
  +the user which the server runs as (usually <EM>nobody</EM>). It does not have permission to read the file.
   
   <P>
  -Now you understand that it's much easier to debug your code if you validate
  +Now you can see that it's much easier to debug your code if you validate
   the return values of the system calls, and properly code arguments to
  -<CODE>die()</CODE> and <CODE>warn()</CODE> calls. <CODE>open()</CODE>
  +<CODE>die()</CODE> and <CODE>warn()</CODE> calls. The <CODE>open()</CODE>
   function is just one of the many system calls perl provides to your
   convenience.
   
  +<P>
  +So now you can code and debug CGI scripts and modules as easily as if they
  +were plain Perl scripts that you execute from a shell.
  +
   <P>
  -So now you can code and debug CGI scripts and modules, as easy as if they
  -were plain perl scripts that you used to execute from a shell.
  +Second problem solved!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Helping_error_log_to_Help_Us">Helping error_log to Help Us</A></H1></CENTER>
   <P>
   It's a good idea to keep it open all the time in a dedicated terminal with
  -help of <EM>tail -f</EM>.
  +the help of <EM>tail -f</EM> or <EM>less -S</EM>, whichever you prefer (the latter allows you to page around the file,
  +search etc.)
   
   <P>
   <PRE>  % tail -f /usr/local/apache/logs/error_log
   </PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE>  % less -S /usr/local/apache/logs/error_log
  +</PRE>
   <P>
  -So you will see all the errors and warning immediately showing up as they
  -happen.
  +So you will see all the errors and warning as they happen.
   
   <P>
  -Another tips is to create an shell <EM>alias</EM>, to make it easier to execute the above command. In tcsh you would do:
  +Another tip is to create a shell <EM>alias</EM>, to make it easier to execute the above command. In tcsh you would do
  +something like this:
   
   <P>
   <PRE>  % alias err &quot;tail -f /usr/local/apache/logs/error_log&quot;
   </PRE>
   <P>
  -and from now on in the shell you set the alias in, executing <EM>err</EM>
  -will call the <EM>tail -f /usr/local/apache/logs/error_log</EM>. Since you want this alias to be available to you all the time, you should
  -put it into a <EM>.tcshrc</EM> file or its equivalent if you don't use
  -<EM>tcsh</EM>. (<EM>.bashrc</EM> for <EM>bash</EM> users)
  +For bash users the command is:
   
   <P>
  +<PRE>  % alias err='tail -f /var/log/apache/error.log'
  +</PRE>
  +<P>
  +and from now on in the shell you set the alias in, executing
  +
  +<P>
  +<PRE>  % err
  +</PRE>
  +<P>
  +will call <EM>tail -f /usr/local/apache/logs/error_log</EM>. Since you want this alias to be available to you all the time, you should
  +put it into your <EM>.tcshrc</EM> file or its equivalent. For <EM>bash</EM> users this is
  +<EM>.bashrc</EM>, or you can put it in <EM>/etc/profile</EM> for use by all users.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="The_Importance_of_Warnings">The Importance of Warnings</A></H1></CENTER>
   <P>
  -Just like errors, perl's mandatory warnings are going to the
  -<CODE>error_log</CODE> file, if the they are enabled.
  +Just like errors, Perl's mandatory warnings go to the <EM>error_log</EM>
  +file, if the they are enabled. Of course you have enabled them in your
  +development server, haven't you?
   
   <P>
   The code you write lives a dual life. In the first life it's being written,
   tested, debugged, improved, tested, debugged, rewritten, tested, debugged.
  -In the second life it's being used, period.
  +In the second life it's <EM>just</EM> used.
  +
  +<P>
  +A significant part of the script's first life is spent on the developer's
  +machine. The other part is spent on the production server where the
  +creature is supposed to be perfect.
   
   <P>
  -A significant part of the first life the script spends at the developers,
  -its personal God's machine. The other part is being spent at the production
  -server where the developer's creature is supposed to be perfect, since it
  -was created in his own image...
  +So when you develop the code you want all the help in the world to help you
  +spot possible problems, and that's where enabling warnings is a must.
  +Whenever you see an error or warning in the <EM>error_log</EM>, you want to get rid of it. That's very important.
   
   <P>
  -So when you develop the code you want all the help in the world, to help
  -you spot possible problems, and that's where enabling warning is a must
  -mode to enable. It's very important to get rid of all or at least most of
  -the warnings that appear in the <CODE>error_log</CODE> file. Why?
  +Why?
   
   <UL>
   <P><LI>
   <P>
  -If there are warnings -- your code is not clean, and if they are waved away
  --- expect them to hit back on production server, when it's too late.
  +If there are warnings, your code is not clean. If they are waved away,
  +expect them to come back on the production server in the form of errors,
  +when it's too late.
   
   <P><LI>
   <P>
  -The other not less important reason, is that when each script's invocation
  -generates more than 5 lines of warnings, it's very hard to catch real
  -problems, as you just cannot see them among all these warnings you believe
  -are unimportant.
  +If each invocation of a script generates more than about five lines of
  +warnings, it will be very hard to catch real problems. You just can't see
  +them among all the other warnings which you used to think were unimportant.
   
   </UL>
   <P>
  -On the other hand, on production server, you really *want* to turn warnings
  -off. And there are good reasons for that:
  +On the other hand, on a production server, you really <EM>want</EM> to turn warnings off. And there are good reasons for that:
   
   <UL>
   <P><LI>
  +<P>
  +There is no added value in having the same warning showing up, again and
  +again, triggered by thousands of script invocations. If your code isn't
  +very clean and generates even a single warning per script invocation, on
  +the heavily loaded server you will end up with a huge
  +<EM>error_log</EM> file in a short time.
  +
   <P>
  -There is no added value in having the same warning showing up, when
  -triggered by thousands of script invocations. If your code isn't very clean
  -and generates even a single warning per script invocation , you will end up
  -with a huge <CODE>error_log</CODE> file in a short time on the heavily loaded server. Imagine what happens
  -when you've got more than one warning appended to the log file. The
  -warnings elimination phase is supposed to be a part of the development
  +The warning elimination phase is supposed to be a part of the development
   process, and should be done before the code goes live.
   
   <P><LI>
   <P>
  -Enabling runtime warning checking has a small performance impact (in any
  -perl script, not just under mod_perl).
  +In any Perl script, not just under mod_perl, enabling runtime warnings has
  +a performance impact.
   
   </UL>
   <P>
   mod_perl gives you a very simple solution to this warnings saga, don't
  -enable warnings in the scripts unless you really have to. Let mod_perl to
  -control this mode globally. All it takes is having a:
  +enable warnings in the scripts unless you really have to. Let mod_perl
  +control this mode globally. All you need to do is put the directive
   
   <P>
   <PRE>  PerlWarn On
   </PRE>
   <P>
  -directive added to <CODE>httpd.conf</CODE> on your development machine and having a:
  +in <EM>httpd.conf</EM> on your development machine and the directive
   
   <P>
   <PRE>  PerlWarn Off
   </PRE>
   <P>
  -directive at the live box's configuration file.
  +on the live box.
   
   <P>
  -If there is a piece of code that generates warnings and really want to
  -disable them only in this code, you can do that too. <CODE>$^W</CODE> special variable allows you to dynamically turn on and off the warnings
  -mode. So just embrace the code into a block, and disable the warnings
  -through the scope of this block. The original value of <CODE>$^W</CODE> will be restored upon exit from the block.
  +If there is a piece of code that generates warnings and you want to disable
  +them only in this code, you can do that too. The Perl special variable <CODE>$^W</CODE> allows you dynamically to turn on and off warnings mode. So just put the
  +code into a block, and disable the warnings in the scope of this block. The
  +original value of <CODE>$^W</CODE> will be restored upon exit from the block.
   
   <P>
   <PRE>  {
      local $^W=0;
  -    # some code that generates warnings
  +    # some code that generates innocuous warnings
     }
   </PRE>
   <P>
  -Again, unless you have a really good reason, for your own sake the advise
  -is avoid this workaround.
  +Unless you have a really good reason, for your own sake the advice is
  +<EM>avoid this technique</EM>.
   
   <P>
  -Don't forget the <CODE>local()</CODE> operand, as if you do, <CODE>$^W</CODE> will affect all the requests processed by the same process that globally
  -changed this variable.
  +Don't forget the <CODE>local()</CODE> operand! If you do, setting <CODE>$^W</CODE> will affect <STRONG>all</STRONG> the requests handled by the Apache child that changed this variable. And
  +for <STRONG>all</STRONG> the scripts it executes, not just the one which changed <CODE>$^W</CODE>!
   
   <P>
  -<CODE>diagnostics</CODE> pragma can shed more light on the errors and warnings as you will see in a
  +The <CODE>diagnostics</CODE> pragma can shed more light on errors and warnings, as you will see in a
   moment.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="diagnostics_pragma">diagnostics pragma</A></H2></CENTER>
   <P>
  -This module extends the terse diagnostics normally emitted by both the perl
  -compiler and the perl interpreter, augmenting them with the more
  -explicative and endearing descriptions found in the <CODE>perldiag</CODE>
  -manpage. Like the other pragmata, it affects the compilation phase of your
  -program rather than merely the execution phase.
  +This module extends the terse diagnostics normally emitted by both the Perl
  +compiler and the Perl interpreter, augmenting them with the more verbose
  +and endearing descriptions found in the <CODE>perldiag</CODE> manpage. Like the other pragmata, it affects the compilation phase of your
  +scripts as well as the execution phase.
   
   <P>
   To use in your program as a pragma, merely invoke
  @@ -506,34 +543,30 @@
   <PRE>    use diagnostics;
   </PRE>
   <P>
  -at the start (or near the start) of your program. This pragma turns on the <CODE>-w</CODE> mode as well.
  +at or near the start of your program. This also turns on <CODE>-w</CODE> mode.
   
   <P>
  -Note that generally this pragma is useful, when you are new to perl, and
  -want a better explanation of the errors and warnings, or when you encounter
  -some warning you've never seen before, e.g. when this new warning was
  -introduced in a newer version of Perl.
  -
  -<P>
  -If leaving the warnings On on production server, might consume your hard
  -disk space much faster, with <CODE>diagnostics</CODE> pragma you will run out of space about ten times faster if your code
  -generates warnings. Since for each line of text generated by mere warnings
  -mode,
  -<CODE>diagnostics</CODE> generates ten times more.
  -
  -<P>
  -The other reason, is a huge performance overhead that is being added in
  -comparison with just having warnings On. Let's see some numbers. We will
  -run the same benchmark, once with enabled diagnostics and once disabled on
  -a subroutine <EM>test_code</EM> which does nothing, but doing a power of two numbers in the loop, a numeric
  -comparison of two strings and assignment of one string to another which
  -never happens, because the conditions is the same all the time and it's
  -false. The <EM>wrong</EM>
  -comparison choice is intentional and you will understand the choice in a
  -second. By the way, the choice of the rest of the code inside
  -<EM>test_code</EM> subroutine was absolutely at random.
  +This pragma is especially useful when you are new to perl, and want a
  +better explanation of the errors and warnings. It's also helpful when you
  +encounter some warning you've never seen before, e.g. when a new warning
  +has been introduced in an upgraded version of Perl.
   
   <P>
  +You may not want to leave <CODE>diagnostics</CODE> mode On for your production server. For each warning, <CODE>diagnostics</CODE> mode generates ten times more output than warnings mode. If your code
  +generates warnings, with the <CODE>diagnostics</CODE> pragma you will use disk space much faster.
  +
  +<P>
  +<CODE>diagnostics</CODE> mode adds a large performance overhead in comparison with just having
  +warnings mode On. Let's see some numbers. We will run a benchmark, once
  +with diagnostics enabled and once disabled, on a subroutine called <EM>test_code</EM>.
  +
  +<P>
  +The code inside the subroutine is unimportant, it does very little, just
  +some arithmetic and a numeric comparison of two strings. It assigns one
  +string to another if the condition tests true but the condition always
  +tests false. To demonstrate the <CODE>diagnostics</CODE> overhead the comparison operator is intentionally <EM>wrong</EM>. It should be a string comparison, not a numeric one.
  +
  +<P>
   <PRE>  use Benchmark;
     use diagnostics;
     
  @@ -567,8 +600,7 @@
     Diagnostics on :17 wallclock secs (13.16 usr +  0.08 sys = 13.24 CPU)
   </PRE>
   <P>
  -Result: the code running with enabled diagnostics runs seven times
  -slower!!!
  +With <CODE>diagnostics</CODE> enabled, the code runs seven times slower!
   
   <P>
   Now let's fix the comparison the way it should be, by replacing
  @@ -589,43 +621,39 @@
     Diagnostics on : 2 wallclock secs ( 1.41 usr +  0.01 sys =  1.42 CPU)
   </PRE>
   <P>
  -Amazing, but now there is no overhead at all. And why is that? As we find
  -out, that <CODE>diagnostics</CODE> pragma slows things down only when something is wrong with the code.
  +Now there is no overhead at all. The <CODE>diagnostics</CODE> pragma slows things down only when warnings are generated.
   
   <P>
  -It was just a little example, but it's obvious that you wouldn't benchmark
  -all your scripts to check whether you have to remove this pragma or not.
  -Just remember to remove it, when your code goes live.
  +Obviously you won't benchmark all your scripts to check whether you have to
  +remove the <CODE>diagnostics</CODE> pragma or not. Just remember to remove it when your code goes live.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Monitoring_the_error_log_file">Monitoring the error_log file</A></H1></CENTER>
   <P>
   While debugging my mod_perl and general CGI code, I keep the
  -<CODE>error_log</CODE> file open in a dedicated terminal window (<EM>xterm</EM>), so I can see errors and warnings as soon as they are appended to the
  +<EM>error_log</EM> file open in a dedicated terminal window (<EM>xterm</EM>), so I can see errors and warnings as soon as they are appended to the
   file. I do it with:
   
   <P>
   <PRE>  tail -f /usr/local/apache/logs/error_log
   </PRE>
   <P>
  -which shows all the lines that are being added lately into the file.
  +which shows the last few lines added to the file.
   
   <P>
  -If you cannot access your <CODE>error_log</CODE> file because you are unable to telnet to your machine (generally a case
  -with some ISPs who provides user CGI support but no telnet access), you
  +If you cannot access your <EM>error_log</EM> file because you are unable to telnet to your machine (generally the case
  +with some ISPs who provide user CGI support but no telnet access), you
   might want to use a CGI script I wrote to fetch the latest lines from the
  -file (with a bonus of colored output for an easier reading). You might need
  -to ask your ISP to install this script for a general usage. See <A HREF="././snippets.html#Watching_the_error_log_File_With">Watching the error_log file without telneting to the server</A>
  +file (with a bonus of colored output for easier reading). You might need to
  +ask your ISP to install this script for general use. See <A HREF="././snippets.html#Watching_the_error_log_File_With">Watching the error_log file without telneting to the server</A> .
   
  -
  -
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Hanging_processes_Detection_and">Hanging processes: Detection and Diagnostics</A></H1></CENTER>
   <P>
  -Sometimes a httpd process might hang in a middle of a request processing,
  -either because there is a bug in your code (i.e. the code is stuck in a
  +Sometimes a httpd process might hang in the middle of processing a request,
  +either because there is a bug in your code (e.g. the code is stuck in a
   while loop, blocked by some system call or because of a resource deadlock)
   or for some other reason. There are two things we want to know: when and
   why this happens.
  @@ -652,13 +680,17 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="An_Example_of_the_Code_that_Migh">An Example of the Code that Might Hang the Process</A></H2></CENTER>
  +<CENTER><H2><A NAME="An_Example_of_Code_that_Might_Ha">An Example of Code that Might Hang a Process</A></H2></CENTER>
  +<P>
  +Deadlock is the situation where, for example, two processes, say X and Y,
  +need two resources, A and B to continue. X holds onto A and Y holds onto B.
  +There is no possibility for Y to continue before X releases A. But X cannot
  +release A before it gets Y.
  +
   <P>
  -Just to give you an idea of what kind of bug might cause the code to hang,
  -let's look at the following example. Your process have to gain lock on some
  -resource (o.e. file) before it continues, so it makes an attempt and if
  -fails (no lock gained), it <CODE>sleep()s</CODE> for a second and increment
  -the counter of attempts.
  +Look at the following example. Your process has to gain a lock on some
  +resource (e.g. a file) before it continues. So it makes an attempt, and if
  +that fails it <CODE>sleep()s</CODE> for a second and increments a counter:
   
   <P>
   <PRE>  until(gain_lock()){
  @@ -667,38 +699,36 @@
     }
   </PRE>
   <P>
  -Either because there are many processes competing on this resource or
  -because there is a deadlock (a situation when two processes X and Y need
  -resources A and B to continue, where X process holds on A and Y on B. There
  -is no possibility for Y process to continue before X releases the resource
  -A. But X cannot release A before it gets Y. Therefore this event is being
  -known as deadlock.
  +Because there are many processes competing for this resource, or perhaps
  +because there is a deadlock, <CODE>gain_lock()</CODE> always fails. The
  +process is hung.
   
   <P>
  -A real world situation that you may encounter very often is an exclusive
  -lock starvation. Generally there are two lock types in use:
  -<EM>SHARED</EM> lock which allows many processes to perform simultaneously
  -<EM>READ</EM> operation and <EM>EXCLUSIVE</EM> lock which ensures an access by a single process, which makes possible a
  -safe <EM>WRITE</EM> operation.
  +Another situation that you may very often encounter is exclusive lock
  +starvation. Generally there are two lock types in use: <EM>SHARED</EM>
  +locks, which allow many processes to perform <EM>READ</EM> operations simultaneously, and <EM>EXCLUSIVE</EM> locks. The latter permits access only by a single process and so makes a
  +safe <EM>WRITE</EM> operation possible.
   
   <P>
  -You can lock any kind of resource, in our example we talk about files.
  +You can lock any kind of resource, although in our examples we will talk
  +about files.
   
   <P>
  -If there is a <EM>READ</EM> lock request, it is granted as soon as file becomes unlocked or already <EM>READ</EM> locked. Lock status becomes
  -<EM>READ</EM> on success.
  +If there is a <EM>READ</EM> lock request, it is granted as soon as the file becomes unlocked or
  +immediately if it is already <EM>READ</EM> locked. The lock status becomes <EM>READ</EM> on success.
   
   <P>
  -If there is a <EM>WRITE</EM> lock request, it is granted as soon as file becomes unlocked. Lock status
  -becomes <EM>WRITE</EM> on success.
  +If there is a <EM>WRITE</EM> lock request, it is granted as soon as the file becomes unlocked. Lock
  +status becomes <EM>WRITE</EM> on success.
   
   <P>
  -What happens to the <EM>WRITE</EM> lock request, is the most important. If the file is being <EM>READ</EM> locked, a process that requests to write will poll until there will be no
  -reading or writing process left. Lots of processes can successfully read
  -the file, since they do not block each other from doing so. This means that
  -a process that wants to write to the file (first obtaining an exclusive
  -lock) never gets a chance to squeeze in. The following diagram represents a
  -possible scenario where everybody read but no one can write:
  +Normally it is the <EM>WRITE</EM> lock request which is the most important. If the file is being <EM>READ</EM> locked, a process that requests to write will poll until there are no
  +reading or writing process left. However, lots of processes can
  +successfully read the file, since they do not block each other from doing
  +so. This means that a process that wants to write to the file (first
  +obtaining an exclusive lock) never gets a chance to squeeze in. The
  +following diagram represents a possible scenario where everybody can read
  +but no one can write:
   
   <P>
   <PRE>  [-p1-]                 [--p1--]
  @@ -708,19 +738,17 @@
        [--p5--]   [----p5----]
   </PRE>
   <P>
  -Let's look at the real code and see it in action. The following script
  -imports <CODE>flock()</CODE> related parameters from the <CODE>Fcntl</CODE> module, opens a file that will be locked and we define and set two
  -variables:
  -<CODE>$lock_type</CODE> and <CODE>$lock_type_verbose</CODE> which are set to <CODE>LOCK_EX</CODE>
  -and <CODE>EX</CODE> if the first command line argument (<CODE>$ARGV[0]) is defined
  -and equal to &lt;EM&gt;w&lt;/EM&gt; indicating that this process will try to gain
  -&lt;EM&gt;WRITE&lt;/EM&gt; (exclusive) lock, otherwise the two are set to &lt;CODE&gt;LOCK_SH&lt;/CODE&gt; and
  -&lt;SH</CODE> for <EM>SHARED</EM> (read) lock.
  +Let's look at some real code and see it in action. The following script
  +imports <CODE>flock()</CODE> related parameters from the <CODE>Fcntl</CODE> module, and opens a file that will be locked. It then defines and sets two
  +variables: <CODE>$lock_type</CODE> and <CODE>$lock_type_verbose</CODE>. These are set to
  +<CODE>LOCK_EX</CODE> and <CODE>EX</CODE> respectively if the first command line argument (<CODE>$ARGV[0]) is defined and equal to &lt;EM&gt;w&lt;/EM&gt;.  This indicates that this
  +process will try to gain a &lt;EM&gt;WRITE&lt;/EM&gt; (exclusive) lock.  Otherwise the
  +two are set to &lt;CODE&gt;LOCK_SH&lt;/CODE&gt; and &lt;SH</CODE> for a <EM>SHARED</EM> (read) lock.
   
   <P>
  -Once the variables are set, we enter the never ending <CODE>while(1)</CODE> loop that attempts to lock the file by the mode set in <CODE>$lock_type</CODE>, report success and type of lock that was gained, then sleeps for a random
  -period between 0 to 9 seconds and unlocks the file. Then the loop starts
  -from the beginning.
  +Once the variables are set, we enter the infinite <CODE>while(1)</CODE> loop that attempts to lock the file by the mode set in <CODE>$lock_type</CODE>. It report success and the type of lock that was gained, then it sleeps
  +for a random period between 0 and 9 seconds and unlocks the file. The loop
  +then starts from the beginning.
   
   <P>
   <PRE>  lock.pl
  @@ -749,8 +777,9 @@
     close LOCK;
   </PRE>
   <P>
  -When spawning a few of the above scripts simultaneously and making sure
  -that the first processes to start are <EM>READ</EM> processes and there is majority of them, it's very easy to see the <EM>WRITE</EM> processes starvation. Execute three read and one write processes like:
  +It's very easy to see <EM>WRITE</EM> process starvation if you spawn a few of the above scripts simultaneously.
  +Start the first few as <EM>READ</EM>
  +processes and then start one <EM>WRITE</EM> process like this:
   
   <P>
   <PRE> % ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl w &amp;
  @@ -770,111 +799,107 @@
     24231: SH
   </PRE>
   <P>
  -and not a single <CODE>EX</CODE> line... When you kill off the reading processes, then the write lock will
  -be gained. Note that this is a rough example, since I've used
  -<CODE>sleep()</CODE> function. To emulate a real situation you need to use <CODE>Time::HiRes</CODE> module which allows you to sleep for microseconds.
  +and not a single <CODE>EX</CODE> line... When you kill off the reading processes, then the write process
  +will gain its lock. Note that as this is a rough example, I used the
  +<CODE>sleep()</CODE> function. To simulate a real situation you need to use
  +the <CODE>Time::HiRes</CODE> module, which allows you to choose more precise intervals to sleep.
  +
  +<P>
  +The interval between lock and unlock is called a <EM>Critical Section</EM>, which should be kept as short as possible (in terms of the time taken to
  +execute the code, and not in terms of the number of lines of code). As you
  +just saw, a single sleep statement can make the critical section long.
  +
  +<P>
  +To summarize, if you have a script that uses both <EM>READ</EM> and <EM>WRITE</EM>
  +locks and the critical section isn't very short, the writing process might
  +be starved. After a while a browser that initiated this request will
  +timeout the connection and abort the request, but it's much more likely
  +that user will press the <EM>Stop</EM> or <EM>Reload</EM> button before that happens. Since the process in question is just waiting,
  +there is no way for Apache to know that the request was aborted. It will
  +hang until the lock is gained. Only when a write to a client's broken
  +connection is attempted will Apache terminate the script.
   
   <P>
  -The interval between lock and unlock is being called a <EM>Critical
  -Section</EM>, which should be kept as little as possible in terms of time, and not in
  -terms of amount of the code. As you just saw, a single sleep statement can
  -make the critical section long.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Detecting_hanging_processes">Detecting hanging processes</A></H2></CENTER>
  +<P>
  +It's not so easy to detect hanging processes. There is no way you can tell
  +how long the request is taking to process by using plain system utilities
  +like <CODE>ps()</CODE> and <CODE>top().</CODE> The reason is that each
  +Apache process serves many requests without quitting. System utilities can
  +tell how long the process has been running since its creation, but this
  +information is useless in our case, since Apache processes normally run for
  +extended periods.
   
   <P>
  -To summarize the presented case, if you have a script that uses both
  -<EM>READ</EM> and <EM>WRITE</EM> locks and the critical section isn't very short, The writing process might
  -get into a starvation mode and after a while a browser that initiated this
  -request will timeout the connection and abort the request, but it's more
  -likely that user will press the
  -<EM>Stop</EM> or <EM>Reload</EM> button before it happens. Since the process in question just waits, there
  -is no way for Apache to know that the request was aborted and it will hang
  -till the lock will be gained and only when a write to a client's broken
  -connection will be attempted, Apache will terminate the script.
  +However there are a few approaches that can help to detect a hanging
  +process.
   
   <P>
  -So this was a single example of how the process can hang.
  +If the process hangs and demands lots of resources it's quite easy to spot
  +it by using the <CODE>top()</CODE> utility. You will see the same process
  +show up in the first few lines of the automatically refreshed report. But
  +often the hanging process uses few resources, e.g. when waiting for some
  +event to happen.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Detecting_hanging_processes">Detecting hanging processes</A></H2></CENTER>
  +Another easy case is when some process thrashes the <EM>error_log</EM>, writing millions of error messages there. Generally this process uses
  +lots of resources and is also easily spotted by using <CODE>top().</CODE>
  +
   <P>
  -It's not so easy to detect the hanging process. There is no way you can
  -tell how long the request is being processed by using plain system
  -utilities like <CODE>ps()</CODE> and <CODE>top().</CODE> The reason is that
  -each Apache process serves many requests without quitting. System utilities
  -can tell how long the process is running since its creation, but this
  -information is useless in our case, since the long running Apache process
  -is a normal and expected behavior.
  +There are other tools that report the status of Apache processes.
   
  +<UL>
  +<P><LI><STRONG><A NAME="item_The">The mod_status module, which is usually accessed from the
  +/server_status location.</A></STRONG>
  +<P><LI><STRONG><A NAME="item_The">The Apache::VMonitor module.</A></STRONG>
  +</UL>
   <P>
  -However there are a few approaches that can help to detect the hanging
  -process.
  +Both tools provide counters of processed requests per Apache process.
  +
  +<P>
  +You can watch the report for a few minutes, and try to spot any process
  +which has the same number of processed requests while its status is 'W'
  +(waiting). This means that it has hung.
  +
  +<P>
  +But if you have fifty processes, it can be quite hard to spot such a
  +process. So let's write a watchdog to do the work for us:
  +
  +<P>
  +META: Apache::SafeHang code
   
   <P>
  -If the process hangs and demands lots of resources it's quite easy to bust
  -it by monitoring the output of <CODE>top()</CODE> utility. You will see the
  -same process show up in the first few lines of the automatically refreshed
  -report. But many times the hanging process, uses little or close to zero
  -resources, e.g. when waiting for some event to happen.
  -
  -<P>
  -Another easy spotting is when some process trashes the <CODE>error_log</CODE>
  -and writes millions of error messages there... Generally this process uses
  -lots of resources and spotted by using <CODE>top()</CODE> as described
  -above.
  -
  -<P>
  -What we have to use are the tools that report the status of the Apache
  -processes. You can use either a mod_status module, which usually accessed
  -from <CODE>/server_status</CODE> location, or an <CODE>Apache::VMonitor</CODE>
  -module. Both tools provide counters of processed requests per Apache
  -process. So what you can do is to watch the report for about 5-10 minutes
  -spotting which process number has the same number of processed requests
  -while its status is 'W' (Which means that it hangs or ``runs away'')
  -
  -<P>
  -But when you have about 50 and more processes, it's quite hard to spot such
  -a process. So let's use a watchdog to do the work for us. I've put together
  -the
  -<A HREF="././modules.html#Apache_Watchdog_RunAway_Hang">Apache::Watchdog::RunAway</A>
  -module which includes the <CODE>amprapmon</CODE> utility whose name stands for
  -<EM>Apache mod_perl Run Away Processes Monitor</EM>. This utility monitors your server all the time and kills the processes
  -that serve a single request for too long. You define the threshold time for
  -the kill-off.
  -
  -<P>
  -When you've got a real problem and the processes hang one after the other,
  -the moment comes when the number of hanging processes becomes equal to the
  -value of <CODE>MaxClients</CODE> directive, which means that no more processes will be spawned and your
  -service is halted from the point of user. This is easy to detect, attempt
  -to resolve and notify the administrator by a simple crontab watchdog that
  -requests some very light script an every minute or so. (See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>)
  -
  -<P>
  -In the watchdog you set a timeout you think is appropriate for your
  -service, which may vary between a few seconds and 1 minute. If the server
  -fails to respond before the timeout expires, watchdog has spotted a trouble
  -and attempts to restart the server. After a restart an email report is
  -being sent to administrator reporting first that there was a problem,
  -second whether the restart was successful or not.
  +If you've got a real problem, and the processes hang one after the other,
  +the time will come when the number of hanging processes is equal to the
  +value of <CODE>MaxClients</CODE>. This means that no more processes will be spawned. As far as the users
  +are concerned your server is down. It is easy to detect this situation,
  +attempt to resolve it and notify the administrator using a simple crontab
  +watchdog that requests some very light script periodically. (See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>)
   
   <P>
  +In the watchdog you set a timeout appropriate for your service, which may
  +be anything from a few seconds to a few minutes. If the server fails to
  +respond before the timeout expires, the watchdog has spotted trouble and
  +attempts to restart the server. After a restart an email report is sent to
  +the administrator saying that there was a problem and whether or not the
  +restart was successful.
  +
  +<P>
   If you get such reports constantly something is wrong with your web service
   and you should revise your code. Note that it's possible that your server
  -is overloaded when being hit by more requests that it can handle, so the
  -requests are being queued and not processed for awhile, which triggers the
  -watchdog's alarm. If this is a case you need to add more servers, memory
  -and probably to split your single machine across a cluster of webserver
  +is being overloaded by more requests that it can handle, so the requests
  +are being queued and not processed for a while, which triggers the
  +watchdog's alarm. If this is a case you may need to add more servers or
  +more memory, or perhaps split your single machine across a cluster of
   machines.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Determination_of_the_reason">Determination of the reason</A></H2></CENTER>
   <P>
  -Given the process pid, there are two ways to find out where it's hanging.
  -Depending on operating system you should have either <CODE>truss</CODE>
  -or <CODE>strace</CODE> utilities available within your code development software. The usage is
  -simple:
  +Given the process id (PID), there are two ways to find out where the server
  +is hanging. Depending on the operating system you should have one of the <CODE>truss</CODE> or <CODE>strace</CODE> utilities available. The usage is simple:
   
   <P>
   <PRE>  % truss -p PID
  @@ -886,11 +911,10 @@
   <PRE>  % strace -p PID
   </PRE>
   <P>
  -Replace PID with a process number you want to check on.
  +Replace PID with the process number you want to check on.
   
   <P>
  -Let's write a program that hangs and deploy strace to find out the point it
  -hangs at:
  +Let's write a program that hangs, and deploy <CODE>strace</CODE> to find the point it hangs at:
   
   <P>
   <PRE>  hangme.pl
  @@ -907,29 +931,28 @@
     }
   </PRE>
   <P>
  -The reason this simple code hangs is obvious from its examination -- the
  -program never breaks from the while loop. As you have noticed, I print the
  -PID of the current process to the browser, to learn what process to look
  -after. Of course in a real situation, you cannot do the same trick. In the
  -previous section I have presented a few ways to detect the runaway
  -processes and their PIDs.
  +The reason this simple code hangs is obvious. It never breaks from the
  +while loop. As you have noticed, it prints the PID of the current process
  +to the browser. Of course in a real situation you cannot use the same
  +trick. In the previous section I have presented a few ways to detect the
  +runaway processes and their PIDs.
   
   <P>
   I save the above code in a file and execute it from the browser. Note that
  -I've made the STDOUT unbuffered with <CODE>$|=1;</CODE> so I would immediately see the process ID. Once the script make a request
  -the script prints its process PID and obviously hangs. So we press the
  -<CODE>'Stop'</CODE> button, but the process continues to hang in this code. Isn't apache
  -supposed to detect the broken connection and abort the request processing?
  -Yes and No, you will understand soon what's really happening.
  +I've made STDOUT unbuffered with <CODE>$|=1;</CODE> so I will immediately see the process ID. Once the script is requested, the
  +script prints the process PID and obviously hangs. So we press the <CODE>'Stop'</CODE>
  +button, but the process continues to hang in this code. Isn't apache
  +supposed to detect the broken connection and abort the request? Yes and No,
  +you will understand soon what's really happening.
   
   <P>
  -First let's attach to the process and see what's it doing. I use the PID
  +First let's attach to the process and see what it's doing. I use the PID
   the script printed to the browser, which is 10045 in this case:
   
   <P>
   <PRE>  % strace -p 10045
     
  -  [...truncated an identical output...]
  +  [...truncated identical output...]
     SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
     SYS_174(0x11, 0, 0xbffff1a0, 0x8, 0x11) = 0
     SYS_175(0x2, 0xbffff39c, 0, 0x8, 0x2)   = 0
  @@ -939,10 +962,10 @@
     [...truncated the identical output...]
   </PRE>
   <P>
  -It doesn't what we have expected to see, does it? These are some system
  -calls we don't see in our little example. What we actually see is how Perl
  -translates our code into a system calls. Since we know that our code hangs
  -in this snippet:
  +It isn't what we expected to see, is it? These are some system calls we
  +don't see in our little example. What we actually see is how Perl
  +translates our code into system calls. Since we know that our code hangs in
  +this snippet:
   
   <P>
   <PRE>  while(1){
  @@ -955,13 +978,13 @@
   <CODE>sleep 1</CODE> call.
   
   <P>
  -Generally the situation is quite opposite. You detect the hanging process,
  -you attach to it and watch the trace of calls it does (or the last commands
  -if the process hangs waiting for something, e.g. when blocking on file lock
  -request). From watching the trace you should figure out what actually it's
  -doing and probably find the corresponding lines in your perl code. For
  -example let's see how one process <EM>"hangs"</EM> while requesting an exclusive lock on the file exclusively locked by
  -another process:
  +Generally the situation is the reverse of our example. You detect the
  +hanging process, you attach to it and watch the trace of calls it does (or
  +the last few commands if the process is hanging waiting for something, e.g.
  +when blocking on a file lock request). From watching the trace you figure
  +out what it's actually doing, and probably find the corresponding lines in
  +your Perl code. For example let's see how one process <EM>"hangs"</EM> while requesting an exclusive lock on a file exclusively locked by another
  +process:
   
   <P>
   <PRE>  excl_lock.pl
  @@ -990,21 +1013,20 @@
   </PRE>
   <P>
   The code is simple. The process executing the code forks a second process,
  -and both are doing the same thing: generate an unique symbol to be used as
  -a file handler open the lock file for writing using the generated symbol,
  -lock the file in an exclusive mode sleep for 20 seconds, pretending doing
  -some lengthy operations and close the lock file, which also unlocks the
  -file.
  +and both do the same thing: generate a unique symbol to be used as a file
  +handler, open the lock file for writing using the generated symbol, lock
  +the file in exclusive mode, sleep for 20 seconds (pretending to do some
  +lengthy operation) and close the lock file, which also unlocks the file.
   
   <P>
  -<CODE>gensym</CODE> function is a courtesy of <CODE>Symbol</CODE> module the code imports it from. <CODE>Fcntl</CODE> module provides us with a symbolic constant
  -<CODE>LOCK_EX</CODE> which is being imported with <CODE>:flock</CODE> tag, which imports this an other <CODE>flock()</CODE> function attributes.
  +The <CODE>gensym</CODE> function is imported from the <CODE>Symbol</CODE> module. The
  +<CODE>Fcntl</CODE> module provides us with a symbolic constant <CODE>LOCK_EX</CODE>. This is imported via the <CODE>:flock</CODE> tag, which imports this and other <CODE>flock()</CODE> constants.
   
   <P>
   The code used by both processes is identical, therefore we cannot predict
  -which one will get its hands on the lock file and succeed to lock it first,
  -so we add <CODE>print()</CODE> statements to find out the PID of the
  -blocking on lock request process.
  +which one will get its hands on the lock file and succeed in locking it
  +first, so we add <CODE>print()</CODE> statements to find the PID of the
  +process blocking (waiting to get the lock) on a lock request.
   
   <P>
   When the above code executed from the command line, we see that one of the
  @@ -1018,8 +1040,7 @@
     3037: I'm going to obtain the lock
   </PRE>
   <P>
  -We see that process 3037 is blocking (waiting to get the lock), so we
  -attach to it:
  +Here we see that process 3037 is blocking, so we attach to it:
   
   <P>
   <PRE>  % strace -p 3037
  @@ -1027,32 +1048,40 @@
     about to attach c10
     flock(3, LOCK_EX
   </PRE>
  +<P>
  +It's clear from the above trace, that the process waits for an exclusive
  +lock. (Note, that the missing closing parentnheses is not a typo!)
  +
  +<P>
  +As you become familiar with watching the traces of different processes, you
  +will understand what is happening more easily.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Using_gdb">Using gdb</A></H3></CENTER>
   <P>
  -It's clear from the above trace, that the process waits for exclusive lock.
  +Another approach to see a trace of the running code is to use a debugger
  +such as <CODE>gdb</CODE> (the GNU debugger). It's supposed to work on any platform which supports
  +the GNU development tools. Its purpose is to allow you to see what is going
  +on <EM>inside</EM> a program while it executes, or what it was doing at the moment it crashed.  
   
   <P>
  -The more you watch traces of different processes, the easier the
  -understanding of what actually happens would be
  +To trace the execution of a process, <CODE>gdb</CODE> needs to know the process id (PID) and the path to the binary that the
  +process is executing. For Perl code it's <EM>/usr/bin/perl</EM> (or whatever is the path to your Perl), for httpd processes it will be the
  +path to your httpd executable.
   
   <P>
  -Another approach to see another kind of trace of the running code is to use <CODE>gdb</CODE> (GNU debugger) (or another debugger). It's supposed to work at any platform
  -the GNU development tools were ported to. Its purpose is to allow you to
  -see what is going on ``inside'' another program while it executes--or what
  -another program was doing at the moment it crashed. <CODE>gdb</CODE> requires the path to the binary program that the process you want to
  -examine is executing, in addition to the process ID. In case of perl code
  -it's <CODE>/usr/bin/perl</CODE> or a different path, for httpd process it would be the path to your httpd
  -executable. I will show a few examples of using gdb to get a better
  -understanding.
  +Here are a few examples using gdb.
   
   <P>
  -For example let's go back to our last locking example, execute it as before
  -and attach to the process that didn't get the lock and waits:
  +Let's go back to our last locking example, execute it as before and attach
  +to the process that didn't get the lock:
   
   <P>
   <PRE>  % gdb /usr/bin/perl 3037
   </PRE>
   <P>
  -The moment the debugger was started, we execute <EM>where</EM> command to see the trace:
  +After starting the debugger we execute the <CODE>where</CODE> command to see the trace:
   
   <P>
   <PRE>  (gdb) where
  @@ -1067,10 +1096,10 @@
         at ../sysdeps/generic/libc-start.c:78
   </PRE>
   <P>
  -Again, that's not what we've expected to see and now it's a different
  -trace. <CODE>#0</CODE> tells us the most recent call that was executed, which is a C language
  -level <CODE>flock()'s</CODE> implementation, but the previous call (<CODE>#1</CODE>) isn't <CODE>print()</CODE> as we would expect, but a higher level of
  -Perl's internal <CODE>flock().</CODE> If we follow the trace of calls, what
  +That's not what we expected to see and now it's a different trace.
  +<CODE>#0</CODE> tells us the most recent call that was executed, which is a C language
  +<CODE>flock()</CODE> implementation. But the previous call (<CODE>#1</CODE>) isn't <CODE>print(),</CODE> as we would expect, but a higher level of
  +Perl's internal <CODE>flock().</CODE> If we follow the trace of calls what
   we actually see is an Opcodes tree, which can be better presented as:
   
   <P>
  @@ -1082,29 +1111,27 @@
               __flock ()
   </PRE>
   <P>
  -So I would say that it's less useful than <CODE>strace</CODE>, since it's almost impossible to know which of the <CODE>flock()s</CODE>
  -was called if there are more than one in the code, something that is <CODE>strace</CODE> solves by showing the sequence of the system calls that are being executed,
  -so using the sequence we can locate the corresponding lines in the code. 
  +So I would say that it's less useful than <CODE>strace</CODE>, since if there are several <CODE>flock()s</CODE> it's almost impossible
  +to know which of them was called. This problem is solved by <CODE>strace</CODE>, which shows the sequence of the system calls executed. Using this
  +sequence we can locate the corresponding lines in the code.
   
   <P>
  -(META: the above is wrong - you can ask to display the previous command!
  -What is it?)
  +(META: the above is wrong - you can ask to display the previous command
  +executed by the program (not gdb)! What is it?)
   
   <P>
  -For your information, when you attach to a running process with debugger,
  -the program stops its executing and the control over the program is being
  -passed to a debugger, so you can continue the normal program run with <CODE>continue</CODE> command or to execute it step by step with <CODE>next</CODE> and <CODE>step</CODE> commands you type at the <CODE>gdb</CODE>
  -prompt. (<CODE>next</CODE> steps over any function calls in the line, while
  -<CODE>step</CODE> steps into them).
  +When you attach to a running process with debugger, the program stops
  +executing and control of the program is passed to the debugger. You can
  +continue the normal program run with the <CODE>continue</CODE> command or execute it step by step with the <CODE>next</CODE> and <CODE>step</CODE> commands which you type at the <CODE>gdb</CODE> prompt. (<CODE>next</CODE> steps over any function calls in the line, while <CODE>step</CODE> steps into them).
   
   <P>
  -C/C++ debuggers is a very large topic and I wouldn't discuss it in the
  -scope of this document, but a gdb man page is quite a good document to
  -start with. You might want also to check the <CODE>ddd</CODE> (Data Display Debbuger) which provides a visual interface to <CODE>gdb</CODE> and other debuggers. It even knows to debug perl programs!!!
  +C/C++ debuggers are a very large topic and beyond the scope of this
  +document, but the gdb man page is quite good and you can try <CODE>info
  +gdb</CODE> as well. You might also want to check the <CODE>ddd</CODE> (Data Display Debbuger) which provides a visual interface to <CODE>gdb</CODE> and other debuggers. It even knows how to debug Perl programs!
   
   <P>
  -For a completeness let's see the gdb trace of the httpd process that still
  -hangs in the <CODE>while(1)</CODE> loop of the first example in this section.
  +For completeness, let's see the gdb trace of the httpd process that's still
  +hanging in the <CODE>while(1)</CODE> loop of the first example in this section:
   
   <P>
   <PRE>  % gdb /usr/local/apache/bin/httpd 1005
  @@ -1132,21 +1159,16 @@
         at ../sysdeps/generic/libc-start.c:78
   </PRE>
   <P>
  -Just as before we can see a complete trace of the last executed call.
  +As before we can see a complete trace of the last executed call.
   
   <P>
  -As you noticed I still didn't provide the promised explanation of the
  -reason, the hanging in <CODE>while(1)</CODE> loop request processing wasn't aborted by Apache. The next section covers
  -the case.
  -
  -<P>
   #=head1 Examples of strace (or truss) usage
   
   <P>
  -#(META: below are some snippets of strace outputs from list's emails)
  +#(META: below are some snippets of strace outputs from list emails)
   
   <P>
  -#[there was a talk about Streaming LWP through mod_perl and the topic #was
  +#[there was talk about Streaming LWP through mod_perl and the topic #was
   suggested optimal buffer size]
   
   <P>
  @@ -1167,28 +1189,24 @@
   <CODE>write(4,</CODE> ``ite,\nseek, tell, or eo''..., 25657) = 25657
   
   <P>
  +As you have noticed, I still haven't explained why the process hanging in
  +the <CODE>while(1)</CODE> loop isn't aborted by Apache. The next section covers this.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A></H1></CENTER>
   <P>
  -When a user presses <STRONG>STOP</STRONG> or <STRONG>RELOAD</STRONG> buttons, Apache detects this event via a <CODE>SIGPIPE</CODE> signal (Broken pipe) and ceases the script execution and performs all the
  -cleanup stuff it has to do. It's important to stress the point that <CODE>SIGPIPE</CODE> will be triggered only when a process, that handles the connection that
  -went broken, will attempt to send some data to the client (browser). If the
  -script is doing some lengthy operation, without writing a thing to the
  -client, it wouldn't be stopped until before the operation is completed and
  -at least one character was sent back to the client.
  -
  -<P>
  -This will work for apache &gt;= 1.3.6, where it will not catch SIGPIPE
  -anymore and modperl will do it much better. Here is a snippet from a Apache
  -1.3.6 CHANGES file.
  -
  -<P>
  -<PRE>  *) SIGPIPE is now ignored by the server core.  The request write
  -  routines (ap_rputc, ap_rputs, ap_rvputs, ap_rwrite, ap_rprintf,
  -  ap_rflush) now correctly check for output errors and mark the
  -  connection as aborted.  Replaced many direct (unchecked) calls to
  -  ap_b* routines with the analogous ap_r* calls.  [Roy Fielding]
  -</PRE>
  +When a user presses a <STRONG>STOP</STRONG> or <STRONG>RELOAD</STRONG> button, Apache could detect this via the <CODE>SIGPIPE</CODE> signal (Broken pipe). It could then halt the script execution and perform
  +all the cleanup stuff it has to do. But the <CODE>SIGPIPE</CODE> will be triggered only when the process attempts to send some data to the
  +client browser via the broken connection. If the script is doing some
  +lengthy operation, without writing anything to the client, it won't be
  +stopped until that operation is completed and an attempt is made to send at
  +least one character the client.
  +
  +<P>
  +Apache &gt;= 1.3.6 does not catch SIGPIPE anymore, and modperl can do the
  +job much better.
  +
   <P>
   Since Apache version 1.3.6:
   
  @@ -1199,18 +1217,24 @@
   
   <P><LI>
   <P>
  -If you want the old <CODE>SIGPIPE</CODE> semanics, simply configure:
  +If you want a similar to the old <CODE>SIGPIPE</CODE> behaviour, simply configure:
   
   <P>
   <PRE>  PerlFixupHandler Apache::SIG
   </PRE>
  +<P>
  +When Apache's <CODE>SIGPIPE</CODE> handler is used, Perl may be left in the middle of it's eval context,
  +causing bizarre errors during subsequent requests are handled by that
  +child. When <CODE>Apache::SIG</CODE> is used, it installs a different <CODE>SIGPIPE</CODE> handler which rewinds the context to make sure Perl is back to normal
  +state, preventing these bizarre errors.
  +
   </UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Detecting_Aborted_Connections">Detecting Aborted Connections</A></H2></CENTER>
   <P>
  -Let's use the knowledge we have acquired before to trace the execution of
  -the code and see all the events as they are happening.
  +Let's use the knowledge we have acquired to trace the execution of the code
  +and see all the events as they happen.
   
   <P>
   Let's take a little script that obviously ``hangs'' the server:
  @@ -1229,22 +1253,21 @@
   </PRE>
   <P>
   The script gets a request object <CODE>$r</CODE> by <CODE>shift()ing</CODE> it from the <CODE>@_</CODE>
  -argument list passed by the <CODE>handler()</CODE> subroutine. (The magic
  -is being done by <CODE>Apache::Registry</CODE> of course). Then the script sends a
  -<EM>Content-type</EM> header, saying to the client that we are going to send a plain text.
  -
  -<P>
  -We print out a single line telling us the number of the process that
  -handles this request, which we need to know in order to run the tracing
  -utility. Then we flush Apache's buffer, since if we don't we would never
  -see the line printed. That's because the length of the output we print is
  -very small and the buffer wouldn't be flushed before it becomes full or the
  -request is over. Since our script intentionally hangs, we have to enforce
  -the buffer to get flushed.
  +argument list passed by the <CODE>handler()</CODE> subroutine. (This magic
  +is done by <CODE>Apache::Registry</CODE>). Then the script sends a <EM>Content-type</EM>
  +header, telling the client that we are going to send some plain text.
  +
  +<P>
  +We print out a single line telling us the id of the process that handles
  +this request, which we need to know in order to run the tracing utility.
  +Then we flush Apache's buffer. (If we don't flush the buffer we will never
  +see the line printed. That's because our output is shorter than the buffer
  +size and the script intentionally hangs, so the buffer won't be
  +auto-flushed as the script hangs at the end.)
   
   <P>
  -Then we enter a never ending <CODE>while(1)</CODE> loop, which all it does is incrementing a dummy <CODE>$i</CODE> variable and sleeping for a second, before returning on the two operations
  -again and again.
  +Then we enter an infinite loop, which just increments a dummy variable and
  +sleeps for a second.
   
   <P>
   Running <CODE>strace -p PID</CODE>, where <EM>PID</EM> is the process ID as printed to the browser, we see the following output
  @@ -1259,12 +1282,11 @@
     time([941281947])                       = 941281947
   </PRE>
   <P>
  -Let's leave the <CODE>strace</CODE> running and press the <STRONG>STOP</STRONG> button now. Anything was changed? No, the same trace printed every second.
  -Which means that Apache didn't detect the broken connection, which verifies
  -the statement that the script has to write something to trigger the <CODE>SIGPIPE</CODE> event.
  +Let's leave <CODE>strace</CODE> running and press the <STRONG>STOP</STRONG> button. Did anything change? No, the same trace printed every second. Which
  +means that Apache didn't detect the broken pipe.
   
   <P>
  -Let's try to write that will write a NULL <CODE>\0</CODE> character to the client so the detection would be possible as soon the <STRONG>Stop</STRONG> button was pressed:
  +Let's try to write a NULL <CODE>\0</CODE> character to the client so the broken pipe will be detected as soon the <STRONG>Stop</STRONG> button is pressed:
   
   <P>
   <PRE>  while(1){
  @@ -1280,8 +1302,9 @@
   loop.
   
   <P>
  -But if we run this script and strace on it as before, we see that it still
  -doesn't work. What's missing is a flushing of the buffer, when we add it:
  +We run this script and strace on it as before, but we see that it still
  +doesn't work. The trouble is we aren't flushing the buffer. After printing
  +the NULL, add $r-&gt;rflush():
   
   <P>
   <PRE>  my $r = shift;
  @@ -1301,8 +1324,8 @@
     }
   </PRE>
   <P>
  -Watch the strace's output on the running process and press the <STRONG>Stop</STRONG>
  -button, we see:
  +Watch <CODE>strace</CODE>'s output on the running process and then press the
  +<STRONG>Stop</STRONG> button, you will see:
   
   <P>
   <PRE>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
  @@ -1323,32 +1346,37 @@
     fcntl(18, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}
   </PRE>
   <P>
  -Apache detects the broken pipe as we see from this snippet:
  +Apache detects the broken pipe as you see from this snippet:
   
   <P>
   <PRE>  write(4, &quot;\0&quot;, 1)                       = -1 EPIPE (Broken pipe)
     --- SIGPIPE (Broken pipe) ---
   </PRE>
   <P>
  -Then stops the script, and does all the cleanup work, like access logging:
  +Then it stops the script and does all the cleanup work, like access
  +logging:
   
   <P>
   <PRE>  write(17, &quot;127.0.0.1 - - [30/Oct/1999:13:52&quot;..., 81) = 81
   </PRE>
   <P>
  -That's what we see in a <CODE>access_log</CODE> file, 17 is a file descriptor of this file in this process. We will
  -immediately talk about cleanups, since it's a very critical issue, with
  -aborted scripts. But first let's see how can we make the code more generic.
  +In the <EM>access_log</EM> file we can see the file descriptor of the logfile in this process (17).
   
   <P>
  -<CODE>Apache::SIG</CODE> comes to help us, the following script doesn't need to check for aborted
  -connections.
  +Let's see how can we make the code more general-purpose:
   
   <P>
  -<PRE>  use Apache::SIG ();
  -  Apache::SIG-&gt;set;
  -  
  -  my $r = shift;
  +<CODE>Apache::SIG</CODE> helps us, use this configuration setting in
  +<EM>httpd.conf</EM>:
  +
  +<P>
  +<PRE>  PerlFixupHandler Apache::SIG
  +</PRE>
  +<P>
  +Now the following script doesn't need to check for aborted connections.
  +
  +<P>
  +<PRE>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -1360,42 +1388,39 @@
       sleep 1;
     }
   </PRE>
  -<P>
  -META: it kills the server!!! ???
  -
   <P>
  -<CODE>Apache::SIG</CODE> installs the <CODE>SIGPIPE</CODE> handler, that stops the script's execution for us.
  +<CODE>Apache::SIG</CODE> installs the <CODE>SIGPIPE</CODE> handler, which stops the script's execution for us when it sees the broken
  +pipe. This setting affects all processes of course.
   
   <P>
  -If you would like to log when a request was canceled by a <CODE>SIGPIPE</CODE>
  -in your Apache access_log, you can declare <CODE>Apache::SIG</CODE> as a handler (any <CODE>Perl*Handler</CODE> will do, as long as it is run before
  -<CODE>PerlHandler</CODE>, e.g.  <CODE>PerlFixupHandler</CODE>), and you must also define a custom <CODE>LogFormat</CODE> in your <EM>httpd.conf</EM>, like this:
  +If you would like to log when a request was cancelled by a SIGPIPE in your
  +Apache <EM>access_log</EM>, you must define a custom <CODE>LogFormat</CODE> in your <EM>httpd.conf</EM>, like so:
   
   <P>
  -<PRE>  PerlFixupHandler Apache::SIG LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %s %b %{SIGPIPE}e&quot;
  +<PRE>  PerlFixupHandler Apache::SIG
  +  LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %s %b %{SIGPIPE}e&quot;
   </PRE>
   <P>
  -If the server has noticed that the request was canceled via a
  -<CODE>SIGPIPE</CODE>, then the log line will end with 1, otherwise it will just be a dash.
  +If the server has noticed that the request was cancelled via a
  +<CODE>SIGPIPE</CODE>, then the log line will end with <CODE>1</CODE>, otherwise it will just be a dash.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="The_Importance_of_Cleanup_Code">The Importance of Cleanup Code</A></H2></CENTER>
   <P>
  -Now the question is what happen to the locked resources if there are any?
  -Will they be freed or not? Since if there are not, any script using these
  -resources and the same advisory locking scheme, will be unable to run and
  -will hang, waiting for this resource to get free, something that would
  -never happen.
  +This is a critical issue with aborted scripts.
   
   <P>
  +What happens to locked resources? Will they be freed or not? If not,
  +scripts using these resources and the same locking scheme will hang,
  +waiting for this resource to be freed.
  +
  +<P>
   Under mod_cgi this was a problem only if you happened to use external lock
  -files for lock indication, instead of using <CODE>flock().</CODE> (there
  -are systems where <CODE>flock(2)</CODE> unavailable, and you can use Perl's
  -emulation of this function). If the script was aborted in the between lock
  -and unlock code and you didn't worry to write a cleanup code to remove
  -locks or otherwise write a code to break locks that are too old and
  -suspected to be dead, you are in a big trouble.
  +files for lock indication, instead of using <CODE>flock().</CODE> If the
  +script was aborted between the lock and the unlock code, and you didn't
  +bother to write cleanup code to remove old dead locks then you were in big
  +trouble.
   
   <P>
   With mod_cgi you can create an <CODE>END</CODE> block, and put the cleanup code there:
  @@ -1405,26 +1430,31 @@
       # some code that ensures that locks are removed
     }
   </PRE>
  +<P>
  +When the script is aborted, Apache will run the <CODE>END</CODE> blocks.
  +
   <P>
  -When the script is aborted, Apache will run the <CODE>END</CODE> blocks. But if you use <CODE>flock()</CODE> things are much simpler, since all opened files will be closed and all the
  -internally locked resources will be freed, because when the file is being
  -closed, the lock is being removed as well.
  +If you use <CODE>flock()</CODE> things are much simpler, since all opened files will be closed. When the
  +file is closed, the lock is removed as well and all the locked resources
  +will be freed. There are systems where <CODE>flock(2)</CODE> is
  +unavailable, and for those you can use Perl's emulation of this function.
   
   <P>
  -Things are more complex with mod_perl. Unless you explicitly
  -<CODE>close()</CODE> the files, they wouldn't be automatically closed,
  -since the processes don't exit upon a single request processing completion.
  -Let's see what problems we might encounter and possible solutions for them.
  +With mod_perl things are more complex. Because the processes don't exit
  +after processing a request, files won't be closed unless you explicitly
  +<CODE>close()</CODE> them or reopen with the <CODE>open()</CODE> call,
  +which first closes a file. Let's see what problems we might encounter, and
  +possible solutions for them.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Critical_Section">Critical Section</A></H3></CENTER>
   <P>
  -I want to make a little step aside and discuss a ``critical section'' issue
  -before we continue.
  +First I want to make a little detour to discuss the <EM>"critical
  +section"</EM> issue.
   
   <P>
  -Let's start with resource locking scheme. A schematic representation of a
  +Let's start with a resource locking scheme. A schematic representation of a
   proper locking technique is as follows:
   
   <P>
  @@ -1443,12 +1473,15 @@
   
   <P>
   In a shared locking scheme, where many processes can concurrently access
  -the resource, it's important to keep the critical section as short as
  -possible as well, if there are processes that sometimes want to get an
  -exclusive lock. This code uses a shared lock, but has a non-optimized
  -critical section:
  +the resource, if there are processes that sometimes want to get an
  +exclusive lock it's also important to keep the critical section as short as
  +possible.
   
   <P>
  +The code below uses a shared lock, but has a poorly-designed critical
  +section:
  +
  +<P>
   <PRE>  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
  @@ -1466,13 +1499,23 @@
     
     close $fh; # close unlocks the file
   </PRE>
  +<P>
  +The code opens the file for reading, locks and rewinds to the start, reads
  +all the lines from the file and prints out the lines that contain the
  +string <EM>foo</EM>. Note that the file remains open and locked while the loop executes.
  +
   <P>
  -It opens the file for reading, locks and rewinds to the start, reads all
  -the lines in and prints out the lines that include a <EM>foo</EM> string in them. Since once the file was read, we don't need it opened and
  -locked anymore, we might close it earlier, since the loop might take some
  -time to complete so we move it after the resource was freed:
  +We can optimize the critical section this way:
   
   <P>
  +Once the file has been read, we have all the information we need from it.
  +The loop might take some time to complete. We don't need the file to be
  +open while the loop executes, because we don't access it inside the loop.
  +If we close the file before we start the loop, we will allow other
  +processes to have access to the file if they need it, instead of blocking
  +them for no reason.
  +
  +<P>
   <PRE>  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
  @@ -1492,9 +1535,9 @@
     }
   </PRE>
   <P>
  -This is another very similar script, but now using a shared lock. It reads
  -in a file and writes it back prepending a number of new text lines to a
  -head of the file.
  +This is another very similar script, but now using an exclusive lock. It
  +reads in a file and writes it back, prepending a number of new text lines
  +to the head of the file.
   
   <P>
   <PRE>  use Fcntl qw(:flock);
  @@ -1523,37 +1566,37 @@
     close $fh; # close unlocks the file
   </PRE>
   <P>
  -First let's explain how the code works. I will discuss in a minute why did
  -I use <CODE>Symbol</CODE> module to generate the file handler variables. 
  +First let's see how the code works. I will discuss why I use the
  +<CODE>Symbol</CODE> module to generate the file handles in the next section.
   
   <P>
   Since we want to read the file, modify and write it back, without anyone
  -changing it on the way, we open it for read and write with help of <EM>+&gt;&gt;</EM> (you could get away with <EM>+&lt;</EM> as well, see
  -<EM>perldoc -f open</EM> or <EM>perlfunc</EM> manpage for more information about <CODE>open()</CODE> function) and lock
  -it with exclusive lock. You cannot safely accomplish this task with opening
  -the file first for read and then reopening for write, since another process
  -might change the file, between the stages.
  +else changing it on the way, we open it for read and write with the help of <EM>+&gt;&gt;</EM> and lock it with an exclusive lock. You cannot safely accomplish this task
  +by opening the file first for read and then reopening for write, since
  +another process might change the file between the two. (You could get away
  +with <EM>+&lt;</EM>, see
  +<EM>perldoc -f open</EM> or the <EM>perlfunc</EM> manpage for more information about the <CODE>open()</CODE> function.)
   
   <P>
   Next the code prepares the lines of text it wants to prepend to the head of
  -the file, and assigns them and the content of the file to
  -<CODE>@lines</CODE> array. Now when we have a data that ready to be written back to the file,
  -the file is being rewinded to the start with help of <CODE>seek()</CODE>
  -and <CODE>truncate()d</CODE> to a zero size, which is useless in our case,
  -but a must thing if there is a chance that the file will shrink. In our
  -example the file only grows. But it's better to always use
  -<CODE>truncate(),</CODE> as you never know what changes your code might
  -undergo in the future. This operation is not the one that you will blame
  -for a performance overhead.
  -
  -<P>
  -Finally we write the data to the file and close it, which unlocks it as
  -well. Did you notice that we created the text lines to be prepended, as
  -close to the place of usage as possible, according to a locality of code
  -style, which is good but it makes the critical section longer. In such a
  -places you should sacrifice any style rules you've got used to, in order to
  -make the critical section as short as possible. A corrected version of this
  -script with the shorter critical section looks like:
  +the file, and assigns them and the content of the file to the
  +<CODE>@lines</CODE> array. Now we have our data ready to be written back to the file, so we
  +<CODE>seek()</CODE> to the start of the file and <CODE>truncate()</CODE> it
  +to zero size. In our example the file always grows, so in this case there
  +is no need to truncate it, but if there was a chance that the file might
  +shrink then truncating would be necessary. However it's good practice to
  +use <CODE>truncate(),</CODE> as you never know what changes your code might
  +undergo in the future. The <CODE>truncate()</CODE> operation does not carry
  +any significant performance penalty. Finally we write the data back to the
  +file and close it, which unlocks it as well.
  +
  +<P>
  +Did you notice that we created the text lines to be prepended as close to
  +the place of usage as possible? This is good ``locality of code'' style,
  +but it makes the critical section longer. In such cases you should
  +sacrifice style, in order to make the critical section as short as
  +possible. An improved version of this script with a shorter critical
  +section looks like this:
   
   <P>
   <PRE>  use Fcntl qw(:flock);
  @@ -1583,44 +1626,53 @@
     close $fh; # close unlocks the file
   </PRE>
   <P>
  -The difference is in preparing the text lines before the file is locked and
  -appending the rest of the file to the <CODE>@lines</CODE> array, instead of creating a new array and copying the lines that were
  -available before the locking time after it as in the original example.
  +There are two important differences. Firstly, we prepare the text lines to
  +be prepended <EM>before</EM> the file is locked. Secondly, instead of creating a new array and copying
  +lines from one array to another, we append the file directly to the <CODE>@lines</CODE> array.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Safe_Resource_Locking">Safe Resource Locking</A></H3></CENTER>
   <P>
  -Let's get back to the main issue of this section, which is a safe locking.
  +Let's get back to the main issue of this section, which is safe resource
  +locking.
   
   <P>
  -If didn't make a habit of closing all the files that you open, you will
  -encounter lots of troubles, unless you use the <CODE>Apache::PerlRun</CODE>
  -handler that does the cleanup for you. If you open the file but doesn't
  -close it, you will have a file descriptor leakage. Since a number of file
  -descriptors available is final, at some point you will run out of them and
  -your service will cease its operations.
  -
  -<P>
  -This is bad, but you can live with this till before you run out of file
  -descriptors, of course this will happen much faster on a heavily used
  -server. But this is nothing relative to the trouble you enter yourself into
  -if you lock the files and forget to unlock or close them. Since
  -<CODE>close()</CODE> always unlocks the file, you don't have to explicitly
  -unlock files. Unlocked file will stay locked after your code finished, and
  -all the other scripts requesting to lock the same resource (file) will wait
  -indefinitely for it to become unlocked. Since it would never happen, until
  -the server restart time, all these processes would hang. This is the
  -offending code:
  +Unless you use the <CODE>Apache::PerlRun</CODE> handler that does the cleanup for you, if you don't make a habit of closing
  +all the files that you open you will encounter lots of problems. If you
  +open a file but don't close it, you will have file descriptor leakage.
  +Since the number of file descriptors available to you is finite, at some
  +point you will run out of them and your service will fail.
   
   <P>
  +This is bad, but you can live with it until you run out of file descriptors
  +(which will happen much faster on a heavily used server). But this is
  +nothing compared to the trouble you will give yourself if you lock, but
  +forget to unlock or close your locked files. Since <CODE>close()</CODE>
  +always unlocks the file, you don't have to unlock files explicitly.
  +
  +<P>
  +But a locked file will stay locked after your code has terminated!
  +
  +<P>
  +Any other process requesting a lock on the same file (or resource) will
  +wait indefinitely for it to become unlocked. Since this will not happen
  +until the server reboots, all these processes will hang.
  +
  +<P>
  +Here is an example of such a terrible mistake:
  +
  +<P>
   <PRE>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock IN, LOCK_EX;
     # do something
     # quit without closing and unlocking the file
   </PRE>
  +<P>
  +Is this safe code? No - we forgot to close the file.
  +
   <P>
  -OK, so let's add the <CODE>close():</CODE>
  +So let's add the <CODE>close():</CODE>
   
   <P>
   <PRE>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  @@ -1632,42 +1684,55 @@
     close IN;
   </PRE>
   <P>
  -Is it a safe code now? Unfortunately it is not. If user aborts the request
  -by pressing <CODE>Stop</CODE> or <CODE>Reload</CODE> buttons in the middle of the critical section, there is a chance that
  -script will be aborted in before it had a chance to <CODE>close()</CODE>
  -the file, which returns us back to the situation where we were forgetting
  -to close the files in first place.
  -
  -<P>
  -What is the remedy for this poison? There are few approaches to solve this
  -problem. If you are running under <CODE>Apache::Registry</CODE> and friends handlers, the <CODE>END</CODE> block will perform the cleanup work for you, the same way you might use it
  -in the scripts running under mod_cgi or in the plain perl scripts. Just add
  -the cleanup code to this block and you are all safe. If you are writing
  -your own handlers you <CODE>register_cleanup()</CODE> allows you to
  -register code similar to the <CODE>END</CODE>
  -blocks, since <CODE>END</CODE> blocks will be executed only when a process exits, and not after a request
  -completion.
  -
  -<P>
  -We will see a few examples later. Now I want to show a much easier safe
  -locking solution. The problem we have encountered, is actually lays in the
  -fact that file handlers like <CODE>IN</CODE> are global variables. If we could make them lexically scoped all our
  -worries would go away. You know that lexically scoped (with
  -<CODE>my()</CODE> operand) variables are being automatically destroyed when
  -they go out of scope, so when the program quits all the lexical variables
  -will be destroyed, since they leave the file scope. When the variable
  -holding an opened file descriptor is being destroyed, the file will be
  -automatically closed.
  +Is it safe code now? Unfortunately it is not. There is a chance that the
  +user may abort the request (for example by pressing his browser's
  +<CODE>Stop</CODE> or <CODE>Reload</CODE> buttons) during the critical section. The script will be aborted before it
  +has had a chance to <CODE>close()</CODE> the file, which is just as bad as
  +if we forgot to close it.
  +
  +<P>
  +There are a few approaches we can take to solving this problem. If you are
  +running under <CODE>Apache::Registry</CODE> and friends, the <CODE>END</CODE>
  +block will perform the cleanup work for you. You might use <CODE>END</CODE> in the same way for scripts running under mod_cgi, or in plain Perl
  +scripts. Just add the cleanup code to this block and you are safe. Since
  +under mod_perl the <CODE>END</CODE> blocks will not be executed after the completion of a request, but only
  +when an Apache child process exits, then if you are writing your own
  +handlers you will need to use the <CODE>register_cleanup()</CODE> function
  +to supply cleanup code similar to that used in <CODE>END</CODE> blocks instead of using <CODE>END</CODE> blocks. We will see a few examples later.
  +
  +<P>
  +Of course, if the same child executes the same section of code of the same
  +script, the <CODE>open()</CODE> call on the same file handle will first
  +<CODE>close()</CODE> the file. But this will happen only if it's the same
  +filehandle, which is correct if you use the scalar variable like
  +<CODE>IN</CODE>, <CODE>OUT</CODE>. As you will see in a moment if you use <CODE>Symbol</CODE> or &lt;IO::*&gt; modules, a unique filehandle will be generated every time
  +-- you get a file desriptor leakage and the file will be not unclocked in
  +case it was locked.
  +
  +<P>
  +Now I want to show you a much easier safe locking solution.
  +
  +<P>
  +Although it might not be obvious, the problem we have encountered is
  +actually the fact that file handles like <CODE>IN</CODE> are global variables. If we could make them lexically scoped, all our
  +worries would go away. You know that lexically scoped (with the
  +<CODE>my()</CODE> operand) variables are automatically destroyed when they
  +go out of scope. When the program quits, all the lexical variables will be
  +destroyed since they only have file scope. When a variable holding an
  +opened file descriptor is destroyed, the file will automatically be closed
  +and unlocked.
   
   <P>
   So if you use this technique to work with files, you even don't have to
  -close the files! You still want to make sure that you close them as soon as
  -possible if you recall the critical section discussion. In addition to this
  -safe file handling having the file handlers lexically scoped, protect you
  -from names collisions, e.g when you have to open more than one file, you
  -always have to make sure you didn't use the same name somewhere else in the
  -code and that file is might still be open. To emphasize the risk of
  -collisions think of subroutine that opens a file for you:
  +explicitly close the files! (Of course if you recall the critical section
  +discussion above, you will still want to make sure that you close them as
  +soon as possible.) In addition to the benefits of safe file handling,
  +having the file handlers lexically scoped will protect you from names
  +collisions. If you use global file handles, e.g when you have to open more
  +than one file, you always have to make sure you don't use the same
  +filehandle name somewhere else in the code in case it might still be
  +associated with an open file. To emphasize the risk of collisions think of
  +subroutine that opens a file for you:
   
   <P>
   <PRE>  sub open_file{
  @@ -1682,20 +1747,22 @@
     print $fh1 &quot;X&quot;;
     print $fh2 &quot;Y&quot;;
   </PRE>
  +<P>
  +This code doesn't do what you think it should do. Instead of writing the
  +character <CODE>X</CODE> to <EM>/tmp/x</EM> file and <CODE>Y</CODE> to <EM>/tmp/y</EM>, what you see after running this script is that <EM>/tmp/x</EM> is empty and <EM>/tmp/y</EM>
  +contains a <CODE>XY</CODE> string. Why is that? Because you have used the same global variable <CODE>FILE</CODE> twice, and when you called <CODE>open_file()</CODE> for a second time it
  +opened a different file using the same variable. Since
  +<CODE>open_file()</CODE> always returns a reference to the same global file
  +handle variable, both <CODE>$fh1</CODE> and <CODE>$fh2</CODE> point to it.
  +
   <P>
  -Obviously this code doesn't do what you think it should do. Instead of
  -writing a character <CODE>X</CODE> to <EM>/tmp/x</EM> file and <CODE>Y</CODE> to <EM>/tmp/y</EM>, what you see is that <EM>/tmp/x</EM> is empty and <EM>/tmp/y</EM> contains a <CODE>XY</CODE>
  -string. Why is that? Because you have used the same global variable, and
  -when you have called <CODE>open_file()</CODE> for a second time, it opened
  -a different file using the same variable. Since <CODE>open_file()</CODE>
  -returns a reference to a file handler and it's the same global variable all
  -the time -- both <CODE>$fh1</CODE> and <CODE>$fh2</CODE> point to it.
  +There is another way. As you saw earlier we can generate unique, lexically
  +scoped file handles with the <CODE>Symbol</CODE> module.
   
   <P>
  -However, as you just saw we can generate unique file handlers that can be
  -lexically scoped with <CODE>Symbol</CODE> module.  <CODE>Symbol::gensym()</CODE>
  -creates an anonymous glob and returns a reference to it. Such a glob
  -reference can be used as a file or directory handle.
  +<CODE>Symbol::gensym()</CODE> creates an anonymous glob and returns a reference to it. Such a glob
  +reference can be used as a file or directory handle. Here is how you can
  +use it:
   
   <P>
   <PRE>  use Symbol;
  @@ -1704,9 +1771,11 @@
     flock $fh, LOCK_EX;
     # do something
   </PRE>
  +<P>
  +Now the file will be always unlocked after processing the request.
  +
   <P>
  -Now the file will be always unlocked a the end of the request's processing.
  -Instead of <CODE>close()</CODE> you might use a block:
  +Instead of using <CODE>close(),</CODE> you might use a block:
   
   <P>
   <PRE>  use Symbol;
  @@ -1719,19 +1788,19 @@
     # the file will be automatically closed and unlocked at this point
   </PRE>
   <P>
  -But this is not so obvious to the reader of the code so you might want to
  -avoid the last technique.
  +But this is perhaps not so obvious to the reader of the code, so you might
  +want to avoid this last technique and put in an explicit
  +<CODE>close().</CODE>
   
   <P>
  -You can use the <CODE>IO::*</CODE> modules as well, such as <CODE>IO::File</CODE> or
  -<CODE>IO::Dir</CODE>, but these are much bigger than &lt;Symbol&gt; module, and worth using for
  -file or directory opening only if you are already using them for other
  -features they provide. As a matter of fact, these modules use
  -&lt;Symbol&gt; module themselves. The examples of their usage:
  +You can also use the <CODE>IO::*</CODE> modules, such as <CODE>IO::File</CODE> or
  +<CODE>IO::Dir</CODE>. These are much bigger than the &lt;Symbol&gt; module, and worth using for files or directories only if you are
  +already using them for the other features which they provide. As a matter
  +of fact, these modules use the <CODE>Symbol</CODE> module themselves. Here are some examples of their use:
   
   <P>
   <PRE>  use IO::File;
  -  my $fh = new IO::File &quot;&gt; filename&quot;;
  +  my $fh = IO::File-&gt;new(&quot;&gt;filename&quot;);
     # the rest is as before
   </PRE>
   <P>
  @@ -1739,28 +1808,41 @@
   
   <P>
   <PRE>  use IO::Dir;
  -  my $dh = new IO::Dir &quot;dirname&quot;;
  +  my $dh = IO::Dir-&gt;new(&quot;dirname&quot;);
   </PRE>
   <P>
  +Under perl 5.6 <CODE>Symbol.pm</CODE>-like functionality is a built-in feature, so you can do:
  +
  +<P>
  +<PRE>  open my $fh, &quot;&gt; filename&quot;;
  +</PRE>
  +<P>
  +and <CODE>$fh</CODE> will be automatically vivified as a valid filehandle, so you don't need to
  +use the <CODE>Symbol</CODE> module anymore.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Cleanup_Code">Cleanup Code</A></H3></CENTER>
  +<P>
  +Finally, let's look at the case where we need special clean up code. As you
  +have seen, we solved the problem of accidentally leaving file handles lying
  +around by lexically scoping them. There are however, situations where you
  +absolutely must write cleanup code. A tied dbm file is a good example.
  +
  +<P>
  +A reminder: a dbm file is a simple database, which allows you to store
  +pairs of keys and values in it. As of this writing, Berkeley DB is the most
  +advanced dbm implementation, it allows you to store key/value pairs using
  +the HASH, BTREE and RECNO algorithms. The <CODE>BerkeleyDB</CODE>
  +module provides a Perl interface to Berkeley DB versions 2 and 3, while the <CODE>DB_File</CODE> module handles the older Berkeley DB, version 1. Refer to the <CODE>DB_File</CODE> man page for more information.
  +
  +<P>
  +With the help of the TIE interface, working with dbm files is very simple
  +because they are represented in Perl as simple hash variables. They behave
  +almost exactly like hashes.
  +
   <P>
  -Finally, let's see when do we need a special clean up code. As you just saw
  -we have solved the problem of file handers by lexically scoping them. There
  -are situation, you must write a cleanup code. A good example for this is a
  -tied dbm file.
  -
  -<P>
  -A reminder: dbm file is a simple database, which allows you to store pairs
  -of keys and values in it. As of this writing Berkeley DB is the most
  -advanced dbm implementation, and allows you to store key/values using the
  -HASH, BTREE and RECNO algorithms. (refer to a <CODE>DB_File</CODE> man page for more info.)  <CODE>DB_File</CODE> module provides a Perl interface to 1.x versions of Berkeley DB. (<CODE>BerkeleyDB</CODE> module should handle more recent Berkeley DB versions 2 and 3)
  -
  -<P>
  -Working with dbm files is very simple, because they are represented in Perl
  -as a simple hash variables, with help of TIE interface, and they behave
  -exactly like hashes. In order to access a dbm file you have to tie it
  -first:
  +In order to access a dbm file you have to tie it first:
   
   <P>
   <PRE>  use Fcntl qw(O_RDWR O_CREAT);
  @@ -1771,36 +1853,36 @@
        or die &quot;Can't tie %hash : $!&quot;;
   </PRE>
   <P>
  -A first argument to <CODE>tie()</CODE> is a hash variable, we want the dbm
  -file to be tied to. Following arguments are a name of the module that
  -provides an interface to a dbm implementation we want to use, <CODE>DB_File</CODE> in our case, then a filename the dbm resides in, Fcntl flags, file
  -permissions and finally the interface method (DB_HASH, DB_BTREE or
  -DB_RECNO) to be used.
  +The first argument to <CODE>tie()</CODE> is the hash variable to which we
  +want the dbm file to be tied. The remaining arguments are: the name of the
  +module that provides the interface (<CODE>DB_File</CODE> in this case); the name of our dbm file; Fcntl flags; file permissions; and
  +finally the interface method to be used (DB_HASH, DB_BTREE or DB_RECNO).
   
   <P>
  -From now on we use <CODE>%hash</CODE> to read from and write to a dbm file, like:
  +From now on we use <CODE>%hash</CODE> to read from and write to the dbm file, like this:
   
   <P>
  -<PRE>  my $name = $hash{foo};
  -  $hash{foo} = &quot;Larry Wall&quot;;
  +<PRE>  $hash{foo} = &quot;Larry Wall&quot;;
  +  my $name = $hash{foo};
   </PRE>
   <P>
  -The only nuance is that when we modify the hash by assigning some values,
  -it doesn't write the changes immediately to a file, but caches them to
  -improve a performance. It flushes its cache buffers when either they become
  -full, a <CODE>sync()</CODE> method is being called on its database handler
  -or the hash is being untied (closed). So if the program quits abnormally, a
  -dbm file might get corrupted.
  +The only wrinkle is that when we modify the hash (by assigning some values
  +to it) the changes are not written immediately to the file. They are cached
  +to improve performance. The cache buffers are flushed in the following
  +circumstances: when they become full; when the <CODE>sync()</CODE> method
  +is called on the database handle; and when the hash is untied (closed). So
  +be aware that if the program quits abnormally, the dbm file might be
  +corrupted.
   
   <P>
  -To untie the dbm file, you simply call:
  +To untie the dbm file, simply call:
   
   <P>
   <PRE>  untie %hash;
   </PRE>
   <P>
  -To get the access to <CODE>sync()</CODE> method, you should retrieve the
  -database handler which is being returned by <CODE>tie()</CODE> method:
  +To gain the access to the <CODE>sync()</CODE> method, you should retrieve
  +the database handle which is returned by the <CODE>tie()</CODE> method:
   
   <P>
   <PRE>  my $dbh = tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  @@ -1817,33 +1899,38 @@
   Important: If you have saved a copy of the object returned from
   <CODE>tie(),</CODE> the underlying database file will not be closed until
   both the tied variable is untied and all copies of the saved object are
  -destroyed. We do it as follows
  +destroyed.
   
   <P>
  +We do this as follows:
  +
  +<P>
   <PRE>  undef $dbh;
     untie %hash;
   </PRE>
   <P>
   Of course, you have to lock the dbm file exactly like any other resource if
  -some script modifies its contents. Refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> for more info.
  +some script modifies its contents. Refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> for more information.
   
   <P>
  -Ok, enough with introduction, let's get to the point. Since both
  -<CODE>%hash</CODE> and <CODE>$dbh</CODE> are lexically scoped variables, they always will be destroyed, no matter
  -whether you forgot to <CODE>untie()</CODE> or the request was aborted
  -before the <CODE>untie()</CODE> part.
  +Okay, enough introduction, let's get to the point. Since both <CODE>%hash</CODE>
  +and <CODE>$dbh</CODE> are lexically scoped variables, they will always be destroyed, even if you
  +forgot to <CODE>untie()</CODE> them or if the request was aborted before
  +the <CODE>untie()</CODE> function was called.
   
   <P>
  -Suppose that you want to take the benefit of mod_perl's persistent global
  +Suppose that you want to have the benefit of mod_perl's persistent global
   variables in each process and to use this feature to create persistent dbm
  -hashes. So you tie them only once per process, and save the time to
  -<CODE>tie()</CODE> and <CODE>untie()</CODE> per request. The idea is good,
  -assuming that you remember that you have to flush the cache buffers when
  -you modify the hash that represents the dbm file with <CODE>sync()</CODE>
  -method.
  +hashes. You <CODE>tie()</CODE> them only once per Apache child process,
  +thus saving the time which it would take to <CODE>tie()</CODE> and
  +<CODE>untie()</CODE> them for each client request. Assuming that you
  +remember that you must flush the cache buffers (with the
  +<CODE>sync()</CODE> method) when you modify the hash that represents the
  +dbm file, the idea is a good one. Let's code it...
   
   <P>
  -Let's code the idea:
  +We declare <CODE>$dbh</CODE> and <CODE>%hash</CODE> as global variables, then pull in the
  +<CODE>Fcntl</CODE> module and import the symbols we are going to use. Actually we need only <CODE>LOCK_EX</CODE> from the tags provided by <CODE>:flock</CODE>. We pull in the <CODE>DB_File</CODE> and <CODE>Symbol</CODE> modules:
   
   <P>
   <PRE>  use strict;
  @@ -1851,45 +1938,39 @@
     use Fcntl qw(:flock O_RDWR O_CREAT);
     use DB_File;
     use Symbol;
  -</PRE>
  -<P>
  -We declare <CODE>$dbh</CODE> and <CODE>%hash</CODE> as global variables, then pull in the
  -<CODE>Fcntl</CODE> module and import the symbols we are going to use. Actually we need only <CODE>LOCK_EX</CODE> from the tags provided by <CODE>:flock</CODE>. We pull in <CODE>DB_File</CODE> and <CODE>Symbol</CODE> modules.
  -
  -<P>
  -<PRE>  my $r = shift;
  +  
  +  # Send the I&lt;Content-type&gt; header of plain text type and tell the
  +  # user the PID of the process that's serving the request:
  +  
  +  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     $r-&gt;print(&quot;PID $$\n&quot;);
  -</PRE>
  -<P>
  -Send the <EM>Content-type</EM> header of plain text type and tell the user the PID of the process that
  -serves the request.
  -
  -<P>
  -<PRE>  my $filename = &quot;/tmp/mydb&quot;;
  +  
  +  # The location of the dbm file and its lock file:
  +  
  +  my $filename = &quot;/tmp/mydb&quot;;
     my $lockfile = &quot;$filename.lock&quot;;
  -</PRE>
  -<P>
  -Configure the location of the dbm file and its lock file.
  -
  -<P>
  -<PRE>  my $fh = gensym;
  +  
  +  # Generate a unique anonymous glob, store it in a lexically scoped
  +  # variable C&lt;$fh&gt;, and lock the file.  This in turn advisory locks
  +  # the dbm file (which will be safely tied):
  +  
  +  my $fh = gensym;
     open $fh, &quot;&gt;$lockfile&quot; or die &quot;Cannot open $lockfile: $!&quot;;
     flock $fh, LOCK_EX;
   </PRE>
   <P>
  -Generate a unique anonymous glob, store it in a lexically scoped variable <CODE>$fh</CODE> and lock the file, which in turn advisory locks the dbm file which will be
  -safely tied now, because for the other copies of this script to access the
  -following code they have to acquire the lock file first, and since it's an
  -exclusive lock, only one replication of the script will be able to tie the
  -dbm file.
  -
  +<PRE>  # Other copies of this script which wish to access the following
  +  # code have to acquire the lock file first.  Since it's an exclusive
  +  # lock, only one copy of the script will be able to tie the dbm
  +  # file.
  +</PRE>
   <P>
   <PRE>  $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
        or die &quot;Can't tie %hash : $!&quot;;
   </PRE>
   <P>
  -This code snippet demands some deeper explanation.
  +This code snippet demands some explanation.
   
   <P>
   <PRE>  $a ||= $b;
  @@ -1901,49 +1982,59 @@
   <PRE>  $a = $a || $b;
   </PRE>
   <P>
  -The <CODE>||</CODE> check is a boolean one (testing for truth) and it doesn't care about
  -undefined values, since <CODE>undef</CODE> is <CODE>false</CODE> in Perl. So what it does is: leave <CODE>$a</CODE> unmodified if it's a true value, otherwise test <CODE>$b</CODE> and assign its value to <CODE>$a</CODE> if it's <EM>true</EM>. If it's <EM>false</EM> as well, <CODE>$a</CODE> stays undefined. (note that 0 and <CODE>&quot;&quot;</CODE>
  -(empty string) are both <EM>defined</EM> but <EM>false</EM> values!) (refer to <CODE>perlop(1)</CODE> manpage for more info about <CODE>||</CODE> operator)
  +The boolean test <CODE>||</CODE> (logical OR) doesn't care about undefined values, since <CODE>undef</CODE> is <CODE>false</CODE> in Perl. So what it does is this:
   
   <P>
  -Back to our <CODE>tie()</CODE> snippet. For each mod_perl process when this
  -code will be executed for the first time, <CODE>$dbh</CODE> variable is undefined, therefore a right part of the statement will be
  -executed, which will <CODE>tie()</CODE> the dbm file. On every consequent
  -code execution in the same process, <CODE>$dbh</CODE> will contain a database handler which is a <EM>true</EM>
  -value, so the <CODE>tie()</CODE> call will be saved.
  +If <CODE>$a</CODE> is <EM>true</EM>, leave it unmodified. Otherwise test <CODE>$b</CODE>.
   
   <P>
  -<PRE>  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  -</PRE>
  +If <CODE>$b</CODE>  <EM>true</EM>, assign the value of <CODE>$b</CODE> to <CODE>$a</CODE>.
  +
  +<P>
  +If <CODE>$b</CODE> is <EM>false</EM>, <CODE>$a</CODE> stays undefined.
  +
  +<P>
  +Note that 0 and <CODE>&quot;&quot;</CODE> (the empty string) are both <EM>defined</EM>, but they are <EM>false</EM> values! Refer to the <CODE>perlop(1)</CODE> manpage for more information
  +about the <CODE>||</CODE> operator.
  +
  +<P>
  +Back to our <CODE>tie()</CODE> snippet. For each mod_perl process, when
  +this code is executed for the first time, the <CODE>$dbh</CODE> variable is undefined. Therefore the right-hand part of the statement will
  +be executed, <CODE>tie()ing</CODE> the dbm file. On every subsequent
  +invocation of the code by that same process, <CODE>$dbh</CODE> will contain a database handle. This is considered by Perl to be a <EM>true</EM> value, so the <CODE>tie()</CODE> call will not be executed, eliminating the
  +overhead of the call to <CODE>tie().</CODE>
  +
   <P>
  -Fill the dbm file with random keys and values. Each invocation of the code
  -would either generate a new key/value pair or override an old one, if an
  -existing key will be chosen by <CODE>rand().</CODE>
  +Now we fill the dbm file with random key/value pairs. Each invocation of
  +the code will either generate a new key/value pair or, if an existing key
  +is returned by <CODE>rand(),</CODE> override an old one.
   
   <P>
  -<PRE>  $dbh-&gt;sync();
  +<PRE>  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  +  $dbh-&gt;sync();
   </PRE>
   <P>
  -The most important part of the code is to flush the modifications.
  +The most important part of the code is to flush the modifications to the
  +dbm.
   
   <P>
   <PRE>    # unlock the db
     close $fh;
   </PRE>
   <P>
  -Now it's safe to unlock the dbm file. Please refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> to learn why you should NOT use a dbm's file descriptor to lock itself. To
  -make long explanations short -- it may get your dbm file corrupted.
  +Now it's safe to unlock the dbm file. Please refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> to learn why you should use a dbm's file descriptor to lock itself. To cut
  +a long story short, if you don't you may corrupt your dbm file.
   
   <P>
  -<PRE>    # printout the contents of the the dbm file
  -  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;
  -</PRE>
  -<P>
   After we leave the critical section, we can take our time and print out the
   current contents of the dbm file.
   
   <P>
  -Here is the same code in one piece:
  +<PRE>  # print the contents of the the dbm file
  +  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;
  +</PRE>
  +<P>
  +Here is the same code with fewer comments:
   
   <P>
   <PRE>  use strict;
  @@ -1968,7 +2059,7 @@
     $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
        or die &quot;Can't tie %hash : $!&quot;;
     
  -    # fill the dbmfile with random keys values 
  +    # fill the dbmfile with random key/value pairs
     $hash{int rand 10} = (qw(a b c d))[int rand 4];
     
       # sync the DB
  @@ -1977,35 +2068,40 @@
       # unlock the db
     close $fh;
     
  -    # printout the contents of the the dbm file
  +    # print the contents of the the dbm file
     print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;
   </PRE>
   <P>
   Well, if you run this code, you pretty soon figure out that this code
   doesn't do what we thought it would. What happens is that each process
  -keeps its own copy of the <CODE>%hash</CODE> and modifies it. When the process calls <CODE>sync()</CODE> method, the dbm
  -file is being updated and now equal to the contents of the <CODE>%hash</CODE> of this process. If the next request will be processed by the process that
  -didn't yet <CODE>tie()d</CODE> the <CODE>%hash</CODE> it would be initialized to the value of the <CODE>%hash</CODE> of the last process that called <CODE>sync()</CODE> on this dbm file, but
  -if it would be handled by a process that already tied <CODE>%hash</CODE> before it wouldn't read the contents from the dbm file but use its private
  -value of the <CODE>%hash</CODE>.
  +keeps its own copy of the <CODE>%hash</CODE> and modifies it. When the process calls the <CODE>sync()</CODE> method, the
  +dbm file is updated with the contents of the private <CODE>%hash</CODE> of this process. If a request happens to be served by a process that hasn't
  +yet <CODE>tie()d</CODE> the <CODE>%hash</CODE>, the dbm file will be initialized to the value of the <CODE>%hash</CODE> used by the process that last called <CODE>sync()</CODE> on the dbm file.
  +But if it is handled by a process that has already tied the <CODE>%hash</CODE>, it won't read the contents of the dbm file but will use its private value
  +of the
  +<CODE>%hash</CODE> instead.
   
   <P>
   In reality things are even more complicated. The above scenario is true
  -only when the hash file is smaller than a buffer size of the dbm file, when
  -it becomes bigger than buffer, its contents are being flushed. So when you
  -do <CODE>keys %hash</CODE>, all the keys should be brought from the dbm file, which causes the
  -process to read the values saved by the previous <CODE>sync()</CODE> calls
  -and buffer overflow automatic flushes. Which creates a whole big mess with
  -data and makes the whole idea unreal and useless.
  +only when the hash file is smaller than the buffer size of the dbm file.
  +When it becomes bigger than the buffer, its contents are flushed. When you
  +do <CODE>keys %hash</CODE>, all the keys will be brought from the dbm file which causes the process
  +to read the values saved by the previous <CODE>sync()</CODE> calls and
  +automatic flushes caused by buffer overflow.
  +
  +<P>
  +Which creates a whole big mess with the data and makes the whole idea is
  +useless.
   
   <P>
  -But if we have arrived so far, let's see what other thing is flawed in this
  -code. It's the <CODE>sync()</CODE> call. If script is being stopped before
  -<CODE>sync()</CODE> called, the dbm will be unlocked, since <CODE>$fh</CODE> is lexically scoped, but it wouldn't be properly <CODE>sync()ed,</CODE>
  -which at some point will corrupt the dbm file.
  +But if you have followed me this far, let's see what else is wrong with
  +this code. It's the <CODE>sync()</CODE> call. If the script somehow stops
  +before <CODE>sync()</CODE> is called, the dbm will be unlocked because <CODE>$fh</CODE>
  +is lexically scoped. But it won't be properly <CODE>sync()ed,</CODE> which
  +at some point will corrupt the dbm file.
   
   <P>
  -The solution is quite simple -- write an <CODE>END</CODE> block to sync the file:
  +The solution is simple. Write an <CODE>END</CODE> block to sync the file:
   
   <P>
   <PRE>  END{
  @@ -2014,22 +2110,25 @@
     }
   </PRE>
   <P>
  -The above will work only for <CODE>Apache::Registry</CODE> scripts, otherwise the <CODE>END</CODE> will be postponed till the process termination time. If you write a handler
  -in Perl API use the <CODE>register_cleanup()</CODE> method instead. It accepts a reference to a subroutine as an argument:
  +Under mod_perl, the above will work only for <CODE>Apache::Registry</CODE>
  +scripts. Otherwise execution of the <CODE>END</CODE> block will be postponed until the process terminates. If you write a
  +handler in the Perl API use the <CODE>register_cleanup()</CODE> method instead. It accepts a reference to a subroutine as an argument:
   
   <P>
   <PRE>  $r-&gt;register_cleanup(sub { $dbh-&gt;sync() });
   </PRE>
   <P>
  -Even a more correct code would be to check whether the connection was
  -aborted, since you if you don't check -- the cleanup code will be always
  -executed, which can be an unwanted thing for a normally finished scripts.
  +Even better would be to check whether the client connection has been
  +aborted. If you don't check, the cleanup code will always be executed and
  +for normally terminated scripts this may not be what you want:
   
   <P>
  -<PRE>  $r-&gt;register_cleanup
  -   (sub { 
  +<PRE>  $r-&gt;register_cleanup(
  +    # make sure that the DB is flushed
  +    sub{ 
         $dbh-&gt;sync() if Apache-&gt;request-&gt;connection-&gt;aborted();
  -        });
  +    }
  +  );
   </PRE>
   <P>
   So in the case of <CODE>END</CODE> block usage you would use:
  @@ -2037,14 +2136,14 @@
   <P>
   <PRE>  END{
       # make sure that the DB is flushed
  -     $dbh-&gt;sync() if Apache-&gt;request-&gt;connection-&gt;aborted();
  +    $dbh-&gt;sync() if Apache-&gt;request-&gt;connection-&gt;aborted();
     }
   </PRE>
   <P>
  -Note that if you use <CODE>register_cleanup()</CODE> it should be used at the beginning of the script, or as soon as variables
  -you want to use in this code becomes available. If you use it at the end of
  -the script, and script is being aborted before this code is reached, there
  -will be no cleanup performed.
  +Note that if you use <CODE>register_cleanup()</CODE> it should be called at the beginning of the script, or as soon as the
  +variables you want to use in this code become available. If you use it at
  +the end of the script, and the script happens to be aborted before this
  +code is reached, there will be no cleanup performed.
   
   <P>
   For example <CODE>CGI.pm</CODE> registers the cleanup subroutine in its <CODE>new()</CODE> method:
  @@ -2060,8 +2159,8 @@
     }
   </PRE>
   <P>
  -There is also another way to register a cleanup code for Perl API handlers.
  -You may use a <CODE>PerlCleanupHandler</CODE> in the configuration file, like:
  +There is another way to register a section of cleanup code for Perl API
  +handlers. You may use <CODE>PerlCleanupHandler</CODE> in the configuration file, like this:
   
   <P>
   <PRE>  &lt;Location /foo&gt;
  @@ -2072,18 +2171,17 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -where <CODE>Apache::MyModule::cleanup()</CODE> is supposed to perform a cleanup.
  +<CODE>Apache::MyModule::cleanup()</CODE> performs the cleanup, obviously.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A></H1></CENTER>
  +<CENTER><H1><A NAME="Handling_Server_Timeout_Cases_an">Handling Server Timeout Cases and Working with $SIG{ALRM}</A></H1></CENTER>
   <P>
  -A similar situation to <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Pressed Stop button disease</A> happens when client (browser) timeouts the connection (is it about 2
  -minutes?) . There are cases when your script is about to perform a very
  -long operation and there is a chance that its duration will be longer than
  -the client's timeout. One case I can think about is the DataBase
  -interaction, where the DB engine hangs or needs a lot of time to return
  -results. If this is the case, use <CODE>$SIG{ALRM}</CODE> to prevent the timeouts:
  +A similar situation to <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Pressed Stop button disease</A> happens when the browser times out the connection (is it about 2 minutes?).
  +There are cases when your script is about to perform a very long operation
  +and there is a chance that its duration will be longer than the client's
  +timeout. One example is database interaction, where the DB engine hangs or
  +needs a long time to return the results. If this is the case, use <CODE>$SIG{ALRM}</CODE> to prevent the timeouts:
   
   <P>
   <PRE>    $timeout = 10; # seconds
  @@ -2098,35 +2196,37 @@
     die $@ if $@;
   </PRE>
   <P>
  -But, as lately it was discovered <CODE>local $SIG{'ALRM'}</CODE> does not restore the original underlying C handler. It was fixed in the
  -mod_perl 1.19_01 (CVS version). As a matter of fact none of the
  -<CODE>local $SIG{FOO}</CODE> restore the original C handler - read <A HREF="././debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A> for a debug technique and a possible workaround.
  +It was recently discovered that <CODE>local $SIG{'ALRM'}</CODE> does not restore the original underlying C handler. This was fixed in
  +mod_perl 1.19_01 (CVS version). As a matter of fact none of the <CODE>local $SIG{FOO}</CODE>
  +signals restores the original C handler - read <A HREF="././debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A> for a debug technique and a possible workaround.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Looking_inside_the_server">Looking inside the server</A></H1></CENTER>
  +<P>
  +Your server is up and running, but something appears to be wrong. You want
  +to see the numbers to tune your code or server configuration. You just want
  +to know what's really going on inside the server.
  +
   <P>
  -Your server is up and running. But something appears to be wrong. You want
  -to see the numbers to tune your code or server configuration. Finally you
  -just want to know what's really going on inside the server. How do you do
  -it?
  +How do you do it?
   
   <P>
   There are a few tools that allow you to look inside the server. 
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Apache_Status_Embedded_inter">Apache::Status -- Embedded interpreter status information</A></H2></CENTER>
  +<CENTER><H2><A NAME="Apache_Status_Embedded_Inter">Apache::Status -- Embedded Interpreter Status Information</A></H2></CENTER>
   <P>
   This is a very useful module. It lets you watch what happens to the Perl
  -parts of the server. To see the size of all subroutines and variables, see
  -variables dumps and lexical info, OPcode trees and more.
  +parts of the server. You can see the size of all subroutines and variables,
  +variable dumps, lexical information, OPcode trees, and more.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Minimal_Configuration">Minimal Configuration</A></H3></CENTER>
   <P>
  -This configuration enables the <CODE>Apache::Status</CODE> module without all the additional features. Add this to <EM>http.conf</EM>:
  +This configuration enables the <CODE>Apache::Status</CODE> module with its minimum feature set. Add this to <EM>httpd.conf</EM>:
   
   <P>
   <PRE>  &lt;Location /perl-status&gt;
  @@ -2138,8 +2238,7 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -If you are going to use <CODE>Apache::Status</CODE> it's important to put it as the first module in the start-up file, or in
  -the httpd.conf:
  +If you are going to use <CODE>Apache::Status</CODE> it's important to put it as the first module in the start-up file, or in <EM>httpd.conf</EM>:
   
   <P>
   <PRE>  # startup.pl
  @@ -2148,12 +2247,15 @@
     use Apache::DBI ();
   </PRE>
   <P>
  -If you don't put <CODE>Apache::Status</CODE> before <CODE>Apache::DBI</CODE>, you wouldn't get <CODE>Apache::DBI</CODE>'s menu entry in status. For more about
  +If you don't put <CODE>Apache::Status</CODE> before <CODE>Apache::DBI</CODE>, you won't get the <CODE>Apache::DBI</CODE> menu entry in the status. For more about
   <CODE>Apache::DBI</CODE> see <A HREF="././performance.html#Persistent_DB_Connections">Persistent DB Connections</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Extended_Configuration">Extended Configuration</A></H3></CENTER>
  +<P>
  +There are several variables which you can use to modify the behaviour of <CODE>Apache::Status</CODE>.
  +
   <UL>
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusOptionsAll On</A></STRONG>
   <P>
  @@ -2161,12 +2263,12 @@
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusDumper On</A></STRONG>
   <P>
  -When browsing symbol tables, the values of arrays, hashes ans calars can be
  -viewed via <CODE>Data::Dumper</CODE>.
  +When you are browsing symbol tables, you can view the values of your
  +arrays, hashes and scalars with <CODE>Data::Dumper</CODE>.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusPeek On</A></STRONG>
   <P>
  -With this option On and the <CODE>Apache::Peek</CODE> module installed, functions and variables can be viewed ala <CODE>Devel::Peek</CODE> style.
  +With this option On and the <CODE>Apache::Peek</CODE> module installed, functions and variables can be viewed in <CODE>Devel::Peek</CODE> style.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusLexInfo On</A></STRONG>
   <P>
  @@ -2184,7 +2286,7 @@
   <PRE>  PerlSetVar StatusDeparseOptions &quot;-p -sC&quot;
   </PRE>
   <P>
  -See the B::Deparse manpage for details.
  +See the <CODE>B::Deparse</CODE> manpage for details.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusTerse On</A></STRONG>
   <P>
  @@ -2198,32 +2300,36 @@
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusTerseSizeMainSummary On</A></STRONG>
   <P>
  -With this option On and the <CODE>B::TerseSize</CODE> module installed, a ``Memory Usage'' will be added to the <CODE>Apache::Status</CODE> main menu. This option is disabled by default, as it can be rather cpu
  +With this option On and the <CODE>B::TerseSize</CODE> module installed, ``Memory Usage'' will be added to the <CODE>Apache::Status</CODE> main menu. This option is disabled by default, as it can be rather cpu
   intensive to summarize memory usage for the entire server. It is strongly
   suggested that this option only be used with a development server running
   in -X mode, as the results will be cached.
   
  +<P>
  +Remember to preload <CODE>B::TerseSize</CODE> with: 
  +
  +<P>
  +<PRE>  PerlModule B::Terse
  +</PRE>
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusGraph</A></STRONG>
   <P>
   When <CODE>StatusDumper</CODE> (see above) is enabled, another link <EM>"OP Tree
   Graph"</EM> will be present with the dump if this configuration variable is set to On.
   
  -<P>
  -This requires the B module (part of the Perl compiler kit) and
  -<CODE>B::Graph</CODE> (version 0.03 or higher) module to be installed along with the dot program.
  -
   <P>
  +This requires the B module (part of the Perl compiler kit) and the
  +<CODE>B::Graph</CODE> module version 0.03 or higher to be installed along with the `dot' program.
   Dot is part of the graph visualization toolkit from AT&amp;T: <A
  -HREF="http://www.research.att.com/sw/tools/graphviz/">http://www.research.att.com/sw/tools/graphviz/</A>).
  +HREF="http://www.research.att.com/sw/tools/graphviz/.">http://www.research.att.com/sw/tools/graphviz/.</A>
   
   
   <P>
  -WARNING: Some graphs may produce very large images, some graphs may produce
  -no image if <CODE>B::Graph</CODE>'s output is incorrect.
  +WARNING: Some graphs may produce very large images, and some graphs may
  +produce no image if <CODE>B::Graph</CODE>'s output is incorrect.
   
   </UL>
   <P>
  -You will find more information about this module in its manpage.
  +There is more information about <CODE>Apache::Status</CODE> in its manpage.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2238,8 +2344,10 @@
     process 187138, running since Thu Nov 19 09:50:33 1998
   </PRE>
   <P>
  -Below all sections should be links:
  +Below all the sections are links when you view them through <EM>/perl-status</EM>
  +
   
  +
   <P>
   <PRE>  Signal Handlers
     Enabled mod_perl Hooks
  @@ -2261,43 +2369,67 @@
     /home/perl/apache-startup.pl  /home/perl/apache-startup.pl
   </PRE>
   <P>
  -From some menus you can continue deeper to peek into the internals of the
  -server, to see the values of the global variables in the packages, to the
  -cached scripts and modules, and much more. Just click around...
  +From some menus you can move deeper to peek into the internals of the
  +server, to see the values of the global variables in the packages, to see
  +the cached scripts and modules, and much more. Just click around...
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A></H3></CENTER>
   <P>
  -Sometimes when you fetch <CODE>/perl-status</CODE> and follow the <STRONG>Compiled
  -Registry Scripts</STRONG> you see no listing of scripts at all. This is absolutely correct: <CODE>Apache::Status</CODE> shows the registry scripts compiled in the httpd child which is serving
  -your request for /perl-status. If a child has not compiled yet the script
  -you are asking for, /perl-status will just show you the main menu.
  +Sometimes when you fetch <EM>/perl-status</EM> and look at the <STRONG>Compiled
  +Registry Scripts</STRONG> you see no listing of scripts at all. This is correct: <CODE>Apache::Status</CODE> shows the registry scripts compiled in the httpd child which is serving
  +your request for <EM>/perl-status</EM>. If the child has not yet compiled the script you are asking for,
  +<EM>/perl-status</EM> will just show you the main menu.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="mod_status">mod_status</A></H2></CENTER>
   <P>
  -The Status module allows a server administrator to find out how well their
  -server is performing. A HTML page is presented that gives the current
  -server statistics in an easily readable form. If required this page can be
  -made to automatically refresh (given a compatible browser). Another page
  +The Status module allows a server administrator to find out how well the
  +server is performing. An HTML page is presented that gives the current
  +server statistics in an easily readable form. If required, given a
  +compatible browser this page can be automatically refreshed. Another page
   gives a simple machine-readable list of the current server state.
   
   <P>
  -This is the Apache module written in C, and it gets compiled by default, so
  -no special build instructions are required.
  +This Apache module is written in C. It is compiled by default, so all you
  +have to do to use it is enable it in your configuration file:
   
  +<P>
  +<PRE>  &lt;Location /status&gt;
  +    SetHandler server-status
  +  &lt;/Location&gt;
  +</PRE>
   <P>
  -The details given are:
  +For security reasons you will probably want to limit access to it. If you
  +have installed Apache according to the instructions you will find a
  +prepared configuration section in <EM>httpd.conf</EM>: to enable use of the mod_status module, just uncomment it.
   
  +<P>
  +<PRE>  ExtendedStatus On
  +  &lt;Location /status&gt;
  +    SetHandler server-status
  +    order deny,allow
  +    deny from all
  +    allow from localhost
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +You can now access server statistics by using a Web browser to access the
  +page <A HREF="http://localhost/status">http://localhost/status</A> (as long
  +as your server recognizes localhost:).
  +
  +<P>
  +The details given by mod_status are:
  +
   <UL>
   <P><LI><STRONG><A NAME="item_The">The number of children serving requests</A></STRONG>
   <P><LI><STRONG><A NAME="item_The">The number of idle children</A></STRONG>
   <P><LI><STRONG><A NAME="item_The">The status of each child, the number of requests that child
   has performed and the total number of bytes served by the child</A></STRONG>
  -<P><LI><STRONG><A NAME="item_A">A total number of accesses and byte count served</A></STRONG>
  -<P><LI><STRONG><A NAME="item_The">The time the server was started/restarted and the time it has
  +<P><LI><STRONG><A NAME="item_A">A total number of accesses and the total bytes served</A></STRONG>
  +<P><LI><STRONG><A NAME="item_The">The time the server was last started/restarted and how long it has
   been running for</A></STRONG>
   <P><LI><STRONG><A NAME="item_Averages">Averages giving the number of requests per second, the number
   of bytes served per second and the average number of bytes per request</A></STRONG>
  @@ -2306,23 +2438,6 @@
   <P><LI><STRONG><A NAME="item_The">The current hosts and requests being processed</A></STRONG>
   </UL>
   <P>
  -To enable it, just uncomment the already prepared configuration section in <EM>httpd.conf</EM>:
  -
  -<P>
  -<PRE>  ExtendedStatus On
  -  &lt;Location /server-status&gt;
  -  SetHandler server-status
  -  order deny,allow
  -  deny from all
  -  allow from .foo.com
  -  &lt;/Location&gt;
  -</PRE>
  -<P>
  -You can now access server statistics by using a Web browser to access the
  -page <A
  -HREF="http://localhost/server-status">http://localhost/server-status</A>
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A></H2></CENTER>
   <P>
  @@ -2330,26 +2445,31 @@
   <A HREF="././debug.html#mod_status">mod_status</A>. It provides all the information mod_status provides and much more.
   
   <P>
  -This module emulates the reporting functionalities of <CODE>top(),</CODE>
  +This module emulates the reporting functions of the <CODE>top(),</CODE>
   <CODE>mount(),</CODE> <CODE>df()</CODE> and <CODE>ifconfig()</CODE>
  -utilities. There is a special mode for mod_perl processes. It has a visual
  -alert capabilities and configurable automatic refresh mode. All the
  -sections can be shown/hidden dynamically through the web interface.
  +utilities. There is a special mode for mod_perl processes. It has visual
  +alert capabilities and a configurable `automatic refresh' mode. It provides
  +a Web interface, which can be used to show or hide all the sections
  +dynamically.
   
   <P>
   The are two main modes:
   
  +<UL>
  +<P><LI>
   <P>
  -o Multi processes mode -- All system processes and information are shown.
  +Multi processes mode -- All system processes and information is shown.
   
  +<P><LI>
   <P>
  -o Single process mode -- An indepth information about a single process is
  +Single process mode -- In-depth information about a single process is
   shown.
   
  +</UL>
   <P>
   The main advantage of this module is that it reduces the need to telnet to
  -machine in order to monitor it. And provides an indepth information about
  -mod_perl processes that cannot be acquired from telneting to machine.
  +the machine in order to monitor it. Indeed it provides information about
  +mod_perl processes that cannot be acquired from telneting to the machine.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2364,7 +2484,7 @@
   <P>
   <PRE>  # startup file or &lt;Perl&gt; section:
     use Apache::VMonitor();
  -  $Apache::VMonitor::Config{BLINKING} = 1;
  +  $Apache::VMonitor::Config{BLINKING} = 0; # Blinking is evil
     $Apache::VMonitor::Config{REFRESH}  = 0;
     $Apache::VMonitor::Config{VERBOSE}  = 0;
     $Apache::VMonitor::Config{SYSTEM}   = 1;
  @@ -2378,17 +2498,16 @@
     $Apache::VMonitor::PROC_REGEX = join &quot;\|&quot;, qw(httpd mysql squid);
   </PRE>
   <P>
  -More information available in the extensive module's manpage.
  +More information available in the module's extensive manpage.
   
   <P>
  -It requires Apache::Scoreboard and GTop to work. GTop in turn requires
  -libgtop library. It's not available for all platfrorms. Visit <A
  +It requires <CODE>Apache::Scoreboard</CODE> and <CODE>GTop</CODE> to work.  <CODE>GTop</CODE> in turn requires the <CODE>libgtop</CODE> library but is not available for all platforms. Visit <A
   HREF="http://www.home-of-linux.org/gnome/libgtop/">http://www.home-of-linux.org/gnome/libgtop/</A>
   to check whether your platform/flavor is supported.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Sometimes_script_works_sometime">Sometimes script works, sometimes does not</A></H1></CENTER>
  +<CENTER><H1><A NAME="Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A></H1></CENTER>
   <P>
   See <A HREF="././porting.html#Sometimes_it_Works_Sometimes_it">Sometimes it Works Sometimes it does Not</A>
   
  @@ -2398,105 +2517,108 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Code_Debug">Code Debug</A></H1></CENTER>
   <P>
  -When the code doesn't perform what it's expected to, either never or just
  -sometimes we say that this code requires debugging. There are a few levels
  -of debug complexity.
  +When the code doesn't perform as expected, either never or just sometimes,
  +we say that the code needs debugging. There are several levels of debugging
  +complexity.
   
   <P>
  -The basic level is when perl terminates the program in the interpretation
  -(compilation) stage before it started to run. Usually that happens when
  -either there are syntax errors or some module is missing. Sometimes it
  -takes an effort to solve this task, since code that uses Apache CORE
  -modules generally wouldn't compile when executed from shell. We will learn
  -how to solve syntax problems in mod_perl code quite easily.
  +The basic level is when Perl terminates the program during the compilation
  +phase, before it tries to run the resulting byte-code. This usually happens
  +because there are syntax errors in the code, or perhaps a module is
  +missing. Sometimes it takes quite an effort to solve these problems, since
  +code that uses Apache CORE modules generally won't compile when executed
  +from the shell. We will learn how to solve syntax problems in mod_perl code
  +quite easily.
   
   <P>
   Once the program compiles and begins to run, there might be logical
  -(algorithmic) problems, when the program doesn't do the right thing you
  -programmed it to do. This is somewhat harder to solve, especially when
  -there is a lot of code that need to be observed and reviewed, but it's just
  -a matter of time. Perl helps a lot to locate typos when you enable to
  -warnings, for example it warns you about places when you wanted to compare
  -to numbers, but omitted the second '=' character, so you end up with
  -something like <CODE>if $yes = 1</CODE> instead of <CODE>if $yes ==
  -1</CODE>.
  -
  -<P>
  -The next level is when the program does what it expected to most of the
  -time, but occasionally it misbehaves, but doing something different. An
  -observation of the code generally doesn't help, and either
  -<CODE>print()</CODE> statements or perl debugger come to help. Many times
  -it's quite easy to debug with <CODE>print(),</CODE> but sometimes the
  -overhead of typing the debug messages can be very tedious, especially when
  -you didn't yet spot the lines where the bug happens to hide. That's where a
  -perl debugger comes to help.
  -
  -<P>
  -While <CODE>print()</CODE> statements are always work, running the perl
  -debugger for CGI scripts, might be quite a challenge. But with a right
  -knowledge and tools in hand the debug process becomes much easier.
  -Unfortunately there is no way to easy the debug of the program itself, as
  -it depends on the code you wrote, and it can be quite a nightmare to debug
  -a really complex code.
  -
  -<P>
  -The worst thing you can think of, is when the process terminates in the
  -middle of a request processing and dumps core. Operating system dumps core
  -(read: creates a file called <EM>core</EM> in directory the process was running at) when the program tries to access a
  -memory area that doesn't belong to it, which generally happens when there
  -is a bug. This is something that you would almost never see with plain perl
  -scripts, but can easily happen if you use modules whose guts are written in <EM>C</EM> or <EM>C++</EM> and something goes wrong with them. Occasionally there is a bug in
  -underlying C code of mod_perl itself, that was in a deep slumber before
  -your code waked it up.
  -
  -<P>
  -In the following sections we would go in details through each of the
  -presented problems, thoroughly discuss them and present a few techniques to
  -solve them.
  +problems, when the program doesn't do what you thought you had programmed
  +it to do. These are somewhat harder to solve, especially when there is a
  +lot of code to be inspected and reviewed, but it's just a matter of time.
  +Perl can help a lot, for example to locate typos, when we enable warnings.
  +For example, if you wanted to compare two numbers, but you omitted the
  +second '=' character so that you had something like <CODE>if $yes = 1</CODE> instead of <CODE>if $yes == 1</CODE>, it warns us about the missing '='.
  +
  +<P>
  +The next level is when the program does what it's expected to do most of
  +the time, but occasionally misbehaves. Often you find that
  +<CODE>print()</CODE> statements or the Perl debugger can help, but
  +inspection of the code generally doesn't. Often it's quite easy to debug
  +with <CODE>print(),</CODE> but sometimes typing the debug messages can
  +become very tedious. That's where the Perl debugger comes into its own.
  +
  +<P>
  +While <CODE>print()</CODE> statements always work, running the perl
  +debugger for CGI scripts might be quite a challenge. But with the right
  +knowledge and tools handy the debug process becomes much easier.
  +Unfortunately there is no one easy way to debug your programs, as the
  +debugging depends entirely on your code. It can be a nightmare to debug
  +really complex code, but as your style matures you can learn ways to write
  +simpler code that is easier to debug. You will probably find that when you
  +write simpler clearer code it does not need so much debugging in the first
  +place.
  +
  +<P>
  +One of the most difficult cases to debug, is when the process just
  +terminates in the middle of processing a request and dumps core. Often when
  +there is a bug the program tries to access a memory area that doesn't
  +belong to it. The operating system halts the process, tidies up and dumps
  +core (it creates a file called <EM>core</EM> in the current directory of the process that was running). This is
  +something that you rarely see with plain perl scripts, but it can easily
  +happen if you use modules written in <EM>C</EM> or <EM>C++</EM> and something goes wrong with them. Occasionally you will come across a bug
  +in mod_perl itself (mod_perl is written in C), that was in a deep slumber
  +before your code awakened it.
  +
  +<P>
  +In the following sections we will go through in detail each of the problems
  +presented, thoroughly discuss them and present a few techniques to solve
  +them.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Locating_and_correcting_Syntax_E">Locating and correcting Syntax Errors</A></H2></CENTER>
   <P>
  -While developing code, many times we do some syntax mistakes, like
  -forgetting to put a semicolon at the end of statement ([S] unless it's an
  -end of a block, where it's not required, but better if used since there is
  -a chance that you will add more code at the end, and when you do, you might
  -forget to add the missing semicolon.[/S]), comma in the list ([S] for the
  -same reason, more items might be added to the list and perl has no problem
  -when you finish the list with comma unlike other languages.[/S]) or else.
  +While developing code we often make syntax mistakes, like forgetting to put
  +a comma in a list, or a semicolon at the end of a statement.
   
   <P>
  -One of the approaches to locate the syntactically incorrect code, is to
  -execute the script from shell with <EM>-c</EM> flag that only validates the syntax but wouldn't run the code (Actually, it
  -will execute
  +(Even after a block, where a semicolon is not required, it may be better to
  +put one in: there is a chance that you will add more code later, and when
  +you do you might forget to add the now required semicolon. Similarly, more
  +items might be added later to a list; unlike many other languages, Perl has
  +no problem when you end a list with a redundant comma.)
  +
  +<P>
  +One approach to locating syntactically incorrect code is to execute the
  +script from the shell with the <EM>-c</EM> flag. This tells Perl to check the syntax but not to run the code
  +(actually, it will execute
   <CODE>BEGIN</CODE>, <CODE>END</CODE> blocks, and <EM>use()</EM> calls, because these are considered as occurring outside the execution of
  -your program. Also it's a good idea to add <CODE>-w</CODE> switch to enable the warnings:
  +your program). (Note also that Perl 5.6.0 has introduced a new special
  +variable, <CODE>$^C</CODE>, which is set to true when perl is run with the <EM>-c</EM> flag; this provides an opportunity to have some further control over <CODE>BEGIN</CODE> and
  +<CODE>END</CODE> blocks during syntax checking.) Also it's a good idea to add the <CODE>-w</CODE> switch to enable warnings:
   
   <P>
   <PRE>  perl -cw test.pl
   </PRE>
   <P>
  -When executed and there are errors in the code, perl will report about the
  -errors and the appropriate line numbers in the script.
  +If there are errors in the code, Perl will report the errors, and tell you
  +at which line numbers in your script the errors were found.
   
   <P>
  -Next step is to execute the script, since besides syntax errors there are
  -run time errors, these are the errors that cause the <EM>"Internal
  -Server Error"</EM> when executes from the browser. With plain CGI scripts it's the same as
  -running a plain perl scripts -- just execute it and see that they work.
  +The next step is to execute the script, since in addition to syntax errors
  +there may be run time errors. These are the errors that cause the <EM>"Internal Server Error"</EM> page when executed from a browser. With plain CGI scripts it's the same as
  +running plain Perl scripts -- just execute them and see that they work.
   
   <P>
  -However the whole thing is quite different with scripts that use
  -<A HREF="#item_Apache_">Apache::*</A> modules which can be used only from within the mod_perl server, since they
  -rely on the code and circumstances , which aren't available when you
  -attempt to execute the script from shell, since there is no Apache request
  -object available to the code.
  +The whole thing is quite different with scripts that use <A HREF="#item_Apache_">Apache::*</A>
  +modules which can be used only from within the mod_perl server environment.
  +These scripts rely on other code, and an environment which isn't available
  +when you attempt to execute the script from the shell. There is no Apache
  +request object available to the code when it is executed from the shell.
   
   <P>
  -If you have problems with code, you can either watch the errors and
  -warnings as they are logged to <EM>error_log</EM> file when you make a request to the script from the browser, or use an
  -<CODE>Apache::FakeRequest</CODE> module written by Doug MacEachern and Andrew Ford.
  +If you have a problem when using <A HREF="#item_Apache_">Apache::*</A> modules, you can make a request to the script from a browser and watch the
  +errors and warnings as they are logged to the <EM>error_log</EM> file. Alternatively you can use the <CODE>Apache::FakeRequest</CODE> module.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2504,14 +2626,14 @@
   <P>
   <CODE>Apache::FakeRequest</CODE> is used to set up an empty Apache request object that can be used for
   debugging. The <CODE>Apache::FakeRequest</CODE>
  -methods just set internal variables of the same name as the method and
  +methods just set internal variables with the same names as the methods and
   return the value of the internal variables. Initial values for methods can
   be specified when the object is created. The print method prints to STDOUT.
   
   <P>
  -Subroutines for Apache constants are also defined so that using
  -<CODE>Apache::Constants</CODE> while debugging works, although the values of the constants are hard-coded
  -rather than extracted from the Apache source code.
  +Subroutines for Apache constants are also defined so that you can use
  +<CODE>Apache::Constants</CODE> while debugging, although the values of the constants are hard-coded rather
  +than extracted from the Apache source code.
   
   <P>
   Let's write a very simple module, which prints <EM>"OK"</EM> to the client's browser:
  @@ -2529,11 +2651,22 @@
     
     1;
   </PRE>
  +<P>
  +You cannot debug this module unless you configure the server to run it, by
  +calling its handler from somewhere. So for example you could put in <EM>httpd.conf</EM>:
  +
  +<P>
  +&lt;Location /ex&gt; SetHandler perl-script PerlHandler Apache::Example
  +&lt;/Location&gt;
  +
  +<P>
  +Then after restarting the server you could start a browser, request the
  +location <A HREF="http://localhost/ex">http://localhost/ex</A> and examine
  +the output. Tedious, no?
  +
   <P>
  -You cannot debug this module unless you configure the server to call its
  -handler from some location. But with help of
  -<CODE>Apache::FakeRequest</CODE> you can write a little script that will emulate a request and return the
  -expected output.
  +But with the help of <CODE>Apache::FakeRequest</CODE> you can write a little script that will emulate a request and return the
  +output.
   
   <P>
   <PRE>  #!/usr/bin/perl
  @@ -2554,18 +2687,31 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Finding_the_Line_Number_the_Erro">Finding the Line Number the Error/Warning has been Triggered at</A></H2></CENTER>
  +<CENTER><H2><A NAME="Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A></H2></CENTER>
   <P>
  -<CODE>Apache::Registry</CODE>, <CODE>Apache::PerlRun</CODE> and modules that compile-via-eval confuse the line numbering. Modules that
  -are read normally by Perl from disk have no problem with file name/line
  -number.
  +Perl has no problem with the line numbers and file names for modules that
  +are read from disk in the normal way, but modules that are compiled via
  +eval such as <CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE>
  +confuse it.
   
  +<P>
  +META: Isn't PERL_MARK_WHERE=1 is a default now?
  +
  +<P>
  +If you compile with the experimental <STRONG>PERL_MARK_WHERE=1</STRONG>, then even for this kind of module Perl will show you almost the exact
  +line which triggered the error.
  +
  +<P>
  +There are compiler directives to reset its counter to some value that you
  +decide. You can always pepper your code with these to help you locate the
  +problem. At the beginning of the line you could write something of the
  +form:
  +
  +<P>
  +<PRE>  #line nnn label
  +</PRE>
   <P>
  -If you compile with the experimental <STRONG>PERL_MARK_WHERE=1</STRONG>, it shows you almost the exact line number, where this is happening.
  -Generally a compiler makes a shift in its line counter. You can always
  -stuff your code with special compiler directives, to reset its counter to
  -the value you will tell. At the beginning of the line you should write (the
  -'#' in column 1):
  +For example:
   
   <P>
   <PRE>  #line 298 myscript.pl
  @@ -2573,18 +2719,23 @@
     #line 890 some_label_to_be_used_in_the_error_message
   </PRE>
   <P>
  +The '#' must be in the first column, so if you cut and paste from this text
  +you must remember to remove any leading white space.
  +
  +<P>
   The label is optional - the filename of the script will be used by default.
  -This specifies the line number of the <STRONG>following</STRONG> line, not the line the directive is on. You can use a little script to
  +This directive sets the line number of the <STRONG>following</STRONG>
  +line, not the line the directive is on. You can use a little script to
   stuff every N lines of your code with these directives, but then you will
  -have to rerun this script every time you add or remove code lines. The
  -script:
  +have to remember to rerun this script every time you add or remove code
  +lines. The script:
   
   <P>
   <PRE>  #!/usr/bin/perl
     # Puts Perl line markers in a Perl program for debugging purposes.  
     # Also takes out old line markers.
     die &quot;No filename to process.\n&quot; unless @ARGV;
  -  my $filename = $ARGV[0];
  +  my $filename = shift;
     my $lines = 100;
     open IN, $filename or die &quot;Cannot open file: $filename: $!\n&quot;;
     open OUT, &quot;&gt;$filename.marked&quot;
  @@ -2592,7 +2743,7 @@
     my $counter = 1;
     while (&lt;IN&gt;) {
       print OUT &quot;#line $counter\n&quot; unless $counter++ % $lines;
  -    next if $_ =~ /^#line /;
  +    next if /^#line /;
       print OUT $_;
     }
     close OUT;
  @@ -2600,9 +2751,9 @@
     chmod 0755, &quot;$filename.marked&quot;;
   </PRE>
   <P>
  -Also notice, that another solution is to move most of the code into a
  -separate modules, which ensures that the line number will be reported
  -correctly.
  +Another way of narrowing down the area to be searched is to move most of
  +the code into a separate modules. This ensures that the line number will be
  +reported correctly.
   
   <P>
   To have a complete trace of calls add:
  @@ -2613,34 +2764,36 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Using_print_Function_for_Debug">Using print() Function for Debugging</A></H2></CENTER>
  +<CENTER><H2><A NAME="Using_print_for_Debugging">Using print() for Debugging</A></H2></CENTER>
   <P>
   The universal debugging tool across nearly all platforms and programming
  -languages is the <CODE>printf()</CODE> or equivalent output function, which
  -can send data to the console, a file, application window and so on. In perl
  -we generally use the <CODE>print()</CODE> function. With an idea of where
  -and when the bug is triggered, a developer can insert <CODE>print()</CODE>
  -statements in the source code to examine the value of data at certain
  -points of execution.
  +languages is <CODE>printf()</CODE> or the equivalent output function. This
  +can send data to the console, a file, an application window and so on. In
  +perl we generally use the <CODE>print()</CODE> function. With an idea of
  +where and when the bug is triggered, a developer can insert
  +<CODE>print()</CODE> statements in the source code to examine the value of
  +data at certain stages of execution.
   
   <P>
   However, it is rather difficult to anticipate all possible directions a
   program might take and what data to suspect of causing trouble. In
  -addition, inline debugging code tends to add bloat and degrade performance
  -of an application. So you have to comment out or remove the debug printings
  -when you think that you have solved the problem, but if later you discover
  -that you need to debug the same code again you need in the best case to
  -uncomment the debug code lines or write them from scratch.
  +addition, inline debugging code tends to add bloat and degrade the
  +performance of an application and can also make the code harder to read and
  +maintain. And you have to comment out or remove the debugging
  +<CODE>print()</CODE> calls when you think that you have solved the problem.
  +But if later you discover that you need to debug the same code again, you
  +need at best to uncomment the debugging code lines or, at worst, to write
  +them again from scratch.
   
   <P>
   Let's see a few examples where we use <CODE>print()</CODE> to debug some
   problem. In one of my applications I wrote a function that returns the date
  -that was a week ago. Here it is:
  +that was one week ago. Here it is:
   
   <P>
  -<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
     
  -  print &quot;A week ago date was &quot;,date_a_week_ago(),&quot;\n&quot;;
  +  print &quot;A week ago the date was &quot;,date_a_week_ago(),&quot;\n&quot;;
     
     # return a date one week ago as a string in format: MM/DD/YYYY
     ####################
  @@ -2675,30 +2828,31 @@
     }
   </PRE>
   <P>
  -This code is pretty straightforward. Get today's date and subtract one from
  -the value of the day we get, updating on the way the month and the year if
  -the boundaries are being crossed (end of month, end of year). Do it seven
  -times in loop, and at the end you should get a date that was a week ago.
  -
  -<P>
  -Note that since <CODE>locatime()</CODE> returns year as a value of
  -current_four_digits_format_year-1900, which means that we don't have a
  -century boundary to worry about, since if we are in the middle of the first
  -week of the year 2000, the value of year returned by
  -<CODE>localtime()</CODE> would be <CODE>100</CODE> and not <CODE>0</CODE> as you mistakenly might assume. So when the code does <CODE>$year--</CODE> it becomes <CODE>99</CODE> and not <CODE>-1</CODE>. At the end we add 1900 and get back a correct four digit year format.
  -
  -<P>
  -Also note that we have to cover the case of the leap year, where there are
  -29 days in the February. For the rest of months we have prepared an array
  -with month lengths.
  +This code is pretty straightforward. We get today's date and subtract one
  +from the value of the day we get, updating the month and the year on the
  +way if boundaries are being crossed (end of month, end of year). If we do
  +it seven times in loop then at the end we should get a date that was a week
  +ago.
  +
  +<P>
  +Note that since <CODE>locatime()</CODE> returns the year as a value of
  +<CODE>current_four_digits_format_year-1900</CODE> (which means that we don't have a century boundary to worry about) then if
  +we are in the middle of the first week of the year 2000, the value of year
  +returned by <CODE>localtime()</CODE> will be <CODE>100</CODE> and not <CODE>0</CODE> as you might mistakenly assume. So when the code does <CODE>$year--</CODE> it becomes <CODE>99</CODE> and not
  +<CODE>-1</CODE>. At the end we add 1900 to get back the correct four-digit year format.
  +(This is all correct as long as you don't go to the years prior to 1900)
  +
  +<P>
  +Also note that we have to account for leap years where there are 29 days in
  +February. For the other months we have prepared an array containing the
  +month lengths.
   
   <P>
   Now when we run this code and check the result, we see that something is
  -wrong. For example if today is <CODE>10/23/1999</CODE> and we expect the above code to print <CODE>10/16/1999</CODE>, it prints: <CODE>09/16/1999</CODE>, which means that we have lost a month, therefore the above code is buggy.
  +wrong. For example, if today is <CODE>10/23/1999</CODE> we expect the above code to print <CODE>10/16/1999</CODE>. In fact it prints <CODE>09/16/1999</CODE>, which means that we have lost a month. The above code is buggy!
   
   <P>
  -Let's stuff a few debug <CODE>print()</CODE> statements in the code near
  -the
  +Let's put a few debug <CODE>print()</CODE> statements in the code, near the
   <CODE>$month</CODE> variable:
   
   <P>
  @@ -2707,7 +2861,7 @@
       my @month_len   = (31,28,31,30,31,30,31,31,30,31,30,31);
     
       my ($day,$month,$year) = (localtime)[3..5];
  -    print &quot;[set] month : $month\n&quot;;
  +    print &quot;[set] month : $month\n&quot;; # DEBUG
       for (my $j = 0; $j &lt; 7; $j++) {
     
         $day--;
  @@ -2718,7 +2872,7 @@
             $year--;
             $month = 12;
           }
  -        print &quot;[loop $i] month : $month\n&quot;;
  +        print &quot;[loop $i] month : $month\n&quot;; # DEBUG
     
             # there are 29 days in February in a leap year
           $month_len[1] =  
  @@ -2741,9 +2895,10 @@
   <PRE>  [set] month : 9
   </PRE>
   <P>
  -Which is supposed to be the number of current month (<CODE>10</CODE>), when it actually is not. We have spotted a bug, since the only code that
  -sets the <CODE>$month</CODE> variable consists of a call to <CODE>localtime().</CODE> So did we find a
  -bug in Perl? let's look at the man page of the <CODE>localtime()</CODE>
  +It is supposed to be the number of the current month (<CODE>10</CODE>), but actually it is not. We have spotted a bug, since the only code that
  +sets the
  +<CODE>$month</CODE> variable consists of a call to <CODE>localtime().</CODE> So did we find a
  +bug in Perl? let's look at the manpage of the <CODE>localtime()</CODE>
   function: % perldoc -f localtime Converts a time as returned by the time
   function to a 9-element array with the time analyzed for the local time
   zone. Typically used as follows:
  @@ -2764,15 +2919,15 @@
     [more info snipped]
   </PRE>
   <P>
  -Which reveals us that we are supposed to increment a value of &lt;$month&gt;, if we want to count months from 1 to 12 and not 0 to 11. Among
  -other interesting facts about <CODE>locatime()</CODE> we also see an
  -explanation about <CODE>$year</CODE>, which as I've mentioned before is being set to the number of years since
  -1900.
  +Which reveals to us that if we want to count months from 1 to 12 and not 0
  +to 11 we are supposed to increment the value of <CODE>$month</CODE>. Among other interesting facts about <CODE>locatime()</CODE> we also see
  +an explanation of
  +<CODE>$year</CODE>, which as I've mentioned before is set to the number of years since 1900.
   
   <P>
  -Thus we have found the bug in our code and learned new things about
  -<CODE>localtime().</CODE> To correct the above code we just add a month's
  -increment after we call <CODE>localtime():</CODE>
  +We have found the bug in our code and learned new things about
  +<CODE>localtime().</CODE> To correct the above code we just increment the
  +month after we call <CODE>localtime():</CODE>
   
   <P>
   <PRE>    my ($day,$month,$year) = (localtime)[3..5];
  @@ -2793,9 +2948,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Using_print_and_Data_Dumper_f">Using print() and Data::Dumper for Debugging</A></H2></CENTER>
   <P>
  -Sometimes you need to peek into a complex data structures, and trying to
  -print them out can be a non-easy task. That's where <CODE>Data::Dumper</CODE>
  -comes to a resque. For example if we create this complex data structure:
  +Sometimes you need to peek into complex data structures, and trying to
  +print them out can be tricky. That's where <CODE>Data::Dumper</CODE> comes to our rescue. For example if we create this complex data structure:
   
   <P>
   <PRE>  $data =
  @@ -2815,7 +2969,7 @@
     print Dumper \$data;
   </PRE>
   <P>
  -What we get is a pretty printed <CODE>$data</CODE>:
  +What we get is a pretty-printed <CODE>$data</CODE>:
   
   <P>
   <PRE>  $VAR1 = \{
  @@ -2833,7 +2987,7 @@
   </PRE>
   <P>
   While writing this example I made a mistake and wrote <CODE>qw(a b c d)</CODE>
  -instead of <CODE>[qw(a b c d)]</CODE>, when I pretty printed the contents of
  +instead of <CODE>[qw(a b c d)]</CODE>. When I pretty-printed the contents of
   <CODE>$data</CODE> I immediately saw my mistake:
   
   <P>
  @@ -2845,27 +2999,25 @@
             };
   </PRE>
   <P>
  -That's not what I wanted of course, I've spotted the bug and corrected it,
  +That's not what I wanted of course, but I spotted the bug and corrected it,
   as you saw in the original example from above.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_Importance_of_Good_Coding_St">The Importance of Good Coding Style and Conciseness</A></H2></CENTER>
  +<CENTER><H2><A NAME="The_Importance_of_a_Good_Concise">The Importance of a Good Concise Coding Style</A></H2></CENTER>
   <P>
  -META: rewrite: blabla about -- very hard to find bugs and even understand
  -the code below because of its obscurity. The example from the previous
  -section is hard to debug too, because there is too much redundancy in it,
  -you should develop a good coding style by creating a concise code but which
  -is easy to understand (See the example below)...
  +Don't strive for elegant, clever code. Try to develop a good coding style
  +by writing code which is concise yet easy to understand. It's much easier
  +to find bugs in concise, simple code. And such code tends to have less
  +bugs.
   
   <P>
  -it's much easier to find bugs
  +The <EM>'one week ago'</EM> example from the previous section is not concise. There is a lot of
  +redundancy in it, and as a result it is harder to debug than it needs to
  +be. Here is a condensed version of the main loop. As you can see, this
  +version won't make it easier to understand the code:
   
   <P>
  -A shrinked version of the main loop, that wouldn't add for easier code
  -understanding looks like:
  -
  -<P>
   <PRE>  for (0..7) {
       next if --$day;
       $year--,$month=12 unless --$month;
  @@ -2876,48 +3028,54 @@
   Don't do that at home :) 
   
   <P>
  -Why did I actually present the latter version? The shrinked version is too
  -obfuscated, which makes it not easy to understand and maintain. From the
  -other hand part of this code is easier to understand.
  +Why did I present this version? Because it is too obscure, which makes it
  +difficult to understand and maintain. On the other hand a part of this code
  +is easier to understand.
   
   <P>
  -Larry Wall, the author of Perl, is a linguist, so he tried to define the
  -syntax in a way that will make coding in Perl much like in English. So it
  -can be a very good idea to learn perl coding idioms, which might seem
  -inconvenient in the beginning but once you get used to them, you will not
  -understand how could you live without them before. I'll show just a few of
  -most used perl coding style idioms. It's a good idea to write the code that
  -more readable but avoid redundancy, like instead of writing:
  +Larry Wall, the author of Perl, is a linguist. He tried to define the
  +syntax of Perl in a way that makes working in Perl much like working in
  +English. So it can be a good idea to learn Perl coding idioms, some of
  +which might seem odd at first but once you get used to them, you will find
  +it difficult to understand how you could have lived without them before.
  +I'll show just a few of the most common Perl coding idioms.
   
   <P>
  -<PRE>  if ($i == 0) ...
  +It's a good idea to write code which is more readable but which avoids
  +redundancy, so it's better to write:
  +
  +<P>
  +<PRE>  unless ($i) {...}
   </PRE>
   <P>
  -it's better to write:
  +rather than:
   
   <P>
  -<PRE>  unless ($i)
  +<PRE>  if ($i == 0) {...}
   </PRE>
  +<P>
  +if you want to test for trueness only.
  +
   <P>
  -Use a much more concise perlish style:
  +Use a much more concise, Perlish style:
   
   <P>
  -<PRE>  for my $j (0..7) {
  +<PRE>  for my $j (0..7) {...}
   </PRE>
   <P>
  -instead of a syntax you've got used from other languages:
  +instead of the syntax used in some other languages:
   
   <P>
  -<PRE>  for (my $j=0; $j&lt;7; $j++) {
  +<PRE>  for (my $j=0; $j&lt;7; $j++) {...}
   </PRE>
   <P>
  -it's much simpler to write and comprehend the code like:
  +It's much simpler to write and comprehend code like this:
   
   <P>
   <PRE>  print &quot;something&quot; if $debug;
   </PRE>
   <P>
  -rather than:
  +than this:
   
   <P>
   <PRE>  if($debug){
  @@ -2925,9 +3083,9 @@
     }
   </PRE>
   <P>
  -A good style that improves understanding, readability and reduces a chance
  -to have a bug is shown below in a form of yet another rewrite of the
  -original version of the code:
  +A good style that improves understanding, readability and reduces the
  +chances of having a bug is shown below in the form of yet another rewrite
  +of our <EM>`one week ago'</EM> code:
   
   <P>
   <PRE>  for (0..7) {
  @@ -2948,8 +3106,8 @@
     } 
   </PRE>
   <P>
  -which is a gold middle between the too verbose style as in the first
  -example and too obfuscated second example.
  +which is a happy medium between the excessively verbose style of the first
  +version and very obscure second version.
   
   <P>
   And of course a two liner, which is much faster and easier to understand
  @@ -2964,57 +3122,58 @@
   <P>
   Just take the current date in seconds since epoch as <CODE>time()</CODE>
   returns, subtract a week in seconds (7*24*60*60 = 604800) and feed the
  -result to <CODE>localtime()</CODE> - voila we've got a date from a week
  +result to <CODE>localtime()</CODE> - voila we've got the date of one week
   ago!
   
   <P>
  -Why the last version is important, when the first one works just fine? Not
  -because of performance issues, and the last one is a twice faster, but
  -because the are more chances that you have a bug in the first version, than
  -in the last one.
  +Why is the last version important, when the first one works just fine? Not
  +because of performance issues (although this last one is twice as fast as
  +the first), but because there are more ways to put a bug in the first
  +version than there are in the last one.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Introduction_into_Perl_Debugger">Introduction into Perl Debugger</A></H2></CENTER>
  +<CENTER><H2><A NAME="Introduction_to_the_Perl_Debugge">Introduction to the Perl Debugger</A></H2></CENTER>
   <P>
  -As we saw it's <EM>almost</EM> always possible to debug code with help of <CODE>print().</CODE> However,
  -it is rather difficult to anticipate all possible directions a program
  -might take and what data to suspect of causing trouble. In addition, inline
  -debugging code tends to add bloat and degrade performance of an
  -application. Although, most applications offer inline debugging as a
  -compile time option to avoid these hits. In any case, this information
  -tends to only be useful to the programmer who added the trace statement in
  -first place.
  +As we saw earlier, it's <EM>almost</EM> always possible to debug code with the help of <CODE>print().</CODE>
  +However, it is impossible to anticipate all the possible directions which a
  +program might take, and difficult to know what code to suspect when trouble
  +occurs. In addition, inline debugging code tends to add bloat and degrade
  +the performance of an application, although most applications offer inline
  +debugging as a compile time option to avoid these hits. In any case, this
  +information tends to only be useful to the programmer who added the print
  +statements in the first place.
   
   <P>
  -Sometimes you have to debug tens of thousands lines Perl application and
  -while you can be a very experienced Perl programmer and can understand Perl
  -code quite well by just looking at it, no mere mortal can begin to
  -understand what will actually happen in such a large application, until the
  -code is running. You just don't know where to start adding trusty
  -<CODE>print()</CODE> statements to see what is happening inside.
  +Sometimes you have to debug tens of thousands lines of Perl in an
  +application, and while you may be a very experienced Perl programmer who
  +can understand Perl code quite well by just looking at it, no mere mortal
  +can even begin to understand what will actually happen in such a large
  +application, until the code is running. So you just don't know where to
  +start adding your trusty <CODE>print()</CODE> statements to see what is
  +happening inside.
   
   <P>
  -The most effective way to track down a bug is running the program with an
  +The most effective way to track down a bug is to run the program inside an
   interactive debugger. The majority of programming languages have such a
  -tool available that allows one to see what is happening inside an
  -application while it is running. Basic features of an interactive debugger
  -allow you to: &lt;ul&gt;
  +tool available, allowing one to see what is happening inside an application
  +while it is running. The basic features of an interactive debugger allow
  +you to:
   
   <UL>
   <P><LI>
   <P>
  -Stop at a certain point in the code, based on a routine name or specific
  -source file and line number
  +Stop at a certain point in the code, based on a routine name or source file
  +and line number
   
   <P><LI>
   <P>
  -Stop at a certain point in the code, based on specific conditions such as
  -the value of a given variable
  +Stop at a certain point in the code, based on conditions such as the value
  +of a given variable
   
   <P><LI>
   <P>
  -Perform an action without stopping, based on the same criteria above
  +Perform an action without stopping, based on the criteria above
   
   <P><LI>
   <P>
  @@ -3031,23 +3190,26 @@
   in the long run.
   
   <P>
  -Most C and C++ programmers are familiar with the interactive GNU debugger (<CODE>gdb</CODE>). <CODE>gdb</CODE> is a stand-alone program that requires your code to be compiled with
  +Most C and C++ programmers are familiar with the interactive GNU debugger (<CODE>gdb</CODE>).  <CODE>gdb</CODE> is a stand-alone program that requires your code to be compiled with
   debugging symbols to be useful. While <CODE>gdb</CODE>
  -can be used to debug the perl interpreter program itself, it cannot be used
  -to debug your own Perl programs. Not to worry, Perl provides its own
  -interactive debugger, called <CODE>perldb</CODE>. Giving control of your Perl program to the interactive debugger is simply
  -a matter of specifying the <CODE>-d</CODE> command line switch. When this switch is used, Perl will insert debugging
  -hooks into the program syntax tree, but leaves the actual job of debugging
  -to a Perl module outside of the perl binary program itself.
  +can be used to debug the Perl interpreter itself, it cannot be used to
  +debug your Perl scripts.
  +
  +<P>
  +Not to worry, Perl provides its own interactive debugger, called
  +<CODE>perldb</CODE>. Giving control of your Perl program to the interactive debugger is simply
  +a matter of specifying the <CODE>-d</CODE> command line switch. When this switch is used, Perl inserts debugging hooks
  +into the program syntax tree, but it leaves the job of debugging to a Perl
  +module separate from the perl binary itself.
   
   <P>
  -I will start by introducing a few basic concepts and commands of the Perl
  -interactive debugger. These basic warm up examples are all run from the
  -command line, outside of the mod_perl, but are all still relevant once we
  -do go inside Apache.
  +I will start by introducing a few of the basic concepts and commands of the
  +Perl interactive debugger. These warm-up examples all run from the command
  +line, independent of mod_perl, but are all still relevant when we do
  +finally go inside Apache.
   
   <P>
  -You may want to keep the the <EM>perldebug</EM> manpage handy for reference while reading this section and for future
  +It might be useful to keep the <EM>perldebug</EM> manpage handy for reference while reading this section, and for future
   debugging sessions on your own.
   
   <P>
  @@ -3068,9 +3230,8 @@
       DB&lt;1&gt;
   </PRE>
   <P>
  -The source line shown is that which Perl is about to execute, the
  -<CODE>next</CODE> command (or just <CODE>n</CODE>) will cause this line to be executed and stop again right before the next
  -line:
  +The source line shown is the line which Perl is <EM>about</EM> to execute, the <CODE>next</CODE> command (or just <CODE>n</CODE>) will cause this line to be executed after which execution will stop again
  +just before the next line:
   
   <P>
   <PRE>  main::(-e:1):   print &quot;mod_perl rules the world&quot;
  @@ -3082,9 +3243,9 @@
     DB&lt;1&gt;
   </PRE>
   <P>
  -In this case, our example code is only one line long, so we are done
  +In this case, our example code is only one line long, so we have finished
   interacting after the first line of code is executed. Let's try again with
  -a bit longer example which is the following script:
  +slightly longer example which is the following script:
   
   <P>
   <PRE>  my $word = 'mod_perl';
  @@ -3093,7 +3254,7 @@
     print &quot;$word @array\n&quot;;
   </PRE>
   <P>
  -Save the script in a file named <EM>domination.pl</EM> and run with the
  +Save the script in a file called <EM>domination.pl</EM> and run with the
   <CODE>-d</CODE> switch:
   
   <P>
  @@ -3105,8 +3266,8 @@
       DB&lt;1&gt;
   </PRE>
   <P>
  -At this point, the first line of code has been executed and the variable <CODE>$word</CODE> has been assigned to the value <EM>mod_perl</EM>. We can check that assumption by using the <CODE>p</CODE> command (a shortage for the
  -<CODE>print</CODE>, the two are interchangeable):
  +At this point, the first line of code has been executed and the variable <CODE>$word</CODE> has been assigned the value <EM>mod_perl</EM>. We can check this by using the <CODE>p</CODE> command (an abbreviation for the <CODE>print</CODE>
  +command, the two are interchangeable):
   
   <P>
   <PRE>  main::(domination.pl:2):      my @array = qw(rules the world);
  @@ -3114,9 +3275,9 @@
     mod_perl
   </PRE>
   <P>
  -The <CODE>print</CODE> command works just like the Perl's builtin <CODE>print()</CODE> function,
  +The <CODE>print</CODE> command works just like the Perl's built-in <CODE>print()</CODE> function,
   but adds a trailing newline and outputs to the <CODE>$DB::OUT</CODE>
  -file handle, which is normally opened to the terminal where perl was
  +file handle, which is normally opened on the terminal where Perl was
   launched from. Let's carry on:
   
   <P>
  @@ -3130,20 +3291,25 @@
     use O inhibit_exit to avoid stopping after program termination,
     h q, h R or h O to get additional info.  
   </PRE>
  +<P>
  +Ouch, <CODE>p @array</CODE> printed <CODE>rulestheworld</CODE> and not <CODE>rules the world</CODE>, as you might expect it to, but that's absolutely correct. If you print an
  +array without expanding it first into a string it will be printed without
  +adding the content of the <CODE>$&quot;</CODE> variable (otherwise known as
  +<CODE>$LIST_SEPARATOR</CODE> if the <CODE>English</CODE> pragma is being used) between the elements of the array.
  +
   <P>
  -Ouch, <CODE>p @array</CODE> printed <CODE>rulestheworld</CODE> and not <CODE>rules the world</CODE>, as you might expect it to, but it's absolutely normal. If you print an
  -array without expanding it first into a string it would be printed without
  -adding spaces (or other content of the <CODE>$&quot;</CODE> variable, otherwise known as <CODE>$LIST_SEPARATOR</CODE> if <CODE>English</CODE> pragma is being used.) between the members of the array. If you do:
  +If you type:
   
   <P>
   <PRE>  print &quot;@array&quot;;
   </PRE>
   <P>
  -you would get the <CODE>rules the world</CODE> output, since the default value of <CODE>$&quot;</CODE> variable is a single space.
  +the output will be <CODE>rules the world</CODE> since the default value of the
  +<CODE>$&quot;</CODE> variable is a single space.
   
   <P>
  -You should notice by now, there is some valuable information to the left of
  -each executable statement:
  +You should have noticed by now that there is some valuable information to
  +the left of each executable statement:
   
   <P>
   <PRE>  main::(domination.pl:4):      print &quot;$word @array\n&quot;;
  @@ -3151,8 +3317,9 @@
   </PRE>
   <P>
   First is the current package name, in this case <CODE>main::</CODE>. Next is the current filename and statement line number, <EM>domination.pl</EM> and 4 in the example above. The number presented at the prompt is the
  -command number which can be used to recall commands in session history,
  -with help of <CODE>!</CODE> command followed by this number. For example, <CODE>!1</CODE> would repeat the first command:
  +command number which can be used to recall commands from the session
  +history, using the <CODE>!</CODE> command followed by this number. For example,
  +<CODE>!1</CODE> would repeat the first command:
   
   <P>
   <PRE>  % perl -d -e0
  @@ -3169,9 +3336,9 @@
   
   <P>
   Things start to get more interesting as the code does. In the example
  -script below (save it in a file named <EM>test.pl</EM>) we've increased the number of source files and packages by including the
  +script below (save it to a file called <EM>test.pl</EM>) we've increased the number of source files and packages by including the
   standard
  -<CODE>Symbol</CODE> module, along with invoking its <CODE>gensym()</CODE> function:
  +<CODE>Symbol</CODE> module, along with an invocation of its <CODE>gensym()</CODE> function:
   
   <P>
   <PRE>  use Symbol ();
  @@ -3190,11 +3357,11 @@
     GLOB(0x80c7a44)
   </PRE>
   <P>
  -First, notice the debugger did not stop at the first line of the file, this
  -is because <CODE>use ...</CODE> is a compile-time statement, not a run-time statement. Also notice, there
  -was more work going on, than the debugger revealed. That's because the <CODE>next</CODE> command does not enter subroutine calls. To step into a subroutine code use
  +First, notice the debugger did not stop at the first line of the file. This
  +is because <CODE>use ...</CODE> is a compile-time statement, not a run-time statement. Also notice there
  +was more work going on than the debugger revealed. That's because the <CODE>next</CODE> command does not enter subroutine calls. To step into a subroutine code use
   the <CODE>step</CODE>
  -command (or <CODE>s</CODE>):
  +command (or its abbreviated form <CODE>s</CODE>):
   
   <P>
   <PRE>  % perl -d test.pl
  @@ -3208,8 +3375,8 @@
   <P>
   Notice the source line information has changed to the
   <CODE>Symbol::gensym</CODE> package and the <CODE>Symbol.pm</CODE> file. We can carry on by hitting the return key at each prompt, which
  -causes the debugger to repeat the last <CODE>step</CODE> or <CODE>next</CODE> command. It wouldn't repeat a
  -<CODE>print</CODE> command for example. The debugger will return out of the subroutine and
  +causes the debugger to repeat the last <CODE>step</CODE> or <CODE>next</CODE> command. It won't repeat a
  +<CODE>print</CODE> command though. The debugger will eventually return from the subroutine
   back to our main program:
   
   <P>
  @@ -3229,15 +3396,13 @@
   </PRE>
   <P>
   Our line-by-line debugging approach has served us well for this small
  -program, but imagine the time it takes to step through a large application
  -at the same pace. There are several ways to speed up a debugging session,
  -one of which is known as <EM>setting a
  -breakpoint</EM>. The <CODE>breakpoint</CODE> command (<CODE>b</CODE>) can be used for instructing the debugger to stop at a named subroutine or
  -at line of a given file. In this example session, we will set a breakpoint
  -at the
  -<CODE>Symbol::gensym</CODE> subroutine at the first prompt, telling the debugger to stop at the first
  -line of this routine when it is called. Rather than move along with <CODE>next</CODE> or <CODE>step</CODE> we enter the <CODE>continue</CODE>
  -command (<CODE>c</CODE>) which tells the debugger to execute each line without stopping until it
  +program, but imagine the time it would take to step through a large
  +application at the same pace. There are several ways to speed up a
  +debugging session, one of which is known as <EM>setting a breakpoint</EM>. The <CODE>breakpoint</CODE> command (<CODE>b</CODE>) can be used for instructing the debugger to stop at a named subroutine or
  +at any line of any file. In this example session, at the first debugger
  +prompt we will set a breakpoint at the <CODE>Symbol::gensym</CODE> subroutine, telling the debugger to stop at the first line of this routine
  +when it is called. Rather than move along with <CODE>next</CODE> or <CODE>step</CODE> we give the <CODE>continue</CODE>
  +command (<CODE>c</CODE>) which tells the debugger to execute the script without stopping until it
   reaches a breakpoint:
   
   <P>
  @@ -3252,7 +3417,7 @@
   <P>
   Now let's pretend we are debugging a large application where
   <CODE>Symbol::gensym</CODE> might be called in various places. When the subroutine breakpoint is
  -reached, the debugger does not reveal where it was called from by default.
  +reached, by default the debugger does not reveal where it was called from.
   One way to find out this information is with the <CODE>Trace</CODE> command (<CODE>T</CODE>):
   
   <P>
  @@ -3261,23 +3426,22 @@
   </PRE>
   <P>
   In this example, the call stack is only one level deep, so only that line
  -is printed, we'll look at an example with a deeper stack later. The
  -left-most character reveals the context in which the subroutine was called. <CODE>$</CODE> represents a scalar context, in others you may see <CODE>@</CODE> which represent a list context or <CODE>.</CODE>
  -which represents a void context. In our case we have called:
  +is printed. We'll look at an example with a deeper stack later. The
  +left-most character reveals the context in which the subroutine was called.  <CODE>$</CODE> represents scalar context, in other examples you may see <CODE>@</CODE> which represents list context or <CODE>.</CODE> which represents void context. In our case we have called:
   
   <P>
   <PRE>  my $sym = Symbol::gensym();
   </PRE>
   <P>
  -which calls the <CODE>Symbol::gensym()</CODE> in a scalar context.
  +which calls the <CODE>Symbol::gensym()</CODE> in scalar context.
   
   <P>
  -Below we've made our <CODE>test.pl</CODE> example a little more complex. First, we've added a <CODE>My::World</CODE> package declaration at the top of the script, so we are no longer working
  +Below we've made our <EM>test.pl</EM> example a little more complex. First, we've added a <CODE>My::World</CODE> package declaration at the top of the script, so we are no longer working
   in the <CODE>main::</CODE> package. Next, we've added a subroutine named <CODE>do_work()</CODE> which
   invokes the familiar
   <CODE>Symbol::gensym</CODE>, along with another function called
  -<CODE>Symbol::qualify</CODE> and returns a hash reference of the results. The <CODE>do_work()</CODE>
  -routine is invoked inside a <EM>for</EM> loop which will be run twice:
  +<CODE>Symbol::qualify</CODE> and then returns a hash reference of the results. The
  +<CODE>do_work()</CODE> routine is invoked inside a <EM>for</EM> loop which will be run twice:
   
   <P>
   <PRE>  package My::World;
  @@ -3305,7 +3469,7 @@
     }
   </PRE>
   <P>
  -We'll start by setting a few breakpoints and then we use <CODE>List</CODE>
  +We'll start by setting a few breakpoints and then we use the <CODE>List</CODE>
   command (<CODE>L</CODE>) to display them:
   
   <P>
  @@ -3323,22 +3487,22 @@
   </PRE>
   <P>
   The filename and line number of the breakpoint are displayed just before
  -the source line itself. Since both breakpoints located at the same file --
  -the filename is being displayed only once. After the source line we see the
  -condition on which to stop, in our case as the constant value 1 indicates,
  -we will always stop at these breakpoint. Later on you'll see how to specify
  -a certain condition.
  -
  -<P>
  -As we see, when <CODE>continue</CODE> command is executed, the normal flow of the program stops at one of these
  -breakpoints, either on line 86 or 95 of <CODE>/usr/lib/perl5/5.00503/Symbol.pm</CODE> file, whichever will be reached first. As you understand the displayed code
  -lines are the first rows of the two subroutines from <CODE>Symbol.pm</CODE>. Lines that qualify to be used as breakpoints cannot be empty lines or
  -comments, there must be a code there.
  -
  -<P>
  -In our example <CODE>List</CODE> command shows the lines the breakpoints were set on, but we cannot tell
  -which breakpoint belongs to which subroutine. There are two ways to find it
  -out. One is to run
  +the source line itself. Because both breakpoints are located in the same
  +file, the filename is displayed only once. After the source line we see the
  +condition on which to stop. In this case, as the constant value 1
  +indicates, we will always stop at these breakpoints. Later on you'll see
  +how to specify a condition.
  +
  +<P>
  +As we will see, when the <CODE>continue</CODE> command is executed, the execution of the program stops at one of these
  +breakpoints, either on line 86 or 95 of the <CODE>/usr/lib/perl5/5.00503/Symbol.pm</CODE> file, whichever is reached first. The displayed code lines are the first
  +rows of the two subroutines from <CODE>Symbol.pm</CODE>. Breakpoints may only be applied to lines of run-time executable code, you
  +cannot put breakpoints on empty lines or comments for example.
  +
  +<P>
  +In our example the <CODE>List</CODE> command shows which lines the breakpoints were set on, but we cannot tell
  +which breakpoint belongs to which subroutine. There are two ways to find
  +this out. One is to run the
   <CODE>continue</CODE> command and when it stops, execute the <CODE>Trace</CODE> command we saw before:
   
   <P>
  @@ -3350,10 +3514,12 @@
     . = My::World::do_work('now') called from file `test.pl' line 6
   </PRE>
   <P>
  -So we see that it was a <CODE>Symbol::gensym</CODE>. The other way is to ask for a listing of code at some lines range. For
  -example, let's check which subroutine line 86 is a part of. We use a <CODE>list</CODE> (lowercase!) command (<CODE>l</CODE>), which displays parts of the code. Among various arguments it accepts,
  -there is one that we want to use here, a lines range. Since the breakpoint
  -is at line 86, let's print a few lines back and forward:
  +So we see that it was <CODE>Symbol::gensym</CODE>. The other way is to ask for a listing of a range of lines from the code.
  +For example, let's check which subroutine line 86 is a part of. We use the <CODE>list</CODE>
  +(lowercase!) command (<CODE>l</CODE>), which displays parts of the code. The
  +<CODE>list</CODE> command accepts various arguments, the one that we want to use here is a
  +range of lines. Since the breakpoint is at line 86, let's print a few lines
  +above and below that line:
   
   <P>
   <PRE>    DB&lt;3&gt; l 85-87
  @@ -3362,7 +3528,7 @@
     87:         my $ref = \*{$genpkg . $name};
   </PRE>
   <P>
  -Now we know it's <CODE>gensym</CODE> sub and we also see the breakpoint displayed with help of <CODE>==&gt;b</CODE> markup. We could also use the name of the sub to display its code:
  +Now we know it's the <CODE>gensym</CODE> sub and we also see the breakpoint displayed with the help of the <CODE>==&gt;b</CODE> markup. We could also use the name of the sub to display its code:
   
   <P>
   <PRE>    DB&lt;4&gt; l Symbol::gensym
  @@ -3374,14 +3540,14 @@
     90      }
   </PRE>
   <P>
  -The <CODE>delete</CODE> command (<CODE>d</CODE>) is used to remove certain breakpoints by specifying the line number of
  -the breakpoint. Let's remove the first one:
  +The <CODE>delete</CODE> command (<CODE>d</CODE>) is used to remove a breakpoint by specifying the line number of the
  +breakpoint. Let's remove the first one:
   
   <P>
   <PRE>    DB&lt;5&gt; d 95
   </PRE>
   <P>
  -The <CODE>Delete</CODE> command (with a capital `D') or <CODE>d</CODE> removes all currently installed breakpoints.
  +The <CODE>Delete</CODE> command (with a capital `D') or <CODE>D</CODE> removes all currently installed breakpoints.
   
   <P>
   Now let's look again at the trace produced at the breakpoint:
  @@ -3397,9 +3563,8 @@
   <P>
   As you can see, the stack trace prints the values which are passed into the
   subroutine. Ah, and perhaps we've found our first bug, as we can see
  -<CODE>do_work()</CODE> was called in a void context, so the return value
  -was lost into thin air. Let's change the for loop logic to check the return
  -value of <CODE>do_work():</CODE>
  +<CODE>do_work()</CODE> was called in void context, so the return value was
  +lost into thin air. Let's change the <EM>'for'</EM> loop to check the return value of <CODE>do_work():</CODE>
   
   <P>
   <PRE>  for (1,2) {
  @@ -3422,8 +3587,9 @@
       DB&lt;2&gt;
   </PRE>
   <P>
  -Our program is still small, but it is getting more difficult to understand
  -the context of just one line of code, the <CODE>window</CODE> command (<CODE>w</CODE>) will list the first few lines of code that surround the current line:
  +Our program is still small, but already it is getting more difficult to
  +understand the context of just one line of code. The <CODE>window</CODE>
  +command (<CODE>w</CODE>) will list a few lines of code that surround the current line:
   
   <P>
   <PRE>    DB&lt;2&gt; w
  @@ -3440,8 +3606,8 @@
   </PRE>
   <P>
   The arrow points to the line which is about to be executed and also
  -contains a <CODE>'b'</CODE> indicating we have set a breakpoint at this line. The breakable lines of
  -code include a <CODE>`:'</CODE> just after the line number.
  +contains a <CODE>'b'</CODE> indicating that we have set a breakpoint at this line. The breakable lines
  +of code include a <CODE>`:'</CODE> immediately after the line number.
   
   <P>
   Now, let's take a look at the value of the <CODE>$stuff</CODE> variable with the trusty old <CODE>print</CODE> command:
  @@ -3451,7 +3617,9 @@
     HASH(0x82b89b4)
   </PRE>
   <P>
  -That's not very useful information. Remember, the <CODE>print</CODE> command works just as the built-in <CODE>print()</CODE> function does. The <CODE>x</CODE> command evaluates a given expression and prints the results in a ``pretty''
  +That's not very useful information. Remember, the <CODE>print</CODE> command works just like the built-in <CODE>print()</CODE> function does.
  +The debugger's
  +<CODE>x</CODE> command evaluates a given expression and prints the results in a ``pretty''
   fashion:
   
   <P>
  @@ -3462,7 +3630,7 @@
        'var' =&gt; 'My::World::now'
   </PRE>
   <P>
  -There, things seem to be okay, lets double check by calling
  +There, things seem to be okay, let's double check by calling
   <CODE>do_work()</CODE> with a different value and print the results:
   
   <P>
  @@ -3510,12 +3678,13 @@
   </PRE>
   <P>
   There are only two arguments in the list, so stopping to look at each one
  -isn't too time consuming, but consider the debugging pace with a large list
  -of 100 or so entries. It is possible to customize breakpoints by specifying
  -a condition. Each time a breakpoint is reached, the condition is evaluated,
  -stopping only if the condition is true. In the session below the <CODE>window</CODE> command shows breakable lines and we set a breakpoint at line 7 with the
  +isn't too time consuming, but consider the debugging pace if we had a large
  +list of 100 or so entries. It is possible to customize breakpoints by
  +specifying a condition. Each time a breakpoint is reached, the condition is
  +evaluated, stopping only if the condition is true. In the session below,
  +the <CODE>window</CODE> command shows breakable lines and we set a breakpoint at line 7 with the
   condition <CODE>$arg eq
  -'later'</CODE>. As we continue, the breakpoint is skipped when <CODE>$arg</CODE> has the value of <EM>now</EM> and stops when it has the value of <EM>later</EM>:
  +'later'</CODE>. As we continue, the breakpoint is skipped when <CODE>$arg</CODE> has the value of <EM>now</EM> but not when it has the value of <EM>later</EM>:
   
   <P>
   <PRE>  % perl -d test.pl
  @@ -3534,7 +3703,7 @@
     11      }
   </PRE>
   <P>
  -<CODE>==&gt;</CODE> symbol shows us the line of the code that's about to be executed.
  +The <CODE>==&gt;</CODE> symbol shows us the line of code that's about to be executed.
   
   <P>
   <PRE>    DB&lt;1&gt; b 7 $arg eq 'later'
  @@ -3554,82 +3723,89 @@
   </PRE>
   <P>
   There are plenty more tricks left to pull from the perldb bag, but you
  -should understand enough about the debugger to try them on your own with
  -the perldebug manpage by your side. A quick online help can be reached by
  -typing a <CODE>h</CODE> command. It will display a list of most useful commands and a short
  -explanation of what they are doing.
  +should now understand enough about the debugger to try them on your own
  +with the perldebug manpage by your side. Quick online help from inside the
  +debugger can be reached by typing the <CODE>h</CODE> command. It will display a list of the most useful commands and a short
  +explanation of what they do.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Interactive_Perl_Debugging_under">Interactive Perl Debugging under mod_cgi</A></H2></CENTER>
   <P>
  -<CODE>Devel::ptkdb</CODE> is a visual Perl debugger that uses perlTk for a user interface.
  +<CODE>Devel::ptkdb</CODE> is a visual Perl debugger that uses perlTk for the user interface and
  +requires a windows system like X-Windows or Windows to run.
   
   <P>
  -To debug plain perl script with it, invoke it as:
  +To debug a plain perl script with ptkdb, invoke it as:
   
   <P>
   <PRE>  % perl -d:ptkdb myscript.pl
   </PRE>
   <P>
  -A Tk application will be loaded. Now you can do most of the debugging you
  -did with command line standard Perl debugger, but using a simple GUI to
  -set/remove breakpoints, browse the code, step thru it and more.
  +The Tk application will be loaded. Now you can do most of the debugging you
  +did with the command line Perl debugger, but using a simple GUI to
  +set/remove breakpoints, browse the code, step through it and more.
   
   <P>
  -With help of ptkdb you can debug your CGI scripts running under mod_cgi. Be
  -sure that that your web server's perl installation includes Tk package. In
  -order to enable the debugger you should change your:
  +With the help of ptkdb you can debug your CGI scripts running under
  +mod_cgi. Be sure that the web server's Perl installation includes the Tk
  +package. In order to enable the debugger you should change your ``shebang''
  +line from
   
   <P>
  -<PRE>  #! /usr/local/bin/perl -wT
  +<PRE>  #! /usr/local/bin/perl -Tw
   </PRE>
   <P>
   to
   
   <P>
  -<PRE>  #! /usr/local/bin/perl -wTd:ptkdb
  +<PRE>  #! /usr/local/bin/perl -Twd:ptkdb
   </PRE>
   <P>
  -You can debug scripts remotely if you're using a Unix based server and
  -where you are authoring the script has an Xserver. The Xserver can be
  -another Unix workstation, a Macintosh or Win32 platform with an appropriate
  -XWindows package. In your script insert the following
  -<CODE>BEGIN</CODE> subroutine:
  +You can debug scripts remotely if you're using a Unix based server and if
  +the machine where you are writing the script has an X-server. The X-server
  +can be another Unix workstation, or a Macintosh or Win32 platform with an
  +appropriate X-Windows package. You must insert the following <CODE>BEGIN</CODE> subroutine into your script:
   
   <P>
  -<PRE>  sub BEGIN {
  +<PRE>  BEGIN {
       $ENV{'DISPLAY'} = &quot;myHostname:0.0&quot; ;
     }
   </PRE>
   <P>
  -You can use either IP (<EM>123.123.123.123:0.0</EM>) or DNS convention (<EM>myhost.com:0.0</EM>). Be sure that your web server has permission to open windows on your
  -Xserver (see the <EM>xhost</EM> manpage for more info).
  +You can use either the IP (<EM>123.123.123.123:0.0</EM>) or the DNS convention (<EM>myhost.com:0.0</EM>). You must be sure that your web server has permission to open windows on
  +your X-server (see the <EM>xhost</EM>
  +manpage for more info).
   
   <P>
  -Access your web page with your browser and <EM>Submit</EM> the script as normal. The ptkdb window should appear on your monitor if you
  -have set correctly the <CODE>$ENV{'DISPLAY'}</CODE> variable. At this point you can start debugging your script. Be aware that
  -your browser may timeout waiting for the script to run.
  +Access the web page with the browser and <EM>Submit</EM> the script as normal. The ptkdb window should appear on the monitor if you
  +have correctly set the <CODE>$ENV{'DISPLAY'}</CODE> variable. At this point you can start debugging your script. Be aware that
  +the browser may timeout waiting for the script to run.
   
   <P>
  -To expedite debugging you may want to setup your breakpoints in advance
  -with a <EM>.ptkdbrc</EM> file and use the <CODE>$DB::no_stop_at_start</CODE>
  -variable. NOTE: for debugging web scripts you may have to have the
  -<EM>.ptkdbrc</EM> file installed in the server account's home directory (~www) or whatever
  -username your webserver is running under. Also try installing a <EM>.ptkdbrc</EM> file in the same directory as the target script.
  +To expedite debugging you may want to set your breakpoints in advance with
  +a <EM>.ptkdbrc</EM> file and use the <CODE>$DB::no_stop_at_start</CODE> variable. NOTE: for debugging web scripts you may have to have the <EM>.ptkdbrc</EM>
  +file installed in the server account's home directory (~www) or whatever
  +username the webserver is running under. Also try installing a <EM>.ptkdbrc</EM> file in the same directory as the target script.
   
   <P>
   META: insert snapshots of ptkdb screen
   
   <P>
  +ptkdb is not part of the standard perl distribution; it is available from
  +CPAN: <A
  +HREF="http://www.perl.com/CPAN/authors/id/A/AE/AEPAGE/">http://www.perl.com/CPAN/authors/id/A/AE/AEPAGE/</A>
  + 
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Non_Interactive_Perl_Debugging_u">Non-Interactive Perl Debugging under mod_perl</A></H2></CENTER>
   <P>
   To debug scripts running under mod_perl either use <A HREF="././debug.html#Interactive_mod_perl_Debugging">Apache::DB (interactive Perl debugging)</A> or an older non-interactive method as described below.
   
   <P>
  -<CODE>NonStop</CODE> debugger option enables us to get some decent debug info when running under
  -mod_perl. For example, before starting the server:
  +The <CODE>NonStop</CODE> debugger option enables you to get some decent debugging information when
  +running under mod_perl. For example, before starting the server:
   
   <P>
   <PRE>  % setenv PERL5OPT -d
  @@ -3638,8 +3814,7 @@
   <P>
   Now watch db.out for line:filename info. This is most useful for tracking
   those core dumps that normally leave us guessing, even with a stack trace
  -from gdb. db.out will show you what Perl code triggered the core. 'man
  -perldebug' for more <CODE>PERLDB_OPTS</CODE>. Note, Perl will ignore <CODE>PERL5OPT</CODE> if <CODE>PerlTaintCheck</CODE> is <CODE>On</CODE>.
  +from gdb.  <EM>db.out</EM> will show you what Perl code triggered the core dump.  <EM>'man perldebug'</EM> for more <CODE>PERLDB_OPTS</CODE>. Note that Perl will ignore <CODE>PERL5OPT</CODE> if <CODE>PerlTaintCheck</CODE> is <CODE>On</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -3650,14 +3825,14 @@
   
   <P>
   The server must be run in non-forking mode to use the interactive debugger,
  -this mode is turned on by passing the <CODE>-X</CODE> flag to httpd executable. It is convenient to use an <CODE>IfDefine</CODE> section around the
  -<CODE>Apache::DB</CODE> configuration, the example below does this using the name <EM>PERLDB</EM>. With this setup, debugging is only turned on when starting the server
  -with <CODE>httpd -D PERLDB</CODE> command.
  +this mode is turned on by passing the <CODE>-X</CODE> flag to the httpd executable. It is convenient to use an <CODE>IfDefine</CODE> section around the <CODE>Apache::DB</CODE> configuration, the example below does this using the name <EM>PERLDB</EM>. With this setup, debugging is only turned on when starting the server
  +with the <CODE>httpd -D PERLDB</CODE> command.
   
   <P>
  -This section should be at the top of your perl configuration section of the
  -configuration file, before any Perl code is pulled in, so debugging symbols
  -will be inserted into the syntax tree, triggered by the call to <CODE>Apache::DB-&gt;init</CODE>. The <CODE>Apache::DB::handler</CODE> can be configured using any of the <CODE>Perl*Handler</CODE> directives, in this case we use a <CODE>PerlFixupHandler</CODE> so handlers in the response phase will bring up the debugger prompt:
  +This section should be at the top of the Perl configuration section of the
  +configuration file, before any other Perl code is pulled in, so that
  +debugging symbols will be inserted into the syntax tree, triggered by the
  +call to <CODE>Apache::DB-&gt;init</CODE>. The <CODE>Apache::DB::handler</CODE> can be configured using any of the <CODE>Perl*Handler</CODE> directives, in this case you use a <CODE>PerlFixupHandler</CODE> so handlers in the response phase will bring up the debugger prompt:
   
   <P>
   <PRE>  &lt;IfDefine PERLDB&gt;
  @@ -3674,14 +3849,13 @@
     &lt;/IfDefine&gt;
   </PRE>
   <P>
  -Since we have used <CODE>/</CODE> as an argument to <CODE>Location</CODE> directive, the debugger will be invoked for any kind of requests (even for
  -static objects (images, static documents), but of course it would
  -immediately quit, unless there is some perl module registered to handle
  -these static objects).
  +Since we have used <CODE>/</CODE> as the argument to the <CODE>Location</CODE> directive, the debugger will be invoked for any kind of request (even for
  +static documents and images) but of course it will immediately quit unless
  +there is some Perl module registered to handle these requests.
   
   <P>
   In our first example, we will debug the standard <CODE>Apache::Status</CODE>
  -module, which is configured like so:
  +module, which is configured like this:
   
   <P>
   <PRE>  PerlModule Apache::Status
  @@ -3703,11 +3877,10 @@
   in our case to <A
   HREF="http://localhost/perl-status.">http://localhost/perl-status.</A> Once
   we are at the prompt, all the standard debugging commands are available.
  -First we run the window for some context of the code being debugged, move
  -to the next statement after <CODE>$r</CODE> has been assigned to and print the request URI. If no breakpoints are set,
  -the continue command will give control back to Apache and the request will
  -finish with the
  -<CODE>Apache::Status</CODE> main menu showing up in the browser window:
  +First we run window to get some of the context for the code being debugged,
  +then we move to the next statement after a value has been assigned to
  +<CODE>$r</CODE>, and finally we print the request URI. If no breakpoints are set, the <CODE>continue</CODE> command will give control back to Apache and the request will finish with
  +the <CODE>Apache::Status</CODE> main menu showing in the browser window:
   
   <P>
   <PRE>  Loading DB routines from perl5db.pl version 1.0402
  @@ -3755,8 +3928,9 @@
   <P>
   When a request is issued, the debugger stops at line 28 of
   <EM>Apache/Registry.pm</EM>. We set a breakpoint at line 140, which is the line that actually calls
  -the script wrapper subroutine. The continue command will bring us to that
  -line, where we can step into the script handler:
  +the script wrapper subroutine. The
  +<CODE>continue</CODE> command will bring us to that line, where we can step into the script
  +handler:
   
   <P>
   <PRE>  Apache::Registry::handler(/usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm:28):
  @@ -3787,7 +3961,8 @@
   
   <P>
   <PRE>    DB&lt;4&gt; w
  -  1:      package Apache::ROOT::perl::test_2epl;use Apache qw(exit);sub handler {  use strict;
  +  1:      package Apache::ROOT::perl::test_2epl;use Apache qw(exit);
  +  sub handler {  use strict;
     2 
     3:        my $r = shift;
     4==&gt;      $r-&gt;send_http_header('text/plain');
  @@ -3804,16 +3979,16 @@
   <P>
   It will always take some practice and patience when putting together
   debugging strategies that make effective use of the interactive debugger
  -for various situations. Once you do have a good strategy in mind, bug
  -squashing can actually be quite a bit of fun!
  +for various situations. Once you have a good strategy, bug squashing can
  +actually be quite a bit of fun!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="ptkdb_and_Interactive_mod_perl_D">ptkdb and Interactive mod_perl Debugging</A></H2></CENTER>
   <P>
  -Well as you we saw earlier you can use a <CODE>ptkdb</CODE> visual debugger to debug CGI scripts running under mod_cgi. It wouldn't
  -work for mod_perl though using the same configuration as used in mod_cgi.
  -We have to tweak the <EM>Apache/DB.pm</EM> module to use <EM>Devel/ptkdb.pm</EM> instead of
  +As you saw earlier you can use the <CODE>ptkdb</CODE> visual debugger to debug CGI scripts running under mod_cgi. But it won't
  +work for mod_perl using the same configuration as used in mod_cgi. We have
  +to tweak the <EM>Apache/DB.pm</EM> module to use <EM>Devel/ptkdb.pm</EM> instead of
   <EM>Apache/perl5db.pl</EM>.
   
   <P>
  @@ -3830,21 +4005,22 @@
   </PRE>
   <P>
   Now when you use the interactive mod_perl debugger configuration from the
  -previous section and issue a request, a <EM>ptkdb</EM> visual debugger will be loaded.
  +previous section and issue a request, the <EM>ptkdb</EM> visual debugger will be loaded.
   
   <P>
  -If you are debugging <CODE>Apache::Registry</CODE> scripts, exactly like in the terminal debugging mode example, you should go
  -to the line 140 or whatever line the <CODE>eval { &amp;{$cv}($r, @_) } if $r-</CODE>seqno;&gt; located and to &lt;step in&gt; to enter your script.
  +If you are debugging <CODE>Apache::Registry</CODE> scripts, as in the terminal debugging mode example, go to line 140 (or to
  +whatever line the <CODE>eval
  +{ &amp;{$cv}($r, @_) } if $r-</CODE>seqno;&gt; statement is located) and press the &lt;step in&gt; button to
  +start the debug of the script itself.
   
   <P>
  -Note, that you can work with ptkdb in plain multi-server mode, so you don't
  -have to start the server with <CODE>-X</CODE> option.
  +Note that you can use Apache with <CODE>ptkdb</CODE> in plain multi-server mode, you don't have to start <CODE>httpd</CODE> with the <CODE>-X</CODE> option.
   
   <P>
   META: One caveat:
   
   <P>
  -* When the request is completed, <CODE>ptkdb</CODE> would hang. Anyone knows what code should be registered for it to exit on
  +When the request is completed, <CODE>ptkdb</CODE> hangs. Does anyone know what code should be registered for it to exit on
   completion? To replace the original <CODE>Apache::DB</CODE> cleanup code, as:
   
   <P>
  @@ -3863,10 +4039,10 @@
   <CENTER><H2><A NAME="Debugging_when_Server_Crashes_on">Debugging when Server Crashes on Startup before Writing to Log File.</A></H2></CENTER>
   <P>
   If your server crashes on startup, you need to start it under gdb and ask
  -it to generate the stack trace.
  +it to generate a stack trace.
   
   <P>
  -I'll emulate a faulty server by starting a startup file with
  +I'll emulate a faulty server by starting a startup file with the
   <CODE>dump()</CODE> command:
   
   <P>
  @@ -3876,14 +4052,14 @@
     1;
   </PRE>
   <P>
  -and requiring this file from the <EM>httpd.conf</EM>:
  +and then requiring this file from the <EM>httpd.conf</EM>:
   
   <P>
   <PRE>  PerlRequire /path/to/startup.pl
   </PRE>
   <P>
   Make sure no server is running on port 80 or use an alternate config with
  -an alternate port if you are on a production server.
  +an alternate port if using a production server.
   
   <P>
   <PRE>  % gdb /path/to/httpd
  @@ -3896,7 +4072,7 @@
   <PRE>  set args -X -f /path/to/alternate/serverconfig_ifneeded.conf
   </PRE>
   <P>
  -if you want the server to start from an alternative configuration file.
  +if the server must be started from an alternative configuration file.
   
   <P>
   Now run the program:
  @@ -3910,8 +4086,8 @@
     0x400da4e1 in __kill () from /lib/libc.so.6
   </PRE>
   <P>
  -At this point the server should die (because of <CODE>dump())</CODE> and
  -when it happens we ask for a stack trace (using <CODE>bt</CODE> or <CODE>where</CODE> commands):
  +At this point the server should die because of the call to
  +<CODE>dump().</CODE> When that happens we use <CODE>bt</CODE> or <CODE>where</CODE> to ask for a stack back trace.
   
   <P>
   <PRE>  (gdb) where
  @@ -3937,13 +4113,15 @@
         at ../sysdeps/generic/libc-start.c:90
   </PRE>
   <P>
  -If you are clueless of what this trace say, send it to the mod_perl mailing
  -list. Make sure to include versions of apache, mod perl and perl.
  +If you do not know what this trace means, you could send it to the mod_perl
  +mailing list to ask for help. Make sure to include the version numbers of
  +Apache, mod_perl and Perl, and use a subject line that says something about
  +the problem rather than 'help'.
   
   <P>
  -In our case we already know that server is supposed to die when compiling
  -the startup file and we can clearly see that from the trace. We always read
  -it from its end upward:
  +In our case we already know that the server is supposed to die when
  +compiling the startup file and we can clearly see that from the trace. We
  +always read it from the bottom upward:
   
   <P>
   We are in config file:
  @@ -3984,33 +4162,32 @@
   
   <P>
   mod_perl comes with a number of useful of gdb macros to ease the debug
  -process . You will find the file with macros at mod_perl source
  -distribution in <EM>.gdbinit</EM> file (mod_perl-x.xx/.gdbinit). You might want to modify the macros
  -definittions.
  +process. You will find the file with macros in the mod_perl source
  +distribution in the <EM>.gdbinit</EM> file (mod_perl-x.xx/.gdbinit). You might want to modify the macro
  +definitions.
   
   <P>
   In order to use this you need to compile mod_perl with
   <CODE>PERL_DEBUG=1</CODE>.
   
   <P>
  -To debug the server, start it :
  +To debug the server, start it:
   
   <P>
   <PRE>  % httpd -X
   </PRE>
   <P>
  -Issue a request to offending script that hangs. Find the PID number of the
  -process that hangs.
  +Issue a request to the offending script that hangs. Find the PID number of
  +the process that hangs.
   
   <P>
  -Go to the root of the server:
  +Go to the server root:
   
   <P>
   <PRE>  % cd /usr/local/apache
   </PRE>
   <P>
  -Now attach to it with gdb (replace PID with actual PID number) and load the
  -macros from <EM>.gdbinit</EM>:
  +Now attach to it with gdb (replace the <CODE>PID</CODE> with the actual process id) and load the macros from <EM>.gdbinit</EM>:
   
   <P>
   <PRE>  % gdb /path/to/httpd PID
  @@ -4032,7 +4209,7 @@
   It should tell you the line/filename of the offending Perl code.
   
   <P>
  -Add this to the .gdbinit:
  +Add this to <EM>.gdbinit</EM>:
   
   <P>
   <PRE>  define longmess
  @@ -4067,15 +4244,15 @@
   <P>
   With Apache versions 1.3.0 and higher, mod_perl will call the
   <CODE>perl_destruct()</CODE> Perl API function during the child exit phase.
  -This will cause proper execution of <STRONG>END</STRONG> blocks found during server startup along with invoking the <STRONG>DESTROY</STRONG> method on global objects who are still alive.
  +This will cause proper execution of <CODE>END</CODE> blocks found during server startup and will invoke the <CODE>DESTROY</CODE> method on global objects which are still alive.
   
   <P>
   It is possible that this operation may take a long time to finish, causing
  -problems during a restart. If your code does not contain and
  -<STRONG>END</STRONG> blocks or <STRONG>DESTROY</STRONG> methods which need to be run during child server shutdown, this destruction
  +problems during a restart. If your code does not contain any
  +<CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, this destruction
   can be avoided by setting the
  -<EM>PERL_DESTRUCT_LEVEL</EM> environment variable to <CODE>-1</CODE>, which will cause mod_perl to skip the call to
  -<CODE>perl_destruct()</CODE> in <CODE>perl_shutdown().</CODE>
  +<CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to <CODE>-1</CODE>. This will cause mod_perl to skip the call to <CODE>perl_destruct()</CODE>
  +in <CODE>perl_shutdown().</CODE>
   
   <P>
   It is only usable if no significant cleanup has to be done by perl
  @@ -4085,10 +4262,13 @@
   transactions is significant but closing an ordinary file isn't.
   
   <P>
  -Enabling <CODE>PERL_DESTRUCT_LEVEL=-1</CODE> speeds the server restart or termination and leads to more robust operation
  -in the face of problems, like running out of memory. If set--
  +Setting <CODE>PERL_DESTRUCT_LEVEL=-1</CODE> speeds the server restart or termination and leads to more robust operation
  +in the face of problems like running out of memory. If set--
   
   <P>
  +META: to be continued
  +
  +<P>
   You can also use <CODE>-DPERL_DESTRUCT_LEVEL</CODE>.
   
   <P>
  @@ -4121,15 +4301,15 @@
     Apache::Debug::dump($r, SERVER_ERROR, &quot;Uh Oh!&quot;);
   </PRE>
   <P>
  -This module sends what may be helpful debugging info to the client rather
  -that the error log.
  +This module sends what may be helpful debugging information to the client
  +rather than to <EM>error_log</EM>.
   
   <P>
   Also, you could try using a larger emergency pool, try this instead of
   Apache::Debug:
   
   <P>
  -<PRE> $^M = 'a' x (1&lt;&lt;18);  #260K buffer
  +<PRE> $^M = 'a' x (1&lt;&lt;18);  #256k buffer
    use Carp ();
    $SIG{__DIE__} = \&amp;Carp::confess;
    eval { Carp::confess(&quot;init&quot;) };
  @@ -4138,7 +4318,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Debug_Tracing">Debug Tracing</A></H1></CENTER>
   <P>
  -To enable mod_perl debug tracing configure mod_perl with the PERL_TRACE
  +To enable mod_perl debug tracing, configure mod_perl with the PERL_TRACE
   option:
   
   <P>
  @@ -4162,8 +4342,8 @@
   <PRE>  PerlSetVar MOD_PERL_TRACE all
   </PRE>
   <P>
  -For example if you want to see a trace of the PerlRequire's and
  -PerlModule's as they are loaded, use:
  +For example if you want to see a trace of the PerlRequire and PerlModule
  +directives as they are executed, use:
   
   <P>
   <PRE>  PerlSetVar MOD_PERL_TRACE d
  @@ -4172,8 +4352,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A></H1></CENTER>
   <P>
  -As you know you need an unstriped executable to be able to debug it. While
  -you can compile the mod_perl with <CODE>-g</CODE> (or <CODE>PERL_DEBUG=1</CODE>) the apache <CODE>install</CODE> strips the symbols.
  +As you know you need an unstripped executable to be able to debug it. While
  +you can compile mod_perl with <CODE>-g</CODE> (or <CODE>PERL_DEBUG=1</CODE>), the Apache <CODE>install</CODE> strips the symbols.
   
   <P>
   Makefile.tmpl contains a line:
  @@ -4188,47 +4368,45 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A></H1></CENTER>
   <P>
  -Current perl implementation does not restore the original apache's C
  -handler when you use <CODE>local $SIG{FOO}</CODE> clause. While save/restore of
  -<CODE>$SIG{ALRM}</CODE> was fixed in the mod_perl 1.19_01 (CVS version), other signals are not yet
  +The current Perl implementation does not restore the original Apache C
  +handler when you use the <CODE>local $SIG{FOO}</CODE> clause. While the save/restore of <CODE>$SIG{ALRM}</CODE> was fixed in mod_perl 1.19_01 (CVS version), other signals are not yet
   fixed. The real fix should probably be in Perl itself.
   
   <P>
  -Until recent <CODE>local $SIG{ALRM}</CODE> restored the <CODE>SIGALRM</CODE> handler to Perl's handler, not the handler it was in the first place
  -(apache's
  -<CODE>alrm_handler()</CODE>). if you build mod_perl with <CODE>PERL_TRACE=1</CODE> and set the <CODE>MOD_PERL_TRACE</CODE> environment variable to <STRONG>g</STRONG>, you will see this in the <CODE>error_log</CODE> file:
  +Until recently <CODE>local $SIG{ALRM}</CODE> restored the <CODE>SIGALRM</CODE> handler to Perl's handler, not the handler it was in the first place
  +(Apache's
  +<CODE>alrm_handler()</CODE>). If you build mod_perl with <CODE>PERL_TRACE=1</CODE> and set the <CODE>MOD_PERL_TRACE</CODE> environment variable to <STRONG>g</STRONG>, you will see this in the <EM>error_log</EM> file:
   
   <P>
   <PRE>  mod_perl: saving SIGALRM (14) handler 0x80b1ff0
     mod_perl: restoring SIGALRM (14) handler from: 0x0 to: 0x80b1ff0
   </PRE>
   <P>
  -If nobody touched <CODE>$SIG{ALRM}</CODE>, <CODE>0x0</CODE> would be the same address as the others.
  +If nobody has touched <CODE>$SIG{ALRM}</CODE>, <CODE>0x0</CODE> will be the same address as the others.
   
   <P>
  -If you work with signal handlers take a look at <CODE>Sys::Signal</CODE> module, which solves the problem:
  +If you work with signal handlers you should take a look at the
  +<CODE>Sys::Signal</CODE> module, which solves the problem:
   
   <P>
  -<CODE>Sys::Signal</CODE> - Set signal handlers with restoration of existing C sighandler. Get it
  -from the CPAN.
  +<CODE>Sys::Signal</CODE> - Set signal handlers with restoration of the existing C sighandler. Get it
  +from CPAN.
   
   <P>
  -The usage is simple, if the original code was:
  +The usage is simple. If the original code was:
   
   <P>
  -<PRE>  eval {
  +<PRE>  # If a timeout happens and C&lt;SIGALRM&gt; is thrown, the alarm() will be
  +  # reset, otherwise C&lt;alarm 0&gt; is reached and timer is reset as well.
  +  eval {
       local $SIG{ALRM} = sub { die &quot;timeout\n&quot; };
       alarm $timeout;
       ... db stuff ...
       alarm 0;
     };
  -   
     die $@ if $@;
   </PRE>
   <P>
  -If a timeout happens and <CODE>SIGALRM</CODE> is thrown, the <CODE>alarm()</CODE> will be reset, otherwise <CODE>alarm 0</CODE> is reached and timer is being reset as well.
  -
  -<P>
   Now you would write:
   
   <P>
  @@ -4237,18 +4415,19 @@
       my $h = Sys::Signal-&gt;set(ALRM =&gt; sub { die &quot;timeout\n&quot; });
       alarm $timeout;
       ... do something that may timeout ...
  -      alarm 0;
  +    alarm 0;
     };
     die $@ if $@;
   </PRE>
   <P>
  -Note that this example was written before <CODE>$SIG{ALRM}</CODE> was internally fixed. So you don't need to use <CODE>Sys::Signal</CODE> with <CODE>$SIG{ALRM}</CODE>. 
  +This should be fixed in Perl 5.6.1, so if you use this version of Perl,
  +chances are that you don't need to use <CODE>Sys::Signal</CODE>.
   
   <P>
  -mod_perl is only trying to deal with those that cause conflict with
  -Apache's. Currently it's only <CODE>SIGALRM</CODE>. If you've found another one that makes you troubles, add it to the list
  -in <EM>perl_config.c</EM> after
  -<EM>"ALRM"</EM>, before <EM>NULL</EM>.
  +mod_perl tries to deal only with those signals that cause conflict with
  +Apache's. Currently this is only <CODE>SIGALRM</CODE>. If there is another one that gives you trouble, you can add it to the
  +list in
  +<EM>perl_config.c</EM> after <EM>"ALRM"</EM>, before <EM>NULL</EM>.
   
   <P>
   <PRE>  static char *sigsave[] = { &quot;ALRM&quot;, NULL };
  @@ -4265,7 +4444,7 @@
   <CODE>Devel::DProf</CODE> module available on CPAN. However, you must have apache version 1.3b3 or
   higher and the <CODE>PerlChildExitHandler</CODE>
   enabled. When the server is started, <CODE>Devel::DProf</CODE> installs an
  -<CODE>END</CODE> block to write the <CODE>tmon.out</CODE> file, which will be run when the server is shutdown. Here's how to start
  +<CODE>END</CODE> block (to write the <CODE>tmon.out</CODE> file) which will be run when the server is shutdown. Here's how to start
   and stop a server with the profiler enabled:
   
   <P>
  @@ -4288,9 +4467,9 @@
   Devel::Peek - A data debugging tool for the XS programmer
   
   <P>
  -Let's see an example of Perl allocating buffer size only once, regardless
  -of <CODE>my()</CODE> scoping, although it will <CODE>realloc()</CODE> if
  -the size is &gt;
  +Let's see an example of Perl allocating a buffer only once, regardless of
  +<CODE>my()</CODE> scoping, although it will <CODE>realloc()</CODE> if the
  +size is &gt;
   <CODE>SvLEN</CODE>:
   
   <P>
  @@ -4327,14 +4506,12 @@
       CUR = 0
   </PRE>
   <P>
  -We can see that on subsequent calls (after the first one) <CODE>$sv</CODE>
  -already has a preallocated memory.
  +We can see that on the second and subsequent calls <CODE>$sv</CODE> already has preallocated memory.
   
   <P>
  -so, if you can afford the memory, the larger the buffer means less
  -<CODE>brk()</CODE> syscalls. if you watch that example with strace, you will only see calls to <CODE>brk()</CODE> in the first time through the loop. So, this is a case where you module
  -might want to pre-allocate the buffer for example for LWP, a file scope
  -lexical, like so:
  +So, if you can afford the memory, a larger buffer means fewer <CODE>brk()</CODE>
  +syscalls. If you watch that example with <CODE>strace</CODE> you will only see calls to <CODE>brk()</CODE> the first time through the loop. So this is a case where your module might
  +want to pre-allocate the buffer like this:
   
   <P>
   <PRE>  package Your::Proxy;
  @@ -4342,14 +4519,18 @@
     my $buffer = ' ' x 100_000;
     $buffer = &quot;&quot;;
   </PRE>
  +<P>
  +Now only the parent has to <CODE>brk()</CODE> at server startup, each child
  +already will already have an allocated buffer. Just reset to ``'' when you
  +are done.
  +
   <P>
  -This way, only the parent has to <CODE>brk()</CODE> at server startup, each
  -child already will already have an allocated buffer, just reset to ``'',
  -when you are done.
  +Note: Preallocating a scalar in this way saves reallocation in v5.005 but
  +may not do so in other versions.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A></H1></CENTER>
  +<CENTER><H1><A NAME="How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A></H1></CENTER>
   <P>
   <CODE>Apache::Leak</CODE> (derived from <CODE>Devel::Leak</CODE>) should help you with this task. Example:
   
  @@ -4364,10 +4545,9 @@
     };
   </PRE>
   <P>
  -The argument to <CODE>leak_test()</CODE> is an anonymous sub, so you can just throw it around any code you suspect
  -might be leaking. Beware, it will run the code twice, because the first
  -time in, new <CODE>SV</CODE>s are created, but does not mean you are leaking, the second pass will give
  -better evidence. You do not need to be inside mod_perl to use it, from the
  +The argument to <CODE>leak_test()</CODE> is an anonymous sub, so you can just throw it any code you suspect might be
  +leaking. Beware, it will run the code twice! The first time in, new <CODE>SV</CODE>s are created, but does not mean you are leaking. The second pass will give
  +better evidence. You do not need to be inside mod_perl to use it. From the
   command line, the above script outputs:
   
   <P>
  @@ -4380,20 +4560,18 @@
     !!! 2 SVs leaked !!!
   </PRE>
   <P>
  -Build a debuggable perl to see dumps of the <CODE>SV</CODE>s. The simple way to have both a normal perl and debuggable perl, is to
  +Build a debuggable Perl to see dumps of the <CODE>SV</CODE>s. The simple way to have both a normal Perl and debuggable Perl is to
   follow hints in the
  -<CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>, when that is built copy the
  -<CODE>perl</CODE> from that directory to your perl bin directory, but name it
  -<CODE>dperl</CODE>.
  +<CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>. When that is built, copy the <CODE>perl</CODE> from that directory to your Perl bin directory, but name it <CODE>dperl</CODE>.
   
   <P>
   Leak explanation: <CODE>$$global = 1;</CODE> : new global variable created
  -<CODE>FooAAA</CODE> with value of <CODE>1</CODE>, will not be destroyed until this module is destroyed.
  +<CODE>FooAAA</CODE> with value of <CODE>1</CODE>, this will not be destroyed until this module is destroyed.
   
   <P>
   <CODE>Apache::Leak</CODE> is not very user-friendly, have a look at
  -<CODE>B::LexInfo</CODE>. You'll see that what might appear to be a leak, is actually just a Perl
  -optimization. e.g. consider this code:
  +<CODE>B::LexInfo</CODE>. It is possible to see something that might appear to be a leak, but is
  +actually just a Perl optimization. e.g. consider this code:
   
   <P>
   <PRE>  sub foo {
  @@ -4405,9 +4583,11 @@
   </PRE>
   <P>
   <CODE>B::LexInfo</CODE> will show you that Perl does not release the value from $string, unless you
  -<CODE>undef()</CODE> it. this is because Perl anticipates the memory will
  +<CODE>undef()</CODE> it. This is because Perl anticipates the memory will
   be needed for another string, the next time the subroutine is entered.
  -you'll see similar for <CODE>@array</CODE> length, <CODE>%hash</CODE> keys, and scratch areas of the pad-list for OPs such as <CODE>join()</CODE>, `<CODE>.</CODE>', etc.
  +You'll see similar behaviour for <CODE>@array</CODE> length,
  +<CODE>%hash</CODE> keys, and scratch areas of the pad-list for OPs such as
  +<CODE>join()</CODE>, `<CODE>.</CODE>', etc.
   
   <P>
   <CODE>Apache::Status</CODE> now includes a new <CODE>StatusLexInfo</CODE> option.
  @@ -4421,15 +4601,16 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A></H1></CENTER>
   <P>
  -Running in httpd -X mode. (good only for testing during development phase).
  +Running in httpd -X mode is good only for testing during the development
  +phase.
   
   <P>
   You want to test that your application correctly handles global variables
  -(if you have any - the less you have of them the better, but sometimes you
  -just can't without them). It's hard to test with multiple servers serving
  -your cgi since each child has a different value for its global variables.
  -Imagine that you have a <CODE>random()</CODE>
  -sub that returns a random number and you have the following script.
  +(if you have any - the less you have of them the better of course - but
  +sometimes you just can't do without them). It's hard to test with multiple
  +servers serving your cgi since each child has a different value for its
  +global variables. Imagine that you have a
  +<CODE>random()</CODE> sub that returns a random number and you have the following script.
   
   <P>
   <PRE>  use vars qw($num);
  @@ -4438,25 +4619,26 @@
   </PRE>
   <P>
   This script initializes the variable <CODE>$num</CODE> with a random value, then increments it on each request and prints it out.
  -Running this script in multiple server environments will result in
  +Running this script in a multiple server environments will result in
   something like <CODE>1</CODE>,
  -<CODE>9</CODE>, <CODE>4</CODE>, <CODE>19</CODE> (number per reload), since each time your script will be served by a
  -different child. (On some OSes, the parent httpd process will assign all of
  -the requests to the same child process if all of the children are idle...
  -AIX...). But if you run in <CODE>httpd -X</CODE>
  -single server mode you will get <CODE>2</CODE>, <CODE>3</CODE>, <CODE>4</CODE>, <CODE>5</CODE>... (assuming that the <CODE>random()</CODE> returned <CODE>1</CODE> at the first call)
  -
  -<P>
  -But do not get too obsessive with this mode, since working only in single
  -server mode sometimes hides problems that show up when you switch to a
  -normal (multi) server mode. Consider an application that allows you to
  -change the configuration at run time.
  -
  -<P>
  -Let's say the script produces a form to change the background color of the
  -page. It's not a good design, but for the sake of demonstrating the
  -potential problem, we will assume that our script doesn't write the changed
  -background color to the disk, but simply changes it in memory, like:
  +<CODE>9</CODE>, <CODE>4</CODE>, <CODE>19</CODE> (a different number each time you hit the browser's reload button) since
  +each time your script will be served by a different child. (On some
  +operating systmes, e.g. AIX, the parent httpd process will assign all of
  +the requests to the same child process if all of the children are idle).
  +But if you run in <CODE>httpd
  +-X</CODE> single server mode you will get <CODE>2</CODE>, <CODE>3</CODE>, <CODE>4</CODE>, <CODE>5</CODE>... (assuming that <CODE>random()</CODE> returned <CODE>1</CODE> at the first call)
  +
  +<P>
  +But do not get too obsessive with this mode, since working in single server
  +mode sometimes hides problems that show up when you switch to normal
  +(multi-server) mode.
  +
  +<P>
  +Consider an application that allows you to change the configuration at run
  +time. Let's say the script produces a form to change the background color
  +of the page. It's not good design, but for the sake of demonstrating the
  +potential problem we will assume that our script doesn't write the changed
  +background color to the disk, but simply changes it in memory, like this:
   
   <P>
   <PRE>  use vars qw($bgcolor);
  @@ -4467,47 +4649,71 @@
   </PRE>
   <P>
   So you have typed in a new color, and in response, your script prints back
  -the html with a new color - you think that's it! It was so simple. And if
  -you keep running in single server mode you will never notice that you have
  -a problem...
  +the html with a new color - you think that's it! It was so simple. If you
  +keep running in single server mode you will never notice that you have a
  +problem...
  +
  +<P>
  +If you run the same code in normal server mode, after you submit the color
  +change you will get the result as expected, but when you call the same URL
  +again (not reload!) the chances are that you will get back the original
  +default color (white in our case), since only the child which processed the
  +color change request knows about the global variable change. Just remember
  +that children can't share information, other than that which they inherited
  +from their parent on their birth. Of course you could use a hidden variable
  +for the color to be remembered, or store it on the server side (database,
  +shared memory, etc).
  +
  +<P>
  +If you use the Netscape client while your server is running in
  +single-process mode, if the output returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the loading of the images will take a long time, since
  +Netscape's
  +<CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
  +keep them open. Because there is only one server process listening, each
  +connection has to time-out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <EM>httpd.conf</EM> to avoid this effect. Alternatively (assuming you use the image size
  +parameters, so that Netscape will be able to render the rest of the page)
  +you can press <STRONG>STOP</STRONG> after a few seconds.
   
   <P>
  -If you run the same code in the normal server mode, after you submit the
  -color change you will get the result as expected, but when you will call
  -the same URL again (not reload!) chances are that you will get back the
  -original default color (white in our case), since except the child who
  -processed the color change request no one knows about their global variable
  -change. Just remember that children can't share information, other than
  -that which they inherited from their parent on their load. Of course you
  -should use a hidden variable for the color to be remembered or store it on
  -the server side (database, shared memory, etc).
  +In addition you should be aware that when running with <CODE>-X</CODE> you will not see the status messages that the parent server normally writes
  +to the error_log. (``server started'', ``server stopped'', etc.). Since <CODE>httpd
  +-X</CODE> causes the server to handle all requests itself, without forking any
  +children, there is no controlling parent to write the status messages.
   
   <P>
  -Also note that since the server is running in single mode, if the output
  -returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. 
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A></H1></CENTER>
  +<P>
  +This module is used to watch an HTTP transaction, looking at client and
  +servers headers.
   
   <P>
  -When you use Netscape client while your server is running in single-process
  -mode, if the output returns a HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time, since the <CODE>KeepAlive</CODE>
  -feature gets in the way. Netscape tries to open multiple connections and
  -keep them open. Because there is only one server process listening, each
  -connection has to time-out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect.
  +With <CODE>Apache::ProxyPassThru</CODE> configured, you are able to watch your browser talk to any server besides
  +the one with this module living inside.
   
   <P>
  -Also note that since the server is running in single mode, if the output
  -returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. If you use
  -Netscape while your server is running in single-process mode, HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
  -keep them open. Because there is only one server process listening, each
  -connection has to time-out before the next succeeds. Turn off
  -<CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect while developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
  -Netscape will be able to render the rest of the page).
  +For more information read the module's manpage.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A></H1></CENTER>
  +<P>
  +<CODE>Apache::DebugInfo</CODE> offers the ability to monitor various bits of per-request data. Its
  +functionality is similar to
  +<A HREF="././debug.html#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders</A>
  +while offering several additional features, including the ability to:
   
  +<DL>
  +<P><DT><STRONG><A NAME="item__">- separate inbound from outbound HTTP headers</A></STRONG><DD>
  +<P><DT><STRONG>- view the contents of $r-&gt;notes and $r-&gt;pnotes</STRONG><DD>
  +<P><DT><STRONG>- view any of these at the various points in the request cycle</STRONG><DD>
  +<P><DT><STRONG>- add output for any request phase from a single entry point</STRONG><DD>
  +<P><DT><STRONG>- use as a PerlInitHandler or with direct method calls</STRONG><DD>
  +<P><DT><STRONG>- use partial IP addresses for filtering by IP</STRONG><DD>
  +<P><DT><STRONG>- offer a subclassable interface</STRONG><DD>
  +</DL>
   <P>
  -In addition you should know that when running with <CODE>-X</CODE> you will not see any control messages that the parent server normally
  -writes to the error_log. (Like ``server started, server stopped and etc''.)
  -Since
  -<CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
  -children, there is no controlling parent to write status messages.
  +See the module's manpage for more details.
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -4542,7 +4748,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.10      +28 -11    modperl-site/guide/download.html
  
  Index: download.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/download.html,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- download.html	2000/03/04 20:31:45	1.9
  +++ download.html	2000/04/09 14:19:39	1.10
  @@ -35,6 +35,7 @@
   	<LI><A HREF="#mod_proxy_add_forward">mod_proxy_add_forward</A>
   	<LI><A HREF="#httperf_webserver_Benchmarking">httperf - webserver Benchmarking tool</A>
   	<LI><A HREF="#ab_ApacheBench">ab - ApacheBench</A>
  +	<LI><A HREF="#mod_backhand_load_balancing_f">mod_backhand - load balancing for Apache</A>
   	<LI><A HREF="#High_Availability_Linux_Project">High-Availability Linux Project</A>
   	<LI><A HREF="#Apache_Request">Apache::Request</A>
   	<LI><A HREF="#DataBases">DataBases</A>
  @@ -66,20 +67,21 @@
   <P>
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
  -Here you will find instructions for downloading the software and the
  +Here you will find instructions for downloading the software and its
   related documentation.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Perl">Perl</A></H1></CENTER>
   <P>
  -Perl is most likely already installed on your machine, but you should at
  -least check the version you are using. It is highly recommended that you
  -have at least Perl version 5.004. You can get the latest perl version from
  -<A HREF="http://www.perl.com/">http://www.perl.com/</A> . Try the direct
  +Perl is probably already installed on your machine, but you should at least
  +check the version you are using. It is highly recommended that you have at
  +least Perl version 5.004. You can get the latest perl version from <A
  +HREF="http://www.perl.com/">http://www.perl.com/</A> . Try the direct
   download link <A
   HREF="http://www.perl.com/pace/pub/perldocs/latest.html">http://www.perl.com/pace/pub/perldocs/latest.html</A>
  -. You can get Perl documentation from the same location.
  +. You can get Perl documentation from the same location (although copious
  +documentation is included in the downloaded Perl distribution).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -108,6 +110,13 @@
   RPM: <A HREF="http://perl.apache.org/rpm/">http://perl.apache.org/rpm/</A>
   
   <P>
  +Debian users will find Perl, Apache and mod_perl are available as .deb
  +files on official image CDs or from the Debian web site <A
  +HREF="http://www.debian.org">http://www.debian.org</A> . The Debian
  +distribution also contains many additional Perl and Apache libraries and
  +modules. 
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Squid_Internet_Object_Cache">Squid - Internet Object Cache</A></H1></CENTER>
   <P>
  @@ -130,8 +139,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="mod_proxy_add_forward">mod_proxy_add_forward</A></H1></CENTER>
   <P>
  -Ask Bjoern Hansen has written a <CODE>mod_proxy_add_forward.c</CODE> module for Apache that sets the <CODE>X-Forwarded-For</CODE> field when doing a ProxyPass, similar to what Squid can do. His module is
  -at: <A
  +Ask Bjoern Hansen has written a <CODE>mod_proxy_add_forward.c</CODE> module for Apache that sets the <CODE>X-Forwarded-For</CODE> field when doing a ProxyPass, similar to what Squid does. His module is at:
  +<A
   HREF="http://modules.apache.org/search?id=124">http://modules.apache.org/search?id=124</A>,
   at <A
   HREF="ftp://ftp.netcetera.dk/pub/apache/mod_proxy_add_forward.c">ftp://ftp.netcetera.dk/pub/apache/mod_proxy_add_forward.c</A>
  @@ -158,14 +167,22 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="mod_backhand_load_balancing_f">mod_backhand -- load balancing for Apache</A></H1></CENTER>
  +<P>
  +<A
  +HREF="http://www.backhand.org/mod_backhand/">http://www.backhand.org/mod_backhand/</A>
  +
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="High_Availability_Linux_Project">High-Availability Linux Project</A></H1></CENTER>
   <P>
  -You will find the definite guide to load balancing techniques at the
  +You will find the definitive guide to load balancing techniques at the
   High-Availability Linux Project site -- <A
   HREF="http://www.henge.com/~alanr/ha/">http://www.henge.com/~alanr/ha/</A>
   
   <P>
  -More load ballancing URLs:
  +More load balancing URLs:
   
   <P>
   lbnamed - a load balancing name server written in Perl, by Roland Schemers
  @@ -258,7 +275,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/03/2000
  +	     <BR>Last Modified at 04/01/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.12      +11 -5     modperl-site/guide/frequent.html
  
  Index: frequent.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/frequent.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- frequent.html	2000/02/09 21:11:40	1.11
  +++ frequent.html	2000/04/09 14:19:39	1.12
  @@ -58,9 +58,9 @@
   <P>
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
  -Some problems come up very often on the mailing list. If you think some
  -important problem that is being reported frequently on the list is not
  -included below, even if it is found elsewhere in the Guide, please <A HREF="././help.html#Contacting_me">tell me</A>.
  +Some problems come up very often on the mailing list. If there is some
  +important problem that is being reported frequently on the list which is
  +not included below, even if it is found elsewhere in the Guide, please <A HREF="././help.html#Contacting_me">tell me</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -87,8 +87,14 @@
   comment out lines like ``LoadModule ...''.
   
   <P>
  -Also dee the section`` <A HREF="././strategy.html#mod_perl_Deployment_Overview">mod_perl Deployment Overview</A>''.
  +META: Not clear on last sentence -- are you saying that if you have a
  +static version people <EM>will</EM> have to comment out lines or they won't? If they will then the text is
  +correct, if the won't then it should be: ``...server with anything, and we
  +shouldn't even need to comment out lines...''
   
  +<P>
  +Also see the section`` <A HREF="././strategy.html#mod_perl_Deployment_Overview">mod_perl Deployment Overview</A>''.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -122,7 +128,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 01/14/2000
  +	     <BR>Last Modified at 04/01/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.8       +113 -112  modperl-site/guide/hardware.html
  
  Index: hardware.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/hardware.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- hardware.html	1999/12/19 19:52:01	1.7
  +++ hardware.html	2000/04/09 14:19:39	1.8
  @@ -80,11 +80,11 @@
   <CENTER><H1><A NAME="Is_it_important_">Is it important?</A></H1></CENTER>
   <P>
   You can invest a lot of time and money into server tuning and code
  -rewriting according the guidelines you have just learned, but your
  +rewriting according the guidelines you have just learned, but your code's
   performance will be really bad if you do not take into account the hardware
  -demands, and do not wisely choose the operating system suited for your
  -needs. While the tips below apply to any webserver, they are written for an
  -administrator of a mod_perl-enabled webserver
  +demands, and do not wisely choose the operating system suited to your
  +needs. While the tips below apply to any webserver, they are aimed at
  +administrators of mod_perl-enabled webservers.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -93,12 +93,12 @@
   First let's talk about Operating Systems (OS). While I am personally a
   Linux devotee, I do not want to start yet another OS war. Assuming this, I
   will try to define what you should be looking for, then when you know what
  -do you want from your OS, go find it. Visit the Web sites of operating
  -systems you are interested in. You can gauge user's opinions by searching
  -relevant discussions in newsgroup and mailing list archives such as Deja -
  -<A HREF="http://deja.com">http://deja.com</A> and eGroups - <A
  +you want from your OS, go find it. Visit the Web sites of operating systems
  +you are interested in. You can gauge user's opinions by searching relevant
  +discussions in newsgroup and mailing list archives such as Deja - <A
  +HREF="http://deja.com">http://deja.com</A> and eGroups - <A
   HREF="http://egroups.com">http://egroups.com</A> . I will leave this fan
  -research up to you. But I would use Linux or something from the
  +research to the reader. But I would use Linux or something from the
   <CODE>*BSD</CODE> family.
   
   <P>
  @@ -112,8 +112,8 @@
   go shop at another service like yours, unless you have a monopoly :) . If
   the OS of your choice crashes every day or so, I would throw it away, after
   doing a little investigation, for there might be a reason for a system
  -crash. Like a runaway server that eats up all the memory and disk, so you
  -cannot blame the OS for that. Generally, people who use the OS for some
  +crash. Like a runaway server that eats up all the memory and disk space, so
  +you cannot blame the OS for that. Generally, people who use the OS for some
   time can tell you a lot about its stability.
   
   <P>
  @@ -122,42 +122,42 @@
   <P>
   You want an OS with a good memory management, some OSes are well known as
   memory hogs. The same code can use twice as much memory on one OS compared
  -to the other. If the size of the mod_perl process is 10Mb and you have tens
  +to another. If the size of the mod_perl process is 10Mb and you have tens
   of these running, it definitely adds up!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Memory_Leakages">Memory Leakages</A></H2></CENTER>
   <P>
  -Some OSes and/or the libraries (like C runtime libraries) suffer from
  -memory leaks. You cannot afford such a system, for you are already know
  -that a single mod_perl process sometimes serves thousands of requests
  -before itimer terminates. So if a leak occurs on every request, your memory
  -demands will be huge. Of course your code can be the cause of the memory
  -leaks as well (check out the <CODE>Apache::Leak</CODE>
  -module). Certainly, you can lower the number of requests to be served over
  +Some OSes and/or their libraries (like C runtime libraries) suffer from
  +memory leaks. We cannot afford such systems, for we already know that a
  +single mod_perl process sometimes serves thousands of requests before it
  +terminates. So if a leak occurs on every request, our memory demands will
  +be huge. Of course our code can be the cause of the memory leaks as well
  +(check out the <CODE>Apache::Leak</CODE>
  +module). Certainly, we can lower the number of requests to be served over
   the process' life, but that can degrade performance.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Sharing_Memory">Sharing Memory</A></H2></CENTER>
   <P>
  -You want an OS with good memory sharing capabilities. As you have learned,
  -if you preload the modules and scripts at server startup, they are shared
  +We want an OS with good memory sharing capabilities. As we have learnt, if
  +we preload the modules and scripts at server startup, they are shared
   between the spawned children, at least for a part of a process' life span,
  -since memory pages become ``dirty'' and cease to be shared. This feature
  -can save you up a lot of memory!
  +since memory pages can become ``dirty'' and cease to be shared. This
  +feature can save us a lot of memory!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Cost_and_Support">Cost and Support</A></H2></CENTER>
   <P>
  -If you are in a big business you are probably do not mind paying another
  -<CODE>$1000</CODE> for some fancy OS and to get the bundled support for it.
  -But if your resources are low, you will look for cheaper and free OS. Free
  -does not mean bad, it can be quite opposite as we all either know from our
  -own experience or read about in news. Free OSes could have and do have the
  -best support you can find. It is very easy to understand - most of the
  +If we are in a big business we probably do not mind paying another
  +<CODE>$1000</CODE> for some fancy OS with bundled support. But if our
  +resources are low, we will look for cheaper and free OSs. Free does not
  +mean bad, it can be quite the opposite as we all either know from our own
  +experience or have read about in the news. Free OSs could have and do have
  +the best support we can find. It is very easy to understand - most of the
   people are not rich and will try to use a cheaper or free OS first if it
   does the work for them. Since it really fits their needs, many people keep
   using it and eventually know it well enough to be able to provide support
  @@ -169,57 +169,56 @@
   
   <P>
   But, let's get back to our world. We are living in material world, and our
  -bosses pay us to keep the systems running. So if you feel that you cannot
  -provide the support yourself and you do not trust the available free
  -resources, you must pay for an OS backed by a company, and blame them for
  -any problem. Your boss wants to be able to sue someone if the project has a
  +bosses pay us to keep the systems running. So if we feel that we cannot
  +provide the support ourselves and we do not trust the available free
  +resources, we must pay for an OS backed by a company, and blame them for
  +any problem. Our boss wants to be able to sue someone if the project has a
   problem caused by the external product that is being used in the project.
  -If you buy a product and the company selling it, claims support, you have
  -someone to sue. You do not have someone to sue other than getting yourself
  -fired if you go with Open Source and it fails.
  +If we buy a product and the company selling it, claims support, we have
  +someone to sue. We do not have someone to sue other than getting ourself
  +fired if we go with Open Source and it fails.
   
   <P>
   Also remember that if you spend less or zero money on OS and Software, you
  -will be able to buy a better and stronger hardware.
  +will be able to buy better and stronger hardware.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Discontinued_products">Discontinued products</A></H2></CENTER>
   <P>
   You have invested a lot of time and money into developing some proprietary
  -software that is bundled with the OS you were developing on. Like writing a
  -mod_perl handler that takes advantage of some proprietary features of the
  -OS and it will not run on any other OS. Things are under control, the
  -performance is great and you sing from happiness. But... one day the
  -company who wrote your beloved OS goes bankrupt, which is not unlikely to
  -happen nowadays. You are stuck with their last masterpiece and no support!
  -What you are going to do then? Invest more into porting the software to
  -another OS...
  +software that is bundled with the OS you were developing under. Like
  +writing a mod_perl handler that takes advantage of some proprietary
  +features of the OS and will not run on any other OS. Things are under
  +control, the performance is great and you sing with happiness. But... one
  +day the company who wrote our beloved OS goes bankrupt, which is not
  +unlikely to happen nowadays, or they produce a newer incompatible version
  +and they will not support the old version our code runs under (and this
  +happens regularly). You are stuck with their last masterpiece and no
  +support! What you are going to do then? Invest more into porting the
  +software to another OS...
   
   <P>
   Everyone can be hit by this mini-disaster, so it is better to check the
   background of the company when making your choice, but still you never know
  -what will happen tomorrow. The OSes in this hazard group are completely
  -developed by a single companies. Free OSes are probably less susceptible to
  +what will happen tomorrow. The OSs in this hazard group are completely
  +developed by single companies. Free OSs are probably less susceptible to
   this, for development is distributed between many companies and developers,
   so if a person who developed a really important part of the kernel lost
   interest in continuing, someone else will pick the falling flag and carry
   on. Of course if tomorrow some better project showed up, developers might
  -migrate there and finally drop the development, but we are here not to let
  -this happen.
  +migrate there and finally drop the development: but in practice people are
  +given support on older versions and helped to migrate to current versions.
   
   <P>
  -In the final analysis, the decision is yours.
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="OS_Releases">OS Releases</A></H2></CENTER>
   <P>
  -Actively developed OSes generally try to keep the pace with the latest
  +Actively developed OSs generally try to keep pace with the latest
   technology developments, and continually optimize the kernel and other
   parts of the OS to become better and faster. Nowadays, Internet and
   networking in general are the hottest targets for system developers.
  -Sometimes a simple OS upgrade to a latest stable version, can save you an
  +Sometimes a simple OS upgrade to the latest stable version, can save you an
   expensive hardware upgrade. Also, remember that when you buy new hardware,
   chances are that the latest software will make the most of it. Since the
   existing software (drivers) might support the brand new product because of
  @@ -232,24 +231,25 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Choosing_Hardware">Choosing Hardware</A></H1></CENTER>
   <P>
  -Since I am not fond of the idea of updating this section every day a new
  -processor or memory type comes out, I will only hint what should you look
  -for and suggest that sometimes the most expensive machine is not the one
  -which provides the best performance.
  +Since I am not fond of the idea of updating this section every time a new
  +processor or memory type comes out, I will only hint about what you should
  +look for and suggest that sometimes the most expensive machine is not the
  +one which provides the best performance.
   
   <P>
   Your demands are based on many aspects and components. Let's discuss some
   of them.
   
   <P>
  -In discussion course you might meet some unfamiliar terms, here are some of
  -them:
  +In discussion course we use terms that may be unfamiliar to some readers: 
   
   <UL>
   <P><LI>
   <P>
  -Clustering - a bunch of machines connected together to perform one big or
  -many small computational tasks in a reasonable time.
  +Clustering - a group of machines connected together to perform one big or
  +many small computational tasks in a reasonable time. Clustering is also
  +used to provide 'fail-over' where if one machine fails its work is
  +transparently transferred to another without any interruption of service.
   
   <P><LI>
   <P>
  @@ -258,7 +258,7 @@
   clustering approach, distributing the load over a number of machines. The
   central server, the one users access when they type the name of the
   service, works as a dispatcher, by redirecting requests to the rest of the
  -machines, sometimes it also collects the results and return them to the
  +machines, sometimes it also collects the results and returns them to the
   users. One of the advantages is that you can take one of the machines down
   for a repair or upgrade, and your service will still work - the main server
   will not dispatch the requests to the machine that was taken down. I will
  @@ -282,24 +282,24 @@
   <CENTER><H2><A NAME="Expected_site_traffic">Expected site traffic</A></H2></CENTER>
   <P>
   If you are building a fan site, but want to amaze your friends with a
  -mod_perl guest book, an old 486 machine will do it. If you are into a
  +mod_perl guest book, an old 486 machine could do it. If you are into a
   serious business, it is very important to build a scalable server, so if
  -your service is successful and becomes popular, you get your server's
  -traffic doubled every few days, you should be ready to add more resources
  +your service is successful and becomes popular, your server's traffic
  +doubles every few days, you should be ready to add more resources
   dynamically. While we can define the webserver scalability more precisely,
   the important thing is to make sure that you can add more power to your
   <CODE>webserver(s)</CODE> without investing additional money into a
  -software developing (almost, you will need a software to connect your
  +software development (almost, you will need a software to connect your
   servers if you add more of them). It means that you should choose a
   hardware/OS that can talk to other machines and become a part of the
   cluster.
   
   <P>
  -From the other hand if you prepare for a big traffic and buy a monster to
  -do the work for you, what happens if your service does not prove to be as
  -successful as you thought it would be. Then you spent too much money and
  -meanwhile there were a new faster processors and other hardware components
  -released, so you loose again.
  +From the other hand if you prepare for a lot of traffic and buy a monster
  +to do the work for you, what happens if your service does not prove to be
  +as successful as you thought it would be. Then you've spent too much money
  +and meanwhile there were a new faster processors and other hardware
  +components have been released, so you lose again.
   
   <P>
   Wisdom and prophecy , that's all it takes :)
  @@ -319,21 +319,21 @@
   If you really need a lot of power do not think about a single strong
   machine (unless you have money to throw away), think about clustering and
   load balancing. You can probably buy 10 times more older but very cheap
  -machines and have a 8 times more power, then purchasing only one single new
  +machines and have a 8 times more power, than purchasing only one single new
   machine. Why is that? Because as I mentioned before generally the
  -performance improvement is marginal while the price is much bigger. Because
  +performance improvement is marginal while the price is much higher. Because
   10 machines will do faster disk I/O, than one single machine, even if the
   disk is much faster. Yes, you have more administration overhead, but there
   is a chance you will have it anyway, for in a short time the machine you
   have just invested in will not stand the load anyway and you will have to
  -purchase more and think how to implement load balancing and file system
  -distribution.
  +purchase more and think about how to implement load balancing and file
  +system distribution.
   
   <P>
   Why I am so convinced? Facts! Look at the most used services on the
   Internet: search engines, email servers and the like -- most of them are
  -using a clustering approach. While you may not always notice that, they do
  -it by hiding the real implementation behind the proxy servers.
  +using a clustering approach. While you may not always notice this, because
  +they hide the real implementation behind proxy servers.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -363,7 +363,7 @@
   located there.
   
   <P>
  -And a bad connectivity can directly influence your machine's performance.
  +And bad connectivity can directly influence your machine's performance.
   Here is a story, one of the developers told on the mod_perl mailing list:
   
   <P>
  @@ -393,7 +393,7 @@
   <CENTER><H2><A NAME="I_O_performance">I/O performance</A></H2></CENTER>
   <P>
   If your service is I/O bound (does a lot of read/write operations to disk,
  -remember that relational databases are sitting on disk as well) you need a
  +remember that relational databases are sitting on disk as well), you need a
   very fast disk. So you should not spend money on Video card and monitor
   (monochrome card and 14`` B&amp;W are perfectly adequate for a server --
   you will probably be telnetted or ssh-ed in most of the time), but rather
  @@ -421,35 +421,36 @@
   <P>
   How much RAM (Randomly Accessed Memory) do you need? Nowadays, chances are
   you will hear: ``Memory is cheap, the more you buy the better''. But how
  -much is enough? The answer pretty straightforward: ``You do not want your
  -machine to swap''. When the CPU needs to write something into memory, but
  -notices that it is already full, it takes the least frequently used memory
  -pages and swaps them out. Swapping out means writing the data to disk.
  -Another process then references some of its own data, which happens to be
  -on one of the pages that were just swapped out. The CPU, ever obliging,
  -swaps it back in again, probably swapping out some other data that will be
  -needed very shortly by another process. Carried to the extreme, the CPU and
  -disk start to thrash hopelessly in circles, without getting any real work
  -done. The less RAM there is, the more often this scenario arises. Worse,
  -you can exhaust swap space as well, and then the troubles really set in...
  -
  -<P>
  -How do you make a decision? You know the highest rate your server expects
  -to serve pages and how long it takes to do so. Now you can calculate how
  -many server processes you need. Knowing the maximum size any of your
  -servers can get, you know how much memory you need. You probably need less
  -memory than you have calculated if your OS supports memory sharing and you
  -know how to make best use of this feature (preloading the modules and
  -scripts at server startup). Do not forget that other essential system
  -processes need memory as well, so you should plan not only for the web
  -server, but also take into account the other players. Remember that
  +much is enough? The answer is pretty straightforward: ``You do not want
  +your machine to swap''. When the CPU needs to write something into memory,
  +but notices that it is already full, it takes the least frequently used
  +memory pages and swaps them out. Swapping out means writing the data to
  +disk. Another process then references some of its own data, which happens
  +to be on one of the pages that has just been swapped out. The CPU, ever
  +obliging, swaps it back in again, probably swapping out some other data
  +that will be needed very shortly by another process. Carried to the
  +extreme, the CPU and disk start to thrash hopelessly in circles, without
  +getting any real work done. The less RAM there is, the more often this
  +scenario arises. Worse, you can exhaust swap space as well, and then the
  +troubles really start...
  +
  +<P>
  +How do you make a decision? You know the highest rate at which your server
  +expects to serve pages and how long it takes to do so. Now you can
  +calculate how many server processes you need. Knowing the maximum size any
  +of your servers can get, you know how much memory you need. You probably
  +need less memory than you have calculated if your OS supports memory
  +sharing and you know how to make best use of this feature (preloading the
  +modules and scripts at server startup). Do not forget that other essential
  +system processes need memory as well, so you should plan not only for the
  +web server, but also take into account the other players. Remember that
   requests can be queued, so you can afford to let your client wait for a few
  -moments until a server is available to serve it, your numbers will be more
  +moments until a server is available to serve it; your numbers will be more
   correct, since you generally do not have the highest load, but you should
   be ready to bear the peaks. So you need to reserve at least 20% of free
   memory for peak situations. Many sites have crashed a few moments after a
  -big scoop about them was posted and unexpected number of requests suddenly
  -came in. (This is called a Slashdot effect, which was born at <A
  +big scoop about them was posted and an unexpected number of requests
  +suddenly came in. (This is called the Slashdot effect, which was born at <A
   HREF="http://slashdot.org">http://slashdot.org</A> ) If you are about to
   announce something cool, be aware of the possible consequences.
   
  @@ -459,7 +460,7 @@
   <P>
   The most important thing to understand is that you might use the most
   expensive components, but still get bad performance. Why? Let me introduce
  -an annoying word: A bottleneck.
  +an annoying word: bottleneck.
   
   <P>
   A machine is an aggregate of many big and small components. Each one of
  @@ -467,8 +468,8 @@
   of RAM (memory), the processor will be under-utilized waiting for the
   kernel to swap the memory pages in and out, because memory is too small to
   hold the most used ones. If you have a lot of memory and a fast processor
  -and a fast disk, but a slow controller - the performance will be bad, and
  -you have wasted money.
  +and a fast disk, but a slow controller - the performance will still be bad,
  +and you will have wasted money.
   
   <P>
   Use a fast NIC (Network Interface Card) that does not create a bottleneck.
  @@ -481,9 +482,9 @@
   <P>
   To use your money optimally you have to understand the hardware very well,
   so you will know what to pick. Otherwise, you should hire a knowledgeable
  -hardware consultants and employ him/her on a regular basis, since your
  -demands will probably change as time goes by and your hardware will
  -likewise be forced to adapt as well.
  +hardware consultants and employ them on a regular basis, since your needs
  +will probably change as time goes by and your hardware will likewise be
  +forced to adapt as well.
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -518,7 +519,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/04/1999
  +	     <BR>Last Modified at 04/01/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.22      +65 -35    modperl-site/guide/help.html
  
  Index: help.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/help.html,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- help.html	2000/03/04 20:31:45	1.21
  +++ help.html	2000/04/09 14:19:39	1.22
  @@ -62,17 +62,16 @@
   <P>
   <CENTER><H1><A NAME="READ_ME_FIRST">READ ME FIRST</A></H1></CENTER>
   <P>
  -If after reading this guide and other documents listed in this section, you
  -feel that your question is not yet answered, please ask the apache/mod_perl
  -mailing list to help you. But first try to browse the mailing list archive.
  -Most of the time you will find the answer for your question by searching
  -the mailing archive, since there is a big chance someone else has already
  -encountered the same problem and found a solution for it. If you ignore
  -this advice, do not be surprised if your question will be left unanswered -
  -it bores people to answer the same question more than once. It does not
  -mean that you should avoid asking questions. Just do not abuse the
  -available help and <STRONG>RTFM</STRONG> before you call for <STRONG>HELP</STRONG>. (You have certainly heard the infamous fable of the shepherd boy and the
  -wolves)
  +If after reading this guide and the other documents listed in this section,
  +and still don't have the answers/information needed, please ask the
  +apache/mod_perl mailing list to help. But please, first try to browse the
  +mailing list archive. Most of the time you will find the answer to your
  +questions by searching the mailing archive, since it is most likely that
  +someone else has already encountered the same problem and found a solution
  +for it. If you ignore this advice, you should not be surprised if your
  +question is left unanswered - it bores people to answer the same question
  +more than once. It does not mean that you should avoid asking questions.
  +But you should not abuse the available help and should <STRONG>RTFM</STRONG> before you call for <STRONG>HELP</STRONG>. (Remember the fable of the shepherd boy and the wolves)
   
   <P>
   For more information See <A HREF="././help.html#Get_help_with_mod_perl">Get helped with mod_perl</A>.
  @@ -81,10 +80,10 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Contacting_me">Contacting me</A></H1></CENTER>
   <P>
  -Hi, I wrote this document to help you with mod_perl. It does not mean that
  -if you have any question regarding mod_perl, perl or whatever you think I
  -might know, you should send it directly to me. Please see the
  -<A HREF="#Get_help_with_mod_perl">Get help with mod_perl</A> section and follow the guidelines as prescribed there.
  +Hi, I wrote this document to help people with mod_perl. It does not mean
  +that if you have any question regarding mod_perl, perl or whatever you
  +think I might know, that you should send it directly to me. Please see the <A HREF="#Get_help_with_mod_perl">Get help with mod_perl</A>
  +section and follow the guidelines described there.
   
   <P>
   However, you are welcome to submit corrections and suggestions directly to
  @@ -92,13 +91,13 @@
   HREF="mailto:stas@stason.org?subject=mod_perl%20guide%20corrections.">stas@stason.org?subject=mod_perl%20guide%20corrections.</A>
   If you are going to <STRONG>submit heavy corrections of the text</STRONG> (I love those!), please help me by downloading the source pages in POD from
   the main (index) page (at the bottom) and directly editing them. I will use
  -Emacs Ediff to perform an easy merge of your changes. Thank you!
  +Emacs Ediff to perform an easy merge of such changes. Thank you!
   
   <P>
   <STRONG>PLEASE NO PERSONAL QUESTIONS, I didn't invite those by writing the
  -guide. They all will be immediately deleted. Please ask the questions
  -at the mod_perl list and if someone or I can answer your question--it
  -will be answered. Thank you!</STRONG>
  +guide. They all will be immediately deleted. Please ask questions
  +on the mod_perl list and if someone or I can answer your question--it
  +will be answered on the list. Thank you!</STRONG>
   
   
   
  @@ -124,8 +123,8 @@
   using the Apache API, written by Lincoln Stein and Doug MacEachern.
   
   <P>
  -Now you can purchase the book at your local bookstore or from the online
  -dealer. O'Reilly lists this book as:
  +The book should be available from your local bookstore or from your
  +favourite on-line bookseller. O'Reilly lists this book as:
   
   <P>
   <PRE>  Writing Apache Modules with Perl and C
  @@ -138,10 +137,10 @@
   <P>
   <A HREF="http://www.modperlbook.com">http://www.modperlbook.com</A> is the
   home site of the new mod_perl book, that Eric Cholet and Stas Bekman are
  -co-authoring together. We expect the book to be published in fall 2000.
  +co-authoring. We expect the book to be published in fall 2000.
   
   <P>
  -Ideas, suggestions and comments are welcome. You may send them to <A
  +Ideas, suggestions and comments are welcome. Please send them to <A
   HREF="mailto:info@modperlbook.com">info@modperlbook.com</A> .
   
   </UL>
  @@ -189,6 +188,20 @@
   HREF="http://www.perlreference.com/mod_perl/">http://www.perlreference.com/mod_perl/</A>
   
   
  +<P><LI><STRONG><A NAME="item_Articles">Articles</A></STRONG>
  +<UL>
  +<P><LI><STRONG><A NAME="item_PerlMonth">PerlMonth</A></STRONG>
  +<P>
  +<A HREF="http://perlmonth.com">http://perlmonth.com</A>
  +
  +<P><LI><STRONG><A NAME="item_Basic">Basic knowledge about Apache stages and
  +mod_perl handlers article in German</A></STRONG>
  +<P>
  +<A
  +HREF="http://www.heise.de/ix/artikel/2000/01/156/">http://www.heise.de/ix/artikel/2000/01/156/</A>
  +
  +
  +</UL>
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl mailing lists</A></STRONG>
   <UL>
   <P><LI><STRONG><A NAME="item_The">The mod_perl mailing list</A></STRONG>
  @@ -199,13 +212,13 @@
   HREF="mailto:modperl-subscribe@apache.org">modperl-subscribe@apache.org</A>
   . To unsubscribe send email to <A
   HREF="mailto:modperl-unsubscribe@apache.org">modperl-unsubscribe@apache.org</A>
  -. Use <A HREF="mailto:modperl@apache.org">modperl@apache.org</A> adress to
  -post to the list.
  +. Use the <A HREF="mailto:modperl@apache.org">modperl@apache.org</A>
  +address to post to the list.
   
   <P>
  -A <STRONG>searchable</STRONG> mod_perl mailing list archive available at <A
  +A <STRONG>searchable</STRONG> mod_perl mailing list archive is available at <A
   HREF="http://forum.swarthmore.edu/epigone/modperl">http://forum.swarthmore.edu/epigone/modperl</A>
  -. We owe it to Ken Williams.
  +. Thanks to Ken Williams for this.
   
   <P>
   More archives available:
  @@ -244,8 +257,7 @@
   </UL>
   <P><LI><STRONG><A NAME="item_The">The advocacy mailing list</A></STRONG>
   <P>
  -The advocacy list for mod_perl advocacy issues, discussions about site,
  -etc.
  +The list for mod_perl advocacy issues, discussions about sites, etc.
   
   <P>
   Subscribe by sending a mail to <A
  @@ -264,16 +276,17 @@
   <P>
   The modperl developers list is the list where you can watch mod_perl
   getting patched. No real discussions happen on this list, but if you want
  -to know about the latest changes in the mod_perl core before the rest of
  -the people, this is a list to be on.
  +to know about the latest changes in the mod_perl core before everyone else,
  +this is a list to be on.
   
   <P>
   To subscribe to this list, send email to <A
   HREF="mailto:modperl-cvs-subscribe@apache.org">modperl-cvs-subscribe@apache.org</A>
   . To unsubscribe send email to <A
   HREF="mailto:modperl-cvs-unsubscribe@apache.org">modperl-cvs-unsubscribe@apache.org</A>
  -. Use <A HREF="mailto:modperl-cvs@apache.org">modperl-cvs@apache.org</A>
  -adress to post to the list.
  +. Use the <A
  +HREF="mailto:modperl-cvs@apache.org">modperl-cvs@apache.org</A> address to
  +post to the list.
   
   <P>
   No archives available.
  @@ -290,7 +303,7 @@
   HREF="http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html">http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html</A>
   
   
  -<P><LI><STRONG><A NAME="item_The">The Perl Home</A></STRONG>
  +<P><LI><STRONG><A NAME="item_The">The Perl Home Page</A></STRONG>
   <P>
   <A HREF="http://www.perl.com/">http://www.perl.com/</A>
   
  @@ -376,6 +389,23 @@
   HREF="http://www.engelschall.com/pw/apache/rewriteguide/">http://www.engelschall.com/pw/apache/rewriteguide/</A>
   
   
  +<P><LI><STRONG><A NAME="item_articles">articles</A></STRONG>
  +<P>
  +Security and Apache: An Essential Primer <A
  +HREF="http://linuxplanet.com/linuxplanet/print/1527/">http://linuxplanet.com/linuxplanet/print/1527/</A>
  +
  +
  +<P>
  +Using Apache with Suexec on Linux <A
  +HREF="http://linuxplanet.com/linuxplanet/print/1445/">http://linuxplanet.com/linuxplanet/print/1445/</A>
  +
  +
  +<P><LI><STRONG><A NAME="item_Limit">Limit the number of Apache children
  +that can be servicing a requested resource at one time.</A></STRONG>
  +<P>
  +A C Apache module available at <A
  +HREF="http://www.fremen.org/apache/">http://www.fremen.org/apache/</A>
  +
   </UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -472,7 +502,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.26      +70 -19    modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- index.html	2000/03/04 20:31:45	1.25
  +++ index.html	2000/04/09 14:19:39	1.26
  @@ -27,7 +27,7 @@
   <CENTER><P><B>Deploying mod_perl technology to give a rocket speed
   to your CGI/perl scripts.</B></P></CENTER>
   
  -<CENTER><P><B>Version 1.21 Mar, 4 2000</B></P></CENTER>
  +<CENTER><P><B>Version 1.22 Apr, 9 2000</B></P></CENTER>
    
   <P><HR WIDTH="100%"></P>
   
  @@ -165,6 +165,7 @@
   	<LI><A HREF="porting.html#die_and_mod_perl">die() and mod_perl</A>
   	<LI><A HREF="porting.html#Testing_the_Code_from_the_Shell">Testing the Code from the Shell</A>
   	<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
  +	<LI><A HREF="porting.html#Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A>
   	<LI><A HREF="porting.html#STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A>
   	<LI><A HREF="porting.html#Global_Variables_Persistance">Global Variables Persistance</A>
   	<LI><A HREF="porting.html#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  @@ -183,8 +184,10 @@
   	<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
   	<LI><A HREF="porting.html#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
   	<LI><A HREF="porting.html#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="porting.html#File_tests_operators">File tests operators</A>
   	<LI><A HREF="porting.html#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="porting.html#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="porting.html#Accessing_Request_Object_in_non_">Accessing Request Object in non-Perl*Handler Modules</A>
   	<LI><A HREF="porting.html#The_Script_Is_Too_Dirty_But_It_">The Script Is Too Dirty, But It Does The Job And I Cannot Afford To Rewrite It.</A>
   	<LI><A HREF="porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun--a closer look</A>
   	<LI><A HREF="porting.html#Sharing_variables_between_proces">Sharing variables between processes</A>
  @@ -222,12 +225,20 @@
   		<LI><A HREF="performance.html#Work_With_Databases">Work With Databases</A>
   	</UL>
   
  -	<LI><A HREF="performance.html#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
  +	<LI><A HREF="performance.html#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Build Options</A>
  +	<LI><A HREF="performance.html#_Dusemymalloc_Perl_Build_Option">-Dusemymalloc Perl Build Option</A>
   	<LI><A HREF="performance.html#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="performance.html#Cached_stat_calls">Cached stat() calls</A>
   	<LI><A HREF="performance.html#Be_carefull_with_symbolic_links">Be carefull with symbolic links</A>
   	<LI><A HREF="performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
  +	<LI><A HREF="performance.html#Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A>
   	<LI><A HREF="performance.html#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#OS_Specific_notes">OS Specific notes</A>
  +		<LI><A HREF="performance.html#Debug">Debug</A>
  +	</UL>
  +
   	<LI><A HREF="performance.html#Limiting_the_Request_Rate_Speed_">Limiting the Request Rate Speed (Robot Blocking)</A>
   	<LI><A HREF="performance.html#Benchmarks_Impressing_Your_Boss">Benchmarks. Impressing Your Boss and Your Colleagues.</A>
   	<UL>
  @@ -235,7 +246,7 @@
   		<LI><A HREF="performance.html#Developers_Talk">Developers Talk</A>
   		<LI><A HREF="performance.html#Benchmarking_a_Graphic_Hits_Coun">Benchmarking a Graphic Hits Counter with Persistent DB Connections</A>
   		<LI><A HREF="performance.html#Benchmarking_Scripts_with_Execut">Benchmarking Scripts with Execution Times Below 1 Second</A>
  -		<LI><A HREF="performance.html#Benchmarking_PerlHandler">Benchmarking PerlHandler</A>
  +		<LI><A HREF="performance.html#Benchmarking_PerlHandlers">Benchmarking PerlHandlers</A>
   	</UL>
   
   	<LI><A HREF="performance.html#Tuning_Apache_s_Configuration_Va">Tuning Apache's Configuration Variables for the Best Performance</A>
  @@ -283,6 +294,14 @@
   	</UL>
   
   	<LI><A HREF="performance.html#Imported_Symbols_and_Memory_Usag">Imported Symbols and Memory Usage</A>
  +	<LI><A HREF="performance.html#TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  +		<LI><A HREF="performance.html#CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A>
  +		<LI><A HREF="performance.html#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
  +	</UL>
  +
   	<LI><A HREF="performance.html#Sending_Plain_HTML_as_Compressed">Sending Plain HTML as Compressed Output</A>
   	<LI><A HREF="performance.html#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   </UL>
  @@ -294,7 +313,7 @@
   	<LI><A HREF="install.html#The_Gory_Details">The Gory Details</A>
   	<UL>
   
  -		<LI><A HREF="install.html#Sources_Configuration_perl_Make">Sources Configuration (perl Makefile.PL ...)</A>
  +		<LI><A HREF="install.html#Source_Configuration_perl_Makef">Source Configuration (perl Makefile.PL ...)</A>
   		<UL>
   
   			<LI><A HREF="install.html#Configuration_parameters">Configuration parameters</A>
  @@ -430,6 +449,7 @@
   	<LI><A HREF="install.html#General_Notes">General Notes</A>
   	<UL>
   
  +		<LI><A HREF="install.html#Is_it_possible_to_run_mod_perl_e">Is it possible to run mod_perl enabled Apache as suExec?</A>
   		<LI><A HREF="install.html#Should_I_Rebuild_mod_perl_if_I_h">Should I Rebuild mod_perl if I have Upgraded Perl?</A>
   		<LI><A HREF="install.html#Perl_installation_requirements">Perl installation requirements</A>
   		<LI><A HREF="install.html#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
  @@ -477,26 +497,28 @@
   		<LI><A HREF="config.html#The_Sample_Start_up_File">The Sample Start-up File</A>
   		<LI><A HREF="config.html#What_Modules_Should_You_Add_to_t">What Modules Should You Add to the Start-up File and Why</A>
   		<LI><A HREF="config.html#The_Confusion_with_use_at_the_">The Confusion with use() at the Server Start-up File</A>
  -		<LI><A HREF="config.html#The_Confusion_with_Global_Variab">The Confusion with Global Variables in Start-up File</A>
  +		<LI><A HREF="config.html#The_Confusion_with_Global_Variab">The Confusion with Global Variables in the Start-up File</A>
   	</UL>
   
  -	<LI><A HREF="config.html#_Perl_Perl_Sections">&lt;Perl&gt;...&lt;/Perl&gt; Sections</A>
  +	<LI><A HREF="config.html#Apache_Configuration_in_Perl">Apache Configuration in Perl</A>
   	<UL>
   
   		<LI><A HREF="config.html#Usage">Usage</A>
   		<LI><A HREF="config.html#Enabling">Enabling</A>
  +		<LI><A HREF="config.html#Caveats">Caveats</A>
   		<LI><A HREF="config.html#Verifying">Verifying</A>
  +		<LI><A HREF="config.html#Strict_Perl_Sections">Strict &lt;Perl&gt; Sections</A>
   		<LI><A HREF="config.html#Debugging">Debugging</A>
   	</UL>
   
   	<LI><A HREF="config.html#Validating_the_Configuration_Syn">Validating the Configuration Syntax</A>
   	<LI><A HREF="config.html#Enabling_Remote_Server_Configura">Enabling Remote Server Configuration Reports</A>
  -	<LI><A HREF="config.html#Publishing_Port_Numbers_Differen">Publishing Port Numbers Different from 80</A>
  +	<LI><A HREF="config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>
   	<LI><A HREF="config.html#Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A>
   	<LI><A HREF="config.html#General_Pitfalls">General Pitfalls</A>
   	<UL>
   
  -		<LI><A HREF="config.html#My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as a Plain Text Instead of Being Executed by the Webserver</A>
  +		<LI><A HREF="config.html#My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A>
   		<LI><A HREF="config.html#My_Script_Works_under_mod_cgi_b">My Script Works under mod_cgi, but when Called via mod_perl I Get a 'Save-As' Prompt</A>
   		<LI><A HREF="config.html#Is_There_a_Way_to_Provide_a_Diff">Is There a Way to Provide a Different startup.pl File for Each Individual Virtual Host</A>
   		<LI><A HREF="config.html#Is_There_a_Way_to_Modify_INC_on">Is There a Way to Modify @INC on a Per-Virtual-Host or Per-Location Basis.</A>
  @@ -507,6 +529,7 @@
   	<LI><A HREF="config.html#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="config.html#Apache_Restarts_Twice_On_Start">Apache Restarts Twice On Start</A>
   	<LI><A HREF="config.html#Knowing_the_proxy_pass_ed_Connec">Knowing the proxy_pass'ed Connection Type</A>
  +	<LI><A HREF="config.html#Adding_Custom_Configuration_Dire">Adding Custom Configuration Directives </A>
   </UL>
   <P>
   <LI><A HREF="strategy.html"><B><FONT SIZE=+1>Choosing the Right Strategy</FONT></B></A></LI><P>
  @@ -545,6 +568,9 @@
   		<LI><A HREF="strategy.html#Three_Machines_Model">Three Machines Model</A>
   	</UL>
   
  +	<LI><A HREF="strategy.html#Do_not_put_mod_ssl_into_mod_perl">Do not put mod_ssl into mod_perl server</A>
  +	<LI><A HREF="strategy.html#Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A>
  +	<LI><A HREF="strategy.html#Multithreading_or_not_Multithrea">Multithreading or not Multithreading</A>
   </UL>
   <P>
   <LI><A HREF="scenario.html"><B><FONT SIZE=+1>Real World Scenarios</FONT></B></A></LI><P>
  @@ -613,9 +639,19 @@
   		<LI><A HREF="scenario.html#Building_process">Building process</A>
   	</UL>
   
  -	<LI><A HREF="scenario.html#mod_proxy_add_forward_and_X_Forw">mod_proxy_add_forward and X-Forwarded-For header</A>
  +	<LI><A HREF="scenario.html#Getting_the_Remote_Server_IP_in_">Getting the Remote Server IP in the Back-end server in the Proxy Setup</A>
  +	<UL>
  +
  +		<LI><A HREF="scenario.html#Build">Build</A>
  +		<LI><A HREF="scenario.html#Use">Use</A>
  +		<LI><A HREF="scenario.html#Security">Security</A>
  +		<LI><A HREF="scenario.html#Caveats">Caveats</A>
  +		<LI><A HREF="scenario.html#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A>
  +	</UL>
  +
   	<LI><A HREF="scenario.html#HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A>
   	<LI><A HREF="scenario.html#mod_rewrite_Examples">mod_rewrite Examples</A>
  +	<LI><A HREF="scenario.html#Caching_in_mod_proxy">Caching in mod_proxy</A>
   </UL>
   <P>
   <LI><A HREF="frequent.html"><B><FONT SIZE=+1>Frequent mod_perl problems</FONT></B></A></LI><P>
  @@ -683,6 +719,7 @@
   
   		<LI><A HREF="troubleshooting.html#Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A>
   		<LI><A HREF="troubleshooting.html#rwrite_returned_1">rwrite returned -1</A>
  +		<LI><A HREF="troubleshooting.html#Can_t_upgrade_that_kind_of_scala">Can't upgrade that kind of scalar ...</A>
   		<LI><A HREF="troubleshooting.html#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>
   		<LI><A HREF="troubleshooting.html#Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A>
   		<LI><A HREF="troubleshooting.html#Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A>
  @@ -847,9 +884,14 @@
   	<LI><A HREF="debug.html#Hanging_processes_Detection_and">Hanging processes: Detection and Diagnostics</A>
   	<UL>
   
  -		<LI><A HREF="debug.html#An_Example_of_the_Code_that_Migh">An Example of the Code that Might Hang the Process</A>
  +		<LI><A HREF="debug.html#An_Example_of_Code_that_Might_Ha">An Example of Code that Might Hang a Process</A>
   		<LI><A HREF="debug.html#Detecting_hanging_processes">Detecting hanging processes</A>
   		<LI><A HREF="debug.html#Determination_of_the_reason">Determination of the reason</A>
  +		<UL>
  +
  +			<LI><A HREF="debug.html#Using_gdb">Using gdb</A>
  +		</UL>
  +
   	</UL>
   
   	<LI><A HREF="debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>
  @@ -866,11 +908,11 @@
   
   	</UL>
   
  -	<LI><A HREF="debug.html#Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A>
  +	<LI><A HREF="debug.html#Handling_Server_Timeout_Cases_an">Handling Server Timeout Cases and Working with $SIG{ALRM}</A>
   	<LI><A HREF="debug.html#Looking_inside_the_server">Looking inside the server</A>
   	<UL>
   
  -		<LI><A HREF="debug.html#Apache_Status_Embedded_inter">Apache::Status -- Embedded interpreter status information</A>
  +		<LI><A HREF="debug.html#Apache_Status_Embedded_Inter">Apache::Status -- Embedded Interpreter Status Information</A>
   		<UL>
   
   			<LI><A HREF="debug.html#Minimal_Configuration">Minimal Configuration</A>
  @@ -888,17 +930,17 @@
   
   	</UL>
   
  -	<LI><A HREF="debug.html#Sometimes_script_works_sometime">Sometimes script works, sometimes does not</A>
  +	<LI><A HREF="debug.html#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A>
   	<LI><A HREF="debug.html#Code_Debug">Code Debug</A>
   	<UL>
   
   		<LI><A HREF="debug.html#Locating_and_correcting_Syntax_E">Locating and correcting Syntax Errors</A>
   		<LI><A HREF="debug.html#Using_Apache_FakeRequest_to_Deb">Using Apache::FakeRequest to Debug Apache Perl Modules</A>
  -		<LI><A HREF="debug.html#Finding_the_Line_Number_the_Erro">Finding the Line Number the Error/Warning has been Triggered at</A>
  -		<LI><A HREF="debug.html#Using_print_Function_for_Debug">Using print() Function for Debugging</A>
  +		<LI><A HREF="debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A>
  +		<LI><A HREF="debug.html#Using_print_for_Debugging">Using print() for Debugging</A>
   		<LI><A HREF="debug.html#Using_print_and_Data_Dumper_f">Using print() and Data::Dumper for Debugging</A>
  -		<LI><A HREF="debug.html#The_Importance_of_Good_Coding_St">The Importance of Good Coding Style and Conciseness</A>
  -		<LI><A HREF="debug.html#Introduction_into_Perl_Debugger">Introduction into Perl Debugger</A>
  +		<LI><A HREF="debug.html#The_Importance_of_a_Good_Concise">The Importance of a Good Concise Coding Style</A>
  +		<LI><A HREF="debug.html#Introduction_to_the_Perl_Debugge">Introduction to the Perl Debugger</A>
   		<LI><A HREF="debug.html#Interactive_Perl_Debugging_under">Interactive Perl Debugging under mod_cgi</A>
   		<LI><A HREF="debug.html#Non_Interactive_Perl_Debugging_u">Non-Interactive Perl Debugging under mod_perl</A>
   		<LI><A HREF="debug.html#Interactive_mod_perl_Debugging">Interactive mod_perl Debugging</A>
  @@ -920,8 +962,10 @@
   	<LI><A HREF="debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
   	<LI><A HREF="debug.html#Code_Profiling">Code Profiling</A>
   	<LI><A HREF="debug.html#Devel_Peek">Devel::Peek</A>
  -	<LI><A HREF="debug.html#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  +	<LI><A HREF="debug.html#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A>
   	<LI><A HREF="debug.html#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
  +	<LI><A HREF="debug.html#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A>
  +	<LI><A HREF="debug.html#Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A>
   </UL>
   <P>
   <LI><A HREF="browserbugs.html"><B><FONT SIZE=+1>Workarounds for some known bugs in browsers.</FONT></B></A></LI><P>
  @@ -944,6 +988,7 @@
   	<LI><A HREF="modules.html#Apache_RegistryNG_Apache_Re">Apache::RegistryNG -- Apache::Registry New Generation</A>
   	<LI><A HREF="modules.html#Apache_RegistryBB_Apache_Re">Apache::RegistryBB -- Apache::Registry Bare Bones </A>
   	<LI><A HREF="modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  +	<LI><A HREF="modules.html#Apache_OutputChain_Chain_Sta">Apache::OutputChain -- Chain Stacked Perl Handlers</A>
   	<LI><A HREF="modules.html#Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location </A>
   	<LI><A HREF="modules.html#Apache_LogSTDERR">Apache::LogSTDERR</A>
   	<LI><A HREF="modules.html#Apache_RedirectLogFix">Apache::RedirectLogFix</A>
  @@ -957,6 +1002,7 @@
   	<LI><A HREF="snippets.html#Emulating_the_Authentication_Mec">Emulating the Authentication Mechanism</A>
   	<LI><A HREF="snippets.html#Caching_the_POSTed_Data">Caching the POSTed Data</A>
   	<LI><A HREF="snippets.html#Cache_Control_for_Regular_and_Er">Cache Control for Regular and Error Modes</A>
  +	<LI><A HREF="snippets.html#Convert_a_POST_Request_into_a_GE">Convert a POST Request into a GET Request</A>
   	<LI><A HREF="snippets.html#Redirect_a_POST_Request_Forward">Redirect a POST Request, Forwarding the Content</A>
   	<LI><A HREF="snippets.html#Reading_POST_Data_then_Redirect">Reading POST Data, then Redirecting or Doing Something Else</A>
   	<LI><A HREF="snippets.html#Redirecting_While_Maintaining_En">Redirecting While Maintaining Environment Variables</A>
  @@ -975,7 +1021,11 @@
   	<LI><A HREF="snippets.html#Code_Unloading">Code Unloading</A>
   	<LI><A HREF="snippets.html#A_Simple_Handler_To_Print_The_En">A Simple Handler To Print The Environment Variables</A>
   	<LI><A HREF="snippets.html#mod_rewrite_Based_On_Query_Strin">mod_rewrite Based On Query String and URI Implemented in Perl</A>
  +	<LI><A HREF="snippets.html#PerlTransHandler_example">PerlTransHandler example</A>
   	<LI><A HREF="snippets.html#Setting_PerlHandler_Based_on_MIM">Setting PerlHandler Based on MIME Type</A>
  +	<LI><A HREF="snippets.html#SSI_and_Embperl_Doing_Both">SSI and Embperl -- Doing Both</A>
  +	<LI><A HREF="snippets.html#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
  +	<LI><A HREF="snippets.html#Authentication_Snippets">Authentication Snippets</A>
   	<LI><A HREF="snippets.html#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
   	<LI><A HREF="snippets.html#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
   </UL>
  @@ -1043,6 +1093,7 @@
   	<LI><A HREF="download.html#mod_proxy_add_forward">mod_proxy_add_forward</A>
   	<LI><A HREF="download.html#httperf_webserver_Benchmarking">httperf - webserver Benchmarking tool</A>
   	<LI><A HREF="download.html#ab_ApacheBench">ab - ApacheBench</A>
  +	<LI><A HREF="download.html#mod_backhand_load_balancing_f">mod_backhand -- load balancing for Apache</A>
   	<LI><A HREF="download.html#High_Availability_Linux_Project">High-Availability Linux Project</A>
   	<LI><A HREF="download.html#Apache_Request">Apache::Request</A>
   	<LI><A HREF="download.html#DataBases">DataBases</A>
  @@ -1155,7 +1206,7 @@
   
   <TR ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 03/04/2000
  +HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 04/09/2000
   </FONT></B></TD>
   
   <TD><A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg"  BORDER=0 ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  
  
  
  1.13      +197 -125  modperl-site/guide/install.html
  
  Index: install.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/install.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- install.html	2000/03/04 20:31:45	1.12
  +++ install.html	2000/04/09 14:19:39	1.13
  @@ -30,7 +30,7 @@
   	<LI><A HREF="#The_Gory_Details">The Gory Details</A>
   	<UL>
   
  -		<LI><A HREF="#Sources_Configuration_perl_Make">Sources Configuration (perl Makefile.PL ...)</A>
  +		<LI><A HREF="#Source_Configuration_perl_Makef">Source Configuration (perl Makefile.PL ...)</A>
   		<UL>
   
   			<LI><A HREF="#Configuration_parameters">Configuration parameters</A>
  @@ -166,6 +166,7 @@
   	<LI><A HREF="#General_Notes">General Notes</A>
   	<UL>
   
  +		<LI><A HREF="#Is_it_possible_to_run_mod_perl_e">Is it possible to run mod_perl enabled Apache as suExec?</A>
   		<LI><A HREF="#Should_I_Rebuild_mod_perl_if_I_h">Should I Rebuild mod_perl if I have Upgraded Perl?</A>
   		<LI><A HREF="#Perl_installation_requirements">Perl installation requirements</A>
   		<LI><A HREF="#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
  @@ -237,20 +238,51 @@
   despair, the next sections will explain in detail each and every step.
   
   <P>
  +Of course there is a way of installing mod_perl in only a couple of minutes
  +if you are using a Linux distrbution that uses RPM or deb files: 
  +
  +<P>
  +<PRE>  % rpm -i apache-xx.xx.rpm
  +  % rpm -i mod_perl-xx.xx.rpm
  +</PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE>  % dpkg -i apache-xx.xx.deb
  +  % dpkg -i mod_perl-xx.xx.deb
  +</PRE>
  +<P>
  +These should set up both Apache and mod_perl correctly for your system.
  +Using a packaged distribution can make installing and reinstalling a lot
  +quicker and easier. (Note that the filenames will vary, and <EM>xx.xx</EM> will differ.)
  +
  +<P>
  +Since mod_perl can be configured in many different ways (features can be
  +enabled or disabled, directories can be modified, etc.) it's preferable to
  +use a manual installation, as a prepackaged version might not suite your
  +needs. Manual installation will allow you to make the fine tuning for the
  +best performance as well.
  +
  +<P>
  +We will talk in extension about the prepackaged versions and scenarios to
  +prepare your own packages for reuse on many machines in this chapter.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="The_Gory_Details">The Gory Details</A></H1></CENTER>
   <P>
   We saw that the basic mod_perl installation is quite simple and takes about
   10 commands. You can copy and paste them from these pages. The parameter <CODE>EVERYTHING=1</CODE> selects a lot of options, but sometimes you will need different ones. You
   may need to pass only specific parameters, to bundle other components with
  -mod_perl etc. You may want to build mod_perl as loadable object instead of
  -compiling it into Apache, so that it can be upgraded without rebuilding
  +mod_perl etc. You may want to build mod_perl as a loadable object instead
  +of compiling it into Apache, so that it can be upgraded without rebuilding
   Apache itself.
   
   <P>
  -To accomplish this you will want to understand various techniques for
  +To accomplish this you will need to understand various techniques for
   mod_perl configuration and building. You need to know what configuration
  -parameters are available to you and when to use them.
  +parameters are available to you and when and how to use them.
   
   <P>
   As with Perl, with mod_perl simple things are simple. But when you need to
  @@ -269,17 +301,17 @@
   We can clearly separate the installation process into the following stages:
   
   <UL>
  -<P><LI><STRONG><A NAME="item_Sources">Sources Configuration,</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Source">Source Configuration,</A></STRONG>
   <P><LI><STRONG><A NAME="item_Building">Building,</A></STRONG>
   <P><LI><STRONG><A NAME="item_Testing">Testing and</A></STRONG>
   <P><LI><STRONG><A NAME="item_Installation">Installation.</A></STRONG>
   </UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Sources_Configuration_perl_Make">Sources Configuration (perl Makefile.PL ...)</A></H2></CENTER>
  +<CENTER><H2><A NAME="Source_Configuration_perl_Makef">Source Configuration (perl Makefile.PL ...)</A></H2></CENTER>
   <P>
   Before building and installing mod_perl you have to configure it. You
  -configure mod_perl as any other Perl module:
  +configure mod_perl just like any other Perl module:
   
   <P>
   <PRE>  % perl Makefile.PL [parameters]
  @@ -302,7 +334,7 @@
   <P><DT><STRONG><A NAME="item_Per">Per-module configuration scripts (ConfigStart/End)</A></STRONG><DD>
   <P>
   This is a mechanism modules can use to link themselves into the
  -configuration process. It is useful for automatically adjusting
  +configuration process. It is useful for automatically adjusting the
   configuration and build parameters from the modules sources. It is
   triggered by <CODE>ConfigStart</CODE>/<CODE>ConfigEnd</CODE> sections inside
   <EM>modulename</EM><CODE>.module</CODE> files.
  @@ -317,15 +349,15 @@
   Since Apache 1.3 this is the way to install mod_perl as cleanly as
   possible. Currently this is a pure Unix-based solution because at present
   the complete Apache 1.3 source configuration mechanism is only available
  -under Unix. It doesn't work on the Win32 platform.
  +under Unix. It doesn't work on the Win32 platform for example.
   
   <P><DT><STRONG><A NAME="item_Dynamic">Dynamic Shared Object (DSO) support</A></STRONG><DD>
   <P>
  -This is beside Windows NT support one of most interesting features in
  +Besides Windows NT support this is one of most interesting features in
   Apache 1.3. Its a way to build Apache modules as so-called <CODE>dynamic
   shared objects</CODE> (usually named <EM>modulename</EM><CODE>.so</CODE>) which can be loaded via the <CODE>LoadModule</CODE> directive in Apache's <CODE>httpd.conf</CODE> file. The benefit is that the modules are part of the <CODE>httpd</CODE> program only on demand, i.e. only when the user wants a module is it loaded
  -into the address space of the <CODE>httpd</CODE> executable. This is interesting for instance in memory consumption and
  -upgrade issues.
  +into the address space of the <CODE>httpd</CODE> executable. This is interesting for instance in relation to memory
  +consumption and upgrading.
   
   <P>
   The DSO mechanism is provided by Apache's <CODE>mod_so</CODE> module which needs to be compiled into the <CODE>httpd</CODE> binary. This is done automatically when DSO is enabled for module <CODE>mod_xxx</CODE> via <CODE>configure
  @@ -335,7 +367,7 @@
   <P><DT><STRONG><A NAME="item_APache">APache eXtenSion (APXS) support tool</A></STRONG><DD>
   <P>
   This is a new support tool from Apache 1.3 which can be used to build an
  -Apache module as a DSO even <STRONG>outside</STRONG> the Apache source-tree. One can say <CODE>APXS</CODE> is for Apache what <CODE>MakeMaker</CODE> and <CODE>XS</CODE> is for Perl. It knows the platform dependent build parameters for making
  +Apache module as a DSO even <STRONG>outside</STRONG> the Apache source-tree. One can say <CODE>APXS</CODE> is for Apache what <CODE>MakeMaker</CODE> and <CODE>XS</CODE> are for Perl. It knows the platform dependent build parameters for making
   DSO files and provides an easy way to run the build commands with them.
   
   </DL>
  @@ -355,9 +387,9 @@
   <CODE>Makefile.PL</CODE> controlled the Apache build process.
   
   <P>
  -This approach is problematic in several ways. It is not very clean. Because
  -it is assumed that mod_perl is the only third-party module which has to be
  -integrated into Apache, it is very restrictive.
  +This approach is problematic in several ways. It is very restrictive and
  +not very clean because it assumes that mod_perl is the only third-party
  +module which has to be integrated into Apache.
   
   <P>
   The new approach described below avoids these problems. It prepares only
  @@ -388,13 +420,13 @@
   <PRE>  &quot;Configure mod_perl with ../apache_x.x.x/src ?&quot;
   </PRE>
   <P>
  -<CODE>APACHE_SRC</CODE> should be used to define the Apache's source tree directory. For example:
  +<CODE>APACHE_SRC</CODE> should be used to define Apache's source tree directory. For example:
   
   <P>
   <PRE>  APACHE_SRC=../apache_x.x.x/src
   </PRE>
   <P>
  -Unless <CODE>APACHE_SRC</CODE> specified, <EM>Makefile.PL</EM> makes an intelligent guess by looking at the directories at the same level
  +Unless <CODE>APACHE_SRC</CODE> is specified, <EM>Makefile.PL</EM> makes an intelligent guess by looking at the directories at the same level
   as the mod_perl sources and suggests a directory with the highest version
   of Apache found there.
   
  @@ -432,7 +464,7 @@
   against.
   
   <P>
  -<CODE>PREP_HTTPD=1</CODE> just means default '<CODE>n</CODE>' to the second prompt, meaning <EM>do not build (make) httpd in the Apache source tree</EM>. But it still will ask you about Apache's source location even if you have
  +<CODE>PREP_HTTPD=1</CODE> just means default '<CODE>n</CODE>' to the second prompt, meaning <EM>do not build (make) httpd in the Apache source tree</EM>. But it will still ask you about Apache's source location even if you have
   used the <CODE>APACHE_SRC</CODE> parameter. Providing the <CODE>APACHE_SRC</CODE>
   parameter will just eliminate the need for <CODE>perl Makefile.PL</CODE> to make a guess.
   
  @@ -451,7 +483,11 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H4><A NAME="Callback_Hooks">Callback Hooks</A></H4></CENTER>
   <P>
  -META: Refer to/explain callback hooks term
  +A callback hook (abbrev. <EM>callback</EM>) is a reference to a subroutine. In Perl we create callbacks with the $callback&nbsp;=
  +\&subroutine syntax, where in this example, <CODE>$callback</CODE> contains a reference to the subroutine called <EM>"subroutine"</EM>. Callbacks are used when we want some action (subroutine call) to occur
  +when some event takes place. Since we don't know exactly when the event
  +will take place we give the event handler a callback to the subroutine we
  +want executed. The handler will call our subroutine at the right time.
   
   <P>
   By default, all callback hooks except for <CODE>PerlHandler</CODE> are turned off. You may enable them by editing <EM>src/modules/perl/Makefile</EM>, or when running <CODE>perl Makefile.PL</CODE>.
  @@ -520,12 +556,12 @@
   <EM>$Config{sitearchexp}/auto/Apache/include</EM> directory.
   
   <P>
  -The reason for installing the header files is to make life simple for
  +The reason for installing the header files is to make life simpler for
   module authors/users when building/installing a module that taps into some
   Apache C functions, e.g. <CODE>Embperl</CODE>, <CODE>Apache::Peek</CODE>, etc.
   
   <P>
  -If you wish not to install these files use:
  +If you don't wish to install these files use:
   
   <P>
   <PRE>  APACHE_HEADER_INSTALL=0
  @@ -534,10 +570,10 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H4><A NAME="PERL_STATIC_EXTS">PERL_STATIC_EXTS</A></H4></CENTER>
   <P>
  -Normally, if an extension is linked static with Perl it is listed in
  -<CODE>Config.pm</CODE>'s <CODE>$Config{static_exts}</CODE>, in which case mod_perl will also link this extension static with httpd.
  -However, if an extension is linked static with Perl after it is installed,
  -it is not listed in
  +Normally, if an extension is statically linked with Perl it is listed in
  +<CODE>Config.pm</CODE>'s <CODE>$Config{static_exts}</CODE>, in which case mod_perl will also statically link this extension with
  +httpd. However, if an extension is statically linked with Perl after it is
  +installed, it is not listed in
   <CODE>Config.pm</CODE>. You may either edit <CODE>Config.pm</CODE> and add these extensions, or configure mod_perl like this:
   
   <P>
  @@ -637,12 +673,12 @@
   <P>
   Notice that this file can be located in your home directory or in the
   <EM>../</EM> directory relative to the mod_perl distribution directory. This file can
  -also start with dot (<EM>.makepl_args.mod_perl</EM>) so you can nicely keep it along with the rest of the dot files in your
  -home directory.
  +also start with dot (<EM>.makepl_args.mod_perl</EM>) so you can keep it nicely hidden along with the rest of the dot files in
  +your home directory.
   
   <P>
  -There is a sample <EM>makepl_args.mod_perl</EM> in the <EM>eg/</EM> directory of mod_perl distribution package, in which you might find a few
  -options to enable experimental features to play with too!
  +There is a sample <EM>makepl_args.mod_perl</EM> in the <EM>eg/</EM> directory of the mod_perl distribution package, in which you might find a
  +few options to enable experimental features to play with too!
   
   <P>
   If you are faced with a compiled Apache and no trace of the parameters used
  @@ -665,14 +701,14 @@
   But this will only work if you have an unstripped httpd binary. By default, <CODE>make install</CODE> strips the binary before installing it.
   
   <P>
  -Another approach is to configure <A HREF="././debug.html#Apache_Status_Embedded_inter">/perl-status location</A> and run <A
  +Another approach is to configure <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status location</A> and run <A
   HREF="http://localhost/perl-status?hooks">http://localhost/perl-status?hooks</A>
   to check the enabled hooks.
   
   <P>
   Yet another approach is to try to use this parameter in the configuration
  -file. If it wasn't enabled Apache will tell you when you will start the
  -server, by reporting an unknown directive.
  +file. If it wasn't enabled Apache will tell you when you start the server,
  +by reporting an unknown directive.
   
   <P>
   Similarly, for example, when you attempt to use <CODE>PerlAuthenHandler</CODE>
  @@ -682,7 +718,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Using_an_Alternative_Configurati">Using an Alternative Configuration File</A></H3></CENTER>
   <P>
  -By default mod_perl provides its own copy of the <EM>Configuration</EM> file to Apache's <CODE>./configure</CODE> utility. If you wish to pass it your own copy, do this:
  +By default mod_perl provides its own copy of the <EM>Configuration</EM> file to Apache's <CODE>./configure</CODE> utility. If you wish to pass it your own version, do this:
   
   <P>
   <PRE>  % perl Makefile.PL CONFIG=Configuration.custom
  @@ -709,11 +745,11 @@
      Aborting!
   </PRE>
   <P>
  -you've got a problem with your compiler. There is chance that it's
  +you've got a problem with your compiler. It is possible that it's
   improperly installed or not installed at all. Sometimes the reason is that
   your Perl executable was built on a different machine, and the software
   installed on your machine is not the same. Generally this happens when you
  -install the prebuilt packages, like RPM or DEB. The dependencies weren't
  +install the prebuilt packages, like RPM or deb. The dependencies weren't
   properly defined in the Perl binary package and you were allowed to install
   it, although some essential package is not installed.
   
  @@ -792,12 +828,18 @@
   Now you should be able to build mod_perl without any problems.
   
   <P>
  -Note that the symbolic link 
  +Note that you might need to prepare this symbolic link as well:
   
   <P>
   <PRE>  lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0
   </PRE>
   <P>
  +with:
  +
  +<P>
  +<PRE>  % ln -s libgdbm.so.2.0.0 libgdbm.so.2
  +</PRE>
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H4><A NAME="Undefined_reference_to_PL_perl_">Undefined reference to `PL_perl_destruct_level'</A></H4></CENTER>
   <P>
  @@ -848,10 +890,11 @@
   <P>
   which compiles the source files and creates an httpd binary and/or a
   separate library for each module, which can either be inserted into the
  -httpd binary when <CODE>make</CODE> is called from Apache source directory or loaded later, at run time.
  +httpd binary when <CODE>make</CODE> is called from the Apache source directory or loaded later, at run time.
   
   <P>
  -Note: don't put the mod_perl directory inside the Apache directory, since <CODE>Apache::src</CODE> won't work then!
  +Note: don't put the mod_perl directory inside the Apache directory. This
  +confuses the build process.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -913,7 +956,7 @@
   </PRE>
   <P>
   Fortunately mod_perl comes with a bunch of tests, which attempt to use all
  -the features you asked for at the configuration stage. If any of the test
  +the features you asked for at the configuration stage. If any of the tests
   fails, the <CODE>make test</CODE> stage will fail.
   
   <P>
  @@ -922,11 +965,11 @@
   
   <P>
   Each file in the testing suite generally includes more than one test, but
  -when you do the testing, the program will solely report how many tests were
  +when you do the testing, the program will only report how many tests were
   passed and the total number of tests defined in the test file. However if
  -not all the tests in the file fail you want to know which ones did. To gain
  -this information you should run the tests in verbose mode. You can enable
  -this mode by using the <CODE>TEST_VERBOSE</CODE>
  +only some of the tests in the file fail you want to know which ones failed.
  +To gain this information you should run the tests in verbose mode. You can
  +enable this mode by using the <CODE>TEST_VERBOSE</CODE>
   parameter:
   
   <P>
  @@ -973,7 +1016,7 @@
   </PRE>
   <P>
   The <CODE>TEST</CODE> script starts the server before the test is executed. If for some reason it
  -fails to start, use <CODE>make start_httpd</CODE> to start it explicitly.
  +fails to start, use <CODE>make start_httpd</CODE> to start it manually.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -1000,19 +1043,28 @@
   For all RedHat fans, before you build Apache yourself, do:
   
   <P>
  -<PRE> % rpm -e apache
  +<PRE>  % rpm -e apache
   </PRE>
   <P>
   to remove the pre-installed RPM package first!
   
   <P>
  +Debian users would do:
  +
  +<P>
  +<PRE>  % dpkg -r apache
  +</PRE>
  +<P>
  +instead.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H4><A NAME="make_test_skipping_test_on_">make test......skipping test on this platform</A></H4></CENTER>
   <P>
   While doing <CODE>make test</CODE> you will notice that some of the tests are reported as <EM>skipped</EM>. The reason is that you are missing some optional modules for these test
   to be passed. For a hint you might want to peek at the content of each test
   (you will find them all in the <CODE>./t</CODE> directory (mnemonic - t, tests). I'll list a few examples, but of course
  -the requirements may change in the future.
  +things may change in the future.
   
   <P>
   <PRE>  modules/cookie......skipping test on this platform
  @@ -1107,7 +1159,7 @@
   <P><DT><STRONG><A NAME="item_mod_perl">mod_perl's Makefile</A></STRONG><DD>
   <P>
   When <CODE>perl Makefile.PL</CODE> is executed,
  -<EM>$APACHE_SRC/modules/perl/Makefile</EM> will be modified to enable various options (e.g. <CODE>ALL_HOOKS=1</CODE>).
  +<EM>$APACHE_SRC/modules/perl/Makefile</EM> may need to be modified to enable various options (e.g. <CODE>ALL_HOOKS=1</CODE>).
   
   <P>
   Optionally, instead of tweaking the options during <CODE>perl Makefile.PL</CODE>
  @@ -1184,8 +1236,8 @@
   <CENTER><H2><A NAME="The_All_In_One_Way">The All-In-One Way</A></H2></CENTER>
   <P>
   If your goal is just to build and install Apache with mod_perl out of their
  -source trees and have no special interests in further adjusting or
  -enhancing Apache proceed as before:
  +source trees and have no special interest in further adjusting or enhancing
  +Apache proceed as before:
   
   <P>
   <PRE>  % tar xzvf apache_x.x.x.tar.gz
  @@ -1213,7 +1265,7 @@
   <OL>
   <P><LI><STRONG><A NAME="item_Prepare_the_Apache_source_tree">Prepare the Apache source tree</A></STRONG>
   <P>
  -The first step is as before extracts the distributions:
  +The first step is as before, extract the distributions:
   
   <P>
   <PRE>  % tar xvzf apache_x.x.x.tar.gz
  @@ -1252,7 +1304,7 @@
   hierarchy.
   
   <P>
  -Important: If you use <CODE>PREP_HTTPD</CODE> as described above, to complete the build you must go into the Apache
  +<STRONG>Important:</STRONG> If you use <CODE>PREP_HTTPD</CODE> as described above, to complete the build you must go into the Apache
   source directory and run <CODE>make</CODE>
   and <CODE>make install</CODE>.
   
  @@ -1341,7 +1393,7 @@
   <PRE>  --enable-shared=perl
   </PRE>
   <P>
  -to the Apache's <CODE>./configure</CODE> options.
  +to Apache's <CODE>./configure</CODE> options.
   
   <P>
   As you can see only an additional <CODE>USE_DSO=1</CODE> or
  @@ -1422,8 +1474,8 @@
   All these scenarios were tested on a Linux platform, you might need to
   refer to the specific component's documentation if something doesn't work
   for you as described below. The intention of this section is not to show
  -how to install other non-mod_perl components alone, but how to do this in a
  -bundle with mod_perl.
  +you how to install other non-mod_perl components alone, but how to do this
  +in a bundle with mod_perl.
   
   <P>
   Also, notice that the links I've used below are very likely to have changed
  @@ -1633,9 +1685,7 @@
           --enable-module=define \
           --activate-module=src/modules/perl/libperl.a \
           --enable-shared=max \
  -        --disable-shared=perl \
  -        --enable-suexec --suexec-caller=nobody \
  -        --suexec-uidmin=500 --suexec-gidmin=500
  +        --disable-shared=perl
   </PRE>
   <P><LI>
   <P>
  @@ -1810,8 +1860,9 @@
   Installation of mod_perl and all the required packages is much easier with
   help of the <CODE>CPAN.pm</CODE> module, which provides you among other features with a shell interface to
   the CPAN repository. CPAN is the Comprehensive Perl Archive Network, a
  -repository of thousands of Perl modules, scripts and documentation. See <A
  -HREF="http://cpan.org">http://cpan.org</A> for more information.
  +repository of thousands of Perl modules, scripts as well as a vast amount
  +of documentation. See <A HREF="http://cpan.org">http://cpan.org</A> for
  +more information.
   
   <P>
   The first thing first is to download the Apache source code and unpack it
  @@ -1832,17 +1883,16 @@
   <PRE>  cpan&gt; 
   </PRE>
   <P>
  -It can be a good idea to install a special <CODE>CPAN</CODE> bundle of modules to make the use easier. The installation is as simple as
  -typing:
  +It can be a good idea to install a special <CODE>CPAN</CODE> bundle of modules to make using the CPAN module easier. Installation is as
  +simple as typing:
   
   <P>
   <PRE>  cpan&gt; install Bundle::CPAN
   </PRE>
   <P>
  -The <CODE>CPAN</CODE> shell will download mod_perl for you, unpack it, check for the
  -prerequisites, detect any missing third party modules, and download and
  -install them. All you need to do to install mod_perl is to type at the
  -prompt:
  +The <CODE>CPAN</CODE> shell can download mod_perl for you, unpack it, check for prerequisites,
  +detect any missing third party modules, and download and install them. All
  +you need to do to install mod_perl is to type at the prompt:
   
   <P>
   <PRE>  cpan&gt; install mod_perl
  @@ -1891,22 +1941,21 @@
   <PRE>  % make install
   </PRE>
   <P>
  -which will complete the installation by installing Apache headers and the
  +which will complete the installation by installing Apache's headers and the
   binary in the appropriate directories.
   
   <P>
  -The only caveat of described process is that you don't have control over
  -the configuration process. Actually, that problem is easy to solve -- you
  -can tell &lt;CPAN.pm&gt; to pass whatever parameters you want to <CODE>perl Makefile.PL</CODE>. You do this with <CODE>o conf makepl_arg</CODE>
  -command:
  +The only caveat of the process I've described is that you don't have
  +control over the configuration process. Actually, that problem is easy to
  +solve -- you can tell <CODE>CPAN.pm</CODE> to pass whatever parameters you want to <CODE>perl Makefile.PL</CODE>. You do this with <CODE>o conf
  +makepl_arg</CODE> command:
   
   <P>
   <PRE>  cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1'
   </PRE>
   <P>
  -Just list all the parameters like you were to pass to the familiar
  -<CODE>perl Makefile.PL</CODE>. If you add the
  -<CODE>APACHE_SRC=/usr/src/apache_x.x.x/src</CODE> and <CODE>DO_HTTPD=1</CODE> parameters, you will be not asked a single question. Of course you must
  +Just list all the parameters as if you were passing them to the familiar <CODE>perl Makefile.PL</CODE>. If you add the
  +<CODE>APACHE_SRC=/usr/src/apache_x.x.x/src</CODE> and <CODE>DO_HTTPD=1</CODE> parameters, you will not be asked a single question. Of course you must
   give the correct path to the Apache source distribution.
   
   <P>
  @@ -1917,8 +1966,8 @@
   </PRE>
   <P>
   If you have previously set <CODE>makepl_arg</CODE> to some value, before you alter it for the mod_perl installation you will
  -probably want to save it somewhere so that you can restore it when you are
  -done with the mod_perl installation. To see the original value, use:
  +probably want to save it somewhere so that you can restore it when you have
  +finished with the mod_perl installation. To see the original value, use:
   
   <P>
   <PRE>  cpan&gt; o conf makepl_arg
  @@ -1934,13 +1983,14 @@
   This will install mod_perl if isn't yet installed, and many other packages
   such as: <CODE>ExtUtils::Embed</CODE>, <CODE>MIME::Base64</CODE>, <CODE>URI::URL</CODE>,
   <CODE>Digest::MD5</CODE>, <CODE>Net::FTP</CODE>, <CODE>LWP</CODE>, <CODE>HTML::TreeBuilder</CODE>, <CODE>CGI</CODE>,
  -<CODE>Devel::Symdump</CODE>, <CODE>Apache::DB</CODE>, <CODE>Tie::IxHash</CODE>, <CODE>Data::Dumper</CODE> and etc.
  +<CODE>Devel::Symdump</CODE>, <CODE>Apache::DB</CODE>, <CODE>Tie::IxHash</CODE>, <CODE>Data::Dumper</CODE> 
  +etc.
   
   <P>
   A helpful hint: If you have a system with all the Perl modules you use and
  -you want to replicate them all at some other place, and if you cannot just
  -copy the whole <CODE>/usr/lib/perl5</CODE> directory because of a possible binary incompatibility of the other system,
  -making your own bundle is a handy solution. To accomplish that the command
  +you want to replicate them all elsewhere, and if you cannot just copy the
  +whole <CODE>/usr/lib/perl5</CODE> directory because of a possible binary incompatibility on the other system,
  +making your own bundle is a handy solution. To accomplish this the command
   <CODE>autobundle</CODE> can be used on the CPAN shell command line. This command writes a bundle
   definition file for all modules that are installed for the currently
   running perl interpreter.
  @@ -1983,7 +2033,7 @@
   advanced packaging systems. For example, almost all Linux OS distributions
   use packaging tools on top of plain tar.gz, allowing you to track
   prerequisites for each package, and providing easy installation, upgrade
  -and cleanup. One of the most well-used packagers is RPM (Red Hat Package
  +and cleanup. One of the most widely-used packagers is RPM (Red Hat Package
   Manager). See <A HREF="http://www.rpm.org">http://www.rpm.org</A> for more
   information.
   
  @@ -1995,10 +2045,11 @@
   <P>
   It will even work on live machines! If you have two identical machines
   (identical software and hardware, although depending on your setup hardware
  -is less critical). Let's say that one is a live server and the other is in
  -development. You build an RPM with a mod_perl binary distribution, install
  -it on the development machine and find it working and stable. You can
  -install the RPM package on the live server without any fear. Make sure that <EM>httpd.conf</EM> is correct, since it generally includes parameters such as hostname which
  +may be less critical). Let's say that one is a live server and the other is
  +in development. You build an RPM with a mod_perl binary distribution,
  +install it on the development machine and satisfy yourself that it is
  +working and stable. You can then install the RPM package on the live server
  +without any fear. Make sure that <EM>httpd.conf</EM> is correct, since it generally includes parameters such as hostname which
   are unique to the live machine.
   
   <P>
  @@ -2082,10 +2133,10 @@
   match what you see in the Eagle Book and this Guide. If you are new to
   mod_perl, Apache, or both you will probably want to get familiar with the
   file system layout used by the examples given here before trying something
  -less standard.
  +non-standard.
   
   <P>
  -Finally, the RPMs found on a typical distribution CDs use mod_perl built
  +Finally, the RPMs found on a typical distribution's CDs use mod_perl built
   with Apache's Dynamic Shared Objects (<CODE>DSO</CODE>) support. While mod_perl can be successfully used as a DSO module, it adds
   a layer of complexity that you may want to live without for now.
   
  @@ -2365,7 +2416,7 @@
   <P>
   Some people have reported that even when the server responds positively to
   the <A HREF="././install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A> tests, the mod_perl API will not function properly. You may want to run the
  -below script to verify the availability of the mod_perl API.
  +following script to verify the availability of the mod_perl API.
   
   <P>
   <PRE>        use strict;
  @@ -2410,7 +2461,7 @@
   <P>
   Let's install the <EM>CGI.pm</EM> package, which includes a few other
   <CODE>CGI::*</CODE> modules. As usual, download the package from the CPAN repository, unpack it
  -and <CODE>chdir</CODE> to the newly-created directory.
  +and <A HREF="#item_chdir">chdir</A> to the newly-created directory.
   
   <P>
   Now do a standard <CODE>perl Makefile.PL</CODE> to prepare a <EM>Makefile</EM>, but this time tell <CODE>MakeMaker</CODE> to use your Perl installation directories instead of the defaults.
  @@ -2530,8 +2581,8 @@
   Of course this example is from version <EM>5.00503</EM> of Perl installed on my x86 architecture PC running Linux. That's why you
   see
   <EM>i386-linux</EM> and <EM>5.00503</EM>. If your system runs a different version of Perl, operating system,
  -processor or chipset architecture, then the directories will have different
  -names.
  +processor or chipset architecture, then some of the directories will have
  +different names.
   
   <P>
   I also have a perl-5.00561 installed under <CODE>/usr/local/lib/</CODE>
  @@ -2557,12 +2608,13 @@
   
   <P>
   All the platform specific files, such as compiled C files glued to Perl
  -with <CODE>XS</CODE> or <CODE>SWIG</CODE>, are supposed to go into <CODE>i386-linux</CODE> like directories.
  +with <CODE>XS</CODE> or <CODE>SWIG</CODE>, are supposed to go into the
  +<CODE>i386-linux</CODE>-like directories.
   
   <P>
  -Important: As we have installed the Perl modules into non-standard
  -directories, we have to let Perl know where to look for the four
  -directories. There are two ways to accomplish this. You can either set the <CODE>PERL5LIB</CODE> environment variable, or you can modify the
  +<STRONG>Important:</STRONG> As we have installed the Perl modules into non-standard directories, we
  +have to let Perl know where to look for the four directories. There are two
  +ways to accomplish this. You can either set the <CODE>PERL5LIB</CODE> environment variable, or you can modify the
   <CODE>@INC</CODE> variable in your scripts.
   
   <P>
  @@ -2616,7 +2668,7 @@
   <CODE>lib</CODE> module uses the <EM>BEGIN</EM> block as well, but internally.
   
   <P>
  -Now, let's assume the following scenario. I have installed <CODE>LWP</CODE>
  +Now, let's assume the following scenario. I have installed the <CODE>LWP</CODE>
   package in my local repository. Now I want to install another module (e.g.
   mod_perl) and it has <CODE>LWP</CODE> listed in its prerequisites list. I know that I have <CODE>LWP</CODE> installed, but when I run <CODE>perl Makefile.PL</CODE>
   for the module I'm about to install I'm told that I don't have <CODE>LWP</CODE>
  @@ -2640,7 +2692,7 @@
   </PRE>
   <P>
   Again make it a single line. If you use bash you can use multi-line
  -commands by terminating line with a backslash (<CODE>\</CODE>), like this:
  +commands by terminating split lines with a backslash (<CODE>\</CODE>), like this:
   
   <P>
   <PRE>  export PERL5LIB=/home/stas/lib/perl5/5.00503:\
  @@ -2704,7 +2756,7 @@
       /usr/lib/perl5/5.00503/CPAN/Config.pm
   </PRE>
   <P>
  -If there is no the <CODE>CPAN</CODE> shell configured on your system, when you start the shell for the first
  +If there is no <CODE>CPAN</CODE> shell configured on your system, when you start the shell for the first
   time it will ask you a dozen configuration questions and then create the <EM>Config.pm</EM> file for you.
   
   <P>
  @@ -2722,8 +2774,8 @@
   <PRE>  % cp /usr/lib/perl5/5.00503/CPAN/Config.pm /home/stas/.cpan/CPAN/MyConfig.pm
   </PRE>
   <P>
  -The only thing left is to change the base directory of &lt;.cpan&gt; in your local file to the one under your home directory. On my
  -machine I replace <CODE>/usr/src/.cpan</CODE> (that's where my system's <CODE>.cpan</CODE> directory resides) with <CODE>/home/stas</CODE>. I use Perl of course!
  +The only thing left is to change the base directory of <EM>.cpan</EM> in your local file to the one under your home directory. On my machine I
  +replace <CODE>/usr/src/.cpan</CODE> (that's where my system's <CODE>.cpan</CODE> directory resides) with <CODE>/home/stas</CODE>. I use Perl of course!
   
   <P>
   <PRE>  % perl -pi -e 's|/usr/src|/home/stas|' /home/stas/.cpan/CPAN/MyConfig.pm
  @@ -2746,8 +2798,8 @@
   <PRE>  'makepl_arg' =&gt; q[PREFIX=/home/stas],
   </PRE>
   <P>
  -Now you've finished the configuration. Assuming that you are logged as the
  -same user you have prepared the local installation for (<EM>stas</EM>
  +Now you've finished the configuration. Assuming that you are logged in as
  +the same user you have prepared the local installation for (<EM>stas</EM>
   in our example), start it like this:
   
   <P>
  @@ -2805,7 +2857,7 @@
   processes can listen to lower numbered ports.
   
   <P>
  -Another important issue you have to solve is how to add startup and
  +Another important issue you have to resolve is how to add startup and
   shutdown scripts to the directories used by the rest of the system
   services. You will have to ask your system administrator to assist you with
   this issue.
  @@ -2926,7 +2978,7 @@
   </PRE>
   <P>
   Note that you can still use the hard-coded <CODE>@INC</CODE> modifications in the scripts themselves, but be aware that scripts modify <CODE>@INC</CODE> in
  -<CODE>BEGIN</CODE> blocks and mod_perl executes the <CODE>BEGIN</CODE> blocks only when it does script compilation. As a result, <CODE>@INC</CODE> will be reset to its original value after the scripts are compiled and the
  +<CODE>BEGIN</CODE> blocks and mod_perl executes the <CODE>BEGIN</CODE> blocks only when it performs script compilation. As a result, <CODE>@INC</CODE> will be reset to its original value after the scripts are compiled and the
   hard-coded settings will be forgotten. See the section '<A HREF="././porting.html#_INC_and_mod_perl">@INC and mod_perl</A>' for more information.
   
   <P>
  @@ -2947,7 +2999,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Resource_Usage">Resource Usage</A></H3></CENTER>
   <P>
  -One more important thing to keep in mind is the consumption of system
  +Another important thing to keep in mind is the consumption of system
   resources. mod_perl is memory hungry. If you run a lot of mod_perl
   processes on a public, multiuser machine, most likely the system
   administrator of this machine will ask you to use less resources and may
  @@ -2975,7 +3027,7 @@
   <P><LI>
   <P>
   Look for another ISP with lots of resources or one that supports mod_perl.
  -You can find a list of these ISP at <A
  +You can find a list of these ISPs at <A
   HREF="http://perl.apache.org">http://perl.apache.org</A> .
   
   </UL>
  @@ -3081,15 +3133,19 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Automating_installation">Automating installation</A></H1></CENTER>
   <P>
  -James G Smith wrote an Apache Builder 
  +James G Smith wrote an Apache Builder, that can install a combination of
  +Apache, mod_perl, and mod_ssl -- it also has limited support for including
  +mod_php in the mix.
   
   <P>
   <A
  -HREF="http://hex.tamu.edu/projects/1999/build-apache/">http://hex.tamu.edu/projects/1999/build-apache/</A>
  -
  +HREF="http://hex.tamu.edu/build-apache">http://hex.tamu.edu/build-apache</A>
  +(the actual Perl script)
   
   <P>
  -(META: provide more info)
  +<A
  +HREF="http://hex.tamu.edu/generic.conf">http://hex.tamu.edu/generic.conf</A>
  +(a sample configuration file)
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -3115,7 +3171,7 @@
   <P>
   Assuming that you have configured the <CODE>&lt;Location /perl-status</CODE>&gt; section in the server configuration file fetch: <A
   HREF="http://www.nowhere.com/perl-status">http://www.nowhere.com/perl-status</A>
  -using your favorite Netscape browser :-)
  +using your favorite Mozilla browser :-)
   
   <P>
   You should see something like this:
  @@ -3218,7 +3274,7 @@
   <CODE>CGI-Perl/1.1</CODE> everything is OK. 
   
   <P>
  -If you there is an error you might have to add a shebang line
  +If there is an error you might have to add a shebang line
   <CODE>#!/usr/bin/perl</CODE> as a first line of the CGI script and then try it again. If you see:
   
   <P>
  @@ -3295,6 +3351,22 @@
   <CENTER><H1><A NAME="General_Notes">General Notes</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Is_it_possible_to_run_mod_perl_e">Is it possible to run mod_perl enabled Apache as suExec?</A></H2></CENTER>
  +<P>
  +The answer is <STRONG>No</STRONG>. The reason is that you can't <EM>"suid</EM> a part of a process. mod_perl lives inside the Apache process. You have to
  +fork somewhere to be someone else, and at that point, you aren't mod_perl
  +anymore.
  +
  +<P>
  +You have to use mod_cgi if you need this functionality.
  +
  +<P>
  +Another solution is to use a crontab to call some script that will check
  +whether there is something to do and will execute it. The mod_perl script
  +will be able to create and update this todo list.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Should_I_Rebuild_mod_perl_if_I_h">Should I Rebuild mod_perl if I have Upgraded Perl?</A></H2></CENTER>
   <P>
   Yes, you should. You have to rebuild the mod_perl enabled server since it
  @@ -3307,12 +3379,12 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Perl_installation_requirements">Perl installation requirements</A></H2></CENTER>
   <P>
  -Make sure you have Perl installed!. The latest stable version if possible.
  -Minimum perl.5.004! If you don't have it, install it. Follow the
  +Make sure you have Perl installed! The latest stable version if possible.
  +Minimum perl 5.004! If you don't have it, install it. Follow the
   instructions in the distribution's <CODE>INSTALL</CODE> file.
   
   <P>
  -During the configuration stage (while running <CODE>./Configure</CODE>), to be able to load dynamically Perl Modules extensions, make sure you
  +During the configuration stage (while running <CODE>./Configure</CODE>), to be able to dynamically load Perl module extensions, make sure you
   answer
   <CODE>YES</CODE> to the question:
   
  @@ -3324,13 +3396,13 @@
   <CENTER><H2><A NAME="mod_auth_dbm_nuances">mod_auth_dbm nuances</A></H2></CENTER>
   <P>
   If you are a <CODE>mod_auth_dbm</CODE> or <CODE>mod_auth_db</CODE> user you may need to edit Perl's <CODE>Config</CODE> module. When Perl is configured it attempts to find libraries for ndbm,
  -gdbm, db, etc., for the *DBM*_File modules. By default, these libraries are
  +gdbm, db, etc., for the DB*_File modules. By default, these libraries are
   linked with Perl and remembered by the
   <CODE>Config</CODE> module. When mod_perl is configured with apache, the
  -<CODE>ExtUtils::Embed</CODE> module returns these libraries to be linked with httpd so Perl extensions
  +<CODE>ExtUtils::Embed</CODE> module requires these libraries to be linked with httpd so Perl extensions
   will work under mod_perl. However, the order in which these libraries are
   stored in <STRONG>Config.pm</STRONG> may confuse
  -<CODE>mod_auth_db*</CODE>. If <CODE>mod_auth_db*</CODE> does not work with mod_perl, take a look at this order with the following
  +<CODE>mod_auth_db*</CODE>. If <CODE>mod_auth_db*</CODE> does not work with mod_perl, take a look at the order with the following
   command:
   
   <P>
  @@ -3373,7 +3445,7 @@
   <CENTER><H2><A NAME="Stripping_Apache_to_make_it_almo">Stripping Apache to make it almost a Perl-server</A></H2></CENTER>
   <P>
   Since most of the functionality that various apache mod_* modules provide
  -is implemented in <A HREF="#item_Apache_">Apache::{*}</A> Perl modules, it was reported that one can build an Apache server with
  +is implemented in the <A HREF="#item_Apache_">Apache::{*}</A> Perl modules, it was reported that one can build an Apache server with
   mod_perl only. If you can reduce the requirements to whatever mod_perl can
   handle, you can eliminate almost every other module. Then basically you
   will have a Perl-server, with C code to handle the tricky HTTP bits. The
  @@ -3398,19 +3470,19 @@
   <P>
   When you run <CODE>perl Makefile.PL</CODE>, a <EM>Makefile</EM> is created. This
   <EM>Makefile</EM> includes the same compilation options that were used to build Perl itself.
  -They are stored in the <EM>Config.pm</EM> module and can be displayed with <CODE>Perl -V</CODE> command. All these options are re-applied when compiling Perl modules.
  +They are stored in the <EM>Config.pm</EM> module and can be displayed with the <CODE>Perl -V</CODE> command. All these options are re-applied when compiling Perl modules.
   
   <P>
   If you use a different compiler to build Perl extensions, chances are that
   the options that a different compiler uses won't be the same, or they might
   be interpreted in a completely different way. So the code either won't
  -compile, it will dump core when run or maybe it will behave in the most
  +compile or it will dump core when run or maybe it will behave in most
   unexpected ways.
   
   <P>
   Since mod_perl uses Perl, Apache and third party modules, and they all work
  -together, it's a must to use the same compiler while building each of the
  -components.
  +together, it's essential to use the same compiler while building each of
  +the components.
   
   <P>
   You shouldn't worry about this when compliling Perl modules since Perl will
  @@ -3481,7 +3553,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.20      +69 -7     modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- intro.html	2000/03/04 20:31:46	1.19
  +++ intro.html	2000/04/09 14:19:39	1.20
  @@ -552,12 +552,16 @@
   
   <P><LI>
   <P>
  -<STRONG>Ged W. Haywood</STRONG> for reviewing and fixing a big part of the guide, providing lots of
  -constructive critics and helping to reorganize the guide to make it more
  -user friendly.
  +<STRONG>Ged W. Haywood</STRONG> for reviewing and fixing the whole guide, providing lots of constructive
  +critics and helping to reorganize the guide to make it more user friendly.
   
   <P><LI>
   <P>
  +<STRONG>Mark Summerfield</STRONG> for reviewing and fixing a big part of the guide, to improve readability
  +and suggesting useful extensions.
  +
  +<P><LI>
  +<P>
   <STRONG>Jeffrey W. Baker</STRONG> for his ``guide to mod_perl database performance''.
   
   <P><LI>
  @@ -577,78 +581,136 @@
   Credits of course go to ( alphabetically sorted ):
   
   <UL>
  +<P><LI><STRONG><A NAME="item_Ajay">Ajay Shah</A></STRONG>
   <P><LI><STRONG><A NAME="item_Andreas">Andreas J. Koenig</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Andreas">Andreas Piesk</A></STRONG>
   <P><LI><STRONG><A NAME="item_Andrei">Andrei A. Voropaev</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Andrew">Andrew Ford</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Anthony">Anthony D. Ettinger</A></STRONG>
   <P><LI><STRONG><A NAME="item_Ask">Ask Bjoern Hansen</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Autarch">Autarch</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Bill">Bill Moseley</A></STRONG>
   <P><LI><STRONG><A NAME="item_Brian">Brian Moseley</A></STRONG>
   <P><LI><STRONG><A NAME="item_Chad">Chad K. Lewis</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Chris">Chris Nokleberg</A></STRONG>
   <P><LI><STRONG><A NAME="item_Christof">Christof Damian</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Christophe">Christophe Dupre</A></STRONG>
   <P><LI><STRONG><A NAME="item_Cliff">Cliff Rayman</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Craig">Craig</A></STRONG>
   <P><LI><STRONG><A NAME="item_Daniel">Daniel Koch</A></STRONG>
   <P><LI><STRONG><A NAME="item_Daniel">Daniel W. Burke</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Darren">Darren Chamberlain</A></STRONG>
   <P><LI><STRONG><A NAME="item_Dave">Dave Hodgkinson</A></STRONG>
   <P><LI><STRONG><A NAME="item_David">David Harris</A></STRONG>
  +<P><LI><STRONG><A NAME="item_David">David Huggins-Daines</A></STRONG>
   <P><LI><STRONG><A NAME="item_David">David Landgren</A></STRONG>
  +<P><LI><STRONG><A NAME="item_David">David Mitchell</A></STRONG>
   <P><LI><STRONG><A NAME="item_Dean">Dean Fitz</A></STRONG>
   <P><LI><STRONG><A NAME="item_Doug">Doug Bagley</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Doug">Doug Kyle</A></STRONG>
   <P><LI><STRONG><A NAME="item_Ed">Ed Park</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ed">Ed Phillips</A></STRONG>
   <P><LI><STRONG><A NAME="item_Edmund">Edmund Mergl</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Edwin">Edwin Pratomo</A></STRONG>
   <P><LI><STRONG><A NAME="item_Eric">Eric Cholet</A></STRONG>
   <P><LI><STRONG><A NAME="item_Eric">Eric Strovink</A></STRONG>
   <P><LI><STRONG><A NAME="item_Evan">Evan A. Zacks</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ewan">Ewan Edwards</A></STRONG>
   <P><LI><STRONG><A NAME="item_Frank">Frank Schoeters</A></STRONG>
  -<P><LI><STRONG><A NAME="item_G">G.Richter</A></STRONG>
   <P><LI><STRONG><A NAME="item_Garr">Garr Updegraff</A></STRONG>
   <P><LI><STRONG><A NAME="item_Ged">Ged W. Haywood</A></STRONG>
  -<P><LI><STRONG><A NAME="item_Geoffrey">Geoffrey S Young</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Geoff">Geoff Crawshaw</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Geoffrey">Geoffrey Young</A></STRONG>
   <P><LI><STRONG><A NAME="item_Gerald">Gerald Richter</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Gerd">Gerd Knops</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Greg">Greg Cope</A></STRONG>
   <P><LI><STRONG><A NAME="item_Gunther">Gunther Birznieks</A></STRONG>
   <P><LI><STRONG><A NAME="item_Henrique">Henrique Pantarotto</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Honza">Honza Pazdziora</A></STRONG>
   <P><LI><STRONG><A NAME="item_Howard">Howard Jones</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ilya">Ilya Obshadko</A></STRONG>
  +<P><LI><STRONG><A NAME="item_James">James Furness</A></STRONG>
   <P><LI><STRONG><A NAME="item_James">James G Smith</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jan">Jan Peter Hecking</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jason">Jason Bodnar</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jauder">Jauder Ho</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jay">Jay J</A></STRONG>
  -<P><LI><STRONG><A NAME="item_Jeff">Jeff Baker</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jeff">Jeff Rowe</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jeffrey">Jeffrey W. Baker</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jie">Jie Gao</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Joao">Joao Fonseca</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Joe">Joe Slag</A></STRONG>
  +<P><LI><STRONG><A NAME="item_John">John Armstrong</A></STRONG>
  +<P><LI><STRONG><A NAME="item_John">John Deighan</A></STRONG>
  +<P><LI><STRONG><A NAME="item_John">John Hyland</A></STRONG>
   <P><LI><STRONG><A NAME="item_John">John Milton</A></STRONG>
   <P><LI><STRONG><A NAME="item_John">John Walker</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jon">Jon Orwant</A></STRONG>
   <P><LI><STRONG><A NAME="item_Jonathan">Jonathan Peterson</A></STRONG>
   <P><LI><STRONG><A NAME="item_Joshua">Joshua Chamas</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Kavitha">Kavitha</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ken">Ken Williams</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Kevin">Kevin Murphy</A></STRONG>
   <P><LI><STRONG><A NAME="item_Leslie">Leslie Mikesell</A></STRONG>
   <P><LI><STRONG><A NAME="item_Lincoln">Lincoln Stein</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Mads">Mads Toftum</A></STRONG>
   <P><LI><STRONG><A NAME="item_Mark">Mark Mills</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Mark">Mark Summerfield</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Marko">Marko van der Puil</A></STRONG>
   <P><LI><STRONG><A NAME="item_Marshall">Marshall Dudley</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Matt">Matt Sergeant</A></STRONG>
   <P><LI><STRONG><A NAME="item_Matthew">Matthew Darwin</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Michael">Michael Blakeley</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Michael">Michael Finke</A></STRONG>
   <P><LI><STRONG><A NAME="item_Michael">Michael Hall</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Michael">Michael Schout</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Mike">Mike Depot</A></STRONG>
   <P><LI><STRONG><A NAME="item_Mike">Mike Fletcher</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Mike">Mike Miller</A></STRONG>
   <P><LI><STRONG><A NAME="item_Nancy">Nancy Lin</A></STRONG>
   <P><LI><STRONG><A NAME="item_Nathan">Nathan Torkington</A></STRONG>
   <P><LI><STRONG><A NAME="item_Nathan">Nathan Vonnahme</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Nick">Nick Tonkin</A></STRONG>
   <P><LI><STRONG><A NAME="item_Oleg">Oleg Bartunov</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Pascal">Pascal Eeftinck</A></STRONG>
   <P><LI><STRONG><A NAME="item_Perrin">Perrin Harkins</A></STRONG>
   <P><LI><STRONG><A NAME="item_Peter">Peter Galbavy</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Peter">Peter Haworth</A></STRONG>
   <P><LI><STRONG><A NAME="item_Peter">Peter Skov</A></STRONG>
   <P><LI><STRONG><A NAME="item_Philip">Philip Jacob</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Philip">Philip Newton</A></STRONG>
   <P><LI><STRONG><A NAME="item_Radu">Radu Greab</A></STRONG>
  +<P><LI><STRONG>Radu Greab</STRONG>
   <P><LI><STRONG><A NAME="item_Ralf">Ralf Engelschall</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ralf">Ralf S. Engelschall</A></STRONG>
   <P><LI><STRONG><A NAME="item_Randal">Randal L. Schwartz</A></STRONG>
   <P><LI><STRONG><A NAME="item_Randy">Randy Harmon</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Randy">Randy Kobes</A></STRONG>
   <P><LI><STRONG><A NAME="item_Rauznitz">Rauznitz Balazs</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Rex">Rex Staples</A></STRONG>
   <P><LI><STRONG><A NAME="item_Richard">Richard A. Wells</A></STRONG>
   <P><LI><STRONG><A NAME="item_Richard">Richard Dice</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Richard">Richard More</A></STRONG>
   <P><LI><STRONG><A NAME="item_Rick">Rick Myers</A></STRONG>
   <P><LI><STRONG><A NAME="item_Robin">Robin Berjon</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Scott">Scott Fagg</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Sean">Sean Dague</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Shane">Shane shane@isupportlive.com</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Stephane">Stephane Benoit</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Stephen">Stephen Judd</A></STRONG>
   <P><LI><STRONG><A NAME="item_Steve">Steve Reppucci</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Steve">Steve Willer</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Terry">Terry West</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Tom">Tom Brown</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Tom">Tom Christiansen</A></STRONG>
   <P><LI><STRONG><A NAME="item_Tom">Tom Hughes</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Tom">Tom Mornini</A></STRONG>
   <P><LI><STRONG><A NAME="item_Tzvetan">Tzvetan Stoyanov</A></STRONG>
   <P><LI><STRONG><A NAME="item_Ulrich">Ulrich Pfeifer</A></STRONG>
   <P><LI><STRONG><A NAME="item_Vivek">Vivek Khera</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Ward">Ward Vandewege</A></STRONG>
   <P><LI><STRONG><A NAME="item_Wesley">Wesley Darlington</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Yann">Yann Kerhervé</A></STRONG>
   <P><LI>
   <P><LI><STRONG><A NAME="item_Did">Did I miss your name? Tell me!</A></STRONG>
   </UL>
  @@ -692,7 +754,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +4256 -3964modperl-site/guide/mod_perl_guide.pdf.gz
  
  	<<Binary file>>
  
  
  1.14      +59 -14    modperl-site/guide/modules.html
  
  Index: modules.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/modules.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- modules.html	2000/03/04 20:31:47	1.13
  +++ modules.html	2000/04/09 14:19:41	1.14
  @@ -36,6 +36,7 @@
   	<LI><A HREF="#Apache_RegistryNG_Apache_Re">Apache::RegistryNG - Apache::Registry New Generation</A>
   	<LI><A HREF="#Apache_RegistryBB_Apache_Re">Apache::RegistryBB - Apache::Registry Bare Bones </A>
   	<LI><A HREF="#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  +	<LI><A HREF="#Apache_OutputChain_Chain_Sta">Apache::OutputChain - Chain Stacked Perl Handlers</A>
   	<LI><A HREF="#Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location </A>
   	<LI><A HREF="#Apache_LogSTDERR">Apache::LogSTDERR</A>
   	<LI><A HREF="#Apache_RedirectLogFix">Apache::RedirectLogFix</A>
  @@ -206,23 +207,19 @@
   <P>
   <PRE>    # in your startup.pl:
       use Apache::GTopLimit;
  -</PRE>
  -<P>
  -<PRE>    # Control the life based on memory size
  +  
  +    # Control the life based on memory size
       # in KB, so this is 10MB
       $Apache::GTopLimit::MAX_PROCESS_SIZE = 10000;
  -</PRE>
  -<P>
  -<PRE>    # Control the life based on Shared memory size
  +  
  +    # Control the life based on Shared memory size
       # in KB, so this is 4MB
       $Apache::GTopLimit::MIN_PROCESS_SHARED_SIZE = 4000;
  -</PRE>
  -<P>
  -<PRE>    # watch what happens  
  +  
  +    # watch what happens  
       $Apache::GTopLimit::DEBUG = 1;
  -</PRE>
  -<P>
  -<PRE>    # in your httpd.conf:   
  +  
  +    # in your httpd.conf:   
       PerlFixupHandler Apache::GTopLimit
       # you can set this up as any Perl*Handler that handles
       # part of the request, even the LogHandler will do.
  @@ -361,7 +358,7 @@
   <P>
   It works just like <CODE>Apache::Registry</CODE>, but does not test the x bit (-x) only compiles the file once (no
   <CODE>stat()</CODE> call is made per requsest), skips the OPT_EXECCGI
  -checks and does not <CODE>chdir()</CODE> into the script parent directory. It uses the OO interface.
  +checks and does not <A HREF="#item_chdir">chdir()</A> into the script parent directory. It uses the OO interface.
   
   <P>
   Configuration:
  @@ -430,6 +427,54 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_OutputChain_Chain_Sta">Apache::OutputChain -- Chain Stacked Perl Handlers</A></H1></CENTER>
  +<P>
  +Apache::OutputChain was written as a way of exploring possibilities of
  +stacked handlers in mod_perl. It ties the STDOUT to object, which catches
  +the output and makes it easy to build a chain of modules that work on
  +output stream of data.
  +
  +<P>
  +Examples of modules that are build on this idea are
  +<CODE>Apache::SSIChain</CODE>, <CODE>Apache::GzipChain</CODE> and <CODE>Apache::EmbperlChain</CODE>
  +-- the first processes the SSI's in the stream, the second compresses the
  +output on the fly, the last adds the Embperl processing.
  +
  +<P>
  +The syntax goes like
  +
  +<P>
  +<PRE>  &lt;Files *.html&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::OutputChain Apache::SSIChain Apache::PassHtml
  +  &lt;/Files&gt;
  +</PRE>
  +<P>
  +The modules are written in the reverse order of their execution -- here the <CODE>Apache::PassHtml</CODE> module simply picks the file's content and sends it to STDOUT ... here it's
  +processed by <CODE>Apache::SSIChain</CODE>
  +... and then goes to <CODE>Apache::OutputChain</CODE> that sends the result to the browser.
  +
  +<P>
  +Alternative to this approach is <CODE>Apache::Filter</CODE>, which has more natural ``forward'' configuration order and it's easier to
  +make other modules to be compliant with <CODE>Apache::Filter</CODE>.
  +
  +<P>
  +It works with <CODE>Apache::Registry</CODE> as well, for example:
  +
  +<P>
  +<PRE>  Alias /foo /home/httpd/perl/foo
  +  &lt;Location /foo&gt;
  +    SetHandler &quot;perl-script&quot;
  +    Options +ExecCGI
  +    PerlHandler Apache::OutputChain Apache::GzipChain Apache::Registry
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +It's really a regular <CODE>Apache::Registry</CODE> setup, except for the added modules in the PerlHandler line.
  +<A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain</A> allows to compress the output on the fly.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location</A></H1></CENTER>
   <P>
   With that module, you can configure <CODE>@INC</CODE> and have modules reloaded for a given <CODE>Location</CODE>, e.g. say two versions of <CODE>Apache::Status</CODE>
  @@ -626,7 +671,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/29/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.12      +42 -8     modperl-site/guide/multiuser.html
  
  Index: multiuser.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/multiuser.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- multiuser.html	2000/02/09 21:11:45	1.11
  +++ multiuser.html	2000/04/09 14:19:41	1.12
  @@ -174,17 +174,51 @@
   <P>
   Another problem you will have to solve is how to assign ports between
   users. Since user can pick any port above 1024 to run his server on, you
  -will have to make some regulation here. A simple example will stress the
  -importance of this problem: I am a malicious user or I just a rival of some
  -fellow who runs his own server on your ISP. All I should do is to find out
  -what port his server is listening to (e.g. with help of <CODE>netstat(8)</CODE>) and configure my own server to listen on the same port. While I am unable
  +will have to make some regulation here.
  +
  +<P>
  +A simple example will stress the importance of this problem: I am a
  +malicious user or I just a rival of some fellow who runs his own server on
  +your ISP. All I should do is to find out what port his server is listening
  +to (e.g. with help of <CODE>netstat(8)</CODE>) and configure my own server to listen on the same port. While I am unable
   to bind to this same port, imagine what will happen when you reboot your
   system and my startup script happen to be run before my rivals! I get the
   port first, now all requests will be redirected to my server and let your
  -imagination go wild about what nasty things might happen then. Of course
  -the ugly things will be revealed pretty soon, but the damage has been done.
  +imagination go wild about what nasty things might happen then.
  +
  +<P>
  +Of course the ugly things will be revealed pretty soon, but the damage has
  +been done.
   
   </UL>
  +<P>
  +Basically you can preassign each user a port, without her having to worry
  +about finding a free one, enforce the <CODE>MaxClients</CODE> and similar values by implementing the following scenario:
  +
  +<P>
  +For each user have two configuration files, the main file,
  +<EM>httpd.conf</EM> (non-writable by user) and the user's file,
  +<EM>username.httpd.conf</EM> where she can specify her own configuration parameters and override the
  +ones defined in <EM>httpd.conf</EM>. This is how the main config file looks like:
  +
  +<P>
  +<PRE>  httpd.conf
  +  ----------
  +  # Some global/default settings
  +  Include username.httpd.conf
  +  # Section for user specific params
  +</PRE>
  +<P>
  +<PRE>  username.httpd.conf
  +  -------------------
  +  # Setting that you user would like to add/override,
  +  # like &lt;Location&gt; and PerlModule directives, etc.
  +</PRE>
  +<P>
  +So in the <EM>httpd.conf</EM> you can override the port number and other settings, since user could
  +modify them. Since this section is being processed last, these are the
  +setting that will take the effect. You can use <A HREF="././config.html#Apache_Configuration_in_Perl">Perl sections</A> to make the configuration much easier.
  +
   <P><LI>
   <P>
   A much better, but costly solution is <STRONG>co-location</STRONG>. Let user to hook her (or ISP's) stand alone machine into your network,
  @@ -206,7 +240,7 @@
   If you are about to use <STRONG>Virtual Hosts</STRONG> you might want to read these sections:
   
   <P>
  -<A HREF="././config.html#_Perl_Perl_Sections">Perl Sections</A>
  +<A HREF="././config.html#Apache_Configuration_in_Perl">Apache Configuration in Perl</A>
   
   
   
  @@ -263,7 +297,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/05/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.25      +602 -121  modperl-site/guide/performance.html
  
  Index: performance.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/performance.html,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- performance.html	2000/03/04 20:31:47	1.24
  +++ performance.html	2000/04/09 14:19:41	1.25
  @@ -55,12 +55,20 @@
   		<LI><A HREF="#Work_With_Databases">Work With Databases</A>
   	</UL>
   
  -	<LI><A HREF="#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
  +	<LI><A HREF="#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Build Options</A>
  +	<LI><A HREF="#_Dusemymalloc_Perl_Build_Option">-Dusemymalloc Perl Build Option</A>
   	<LI><A HREF="#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="#Cached_stat_calls">Cached stat() calls</A>
   	<LI><A HREF="#Be_carefull_with_symbolic_links">Be carefull with symbolic links</A>
   	<LI><A HREF="#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
  +	<LI><A HREF="#Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A>
   	<LI><A HREF="#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A>
  +	<UL>
  +
  +		<LI><A HREF="#OS_Specific_notes">OS Specific notes</A>
  +		<LI><A HREF="#Debug">Debug</A>
  +	</UL>
  +
   	<LI><A HREF="#Limiting_the_Request_Rate_Speed_">Limiting the Request Rate Speed (Robot Blocking)</A>
   	<LI><A HREF="#Benchmarks_Impressing_Your_Boss">Benchmarks. Impressing Your Boss and Your Colleagues.</A>
   	<UL>
  @@ -68,7 +76,7 @@
   		<LI><A HREF="#Developers_Talk">Developers Talk</A>
   		<LI><A HREF="#Benchmarking_a_Graphic_Hits_Coun">Benchmarking a Graphic Hits Counter with Persistent DB Connections</A>
   		<LI><A HREF="#Benchmarking_Scripts_with_Execut">Benchmarking Scripts with Execution Times Below 1 Second</A>
  -		<LI><A HREF="#Benchmarking_PerlHandler">Benchmarking PerlHandler</A>
  +		<LI><A HREF="#Benchmarking_PerlHandlers">Benchmarking PerlHandlers</A>
   	</UL>
   
   	<LI><A HREF="#Tuning_Apache_s_Configuration_Va">Tuning Apache's Configuration Variables for the Best Performance</A>
  @@ -116,6 +124,14 @@
   	</UL>
   
   	<LI><A HREF="#Imported_Symbols_and_Memory_Usag">Imported Symbols and Memory Usage</A>
  +	<LI><A HREF="#TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A>
  +	<UL>
  +
  +		<LI><A HREF="#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  +		<LI><A HREF="#CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A>
  +		<LI><A HREF="#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
  +	</UL>
  +
   	<LI><A HREF="#Sending_Plain_HTML_as_Compressed">Sending Plain HTML as Compressed Output</A>
   	<LI><A HREF="#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   </UL>
  @@ -230,8 +246,8 @@
   boxes do you have, and how much RAM does each mod_perl process use?
   Multiply the first two and divide by the third. Ask yourself whether it is
   better to switch to another, possibly just as inefficient language or
  -whether that will actually cost more than throwing another Ultra 2 into the
  -rack.
  +whether that will actually cost more than throwing another powerful machine
  +into the rack.
   
   <P>
   Also ask yourself whether switching to another language will even help. In
  @@ -255,32 +271,43 @@
   it (and most sane systems do), you might save memory by sharing it between
   child processes. This is only possible when you preload code at server
   startup. However, during a child process' life its memory pages tend to
  -become unshared. There is no way we can make Perl allocate memory so that
  -(dynamic) variables land on different memory pages from constants, so the <STRONG>copy-on-write</STRONG> effect (we will explain this in a moment) will hit you almost at random.
  +become unshared.
  +
  +<P>
  +There is no way we can make Perl allocate memory so that (dynamic)
  +variables land on different memory pages from constants, so the
  +<STRONG>copy-on-write</STRONG> effect (we will explain this in a moment) will hit you almost at random.
   
   <P>
   If you are pre-loading many modules you might be able to trade off the
   memory that stays shared against the time for an occasional fork by tuning <CODE>MaxRequestsPerChild</CODE>. Each time a child reaches this upper limit and dies it should release its
   unshared pages. The new child which replaces it will share its fresh pages
  -until it scribbles on them. The ideal is a point where your processes
  -usually restart before too much memory becomes unshared. You should make
  -some measurements to see if it makes a real difference, and to find the
  -range of reasonable values. If you have success with this tuning the value
  -of <CODE>MaxRequestsPerChild</CODE> will probably be peculiar to your situation and may change with changing
  +until it scribbles on them.
  +
  +<P>
  +The ideal is a point where your processes usually restart before too much
  +memory becomes unshared. You should make some measurements to see if it
  +makes a real difference, and to find the range of reasonable values. If you
  +have success with this tuning the value of
  +<CODE>MaxRequestsPerChild</CODE> will probably be peculiar to your situation and may change with changing
   circumstances.
   
   <P>
   It is very important to understand that your goal is not to have
   <CODE>MaxRequestsPerChild</CODE> to be 10000. Having a child serving 300 requests on precompiled code is
   already a huge overall speedup, so if it is 100 or 10000 it probably does
  -not really matter if you can save RAM by using a lower value. Do not forget
  -that if you preload most of your code at server startup, the fork to spawn
  -a new child will be very very fast, because it inherits most of the
  -preloaded code and the perl interpreter from the parent process. During the
  -life of the child its memory pages (which aren't really its own to start
  -with, it uses the parent's pages) gradually get `dirty' - variables which
  -were originally inherited and shared are updated or modified -- and the
  -<EM>copy-on-write</EM> happens. This reduces the number of shared memory pages, thus increasing
  +not really matter if you can save RAM by using a lower value.
  +
  +<P>
  +Do not forget that if you preload most of your code at server startup, the
  +fork to spawn a new child will be very very fast, because it inherits most
  +of the preloaded code and the perl interpreter from the parent process.
  +
  +<P>
  +During the life of the child its memory pages (which aren't really its own
  +to start with, it uses the parent's pages) gradually get `dirty' -
  +variables which were originally inherited and shared are updated or
  +modified -- and the <EM>copy-on-write</EM> happens. This reduces the number of shared memory pages, thus increasing
   the memory requirement. Killing the child and spawning a new one allows the
   new child to get back to the pristine shared memory of the parent process.
   
  @@ -518,8 +545,8 @@
   following directives into <CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>  PerlModule CGI;
  -  PerlModule DBI;
  +<PRE>  PerlModule CGI
  +  PerlModule DBI
   </PRE>
   <P>
   But an even better approach is to create a separate startup file (where you
  @@ -668,8 +695,9 @@
     httpd    188104  0.0  1.0 4188 2940      - A    17:05:27  0:00 httpd
   </PRE>
   <P>
  -Observation: the child httpd has grown by 1172K - no change! So does CGI-&gt;<CODE>compile(':all')</CODE> help us? We probably do not use all the
  -methods which CGI provides, so in real use it's faster.
  +Observation: the child httpd has grown by 1172K - no change! So does
  +<CODE>CGI-&gt;compile(':all')</CODE> help us? We probably do not use all the methods which CGI provides, so in
  +real use it's faster.
   
   <P>
   You might want to compile only the tags you are going to use, then you will
  @@ -971,30 +999,47 @@
   By default it is On.
   
   <P>
  -Note that you can still set ENV variables. For example when you use the
  -following configuration:
  +Note that you can still set enviroment variables. For example when you use
  +the following configuration:
  +
  +<P>
  +<PRE>  PerlModule Apache::RegistryNG
  +  &lt;Location /perl&gt;
  +    PerlSetupEnv Off
  +    PerlSetEnv TEST hi
  +    SetHandler perl-script
  +    PerlHandler Apache::RegistryNG
  +    Options +ExecCGI
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +and you issue a request (for example <A
  +HREF="http://localhost/perl/setupenvoff.pl">http://localhost/perl/setupenvoff.pl</A>)
  +for this script:
   
   <P>
  -<PRE> &lt;Location /perl&gt;
  -   PerlSetupEnv Off
  -   PerlSetEnv TEST hi
  -   SetHandler perl-script
  -   PerlHandler Apache::RegistryNG-&gt;handler
  -   Options +ExecCGI
  - &lt;/Location&gt;
  +<PRE>  setupenvoff.pl
  +  --------------
  +  use Data::Dumper;
  +  my $r = Apache-&gt;request();
  +  $r-&gt;send_http_header('text/plain');
  +  print Dumper(\%ENV);
   </PRE>
   <P>
  -A script having a <CODE>print Data::Dumper(\%ENV)</CODE> line, prints:
  +you should see something like this:
   
   <P>
   <PRE>  $VAR1 = {
               'GATEWAY_INTERFACE' =&gt; 'CGI-Perl/1.1',
  -            'MOD_PERL' =&gt; 'mod_perl/1.21_01-dev',
  +            'MOD_PERL' =&gt; 'mod_perl/1.22',
               'PATH' =&gt; '/usr/lib/perl5/5.00503:... snipped ...',
               'TEST' =&gt; 'hi'
             };
   </PRE>
   <P>
  +Notice that we have gotten the environment variable <EM>TEST</EM> set.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Proxying_the_mod_perl_Server">Proxying the mod_perl Server</A></H1></CENTER>
   <P>
  @@ -1072,6 +1117,9 @@
   handshake, turning it off will be kinder to the network.
   
   <P>
  +SSL connections benefit the most from <CODE>KeepAlive</CODE> in case you didn't configure the server to cache session ids.
  +
  +<P>
   You have probably followed the advice to send all the requests for static
   objects to a plain Apache server. Since most pages include more than one
   unique static image, you should keep the default
  @@ -1115,23 +1163,26 @@
   
   <P>
   A much better approach would be to spawn a sub-process, hand it the
  -information it needs to do the task, and have it detach (close x3 +
  -<CODE>setsid()</CODE>). This is wise only if the parent which spawns this process immediately
  +information it needs to do the task, and have it detach (close STDIN,
  +STDOUT and STDERR + execute <CODE>setsid()</CODE>). This is wise only if the parent which spawns this process immediately
   continues, and does not wait for the sub-process to complete. This approach
   is suitable for a situation when you want to use the Web interface to
   trigger a process which takes a long time, such as processing lots of data
  -or sending email to thousands of users. Otherwise, you should convert the
  -code into a module, and call its functions or methods from CGI script.
  +or sending email to thousands of users (no SPAM please!). Otherwise, you
  +should convert the code into a module, and call its functions and methods
  +from CGI script.
   
   <P>
   Just making a <CODE>system()</CODE> call defeats the whole idea behind mod_perl. The Perl interpreter and
  -modules should be loaded again for this external program to run.
  +modules should be loaded again for this external program to run if it's a
  +Perl program. Remember that backticks <EM>`program`</EM> variant of <CODE>system()</CODE> behaves in the same way.
   
   <P>
   Basically, you would do:
   
   <P>
  -<PRE>  $params=FreezeThaw::freeze(
  +<PRE>  use FreezeThaw ();
  +  $params=FreezeThaw::freeze(
           [all data to pass to the other process]
           );
     system(&quot;program.pl&quot;, $params);
  @@ -1154,7 +1205,7 @@
     close STDIN;
     close STDOUT;
     close STDERR;
  -  # you might need to reopen the STDERR
  +  # you might need to reopen the STDERR, i.e.
     # open STDERR, &quot;&gt;/dev/null&quot;;
     setsid(); # to detach
   </PRE>
  @@ -1163,7 +1214,7 @@
   <CODE>system()</CODE> returns and permits Apache to get on with things.
   
   <P>
  -This has obvious problems:  
  +This has obvious problems:
   
   <UL>
   <P><LI>
  @@ -1220,10 +1271,9 @@
   
   <P><LI>
   <P>
  -Next, Perl will find <CODE>/bin/echo</CODE> along the search path, and invoke it directly. Perl <CODE>system()</CODE>
  -is *not* <CODE>system(3)</CODE> [C-library]. Only when the command has shell meta-chars does Perl invoke a
  -real shell. That's a *very* nice optimization. In other words, only if you
  -do:
  +Next, Perl will find <CODE>/bin/echo</CODE> along the search path, and invoke it directly. Perl's <CODE>system()</CODE>
  +is <STRONG>not</STRONG> the <CODE>system(3)</CODE> call [C-library]. Only when the command has shell meta-chars does Perl
  +invoke a real shell. That's a <EM>very</EM> nice optimization. In other words, only if you do:
   
   <P>
   <PRE>  system &quot;sh -c 'echo foo'&quot;
  @@ -1234,32 +1284,41 @@
   replace your virtual memory page table with one pointing to the existing
   program code plus your data space.
   
  +<P>
  +Notice that the shell will be called also in the case where
  +<CODE>system()</CODE> accepts one single argument (i.e. <CODE>system(&quot;echo foo&quot;)</CODE>) and not the list of arguments (i.e. <CODE>system(&quot;echo&quot;,&quot;foo&quot;)</CODE>). The shell will be invoked also in the case where shell meta characters
  +will be used (i.e. <CODE>system(&quot;echo foo*&quot;)</CODE>).
  +
   <P><LI>
   <P>
   Then the shell parses the passed command.
   
   <P>
  -Since it is <CODE>echo</CODE>, it will execute it as a built-in in the latter example or as <CODE>/bin/echo</CODE> in the former and be done, but this is only an example. You aren't calling <CODE>system(&quot;echo Hi&quot;)</CODE> in your mod_perl scripts, right?
  +Since it is the <CODE>echo</CODE> utility, it will execute it as a built-in in the latter example or as <CODE>/bin/echo</CODE> in the former and be done, but this is only an example. You aren't calling <CODE>system(&quot;echo Hi&quot;)</CODE> in your mod_perl scripts, right?
   
   </OL>
   <P>
   Most real programs (heavy programs executed as a subprocess) would involve
   repeating the process to load the specified command or script. This might
   involve some actual demand paging from the program file if you execute new
  -code. The only place you will see real overhead from this scheme is when
  -the parent process is huge (unfortunately like mod_perl...) and the page
  -table becomes large as a side effect. The whole point of mod_perl is to
  -avoid having to <CODE>fork()</CODE> or <CODE>exec()</CODE> something on
  -every hit. Perl can do just about anything by itself. However, you probably
  -won't get into trouble until you hit about 30 forks/second on a so-so
  -pentium.
  +code.
   
   <P>
  +The only place you will see real overhead from this scheme is when the
  +parent process is huge (unfortunately like mod_perl...) and the page table
  +becomes large as a side effect. The whole point of mod_perl is to avoid
  +having to <CODE>fork()</CODE> or <CODE>exec()</CODE> something on every
  +hit. Perl can do just about anything by itself.
  +
  +<P>
   Now let's get to the gory details of forking. Normally, every process has
   its parent. Many processes are children of the <CODE>init</CODE> process, whose <CODE>PID</CODE> is <CODE>1</CODE>. When you fork a process you must <CODE>wait()</CODE> or
   <CODE>waitpid()</CODE> for it to finish. If you don't wait for it, it
  -becomes a zombie. A zombie is a process that doesn't have a parent. When
  -the child quits, it reports the termination to its parent. If no parent
  +becomes a zombie.
  +
  +<P>
  +A zombie is a process that doesn't have a parent. When the child quits, it
  +reports about the termination to its parent. If no parent
   <CODE>wait()s</CODE> to collect the exit status of the child, it gets
   ``confused'' and becomes a ghost process, that can be seen, but not killed.
   It will be killed only when you stop the httpd process that spawned it!
  @@ -1276,7 +1335,7 @@
   <P>
   <PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
     
  -  defined (my $kid = fork) or die &quot;Cannot fork: $!\n&quot;;
  +  defined (my $kid = fork) or die &quot;Cannot fork: $!&quot;;
     if ($kid) {
       waitpid($kid,0);
       print &quot;Parent has finished\n&quot;;
  @@ -1290,7 +1349,9 @@
   spawn a process that will take a long time to complete. So if the server
   child that spawns this process has to wait for it to finish, you have
   gained nothing. You can neither wait for its completion, nor continue
  -because you will get yet another zombie process.
  +because you will get yet another zombie process. This is called a blocking
  +call, since the process is blocked to so anything else before this call
  +gets completed.
   
   <P>
   The simplest solution is to ignore your dead children. This doesn't work
  @@ -1407,6 +1468,9 @@
   for mod_perl.
   
   <P>
  +META: why is it a better thing to use?
  +
  +<P>
   Read <EM>perlipc</EM> manpage for more information about signal handlers.
   
   <P>
  @@ -1520,7 +1584,7 @@
   If you do some DB processing, you will often encounter the need to read
   lots of records into your program, and then print them to the browser after
   they are formatted. I won't even mention the horrible case where
  -programmers read in the whole DB and then use perl to process it!!! Use a
  +programmers read in the whole DB and then use Perl to process it!!! Use a
   relational DB and let the SQL do the job, so you get only the records you
   need!
   
  @@ -1708,7 +1772,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A></H1></CENTER>
  +<CENTER><H1><A NAME="_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Build Options</A></H1></CENTER>
   <P>
   Newer Perl versions also have build time options to reduce runtime memory
   consumption. These options might shrink the size of your httpd by about
  @@ -1743,10 +1807,38 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="_Dusemymalloc_Perl_Build_Option">-Dusemymalloc Perl Build Option</A></H1></CENTER>
  +<P>
  +You have a choice to use the native or Perl's own <CODE>malloc()</CODE>
  +implementation. The choice depends on your Operating System. Unless you
  +know which of the two is better on yours, you better try both and compare
  +the benchmarks.
  +
  +<P>
  +To build without Perl's <CODE>malloc(),</CODE> you can use the Configure
  +command:
  +
  +<P>
  +<PRE>  % sh Configure -Uusemymalloc&quot;
  +</PRE>
  +<P>
  +Note that:
  +
  +<P>
  +<PRE>  -U == undefine usemymalloc (use system malloc)
  +  -D == define   usemymalloc (use Perl's malloc)
  +</PRE>
  +<P>
  +It seems that Linux is still defaults to system malloc, you might want to
  +configure Perl with -Dusemymalloc. However Perl's malloc is not as much of
  +a win under linux, but makes a <STRONG>huge</STRONG> difference under Solaris.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Checking_script_modification_tim">Checking script modification times</A></H1></CENTER>
   <P>
   Under <CODE>Apache::Registry</CODE> the requested CGI script is always being
  -<CODE>stat()</CODE>'ed to check whether it was modified. It adds a very little overhead, but
  +<A HREF="#item_stat">stat()</A>'ed to check whether it was modified. It adds a very little overhead, but
   if you are into squeezing all the juice from the server, you might want to
   save this call. If you do, take a look at
   <A HREF="././modules.html#">Apache::RegistryBB</A> module.
  @@ -1755,9 +1847,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Cached_stat_calls">Cached stat() calls</A></H1></CENTER>
   <P>
  -When you do a <CODE>stat()</CODE> (or its variations <CODE>-M</CODE> - modification time,
  -<CODE>-A</CODE> last access time, <CODE>-C</CODE> inode-change time, and others), the information is cached. If you need to
  -make an additional check for the same file, use the <CODE>_</CODE> variable and save the overhead of this check. For example when testing for
  +When you do a <CODE>stat()</CODE> (or its variations <CODE>-M</CODE> -- last modification time, <CODE>-A</CODE> -- last access time, <CODE>-C</CODE> -- last inode-change time, and others), the information is cached. If you
  +need to make an additional check for the same file, use the <CODE>_</CODE> variable and save the overhead of this check. For example when testing for
   existence and read permissions you might use:
   
   <P>
  @@ -1781,18 +1872,6 @@
   Two <CODE>stat()</CODE> syscalls saved!
   
   <P>
  -Remember that with mod_perl you might get negative times when you use the <CODE>-M</CODE> and similar file tests.  <CODE>-M</CODE> returns the difference in time between the modification time of the file
  -and the time the script was started. Because the <CODE>^T</CODE> variable is not reset on each script invocation, and is equal to the time
  -when the process was forked, you might want to perform:
  -
  -<P>
  -<PRE>  $^T = time;
  -</PRE>
  -<P>
  -at the beginning of your scripts to simulate the regular perl script
  -behaviour of file tests.
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Be_carefull_with_symbolic_links">Be carefull with symbolic links</A></H1></CENTER>
   <P>
  @@ -1813,7 +1892,7 @@
   
   <P>
   To detect this, use the
  -<A HREF="././debug.html#Apache_Status_Embedded_inter">/perl-status</A> handler to see all the compiled scripts and their packages. In our example,
  +<A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A> handler to see all the compiled scripts and their packages. In our example,
   when requesting: <A
   HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A>
   you would see:
  @@ -1840,6 +1919,14 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A></H1></CENTER>
  +<P>
  +<CODE>Apache::GTopLimit</CODE> module allows you to kill off Apache httpd processes if they grow too large
  +(just like <CODE>Apache::SizeLimit</CODE>) or have too little of shared memory. See
  +<A HREF="././modules.html#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit</A>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A></H1></CENTER>
   <P>
   <CODE>Apache::Resource</CODE> uses the <CODE>BSD::Resource</CODE> module, which in turn uses the C function <CODE>setrlimit()</CODE> to set limits on system resources such as memory and cpu usage.
  @@ -1871,6 +1958,48 @@
   and hard limits.
   
   <P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="OS_Specific_notes">OS Specific notes</A></H2></CENTER>
  +<P>
  +Note that under Linux <CODE>malloc()</CODE> uses <CODE>mmap()</CODE>
  +instead of <CODE>brk().</CODE> This is done to conserve virtual memory -
  +that is, when you malloc a large block of memory, it isn't actually given
  +to your program until you initialize it. The old-style <CODE>brk()</CODE>
  +syscall obeyed resource limits on data segment size as set in
  +<CODE>setrlimit()</CODE> - <CODE>mmap()</CODE> doesn't.
  +
  +<P>
  +<CODE>Apache::Resource</CODE>'s defaults put caps on data size and stack size. Linux's current memory
  +allocation scheme doesn't honor these limits, so if you just do
  +
  +<P>
  +<PRE>  PerlSetEnv PERL_RLIMIT_DEFAULTS On
  +  PerlModule Apache::Resource
  +  PerlChildInitHandler Apache::Resource
  +</PRE>
  +<P>
  +Your Apache processes are still free to use as much memory as they like.
  +
  +<P>
  +However, <CODE>BSD::Resource</CODE> also has a limit called <CODE>RLIMIT_AS</CODE>
  +(Address Space) which limits the total number of bytes of virtual memory
  +assigned to a process. Happily, Linux's memory manager DOES honor this
  +limit.
  +
  +<P>
  +Therefore, you _can_ limit memory usage under Linux with
  +<CODE>Apache::Resource</CODE> -- simply add a line to <EM>httpd.conf</EM>:
  +
  +<P>
  +<PRE>  PerlSetEnv PERL_RLIMIT_AS  67108864
  +</PRE>
  +<P>
  +This example sets a hard and soft limit of 64Mb of total address space.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Debug">Debug</A></H2></CENTER>
  +<P>
   To debug add:
   
   <P>
  @@ -1881,7 +2010,7 @@
     PerlChildInitHandler Apache::Resource
   </PRE>
   <P>
  -and look in the error_log to see what it's doing.
  +and look in the <EM>error_log</EM> to see what it's doing.
   
   <P>
   Refer to <CODE>perldoc Apache::Resource</CODE> and <CODE>man 2 setrlimit</CODE> for more info.
  @@ -2052,8 +2181,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Benchmarking_Scripts_with_Execut">Benchmarking Scripts with Execution Times Below 1 Second</A></H2></CENTER>
   <P>
  -As noted before, for very fast scripts you will have to use the
  -<CODE>Time::HiRes</CODE> module, its usage is similar to <CODE>Benchmark</CODE>'s.
  +If you want to get the benchmark results in micro-seconds and not in tens
  +milli-seconds as you get with the <CODE>Benchmark</CODE> module, you will have to use the <CODE>Time::HiRes</CODE> module, its usage is similar to
  +<CODE>Benchmark</CODE>'s.
   
   <P>
   <PRE>  use Time::HiRes qw(gettimeofday tv_interval);
  @@ -2068,12 +2198,32 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Benchmarking_PerlHandler">Benchmarking PerlHandler</A></H2></CENTER>
  +<CENTER><H2><A NAME="Benchmarking_PerlHandlers">Benchmarking PerlHandlers</A></H2></CENTER>
  +<P>
  +The <CODE>Apache::Timeit</CODE> module does <CODE>PerlHandler</CODE> Benchmarking. With help of this module you can log the time taken to
  +process the request, just like you'd use the <CODE>Benchmark</CODE> module to benchmark a regular Perl script. Of course you can extend this
  +module to make more advanced processing like putting the results into a
  +database for a later processing. But all it takes is adding this
  +configuration directive inside <EM>httpd.conf</EM>:
  +
  +<P>
  +<PRE>  PerlFixupHandler Apache::Timeit
  +</PRE>
  +<P>
  +Since scripts running under <CODE>Apache::Registry</CODE> are running inside the PerlHandler these are getting benchmarked as well.
  +
  +<P>
  +An example of the lines showing up in the <EM>error_log</EM> file:
  +
   <P>
  -At <A
  -HREF="http://perl.apache.org/dist/contrib/">http://perl.apache.org/dist/contrib/</A>
  -you will find the
  -<CODE>Apache::Timeit</CODE> package which does <CODE>PerlHandler</CODE> Benchmarking.
  +<PRE>  timing request for /perl/setupenvoff.pl:
  +    0 wallclock secs ( 0.04 usr +  0.01 sys =  0.05 CPU)
  +  timing request for /perl/setupenvoff.pl:
  +    0 wallclock secs ( 0.03 usr +  0.00 sys =  0.03 CPU)
  +</PRE>
  +<P>
  +The <CODE>Apache::Timeit</CODE> package is a part of the <EM>Apache-Perl-contrib</EM>
  +files collection available from CPAN.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2086,11 +2236,12 @@
   
   <P>
   All the above parameters should be specified on the basis of the resources
  -you have. With a plain apache server, it's no big deal if you run too many
  -servers (not <STRONG>far</STRONG> too many, of course) since the processes are about 1Mb and don't eat a lot
  -of your RAM. Generally the numbers are even smaller with memory sharing.
  -The situation is different with mod_perl. I have seen mod_perl processes of
  -20Mb and more. Now if you have <CODE>MaxClients</CODE> set to 50: 50x20Mb = 1Gb. Do you have 1Gb of RAM? Probably not. So how do
  +you have. With a plain apache server, it's no big deal if you run many
  +servers since the processes are about 1Mb and don't eat a lot of your RAM.
  +Generally the numbers are even smaller with memory sharing. The situation
  +is different with mod_perl. I have seen mod_perl processes of 20Mb and
  +more. Now if you have <CODE>MaxClients</CODE>
  +set to 50: 50x20Mb = 1Gb. Do you have 1Gb of RAM? Probably not. So how do
   you tune the parameters? Generally by trying different combinations and
   benchmarking the server. Again mod_perl processes can be of much smaller
   size with memory sharing.
  @@ -2724,8 +2875,8 @@
   
   <P>
   You will be wondering what will happen to your server if there are more
  -than <CODE>MaxClients</CODE> concurrent users at any time. This situation is accompanied by the
  -following warning message in the <CODE>error_log</CODE>:
  +concurrent users than <CODE>MaxClients</CODE> at any time. This situation is accompanied by the following warning message
  +in the <CODE>error_log</CODE>:
   
   <P>
   <PRE>  [Sun Jan 24 12:05:32 1999] [error] server reached MaxClients setting,
  @@ -2742,9 +2893,9 @@
   immediately, despite the fact that they do not get an error response. The
   error can be allowed to persist to balance available system resources and
   response time, but sooner or later you will need to get more RAM so you can
  -start more children. The best approach is to try not to have this condition
  -reached at all, and if you reach it often you should start to worry about
  -it.
  +start more child processes. The best approach is to try not to have this
  +condition reached at all, and if you reach it often you should start to
  +worry about it.
   
   <P>
   It's important to understand how much real memory a child occupies. Your
  @@ -2806,7 +2957,8 @@
                  10 - 8
   </PRE>
   <P>
  -390% more servers! You've got the point. :)
  +390% more servers! Now you can feel the importance of having as much shared
  +memory as possible.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2840,10 +2992,15 @@
   <CODE>Apache::PerlRun</CODE> if this is the case.
   
   <P>
  -Another approach is to use <CODE>Apache::SizeLimit</CODE>. See <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the size of processes</A>.
  +Another approach is to use the
  +<A HREF="././performance.html#Limiting_the_Size_of_the_Process">Apache::SizeLimit</A> or the <A HREF="././performance.html#Keeping_the_Shared_Memory_Limit">Apache::GTopLimit</A>
  +modules. By using any of the two modules you should be able to discontinue
  +using the <CODE>MaxRequestPerChild</CODE>, although for some developers, using both in combination does the job. In
  +addition the latter module allows to kill the servers whose shared memory
  +size is going below specified limit.
   
   <P>
  -See also <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A> and <A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>.
  +See also <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A> and <A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>. 
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -2912,7 +3069,8 @@
   number as large as possible (10000?). If you use
   <CODE>Apache::SizeLimit</CODE>, you can set this parameter to 0 (equal to infinity). You will want this
   parameter to be smaller if your code becomes unshared over the process'
  -life.
  +life. And <CODE>Apache::GTopLimit</CODE>
  +comes into the game with the shared memory limitation feature.
   
   <P><LI><STRONG><A NAME="item_StartServers">StartServers</A></STRONG>
   <P>
  @@ -3076,6 +3234,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Handling_Timeouts">Handling Timeouts</A></H2></CENTER>
   <P>
  +META: this is duplicated in the databases.pod -- should be resolved!
  +
  +<P>
   Some databases disconnect the client after a certain time inactive. This
   problem is known as the <STRONG>morning bug</STRONG>. The <CODE>ping()</CODE> method ensures that this will not happen. Some <CODE>DBD</CODE> drivers don't have this method, check the <CODE>Apache::DBI</CODE> manpage to see how to write a
   <CODE>ping()</CODE> method.
  @@ -3703,6 +3864,24 @@
   </PRE>
   </OL>
   <P>
  +BTW, you can check the number of opcodes in the code by a simple command
  +line run. For example comparing 'my&nbsp;%hash' vs 'my&nbsp;%hash&nbsp;=
  +()'.
  +
  +<P>
  +<PRE>  % perl -MO=Terse -e 'my %hash' | wc -l
  +  -e syntax OK
  +      4
  +</PRE>
  +<P>
  +<PRE>  % perl -MO=Terse -e 'my %hash = ()' | wc -l
  +  -e syntax OK
  +     10
  +</PRE>
  +<P>
  +The first one has less opcodes.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A></H1></CENTER>
   <P>
  @@ -3927,9 +4106,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls</A></H1></CENTER>
   <P>
  -If you watch the server calls trace, while this processes a request, you
  -will notice a few <CODE>stat()</CODE> calls are made. For example when I
  -execute <A
  +If you watch the system calls that your server makes (using <EM>truss</EM>
  +or <EM>strace</EM> while processing a request, you will notice that a few <CODE>stat()</CODE>
  +calls are made. For example when I fetch <A
   HREF="http://localhost/perl-status">http://localhost/perl-status</A> and I
   have my DocRoot set to
   <EM>/home/httpd/docs</EM> I see:
  @@ -3942,32 +4121,28 @@
                                    st_size=1024, ...}) = 0
     [snip]
   </PRE>
  -<P>
  -when running the server under <CODE>strace</CODE> or <CODE>truss</CODE> utility.
  -
   <P>
  -If you have some dynamically generated code (not from the script) and your
  -virtual relative URI is like <EM>/news/perl/mod_perl/summary</EM>
  -(there is no such a directory on the web server, the sub sections are only
  -used for requesting a specific report), this will generate
  -<CODE>five(!)</CODE> <CODE>stat()</CODE> calls, before the <CODE>DocumentRoot</CODE> will be found. You will see something like this:
  +If you have some dynamic content and your virtual relative URI is something
  +like <EM>/news/perl/mod_perl/summary</EM> (i.e., there is no such directory on the web server, the path components
  +are only used for requesting a specific report), this will generate
  +<CODE>five(!)</CODE> <CODE>stat()</CODE> calls, before the <CODE>DocumentRoot</CODE> is found. You will see something like this:
   
   <P>
   <PRE>  stat(&quot;/home/httpd/docs/news/perl/mod_perl/summary&quot;, 0xbffff744) = -1 
                         ENOENT (No such file or directory)
  -  stat(&quot;/home/httpd/docs/news/perl/mod_perl&quot;, 0xbffff744) = -1 
  +  stat(&quot;/home/httpd/docs/news/perl/mod_perl&quot;,         0xbffff744) = -1
                         ENOENT (No such file or directory)
  -  stat(&quot;/home/httpd/docs/news/perl&quot;, 0xbffff744) = -1 
  +  stat(&quot;/home/httpd/docs/news/perl&quot;,                  0xbffff744) = -1
                         ENOENT (No such file or directory)
  -  stat(&quot;/home/httpd/docs/news&quot;, 0xbffff744) = -1 
  +  stat(&quot;/home/httpd/docs/news&quot;,                       0xbffff744) = -1
                         ENOENT (No such file or directory)
  -  stat(&quot;/home/httpd/docs&quot;, {st_mode=S_IFDIR|0755, 
  -                                 st_size=1024, ...}) = 0
  +  stat(&quot;/home/httpd/docs&quot;, 
  +                      {st_mode=S_IFDIR|0755, st_size=1024, ...})  =  0
   </PRE>
   <P>
  -You should blame the installed by default <CODE>TransHandler</CODE> for this inefficiency. Of course you could supply your own one, which will
  -be smart enough not to look for this virtual path and immediately return
  -<CODE>OK</CODE>. But in case that you have some virtual host that serves only dynamically
  +You can blame the default installed <CODE>TransHandler</CODE> for this inefficiency. Of course you could supply your own, which will be
  +smart enough not to look for this virtual path and immediately return
  +<CODE>OK</CODE>. But in cases where you have a virtual host that serves only dynamically
   generated documents, you can override the default
   <CODE>PerlTransHandler</CODE> with this one:
   
  @@ -3979,7 +4154,7 @@
     &lt;/VirtualHost&gt;
   </PRE>
   <P>
  -As you see it will affect only this specific virtual host.
  +As you see it affects only this specific virtual host.
   
   <P>
   This has the effect of short circuiting the normal <CODE>TransHandler</CODE>
  @@ -3987,6 +4162,144 @@
   URI -- no more 'stat's!
   
   <P>
  +Watching your server under strace/truss can often reveal more performance
  +hits than trying to optimize the code itself!
  +
  +<P>
  +For example unless configured correctly, Apache might look for the
  +<EM>.htaccess</EM> file in many places, if you don't have one and add many <CODE>open()</CODE>
  +calls.
  +
  +<P>
  +Let's start with this simple configuration, and will try to reduce the
  +number of irrelevant system calls.
  +
  +<P>
  +<PRE>  DocumentRoot &quot;/home/httpd/docs&quot;
  +  &lt;Location /foo/test&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Foo
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +The above configuration allows us ot make a request to <EM>/foo/test</EM>
  +and the Perl <CODE>handler()</CODE> defined in <CODE>Apache::Foo</CODE> will be executed. Notice that in the test setup there is no file to be
  +executed (like in <CODE>Apache::Registry</CODE>). There is no <EM>.htaccess</EM> file as well.
  +
  +<P>
  +This is a typical generated trace.
  +
  +<P>
  +<PRE>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs/foo&quot;,      0xbffff8fc) = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs&quot;, 
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  +  open(&quot;/.htaccess&quot;, O_RDONLY)                 = -1 ENOENT 
  +        (No such file or directory)
  +  open(&quot;/home/.htaccess&quot;, O_RDONLY)            = -1 ENOENT 
  +        (No such file or directory)
  +  open(&quot;/home/httpd/.htaccess&quot;, O_RDONLY)      = -1 ENOENT 
  +        (No such file or directory)
  +  open(&quot;/home/httpd/docs/.htaccess&quot;, O_RDONLY) = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs/test&quot;, 0xbffff774)    = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs&quot;, 
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  +</PRE>
  +<P>
  +Now we modify the <CODE>&lt;Directory</CODE>&gt; entry and add AllowOverride&nbsp;None, which among other things disables <EM>.htaccess</EM> files and will not try to open them.
  +
  +<P>
  +<PRE>  &lt;Directory /&gt;
  +    AllowOverride None
  +  &lt;/Directory&gt;
  +</PRE>
  +<P>
  +We see that the four <CODE>open()</CODE> calls for <EM>.htaccess</EM> have gone.
  +
  +<P>
  +<PRE>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs/foo&quot;,      0xbffff8fc) = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs&quot;, 
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  +  stat(&quot;/home/httpd/docs/test&quot;, 0xbffff774)    = -1 ENOENT 
  +        (No such file or directory)
  +  stat(&quot;/home/httpd/docs&quot;, 
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  +</PRE>
  +<P>
  +Let's try to shortcut the <EM>foo</EM> location with:
  +
  +<P>
  +<PRE>  Alias /foo /
  +</PRE>
  +<P>
  +Which makes Apache to look for the file in the <EM>/</EM> directory and not under <EM>/home/httpd/docs/foo</EM>. Let's run it:
  +
  +<P>
  +<PRE>  stat(&quot;//test&quot;, 0xbffff8fc) = -1 ENOENT (No such file or directory)
  +</PRE>
  +<P>
  +Wow, we've got only one stat call left!
  +
  +<P>
  +Let's remove the last <CODE>Alias</CODE> setting and use:
  +
  +<P>
  +<PRE>    PerlTransHandler  Apache::OK
  +</PRE>
  +<P>
  +as explained above. When we issue the request, we see no
  +<CODE>stat()</CODE> calls. But this is possible only if you serve only
  +dynamically generated documents, i.e. no CGI scripts. Otherwise you will
  +have to write your own <EM>PerlTransHandler</EM> to handle requests as desired.
  +
  +<P>
  +For example this <EM>PerlTransHandler</EM> will not lookup the file on the filesystem if the URI starts with <EM>/foo</EM>, but will use the default
  +<EM>PerlTransHandler</EM> otherwise:
  +
  +<P>
  +<PRE>  PerlTransHandler 'sub { return shift-&gt;uri() =~ m|^/foo| \
  +                        ? Apache::OK : Apache::DECLINED;}'
  +</PRE>
  +<P>
  +Let's see the same configuration using the <CODE>&lt;Perl</CODE>&gt; section and a dedicated package:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;  
  +    package My::Trans;
  +    use Apache::Constants qw(:common);
  +    sub handler{
  +       my $r = shift;
  +       return OK if $r-&gt;uri() =~ m|^/foo|;
  +       return DECLINED;
  +    }
  +</PRE>
  +<P>
  +<PRE>    package Apache::ReadConfig;  
  +    $PerlTransHandler = &quot;My::Trans&quot;;
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +As you see we have defined the <CODE>My::Trans</CODE> package and implemented the <CODE>handler()</CODE> function. Then we have
  +assigned this handler to the
  +<CODE>PerlTransHandler</CODE>.
  +
  +<P>
  +Of course you can move the code in the module into an external file, (e.g. <EM>My/Trans.pm</EM>) and configure the <CODE>PerlTransHandler</CODE> with 
  +
  +<P>
  +<PRE>  PerlTransHandler My::Trans
  +</PRE>
  +<P>
  +in the normal way (no <CODE>&lt;Perl</CODE>&gt; section required.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A></H1></CENTER>
   <P>
  @@ -4042,6 +4355,11 @@
   stack operations, less time to get to the guts of the subroutine.
   
   <P>
  +perl5.6+ does a better method caching, <CODE>Foo-&gt;method()</CODE> is a little bit faster (some constant folding magic), but not
  +<CODE>Foo-&gt;$method()</CODE>. And the improvement does not address the
  +<CODE>@ISA</CODE> lookup that still happens in either case.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="The_Overhead_with_Heavy_Subrouti">The Overhead with Heavy Subroutines</A></H2></CENTER>
   <P>
  @@ -4251,11 +4569,174 @@
   with a reference to an object, but even then it can be passed by value.
   
   <P>
  -I strongly endorse <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>. Its is written in C, giving it a significant memory and performance
  +I strongly endorse <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>. Its core is written in C, giving it a significant memory and performance
   benefit. It has all the functionality of <CODE>CGI.pm</CODE> except HTML generation functions.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A></H1></CENTER>
  +<P>
  +TMTOWTDI, or ``There Is More Than One Way To Do It'' is the main motto of
  +Perl. Unfortunately when you come to the point where performance is the
  +goal, you might have to learn what's more efficient and what's not. Of
  +course it might mean that you will have to use something that you don't
  +really like, or it might be less convenient.
  +
  +<P>
  +So this section is about performance trade-offs.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A></H2></CENTER>
  +<P>
  +At some point you have to decide whether to use <CODE>Apache::Registry</CODE>
  +and similar handlers and stick to writing scripts for the content
  +generation or to write a pure Perl handlers.
  +
  +<P>
  +<CODE>Apache::Registry</CODE> maps a request to a file and generates a subroutine to run the code
  +contained in that file. If you use a
  +PerlHandler&nbsp;My::handler instead of <CODE>Apache::Registry</CODE>, you have a direct mapping from request to subroutine, without the steps
  +in between. These steps include:
  +
  +<DL>
  +<P><DT><STRONG><A NAME="item_stat">stat the $r-&gt;filename</A></STRONG><DD>
  +<P><DT><STRONG><A NAME="item_check">check that it exists and is executable</A></STRONG><DD>
  +<P><DT><STRONG><A NAME="item_generate">generate a Perl package name based on $r-&gt;uri</A></STRONG><DD>
  +<P><DT><STRONG><A NAME="item_chdir">chdir basename $r-&gt;filename</A></STRONG><DD>
  +<P><DT><STRONG><A NAME="item_compare">compare last modified time</A></STRONG><DD>
  +<P><DT><STRONG><A NAME="item_if">if modified or not compiled, compile the subroutine</A></STRONG><DD>
  +<P><DT><STRONG>chdir $old_cwd</STRONG><DD>
  +</DL>
  +<P>
  +If you cut out those steps, you cut out some overhead, plain and simple. Do
  +you NEED to cut out that overhead? We don't know, your requirements
  +determine that.
  +
  +<P>
  +You should take a look at the sister <CODE>Apache::Registry</CODE> modules that don't perform all all these steps, so you can still choose to
  +stick to using scripts to generate the content.
  +
  +<P>
  +On the other hand, if you go the pure Perl handler way you will have to add
  +a special configuration directives for each handler, something that you
  +don't do when you go the ``scripts'' way.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A></H2></CENTER>
  +<P>
  +<CODE>CGI.pm</CODE> is a pure Perl implementation of the most used functions used in the CGI
  +coding. Mainly it has two parts -- the input processing and HTML
  +generation.
  +
  +<P>
  +<CODE>Apache::Request</CODE>'s core is written in C, giving it a significant memory and performance
  +benefit. It has all the functionality of
  +<CODE>CGI.pm</CODE> except HTML generation functions.
  +
  +<P>
  +'use CGI <CODE>qw(-compile</CODE> =&gt; ':all') adds about 1Mb size to the
  +server.
  +<CODE>CGI.pm</CODE> pulls lots of stunts under the covers to provide both a method and function
  +interface, etc.  <CODE>Apache::Request</CODE> is a very thin XS layer on top of a C library and only adds a few kbytes
  +size to the server. this C code is much faster and lighter than the Perl
  +equivalent used in <CODE>CGI.pm</CODE> or similar (e.g. CGI_Lite).
  +
  +<P>
  +This difference might not matter much to you, depending on your
  +requirements.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="_Bloatware_modules">&quot;Bloatware&quot; modules</A></H2></CENTER>
  +<P>
  +Perl modules like IO:: are very convenient, but let's see what it costs to
  +us to use them. (perl5.6.0 over OpenBSD)
  +
  +<P>
  +<PRE>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +   124     696    4166 /usr/local/lib/perl5/5.6.0/Carp.pm
  +   580    2465   17661 /usr/local/lib/perl5/5.6.0/Class/Struct.pm
  +   400    1495   10455 /usr/local/lib/perl5/5.6.0/Cwd.pm
  +   313    1589   10377 /usr/local/lib/perl5/5.6.0/Exporter.pm
  +   225     784    5651 /usr/local/lib/perl5/5.6.0/Exporter/Heavy.pm
  +    92     339    2813 /usr/local/lib/perl5/5.6.0/File/Spec.pm
  +   442    1574   10276 /usr/local/lib/perl5/5.6.0/File/Spec/Unix.pm
  +   115     398    2806 /usr/local/lib/perl5/5.6.0/File/stat.pm
  +   406    1350   10265 /usr/local/lib/perl5/5.6.0/IO/Socket/INET.pm
  +   143     429    3075 /usr/local/lib/perl5/5.6.0/IO/Socket/UNIX.pm
  +  7168   24137  178650 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Config.pm
  +   230    1052    5995 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Errno.pm
  +   222     725    5216 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Fcntl.pm
  +    47     101     669 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO.pm
  +   239     769    5005 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Dir.pm
  +   169     549    3956 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/File.pm
  +   594    2180   14772 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Handle.pm
  +   252     755    5375 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Pipe.pm
  +    77     235    1709 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Seekable.pm
  +   428    1419   10219 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Socket.pm
  +   452    1401   10554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Socket.pm
  +   127     473    3554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/XSLoader.pm
  +    52     161    1050 /usr/local/lib/perl5/5.6.0/SelectSaver.pm
  +   139     541    3754 /usr/local/lib/perl5/5.6.0/Symbol.pm
  +   161     609    4081 /usr/local/lib/perl5/5.6.0/Tie/Hash.pm
  +   109     390    2479 /usr/local/lib/perl5/5.6.0/strict.pm
  +    79     370    2589 /usr/local/lib/perl5/5.6.0/vars.pm
  +   318    1124   11975 /usr/local/lib/perl5/5.6.0/warnings.pm
  +    30      85     722 /usr/local/lib/perl5/5.6.0/warnings/register.pm
  + 13733   48195  349869 total
  +</PRE>
  +<P>
  +Incredible. But it's twice smaller in size on linux:
  +
  +<P>
  +<PRE>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +  [similar lines snipped]
  +  6618   25068  176740 total
  +</PRE>
  +<P>
  +Moreover, that requires 116 happy trips through the kernel's
  +<CODE>namei().</CODE> It syscalls <CODE>open()</CODE> a remarkable 57
  +times, 17 of which failed but leaving 38 that were successful. It also
  +syscalled <CODE>read()</CODE> a curiously identical 57 times, ingesting a
  +total of 180,265 plump bytes. To top it off, this <STRONG><EM>increases your resident set size by two megabytes!</EM></STRONG>
  +(1.5Mb on linux).
  +
  +<P>
  +Happy mallocking...
  +
  +<P>
  +It seems that <CODE>CGI.pm</CODE> suffers from the same decease:
  +
  +<P>
  +<PRE>  % wc `perl -MCGI -le 'print for values %INC'`
  +  1368    6920   43710 /usr/local/lib/perl5/5.6.0/overload.pm
  +  6481   26122  200840 /usr/local/lib/perl5/5.6.0/CGI.pm
  +  7849   33042  244550 total
  +</PRE>
  +<P>
  +You have 16 trips through namei, 7 successful opens, 2 unsuccessful ones,
  +and 213k of data read in.
  +
  +<P>
  +The following numbers show memory sizes (virtual and resident) for v5.6 of
  +Perl on four different operating systems, The three calls each are without
  +any modules, with just -MCGI, and with -MIO (never with both):
  +
  +<P>
  +<PRE>              OpenBSD       FreeBSD      Redhat       Solaris
  +              vsz   rss     vsz  rss     vsz  rss    vsz    rss
  +  Raw Perl    736   772     832 1208    2412  980    2928  2272
  +  w/ CGI     1220  1464    1308 1828    2972 1768    3616  3232
  +  w/ IO      2292  2580    2456 3016    4080 2868    5384  4976
  +</PRE>
  +<P>
  +Anybody who's thinking of choosing one of these might do well to stare at
  +those numbers for a while.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Sending_Plain_HTML_as_Compressed">Sending Plain HTML as Compressed Output</A></H1></CENTER>
   <P>
   See <A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  @@ -4320,7 +4801,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.11      +2 -2      modperl-site/guide/perl.html
  
  Index: perl.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/perl.html,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- perl.html	2000/02/09 21:11:45	1.10
  +++ perl.html	2000/04/09 14:19:41	1.11
  @@ -308,7 +308,7 @@
   addition, under mod_perl, certain uses of the <CODE>eval</CODE>
   operator and ``here documents'' are known to throw off Perl's line
   numbering, so the messages reporting warnings and errors can have incorrect
  -line numbers. (See <A HREF="././debug.html#Finding_the_Line_Number_the_Erro">Finding the Line Number the Error/Warning has been Triggered at</A> for more information).
  +line numbers. (See <A HREF="././debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A> for more information).
   
   <P>
   Getting the trace helps a lot.
  @@ -1900,7 +1900,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/05/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.26      +211 -81   modperl-site/guide/porting.html
  
  Index: porting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/porting.html,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- porting.html	2000/03/04 20:31:47	1.25
  +++ porting.html	2000/04/09 14:19:41	1.26
  @@ -70,6 +70,7 @@
   	<LI><A HREF="#die_and_mod_perl">die() and mod_perl</A>
   	<LI><A HREF="#Testing_the_Code_from_the_Shell">Testing the Code from the Shell</A>
   	<LI><A HREF="#I_O_is_different">I/O is different</A>
  +	<LI><A HREF="#Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A>
   	<LI><A HREF="#STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A>
   	<LI><A HREF="#Global_Variables_Persistance">Global Variables Persistance</A>
   	<LI><A HREF="#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  @@ -88,8 +89,10 @@
   	<LI><A HREF="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
   	<LI><A HREF="#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
   	<LI><A HREF="#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="#File_tests_operators">File tests operators</A>
   	<LI><A HREF="#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="#Accessing_Request_Object_in_non_">Accessing Request Object in non-Perl*Handler Modules</A>
   	<LI><A HREF="#The_Script_Is_Too_Dirty_But_It_">The Script Is Too Dirty, But It Does The Job And I Cannot Afford To Rewrite It.</A>
   	<LI><A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun-a closer look</A>
   	<LI><A HREF="#Sharing_variables_between_proces">Sharing variables between processes</A>
  @@ -664,6 +667,10 @@
   <P>
   <PRE>  PerlSetEnv PERL5LIB /home/httpd/perl:/home/httpd/mymodules
   </PRE>
  +<P>
  +Note that this setting will be ignored if you have the
  +<CODE>PerlTaintMode</CODE> mode turned on.
  +
   <P><LI>
   <P>
   In the startup file directly alter the <CODE>@INC</CODE>. For example
  @@ -773,7 +780,7 @@
   
   <P>
   To make sure that you have set <CODE>@INC</CODE> correctly, configure
  -<A HREF="././debug.html#Apache_Status_Embedded_inter">/perl-status location</A>, fetch <A
  +<A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status location</A>, fetch <A
   HREF="http://www.example.com/perl-status?inc">http://www.example.com/perl-status?inc</A>
   and look at the bottom of the page, where the contents of <CODE>@INC</CODE> will be shown.
   
  @@ -1783,49 +1790,45 @@
   So if you have two different <CODE>Foo</CODE> modules in two different directories and two scripts <CODE>script1.pl</CODE> and <CODE>script2.pl</CODE>, placed like this:
   
   <P>
  -<PRE>  ./perl/tool1/Foo.pm
  -  ./perl/tool1/tool1.pl
  -  ./perl/tool2/Foo.pm
  -  ./perl/tool2/tool2.pl
  +<PRE>  ./tool1/Foo.pm
  +  ./tool1/tool1.pl
  +  ./tool2/Foo.pm
  +  ./tool2/tool2.pl
   </PRE>
   <P>
   Where a sample code could be:
   
   <P>
  -<PRE>  ./perl/tool1/tool1.pl
  -  --------------------
  +<PRE>  ./tool1/tool1.pl
  +  ----------------
     use Foo;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;I'm Script number One\n&quot;;
     foo();
  -  --------------------
   </PRE>
   <P>
  -<PRE>  ./perl/tool1/Foo.pm
  -  --------------------
  +<PRE>  ./tool1/Foo.pm
  +  --------------
     sub foo{
       print &quot;&lt;B&gt;I'm Tool Number One!&lt;/B&gt;\n&quot;;
     }
     1;
  -  --------------------
   </PRE>
   <P>
  -<PRE>  ./perl/tool2/tool2.pl
  -  --------------------
  +<PRE>  ./tool2/tool2.pl
  +  ----------------
     use Foo;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;I'm Script number Two\n&quot;;
     foo();
  -  --------------------
   </PRE>
   <P>
  -<PRE>  ./perl/tool2/Foo.pm
  -  --------------------
  +<PRE>  ./tool2/Foo.pm
  +  --------------
     sub foo{
       print &quot;&lt;B&gt;I'm Tool Number Two!&lt;/B&gt;\n&quot;;
     }
     1;
  -  --------------------
   </PRE>
   <P>
   Both scripts call <CODE>use Foo;</CODE>. Only the first one called will know about <CODE>Foo</CODE>. When you call the second script it will not know about
  @@ -1841,27 +1844,40 @@
   </PRE>
   <P><DT><STRONG>Scenario 2</STRONG><DD>
   <P>
  -If the files do not declare a package, the above is true for files you
  -<CODE>require()</CODE> as well:
  +If the files do not declare a package, the above is true for libraries
  +(i.e. <EM>my-lib.pl"</EM>) you <CODE>require()</CODE> as well:
   
   <P>
  -Suppose the content of the scripts and <CODE>config.pl</CODE> files is exactly like in the example above, and you have a directory
  -structure like this:
  +Suppose that you have a directory structure like this:
   
   <P>
  -<PRE>  ./perl/tool1/config.pl
  -  ./perl/tool1/tool1.pl
  -  ./perl/tool2/config.pl
  -  ./perl/tool2/tool2.pl
  +<PRE>  ./tool1/config.pl
  +  ./tool1/tool1.pl
  +  ./tool2/config.pl
  +  ./tool2/tool2.pl
   </PRE>
   <P>
  -and both scripts contain
  +and both scripts contain:
   
   <P>
   <PRE>  use lib qw(.);
     require &quot;config.pl&quot;;
   </PRE>
   <P>
  +while <EM>./tool1/config.pl</EM> can be something like this:
  +
  +<P>
  +<PRE>  $foo = 0;
  +  1;
  +</PRE>
  +<P>
  +and <EM>./tool2/config.pl</EM>:
  +
  +<P>
  +<PRE>  $foo = 1;
  +  1;
  +</PRE>
  +<P>
   The second scenario is not different from the first, there is almost no
   difference between <CODE>use()</CODE> and <CODE>require()</CODE> if you
   don't have to import some symbols into a calling script. Only the first
  @@ -1874,9 +1890,9 @@
   It is interesting that the following scenario will fail too!
   
   <P>
  -<PRE>  ./perl/tool/config.pl
  -  ./perl/tool/tool1.pl
  -  ./perl/tool/tool2.pl
  +<PRE>  ./tool/config.pl
  +  ./tool/tool1.pl
  +  ./tool/tool2.pl
   </PRE>
   <P>
   where <CODE>tool1.pl</CODE> and <CODE>tool2.pl</CODE> both <CODE>require()</CODE> the <STRONG>same</STRONG>
  @@ -1895,10 +1911,10 @@
   prefixes. The file system layout will be something like:
   
   <P>
  -<PRE>  ./perl/tool1/Tool1/Foo.pm
  -  ./perl/tool1/tool1.pl
  -  ./perl/tool2/Tool2/Foo.pm
  -  ./perl/tool2/tool2.pl
  +<PRE>  ./tool1/Tool1/Foo.pm
  +  ./tool1/tool1.pl
  +  ./tool2/Tool2/Foo.pm
  +  ./tool2/tool2.pl
   </PRE>
   <P>
   And modify the scripts:
  @@ -1911,10 +1927,10 @@
   For <CODE>require()</CODE> (scenario number 2) use the following:
   
   <P>
  -<PRE>  ./perl/tool1/tool1-lib/config.pl
  -  ./perl/tool1/tool1.pl
  -  ./perl/tool2/tool2-lib/config.pl
  -  ./perl/tool2/tool2.pl
  +<PRE>  ./tool1/tool1-lib/config.pl
  +  ./tool1/tool1.pl
  +  ./tool2/tool2-lib/config.pl
  +  ./tool2/tool2.pl
   </PRE>
   <P>
   And each script contains respectively:
  @@ -1948,7 +1964,7 @@
   surprised that it worked for the third scenario as well!
   
   <P>
  -With this solution you loose some portability. If you move the tool around
  +With this solution you lose some portability. If you move the tool around
   in the file system you will have to change the base directory or write some
   additional script that will automatically update the hardcoded path after
   it was moved. Of course you will have to remember to invoke it.
  @@ -1958,8 +1974,8 @@
   Make sure you read all of this solution.
   
   <P>
  -Declare a package in the required files! It should be unique to the rest of
  -the package names you use.  <CODE>%INC</CODE> will then use the unique package name for the key. It's a good idea to use
  +Declare a package name in the required files! It should be unique to the
  +rest of the package names you use.  <CODE>%INC</CODE> will then use the unique package name for the key. It's a good idea to use
   at least two-level package names for your private modules, e.g. <CODE>MyProject::Carp</CODE> and not <CODE>Carp</CODE>, since the latter will collide with an existing standard package. Even if
   as of the time of your coding it doesn't yet exist, a package might enter
   the next perl distribution as a standard module and your code will be
  @@ -2158,7 +2174,7 @@
   <P>
   Note that <CODE>Apache::exit(-2)</CODE> or
   <CODE>Apache::exit(Apache::Constants::DONE)</CODE> will cause the server to exit gracefully, completing the logging functions
  -and protocol requirements etc.
  +and protocol requirements etc. (Apache::Constants::OK == 0).
   
   <P>
   If you need to shut down the child cleanly after the request was completed,
  @@ -2167,8 +2183,7 @@
   because of the <CODE>keepalive</CODE> flag, and the parent tells the child to cleanly quit, because <CODE>MaxRequestsPerChild</CODE> is smaller than the number of requests served.
   
   <P>
  -You can accomplish this in two ways--in the <CODE>Apache::Registry</CODE>
  -script:
  +In the <CODE>Apache::Registry</CODE> script you would do:
   
   <P>
   <PRE>  Apache-&gt;request-&gt;child_terminate;
  @@ -2185,7 +2200,10 @@
   what you want.
   
   <P>
  -Here is an example of assigning of the postprocessing handler:
  +Even if you don't need to call the <CODE>child_terminate()</CODE> at the
  +end of the request if you want the process to quit afterwards, here is an
  +example of assigning of the postprocessing handler, in case you might want
  +to execute your own code a moment before the process quits.
   
   <P>
   <PRE>  my $r = shift;
  @@ -2205,12 +2223,6 @@
   size.
   
   <P>
  -As mentioned before, it is unnecessary to postpone the execution of
  -<CODE>child_terminate().</CODE> You can call it anywhere in the code, it
  -won't terminate the child's execution until the request has been served.
  -Don't confuse it with <CODE>exit().</CODE>
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="die_and_mod_perl">die() and mod_perl</A></H1></CENTER>
   <P>
  @@ -2272,6 +2284,30 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A></H1></CENTER>
  +<P>
  +Under mod_perl <CODE>CORE::print()</CODE> will redirect its data to
  +<CODE>Apache::print()</CODE> since the STDOUT filehandle is tied to the
  +<EM>Apache</EM> module. This allows to run the CGI scripts unmodified under
  +<CODE>Apache::Registry</CODE> and chaining the output of one content handler to the input of the other
  +handler.
  +
  +<P>
  +<CODE>Apache::print()</CODE> behaves mostly like the built-in <EM>print()</EM>
  +function. In addition it sets a timeout so that if the client connection is
  +broken the handler won't wait forever trying to send data.
  +
  +<P>
  +There is also an optimization built into <CODE>Apache::print()</CODE>. If any of the arguments to the method are scalar references to strings,
  +they are automatically dereferenced for you. This avoids needless copying
  +of large strings when passing them to subroutines. For example:
  +
  +<P>
  +<PRE> $long_string = &quot;A&quot; x 10000000;
  + $r-&gt;print(\$long_string);
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A></H1></CENTER>
   <P>
   In mod_perl both <CODE>STDIN</CODE> and <CODE>STDOUT</CODE> are tied to the socket the request came from. <CODE>STDERR</CODE> is tied to the <EM>error_log</EM> file.
  @@ -2304,14 +2340,15 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A></H1></CENTER>
   <P>
  -A HTTP response header consists of at least two fields. HTTP response and <CODE>Content-type</CODE>:
  +A HTTP response header consists of at least two fields. HTTP response and
  +MIME type header <CODE>Content-type</CODE>:
   
   <P>
   <PRE>  HTTP/1.0 200 OK
     Content-Type: text/plain
   </PRE>
   <P>
  -after adding one more new line, you can start printing the content. A more
  +After adding one more new line, you can start printing the content. A more
   complete response includes the date timestamp and server type, like in this
   response:
   
  @@ -2349,15 +2386,15 @@
   to send only the response MIME type (<CODE>Content-type</CODE>) under mod_cgi, why should you do that manually under mod_perl. 
   
   <P>
  -Actually do want to set some headers manually, but not everytime. So
  -mod_perl gives you the default set of headers, just like in the example
  -above. And if you want to override or add more headers you can do that as
  -well. Let's see how to do that.
  +Actually something you do want to set some headers manually, but not
  +everytime. So mod_perl gives you the default set of headers, just like in
  +the example above. And if you want to override or add more headers you can
  +do that as well. Let's see how to do that.
   
   <P>
  -When writing your own handlers and scripts with the Perl API the proper way
  -to send the HTTP header is with <CODE>send_http_header()</CODE> method. If
  -you need to add or override methods you can use the
  +When writing your own handlers and scripts with the Perl Apache API the
  +proper way to send the HTTP header is with <CODE>send_http_header()</CODE>
  +method. If you need to add or override methods you can use the
   <CODE>headers_out()</CODE> method:
   
   <P>
  @@ -2391,17 +2428,15 @@
     return OK if $r-&gt;header_only;
   </PRE>
   <P>
  -If the client issues a HTTP <CODE>HEAD</CODE> request rather than the usual
  +If the client issues an HTTP <CODE>HEAD</CODE> request rather than the usual
   <CODE>GET</CODE>, to be compliant with the HTTP protocol we should not send the document
  -body, but the the HTTP header only. When Apache receives a HEAD request, it
  -sets <EM>header_only()</EM> to true. If we see that this has happened, we return from the handler
  -immediately with an <CODE>OK</CODE>
  -status code.
  +body, but the HTTP header only. When Apache receives a HEAD request, <EM>header_only()</EM> returns <EM>true</EM>. If we see that this has happened, we return from the handler immediately
  +with an <CODE>OK</CODE> status code.
   
   <P>
   Generally, you don't need the explicit content type setting, since Apache
  -does it for you, by looking up the MIME type of the request by matching the
  -extension of the URI in the MIME tables (from the
  +does this for you, by looking up the MIME type of the request by matching
  +the extension of the URI in the MIME tables (from the
   <EM>mime.types</EM> file). So if the request URI is <EM>/welcome.html</EM>, the
   <CODE>text/html</CODE> content-type will be picked. However for CGI scripts or URIs that cannot be
   mapped by a known extension, you should set the appropriate type by using
  @@ -2415,7 +2450,7 @@
     print &quot;Hello world&quot;;
   </PRE>
   <P>
  -it wouldn't work, because the HTTP header will not be sent. By default,
  +it wouldn't work, because the HTTP header will not be sent out. By default,
   mod_perl does not send any headers itself. You may wish to change this by
   adding
   
  @@ -2423,8 +2458,8 @@
   <PRE>  PerlSendHeader On
   </PRE>
   <P>
  -in the <CODE>&lt;Location</CODE>&gt; part of your configuration. Now, the response line and common headers
  -will be sent as they are by mod_cgi. Just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating double newline. Your script
  +in the <CODE>Apache::Registry</CODE>  <CODE>&lt;Location</CODE>&gt; section of your configuration. Now, the response line and common
  +headers will be sent as they are by mod_cgi. Just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating double newline. Your script
   must send that itself, e.g.:
   
   <P>
  @@ -2439,9 +2474,16 @@
   <P>
   Note, that in most UNIX CGI scripts, developers use a simpler ``\n\n'' and
   not ``\r\n\r\n''. There are occasions where sending ``\n'' without ``\r''
  -can cause problems, make it a habit to send ``\r\n'' every time.
  +can cause problems, make it a habit to always send ``\r\n'' every time.
  +
  +<P>
  +If you use an OS which uses the EBCDIC as character set (e.g.
  +BS2000-Posix), you should use this method to send the Content-type header:
   
   <P>
  +<PRE>  shift-&gt;send_http_header('text/html');
  +</PRE>
  +<P>
   The <CODE>PerlSendHeader On</CODE> directive tells mod_perl to intercept anything that looks like a header
   line (such as <CODE>Content-Type:
   text/plain</CODE>) and automatically turn it into a correctly formatted HTTP/1.0 header, the
  @@ -2463,6 +2505,10 @@
    }
   </PRE>
   <P>
  +Note that you can always use the code in the else part of the above
  +example, no matter of whether <CODE>PerlSendHeader</CODE> is directive takes an effect or not.
  +
  +<P>
   If you use <CODE>CGI.pm</CODE>'s <CODE>header()</CODE> function to generate HTTP headers, you do not need to activate this
   directive because <CODE>CGI.pm</CODE> detects
   <EM>mod_perl</EM> and calls <CODE>send_http_header()</CODE> for you.
  @@ -2617,7 +2663,7 @@
   Let's make our smart method more elaborate with <CODE>PerlSendHeader</CODE>
   directive settings, so it always does the right thing. It's especially
   important if you write an application that you are going to distribute,
  -hopefully as Open Source.
  +hopefully under one of the Open Source or GPL licences.
   
   <P>
   You can continue to improve this subroutine even further to handle
  @@ -2732,10 +2778,6 @@
   <CODE>END</CODE> blocks encountered during main server startup, i.e. those pulled in by the <CODE>PerlRequire</CODE> or by any <CODE>PerlModule</CODE>, are suspended.
   
   <P>
  -Apache versions 1.3b3 and later run the <CODE>END</CODE> blocks at
  -<CODE>child_exit()</CODE>.
  -
  -<P>
   Except during the cleanup phase, any <CODE>END</CODE> blocks encountered during compilation of <CODE>Apache::Registry</CODE> scripts, including subsequent invocations when the script is cached in
   memory, are called after the script has completed.
   
  @@ -2846,6 +2888,20 @@
   <EM>perlsec</EM> manpage for more information)
   
   <P>
  +If you have some scripts that won't run under Taint mode, run only the ones
  +that run under mod_perl with enabled Taint mode and the rest on another
  +server with disabled Taint mode -- this can be either a mod_cgi in the
  +front-end server or another back-end mod_perl server. You can use the
  +mod_rewrite module and redirect requests based on the file extensions. For
  +example you can use <EM>.tcgi</EM> for the taint-clean scripts, and <EM>cgi</EM> for the rest.
  +
  +<P>
  +When you have this setup you can start working toward cleaning the rest of
  +the scripts, to make them run under the Taint mode. Just because you have a
  +few dirty scripts doesn't mean that you should jeopardize your whole
  +service.
  +
  +<P>
   Since the <CODE>-T</CODE> switch doesn't have an equivalent perl variable, mod_perl provides the <CODE>PerlTaintCheck</CODE> directive to turn on taint checks. In
   <CODE>httpd.conf</CODE>, enable this mode with:
   
  @@ -2863,7 +2919,18 @@
   <CENTER><H2><A NAME="Other_switches">Other switches</A></H2></CENTER>
   <P>
   Finally, if you still need to to set additional perl startup flags such as <CODE>-d</CODE> and <CODE>-D</CODE>, you can use an environment variable
  -<CODE>PERL5OPT</CODE>. See
  +<CODE>PERL5OPT</CODE>. Switches in this variable are taken as if they were on every Perl command
  +line.
  +
  +<P>
  +Only the <CODE>-[DIMUdmw]</CODE> switches are allowed.
  +
  +<P>
  +When the <CODE>PerlTaintCheck</CODE> variable is turned on, the value of
  +<CODE>PERL5OPT</CODE> will be ignored.
  +
  +<P>
  +See also
   <A HREF="././modules.html#Apache_PerlRun_Run_unaltered_">Apache::PerlRun</A>.
   
   <P>
  @@ -2896,6 +2963,9 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H1></CENTER>
   <P>
  +META: you have a duplication with config.pod here.
  +
  +<P>
   To pass an environment variable from a configuration file, add to it:
   
   <P>
  @@ -2950,8 +3020,28 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="File_tests_operators">File tests operators</A></H1></CENTER>
  +<P>
  +Remember that with mod_perl you might get negative times when you use file
  +test operators like <CODE>-M</CODE> -- last modification time, <CODE>-A</CODE> -- last access time, <CODE>-C</CODE> -- last inode-change time, and others.  <CODE>-M</CODE>
  +returns the difference in time between the modification time of the file
  +and the time the script was started. Because the <CODE>^T</CODE> variable is not reset on each script invocation, and is equal to the time
  +when the process was forked, you might want to perform:
  +
  +<P>
  +<PRE>  $^T = time;
  +</PRE>
  +<P>
  +at the beginning of your scripts to simulate the regular perl script
  +behaviour of file tests.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A></H1></CENTER>
   <P>
  +META: duplication at debug.pod: =head3 Safe Resource Locking
  +
  +<P>
   When you write a script running under mod_cgi, you can get away with sloppy
   programming, like opening a file and letting the interpreter close it for
   you when the script had finished its run:
  @@ -3022,6 +3112,45 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Accessing_Request_Object_in_non_">Accessing Request Object in non-Perl*Handler Modules</A></H1></CENTER>
  +<P>
  +<CODE>Perl*Handler</CODE>s can obtain a reference to the request object when it is passed to them
  +via <CODE>@_</CODE>. For example:
  +
  +<P>
  +<PRE>  sub handler {
  +    my $r = shift;
  +    # ... some code
  +    return OK;
  +  }
  +</PRE>
  +<P>
  +In the <CODE>Apache::Registry</CODE> scripts (and friends), the request object is available through <CODE>Apache-&gt;request($r)</CODE> method. For example:
  +
  +<P>
  +<PRE>  my $r = Apache-&gt;request;
  +  print $r-&gt;uri;
  +</PRE>
  +<P>
  +In order to make the above work, <CODE>Apache::Registry</CODE> internally passes the original object to <CODE>Apache-&gt;request($r)</CODE> (transparantly to the users of itself). It does:
  +
  +<P>
  +<PRE>    sub handler {
  +    my $r = shift;
  +    Apache-&gt;request($r);
  +    # ... lots of woodoo code :)
  +    return OK;
  +  }
  +</PRE>
  +<P>
  +Some modules, like <CODE>CGI.pm</CODE>, rely on the fact that
  +<CODE>Apache-&gt;request()</CODE> will retrieve the request object. So when you use these modules with script
  +running under <CODE>Apache::Registry</CODE> (and friends) everything is fine. However if you write your own
  +<CODE>Perl*Handler</CODE> you should explicitly write <CODE>Apache-&gt;request($r)</CODE>
  +to make these modules work, just like in the above code snippet.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="The_Script_Is_Too_Dirty_But_It_">The Script Is Too Dirty, But It Does The Job And I Cannot Afford To Rewrite It.</A></H1></CENTER>
   <P>
   You still can win from using mod_perl. 
  @@ -3101,7 +3230,7 @@
     print &quot;Done with script\n&quot;;
   </PRE>
   <P>
  -First you'll see:
  +When executed as a plain script you'll see:
   
   <P>
   <PRE>  Foo-&gt;DESTROY
  @@ -3115,9 +3244,10 @@
     Foo-&gt;DESTROY
   </PRE>
   <P>
  -In this case, under mod_perl you wouldn't see <CODE>Foo-&gt;DESTROY</CODE>
  -until the server shutdown, or until your module properly took care of
  -things.
  +If you run this example with circular reference enabled under mod_perl you
  +won't see <CODE>Foo-&gt;DESTROY</CODE> until the server shutdown, or until your module properly took care of
  +things. Note that the <CODE>warn()</CODE> call logs its messages to the <EM>error_log</EM> file, so you should expect the printings there and not together with
  +STDOUT.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -3187,7 +3317,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.24      +126 -15   modperl-site/guide/scenario.html
  
  Index: scenario.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/scenario.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- scenario.html	2000/03/04 20:31:47	1.23
  +++ scenario.html	2000/04/09 14:19:41	1.24
  @@ -89,9 +89,19 @@
   		<LI><A HREF="#Building_process">Building process</A>
   	</UL>
   
  -	<LI><A HREF="#mod_proxy_add_forward_and_X_Forw">mod_proxy_add_forward and X-Forwarded-For header</A>
  +	<LI><A HREF="#Getting_the_Remote_Server_IP_in_">Getting the Remote Server IP in the Back-end server in the Proxy Setup</A>
  +	<UL>
  +
  +		<LI><A HREF="#Build">Build</A>
  +		<LI><A HREF="#Use">Use</A>
  +		<LI><A HREF="#Security">Security</A>
  +		<LI><A HREF="#Caveats">Caveats</A>
  +		<LI><A HREF="#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A>
  +	</UL>
  +
   	<LI><A HREF="#HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A>
   	<LI><A HREF="#mod_rewrite_Examples">mod_rewrite Examples</A>
  +	<LI><A HREF="#Caching_in_mod_proxy">Caching in mod_proxy</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -162,7 +172,7 @@
   test</CODE> step to pass.
   
   <P>
  -Extract both sources. Usually I open all the sources in <EM>/usr/src/</EM>, but your mileage may vary. So move the sources and <CODE>chdir</CODE> to the directory that you want to put the sources in. If you have a non-gnu
  +Extract both sources. Usually I open all the sources in <EM>/usr/src/</EM>, but your mileage may vary. So move the sources and <A HREF="#item_chdir">chdir</A> to the directory that you want to put the sources in. If you have a non-gnu
   <CODE>tar</CODE> utility it will be unable to decompress so you will do it in two steps:
   first uncompress the packages with:
   
  @@ -186,7 +196,7 @@
     % tar xzvf mod_perl-x.xx.tar.gz
   </PRE>
   <P>
  -<CODE>chdir</CODE> to the mod_perl source directory:
  +<A HREF="#item_chdir">chdir</A> to the mod_perl source directory:
   
   <P>
   <PRE>  % cd mod_perl-x.xx
  @@ -389,7 +399,7 @@
   If your programming techniques are sloppy, some of your scripts will not
   work and they may exhibit strange behaviour. Depending on the degree of
   sloppiness they may need anything from minor tweaking to a major rewrite to
  -make them work properly. (See <A HREF="././debug.html#Sometimes_script_works_sometime">Sometimes script works, sometimes does not</A>)
  +make them work properly. (See <A HREF="././debug.html#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A> )
   
   <P>
   The above setup is very basic, but as with Perl, you can start to benefit
  @@ -633,7 +643,7 @@
   </PRE>
   <P>
   <PRE>  % /usr/local/bin/perl Makefile.PL \
  -  APACHE_PREFIX=/usr/local/ \
  +  APACHE_PREFIX=/usr/local \
     APACHE_SRC=../apache_x.x.x/src \
     DO_HTTPD=1 \
     USE_APACI=1 \
  @@ -765,7 +775,7 @@
   number from firewalls and users, by using either mod_proxy's <CODE>ProxyPass</CODE> directive or a proxy server like Squid.
   
   <P>
  -For more details see <A HREF="././config.html#Publishing_Port_Numbers_Differen">Publishing Port Numbers Different From 80 </A>, <A HREF="././scenario.html#Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A>, <A HREF="././scenario.html#Running_Two_webservers_and_Squid">Running Two Webservers and Squid in httpd Accelerator Mode</A> and <A HREF="././scenario.html#mod_proxy">Using mod_proxy</A>.
  +For more details see <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>, <A HREF="././scenario.html#Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A>, <A HREF="././scenario.html#Running_Two_webservers_and_Squid">Running Two Webservers and Squid in httpd Accelerator Mode</A> and <A HREF="././scenario.html#mod_proxy">Using mod_proxy</A>.
   
   <P>
   Now we proceed to the mod_perl specific directives. It will be a good idea
  @@ -1156,7 +1166,7 @@
   correctly. After a time users will change their bookmarks. You can send
   them an email if you know the address, or you could leave a note on your
   pages asking users to update their bookmarks. You will avoid this problem
  -if you do not publish non-80 ports in the first place. See <A HREF="././config.html#Publishing_Port_Numbers_Differen">Publishing port numbers different from 80</A>.
  +if you do not publish non-80 ports in the first place. See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
   <P>
   &lt;META&gt; Need to write up a section about server logging with squid.
  @@ -1487,7 +1497,7 @@
   <P>
   Beware: if you put these two lines in the light <EM>httpd.conf</EM> before the static directories are mentioned, then in this setup the light
   httpd may find itself in an infinite loop if somebody were to request for
  -example <EM></img</EM>&gt;.
  +example <EM>&lt;/img&gt;</EM>.
   
   <P>
   Another way in which <CODE>:8080</CODE>'s can creep into URLs is if you have Perl code which issues a redirect to <CODE>http://$ENV{HTTP_HOST}/...</CODE>. If you are migrating from one heavy server to one heavy and one light,
  @@ -1907,16 +1917,38 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="mod_proxy_add_forward_and_X_Forw">mod_proxy_add_forward and X-Forwarded-For header</A></H1></CENTER>
  +<CENTER><H1><A NAME="Getting_the_Remote_Server_IP_in_">Getting the Remote Server IP in the Back-end server in the Proxy Setup</A></H1></CENTER>
   <P>
   Ask Bjoern Hansen has written the <CODE>mod_proxy_add_forward</CODE> module for Apache. It sets the <CODE>X-Forwarded-For</CODE> field when doing a
  -<CODE>ProxyPass</CODE>, similar to what Squid can do. Its location is specified in the help
  -section. Basically, this module adds an extra HTTP header to proxying
  -requests. You can access that header in the mod_perl-enabled server, and
  -set the IP address of the remote server. You won't need to compile anything
  -into the back-end server.
  +<CODE>ProxyPass</CODE>, similar to what Squid can do. Its location is specified in the <A HREF="././download.html#mod_proxy_add_forward">download</A> section.
  +
  +<P>
  +Basically, this module adds an extra HTTP header to proxying requests. You
  +can access that header in the mod_perl-enabled server, and set the IP
  +address of the remote server. You won't need to compile anything into the
  +back-end server.
   
   <P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Build">Build</A></H2></CENTER>
  +<P>
  +Download the module and use its location as a value of the
  +<EM>--activate-module</EM> argument for <EM>./configure</EM> utility within the Apache source code, so the module could be found.
  +
  +<P>
  +<PRE>  ./configure \
  +  &quot;--with-layout=Apache&quot; \
  +  &quot;--activate-module=src/modules/extra/mod_proxy_add_forward.c&quot; \
  +  &quot;--enable-module=proxy_add_forward&quot; \
  +  ... other options ...
  +</PRE>
  +<P>
  +<EM>--enable-module=proxy_add_forward</EM> enables this module as you have guessed already.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Use">Use</A></H2></CENTER>
  +<P>
   If you are using <CODE>Apache::{Registry,PerlRun}</CODE> just put something like the following into <EM>startup.pl</EM>:
   
   <P>
  @@ -1942,6 +1974,12 @@
   <PRE>  PerlPostReadRequestHandler My::ProxyRemoteAddr
   </PRE>
   <P>
  +Otherwise you retrieve it directly in your code.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Security">Security</A></H2></CENTER>
  +<P>
   Different sites have different needs. If you use the header to set the IP
   address, Apache believes it. This is reflected in the logging for example.
   You really don't want anyone but your own system to set the header, that's
  @@ -1961,6 +1999,9 @@
   access <CODE>REMOTE_ADDR</CODE> as usual.
   
   <P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Caveats">Caveats</A></H2></CENTER>
  +<P>
   It was reported that Ben Laurie's Apache-SSL does not seem to put the IP
   addresses in the <CODE>X-Forwarded-For</CODE> header--it does not set up such a header at all. However, the <CODE>REMOTE_ADDR</CODE> it sets up and contains the IP address of the original client machine.
   
  @@ -1971,6 +2012,53 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A></H2></CENTER>
  +<P>
  +Some users report that they cannot get this module to work as advertised;
  +they verify that the module is built in, but the front-end server is not
  +generating the X-Forwarded-For header when requests are being proxied to
  +the back-end server, and as a result, the back-end server has no idea what
  +the remote IP is.
  +
  +<P>
  +As it turns out, <EM>mod_proxy_add_forward</EM> needs to be configured in Apache before <EM>mod_proxy</EM> in order to operate properly, since Apache gives highest precedence to the
  +last defined module.
  +
  +<P>
  +Moving the two build options required to enable mod_proxy_add_forward while
  +compiling Apache build appears to have no effect on the default
  +configuration order of modules, since in each case, the builds show
  +mod_proxy_add_forward last in the list (or first via <EM>/server-info</EM>).
  +
  +<P>
  +The solution is to explicitly define the configuration order in the
  +<EM>http.conf</EM> file, so that mod_proxy_add_forward appears before mod_proxy, and therefore
  +gets executed after mod_proxy. (Modules are being executed in 'reverse'
  +order, i.e. module that was <EM>Added</EM> first will be executed last.)
  +
  +<P>
  +Obviously, this list would need to be tailored to match the build
  +environment, but to easy this task just insert <CODE>AddModule</CODE> directive before each entry reported by <CODE>httpd -l</CODE> (and removing
  +<EM>httpd_core.c</EM>, of course):
  +
  +<P>
  +<PRE>  ClearModuleList
  +  AddModule mod_env.c
  +  [more modules snipped]
  +  AddModule mod_proxy_add_forward.c
  +  AddModule mod_proxy.c
  +  AddModule mod_rewrite.c
  +  AddModule mod_setenvif.c
  +</PRE>
  +<P>
  +Note that the above snippet is added to <EM>httpd.conf</EM>.
  +
  +<P>
  +With this change, the <CODE>X-Forwarded-For</CODE> header is now being sent to the back-end server, and the remote IP appears
  +in the back-end server's access log.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A></H1></CENTER>
   <P>
   Assuming that you have a setup of one ``front-end'' server, which proxies
  @@ -2029,6 +2117,29 @@
   <P>
   It says: log all the rewrites thru the pipe to <CODE>rotatelogs</CODE> utility which will rotate the logs every 2 hours (86400 secs).
   
  +<P>
  +More examples:
  +
  +<P>
  +Redirect all those ie5 requests for <EM>favicon.ico</EM> to a central image:
  +
  +<P>
  +<PRE>  RewriteRule .*favicon.ico /wherever/favicon.ico [PT,NS]
  +</PRE>
  +<P>
  +A quick way to make dynamic pages look static:
  +
  +<P>
  +<PRE>  RewriteRule ^/wherever/([a-zA-Z]+).html /perl-bin/$1.cgi [PT]
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Caching_in_mod_proxy">Caching in mod_proxy</A></H1></CENTER>
  +<P>
  +This is not really a mod_perl related, so I'll just stress one point. If
  +you want the caching to work the following HTTP headers should be supplied: <CODE>Last-Modified</CODE>, <CODE>Content-Length</CODE> and
  +<CODE>Last-Modified</CODE>.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -2062,7 +2173,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.22      +183 -3    modperl-site/guide/snippets.html
  
  Index: snippets.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/snippets.html,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- snippets.html	2000/03/04 20:31:48	1.21
  +++ snippets.html	2000/04/09 14:19:41	1.22
  @@ -30,6 +30,7 @@
   	<LI><A HREF="#Emulating_the_Authentication_Mec">Emulating the Authentication Mechanism</A>
   	<LI><A HREF="#Caching_the_POSTed_Data">Caching the POSTed Data</A>
   	<LI><A HREF="#Cache_Control_for_Regular_and_Er">Cache Control for Regular and Error Modes</A>
  +	<LI><A HREF="#Convert_a_POST_Request_into_a_GE">Convert a POST Request into a GET Request</A>
   	<LI><A HREF="#Redirect_a_POST_Request_Forward">Redirect a POST Request, Forwarding the Content</A>
   	<LI><A HREF="#Reading_POST_Data_then_Redirect">Reading POST Data, then Redirecting or Doing Something Else</A>
   	<LI><A HREF="#Redirecting_While_Maintaining_En">Redirecting While Maintaining Environment Variables</A>
  @@ -48,7 +49,11 @@
   	<LI><A HREF="#Code_Unloading">Code Unloading</A>
   	<LI><A HREF="#A_Simple_Handler_To_Print_The_En">A Simple Handler To Print The Environment Variables</A>
   	<LI><A HREF="#mod_rewrite_Based_On_Query_Strin">mod_rewrite Based On Query String and URI Implemented in Perl</A>
  +	<LI><A HREF="#PerlTransHandler_example">PerlTransHandler example</A>
   	<LI><A HREF="#Setting_PerlHandler_Based_on_MIM">Setting PerlHandler Based on MIME Type</A>
  +	<LI><A HREF="#SSI_and_Embperl_Doing_Both">SSI and Embperl - Doing Both</A>
  +	<LI><A HREF="#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
  +	<LI><A HREF="#Authentication_Snippets">Authentication Snippets</A>
   	<LI><A HREF="#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
   	<LI><A HREF="#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
   </UL>
  @@ -299,6 +304,38 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Convert_a_POST_Request_into_a_GE">Convert a POST Request into a GET Request</A></H1></CENTER>
  +<P>
  +First, let me stress it: <STRONG>You can only read POST data once</STRONG>. If you need to read it more than once, you need to save it somewhere.
  +
  +<P>
  +A transparent way to do this is to switch the request method from POST to
  +GET and store the POST data in the query string:
  +
  +<P>
  +<PRE>  package Apache::POST2GET;
  +  use Apache::Constants qw(M_GET);
  +  
  +  sub handler {
  +    my $r = shift;
  +    if ($r-&gt;method eq 'POST') { 
  +       my $content = $r-&gt;content;
  +       $r-&gt;args($content);
  +       $r-&gt;method('GET');
  +       $r-&gt;method_number(M_GET);
  +       $r-&gt;headers_in-&gt;unset('Content-length');
  +    }
  +  }
  +  __END__
  +</PRE>
  +<P>
  +Then add this directive to <EM>httpd.conf</EM>:
  +
  +<P>
  +<PRE>  PerlInitHandler Apache::POST2GET
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Redirect_a_POST_Request_Forward">Redirect a POST Request, Forwarding the Content</A></H1></CENTER>
   <P>
   With mod_perl you can easily redirect a POST request to some other
  @@ -373,7 +410,7 @@
   <CENTER><H1><A NAME="More_on_Relative_Paths">More on Relative Paths</A></H1></CENTER>
   <P>
   Many people use relative paths for <CODE>require</CODE>, <CODE>use</CODE>, etc., or open files in the current directory or relative to the current
  -directory. But this will fail if you don't <CODE>chdir()</CODE> into the correct directory first (e.g when you call the script by its full
  +directory. But this will fail if you don't <A HREF="#item_chdir">chdir()</A> into the correct directory first (e.g when you call the script by its full
   path). This code would work:
   
   <P>
  @@ -418,7 +455,7 @@
   The paths will be always correct.
   
   <P>
  -It's different from using <CODE>&quot;./foo&quot;</CODE>, for you first have to <CODE>chdir</CODE> to the directory in which the script is located. (Think about <CODE>crontab</CODE>s!!!)
  +It's different from using <CODE>&quot;./foo&quot;</CODE>, for you first have to <A HREF="#item_chdir">chdir</A> to the directory in which the script is located. (Think about <CODE>crontab</CODE>s!!!)
   
   <P>
   <STRONG>Important:</STRONG>  <CODE>FindBin</CODE> will not work in mod_perl environment as it's loaded and executed only for
  @@ -872,6 +909,45 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="PerlTransHandler_example">PerlTransHandler example</A></H1></CENTER>
  +<P>
  +Suppose that before a content handler get invoked you want make this
  +translation:
  +
  +<P>
  +<PRE>  /articles/10/index.html  =&gt;  /articles/index.html?id=10
  +</PRE>
  +<P>
  +This <EM>TransHandler</EM> will do that for you:
  +
  +<P>
  +<PRE>  My/Trans.pm
  +  -----------
  +  package My::Trans;
  +  use Apache::Constants qw(:common);
  +  sub handler {
  +    my $r = shift;
  +    my $uri = $r-&gt;uri;
  +    my ($id) = ($uri =~ m|^/articles/(.*?)/|);
  +    $r-&gt;uri(&quot;/articles/index.html&quot;);
  +    $r-&gt;args(&quot;id=$id&quot;);
  +    return DECLINED;
  +  }
  +  1;
  +</PRE>
  +<P>
  +and the settings:
  +
  +<P>
  +<PRE>  PerlModule My::Trans 
  +  PerlTransHandler My::Trans
  +</PRE>
  +<P>
  +Notice the technique to set the <EM>args</EM>. By the time the apache-request object has been created, args are handled
  +in a separate slot, so you cannot just push them into an original URI.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Setting_PerlHandler_Based_on_MIM">Setting PerlHandler Based on MIME Type</A></H1></CENTER>
   <P>
   Q: Is there a way to set a PerlHandler for a specific MIME type? Something
  @@ -908,6 +984,110 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="SSI_and_Embperl_Doing_Both">SSI and Embperl -- Doing Both</A></H1></CENTER>
  +<P>
  +This handler allows to use both SSI and Embperl in the same request:
  +
  +<P>
  +Use it in a <CODE>&lt;FilesMatch</CODE>&gt; Section or similar:
  +
  +<P>
  +<PRE>  PerlModule Apache::EmbperlFilter Apache::SSI
  +  &lt;FilesMatch &quot;\.epl&quot;&gt;
  +     PerlSetVar Filter On
  +     PerlHandler Apache::EmbperlFilter Apache::SSI
  +  &lt;/FilesMatch&gt;
  +</PRE>
  +<P>
  +<PRE>  package Apache::EmbperlFilter;
  +  
  +  use Apache::Util qw(parsedate);
  +  use HTML::Embperl;
  +  use Apache::SSI ();
  +  use Apache::Constants;
  +  
  +  use strict;
  +  use vars qw($VERSION);
  +  
  +  $VERSION = '0.03';
  +  my ($r, %param, $input, $output);
  +  
  +  sub handler {
  +      $r = shift;
  +      my ($fh, $status) = $r-&gt;filter_input();
  +      unless ($status == OK) {
  +          return $status
  +      }
  +      local $/ = undef;
  +      $input = scalar(&lt;$fh&gt;);
  +      %param = ();
  +      $param{input} = \$input;
  +      $param{req_rec} = $r;
  +      $param{output} = \$output;
  +      $param{mtime} = mtime();
  +      $param{inputfile} = $r-&gt;filename();
  +      HTML::Embperl::ScanEnvironement(\%param);
  +      HTML::Embperl::Execute(\%param);
  +      print $output;
  +      return OK;
  +  }
  +  
  +  sub mtime {
  +      my $mtime = undef;
  +      if (my $last_modified = $r-&gt;headers_out-&gt;{'Last-Modified'}) {
  +          $mtime = parsedate $last_modified;
  +      }
  +      $mtime;
  +  }
  +  
  +  1;
  +  __END__
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A></H1></CENTER>
  +<P>
  +Assuming that you have more than one front-end server, and you want to
  +dynamically figure out the front-end server name in the back-end server,
  +mod_proxy and mod_rewrite provide the solution.
  +
  +<P>
  +Compile apache with both mod_proxy and mod_rewrite, then use a directive
  +something like this
  +
  +<P>
  +<PRE>  RewriteEngine On
  +  RewriteLog /somewhere/rewrite.log
  +  RewriteLogLevel 3
  +  RewriteRule ^/foo/bar(.*)$
  +  <A HREF="http://example.com:8080/foo/bar/">http://example.com:8080/foo/bar/</A>$1?IP=%{REMOTE_HOST} [QSA,P]
  +</PRE>
  +<P>
  +This will have all the urls starting with <EM>/some/url</EM> proxied off to the other server at the same url. It will append the <CODE>REMOTE_HOST</CODE>
  +header as a query string arguement. (QSA = Query String Append, P = Proxy).
  +There is probably a way to remap it as an X-Header of somesort, but if
  +query string is good enough for you, then this should work really nicely.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Authentication_Snippets">Authentication Snippets</A></H1></CENTER>
  +<P>
  +Getting authenticated username: <CODE>$r-&gt;connection-&gt;user()</CODE>, or
  +<CODE>$ENV{REMOTE_USER}</CODE> if you're in CGI emulation.
  +
  +<P>
  +The code example:
  +
  +<P>
  +<PRE>  my $r = shift;
  +  
  +  my ($res, $sent_pwd) = $r-&gt;get_basic_auth_pw;
  +  return $res if $res; #decline if not Basic
  +  
  +  my $user = $r-&gt;connection-&gt;user;
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A></H1></CENTER>
   <P>
   Well, as it's always with Perl -- TMTOWTDI (There Is More Than One Way To
  @@ -1158,7 +1338,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/16/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.13      +264 -3    modperl-site/guide/strategy.html
  
  Index: strategy.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/strategy.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- strategy.html	2000/03/04 20:31:48	1.12
  +++ strategy.html	2000/04/09 14:19:41	1.13
  @@ -59,6 +59,9 @@
   		<LI><A HREF="#Three_Machines_Model">Three Machines Model</A>
   	</UL>
   
  +	<LI><A HREF="#Do_not_put_mod_ssl_into_mod_perl">Do not put mod_ssl into mod_perl server</A>
  +	<LI><A HREF="#Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A>
  +	<LI><A HREF="#Multithreading_or_not_Multithrea">Multithreading or not Multithreading</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -192,8 +195,11 @@
   The DSO module (<CODE>mod_so</CODE>) adds size and complexity to your binaries.
   
   <P>
  -See <A HREF="././install.html#Build_mod_perl_as_a_DSO_inside_t">Build mod_perl as DSO inside Apache source tree via APACI</A>
  +Refer to the section <A HREF="././strategy.html#Pros_and_Cons_of_Building_mod_pe">"Pros and Cons of Building mod_perl as DSO</A> for more information.
   
  +<P>
  +Build details: <A HREF="././install.html#Build_mod_perl_as_a_DSO_inside_t">Build mod_perl as DSO inside Apache source tree via APACI</A>
  +
   
   
   <P><LI>
  @@ -362,7 +368,7 @@
   <CODE>/icons/arrow.gif</CODE> is a relative one. Using <CODE>&lt;BASE
   HREF=&quot;http://www.nowhere.com/&quot;</CODE>&gt; in the generated HTML is another way to handle this problem. Also the <CODE>httpd_perl</CODE> server could rewrite the requests back to <CODE>httpd_docs</CODE> (much slower) and you still need the attention of the heavy servers. This
   is not an issue if you hide the internal port implementations, so the
  -client sees only one server running on port <CODE>80</CODE>. (See <A HREF="././config.html#Publishing_Port_Numbers_Differen">Publishing port numbers different from 80</A>)
  +client sees only one server running on port <CODE>80</CODE>. (See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>)
   
   <P>
   The disadvantages:
  @@ -465,6 +471,10 @@
   
   </UL>
   <P>
  +META: It seems that khttpd, or Phhttpd should be even faster for static
  +content serving, add more info about these two!
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A></H1></CENTER>
   <P>
  @@ -1011,6 +1021,257 @@
   requirement will depend on the number of object you will have to serve and
   the hit rate.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Do_not_put_mod_ssl_into_mod_perl">Do not put mod_ssl into mod_perl server</A></H1></CENTER>
  +<P>
  +If you need an SSL functionality, you can get it by adding the mod_ssl or
  +equivalent apache_ssl to the light front-end server (httpd_docs) or the
  +heavy back-end mod_perl server (httpd_perl). ( The configuration and
  +installation instructions are located
  +<A HREF="././install.html#mod_perl_and_mod_ssl_openssl_">here</A>.)
  +
  +<P>
  +The question is whether it's a good idea to add mod_ssl into the back-end
  +mod_perl enabled server. Given that your internal network is secured or if
  +both the front and back end servers are running on the same machine and you
  +can ensure a safe communication between the processes there is no need for
  +an encrypted traffic between them.
  +
  +<P>
  +If this is the situation you don't have to put mod_ssl into the already too
  +much heavy mod_perl server. You will have the external traffic encrypted by
  +the front-end server, which will proxy-pass the unencrypted request and
  +response data internally.
  +
  +<P>
  +Another important point is if you put the mod_ssl on the back-end, you have
  +to tunnel back your images to it (i.e. have the back-end serve the images)
  +defeating the whole purpose of having the front-end lightweight server. 
  +
  +<P>
  +You cannot serve a secure page which includes non-secured information. If
  +you fetch an html over SSL and have an <CODE>&lt;IMG</CODE>&gt; tag that fetches the image from the non-secure server, the image show
  +broken. This is true for any other non-secured object as well. Of course if
  +the generated response doesn't include any embedded objects, like images --
  +this is not a problem.
  +
  +<P>
  +Choosing the front-end machine to have an SSL functionality also simplifies
  +configuration of mod_perl by eliminating VirtualHost duplication for SSL.
  +mod_perl configuration files can be plenty difficult without the mod_ssl
  +overhead.
  +
  +<P>
  +Also assuming that you have front-end machines under-worked anyway,
  +especially if you run a high-volume web service deploying a cluster of
  +machines to serve requests, you save some CPU as it's known that SSL
  +connections are about 100 times more CPU intensive than non-SSL
  +connections.
  +
  +<P>
  +Of course caching session keys so you don't have to set up a new symmetric
  +key for every single connection, improves the situation. If you use the
  +shared memory session caching mechanism that mod_ssl supports, then the
  +overhead is actually rather small except for the initial connection.
  +
  +<P>
  +But then on the other hand, why even bother to run a full scale mod_ssl in
  +front? You might as well just choose a small tunnel/port forwarding
  +application like Stunnel or one of the many other mentioned at <A
  +HREF="http://www.openssl.org/related/apps.html.">http://www.openssl.org/related/apps.html.</A>
  +
  +
  +<P>
  +Of course if you do a heavy SSL processing you should really be offloading
  +it to dedicated cryptography hardware.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A></H1></CENTER>
  +<P>
  +On modern Unix derivatives there exists a nifty mechanism usually called
  +dynamic linking/loading of Dynamic Shared Objects (DSO) which provides a
  +way to build a piece of program code in a special format for loading it at
  +run-time into the address space of an executable program.
  +
  +<P>
  +As of Apache 1.3, the configuration system supports two optional features
  +for taking advantage of the modular DSO approach: compilation of the Apache
  +core program into a DSO library for shared usage and compilation of the
  +Apache modules into DSO files for explicit loading at run-time.
  +
  +<P>
  +Should you use this method? Read the pros and cons and decide for yourself.
  +
  +<P>
  +Pros:
  +
  +<UL>
  +<P><LI>
  +<P>
  +The server package is more flexible at run-time because the actual server
  +process can be assembled at run-time via <CODE>LoadModule</CODE>
  +
  +<EM>httpd.conf</EM> configuration commands instead of <EM>Configuration</EM>
  +
  +<CODE>AddModule</CODE> commands at build-time. For instance this way one is able to run different
  +server instances (standard &amp; SSL version, with and without mod_perl)
  +with only one Apache installation.
  +
  +<P><LI>
  +<P>
  +The server package can be easily extended with third-party modules even
  +after installation. This is at least a great benefit for vendor package
  +maintainers who can create a Apache core package and additional packages
  +containing extensions like PHP3, mod_perl, mod_fastcgi, etc.
  +
  +<P><LI>
  +<P>
  +Easier Apache module prototyping because with the DSO/apxs pair you can
  +both work outside the Apache source tree and only need an apxs
  +-i command followed by an apachectl&nbsp;restart to bring a new version of your currently developed module into the running
  +Apache server.
  +
  +</UL>
  +<P>
  +Cons:
  +
  +<UL>
  +<P><LI>
  +<P>
  +The DSO mechanism cannot be used on every platform because not all
  +operating systems support dynamic loading of code into the address space of
  +a program.
  +
  +<P><LI>
  +<P>
  +The server is approximately 20% slower at startup time because of the
  +symbol resolving overhead the Unix loader now has to do.
  +
  +<P><LI>
  +<P>
  +The server is approximately 5% slower at execution time under some
  +platforms because position independent code (PIC) sometimes needs
  +complicated assembler tricks for relative addressing which are not
  +necessarily as fast as absolute addressing.
  +
  +<P><LI>
  +<P>
  +Because DSO modules cannot be linked against other DSO-based libraries (ld
  +-lfoo) on all platforms (for instance a.out-based platforms usually don't
  +provide this functionality while ELF-based platforms do) you cannot use the
  +DSO mechanism for all types of modules. Or in other words, modules compiled
  +as DSO files are restricted to only use symbols from the Apache core, from
  +the C library (libc) and all other dynamic or static libraries used by the
  +Apache core, or from static library archives (libfoo.a) containing position
  +independent code. The only chances to use other code is to either make sure
  +the Apache core itself already contains a reference to it, loading the code
  +yourself via <CODE>dlopen()</CODE> or enabling the SHARED_CHAIN rule while
  +building Apache when your platform supports linking DSO files against DSO
  +libraries.
  +
  +<P><LI>
  +<P>
  +Under some platforms (many SVR4 systems) there is no way to force the
  +linker to export all global symbols for use in DSO's when linking the
  +Apache httpd executable program. But without the visibility of the Apache
  +core symbols no standard Apache module could be used as a DSO. The only
  +chance here is to use the SHARED_CORE feature because this way the global
  +symbols are forced to be exported. As a consequence the Apache
  +src/Configure script automatically enforces SHARED_CORE on these platforms
  +when DSO features are used in the Configuration file or on the configure
  +command line.
  +
  +</UL>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Multithreading_or_not_Multithrea">Multithreading or not Multithreading</A></H1></CENTER>
  +<P>
  +I want to quote this question that showed up and the mod_perl list and the
  +answer in their entireness. By the way, this question has been asked before
  +perl5.6 and apache2.0 have been released (both with multithread support).
  +
  +<P>
  +John Henckel has asked:
  +
  +<P>
  +Thanks for your help. I am slowly coming to terms with the fact that Perl
  +is not multithreaded and so it will never be able to scale the way I need
  +it to. It is only a couple thousand lines of code. I will have to rewrite
  +it as a servlet in Java or else a C program using the FastCGI protocol.
  +
  +<P>
  +Many people thing FCGI can't handle multiple concurrent requests, however,
  +that is only a perl limitation. The C-FCGI interface, with multithreading,
  +can process hundreds of CGI request simulataneously in ONE process with ONE
  +socket to the Apache server.
  +
  +<P>
  +Shane has replied:
  +
  +<P>
  +Arg...! Okay, lets backup. Multithreading is not a good idea. What your
  +talking about is a process which takes 4 seconds to complete..., what are
  +we talking about, remote system communication? You have a process which
  +takes 4 seconds to finish, it doesn't matter what you use as your design...
  +it still takes 4 seconds. If you have 100 requests for a 4 second
  +process... its going to take 400 seconds. (Actually, due to context
  +switching, probably more like 500)
  +
  +<P>
  +Multi-threading ADDs, not subtracts from the load. But you see it all
  +depends on what sort of architecture your going to use too. If you going to
  +use a single processor machine, multithreading is going to slow the whole
  +process down. If your using a computer that has 100s of processors, then
  +clearly, multithreading is the approach to take.
  +
  +<P>
  +The perl ``limitation'' of which is you speak is not a limitation per se.
  +Its a limitation if your only using one instance of the perl interpretor.
  +But you are free to use more than one instance of that interpretor.
  +(perldoc perlembed) However, it makes zero sense to have more interpretors
  +than processors... due the context switching issue.
  +
  +<P>
  +The best way to solve the problem is to have one ``processing'' thread per
  +processor. (I.e. the thread that does work on the request that is supposed
  +to take 4 seconds) That thread can be directly written in c, or you can
  +write some code for a perl interpretor to process. No big deal.., just keep
  +in mind, if you start opening up more processing threads than processors
  +you have and start cramming requests down throat faster than once per four
  +seconds, the things going to tumble like dominos. The best thing you could
  +possibly do is this: Setup an engine of your own to handle this 4 second
  +long process. Initiate as many threads as you have processors. Start a
  +queue of processes that can be however long. Hand out 4 second long
  +processes to the queue.
  +
  +<P>
  +This design will keep things from crashing. Even better would be to have a
  +series of computers that grab requests from others. I.e. setup a central
  +thread written in c, then have it act as a queue. Processing threads grab
  +new requests from that queue, and deliver them. This is of course based on
  +your effort of running a process that takes 4 seconds.
  +
  +<P>
  +If this is about remote communication, which I have no idea why it wouldn't
  +be unless your doing some strange number crunching, then what you want to
  +do is read up on <CODE>select(),</CODE> and <CODE>poll().</CODE> Or if you
  +want to have it work really well, read up on rt signal queues, and run on
  +the 2.3.x linux kernel, or some other unix variant.
  +
  +<P>
  +I'll reiterate... having more threads than processors in ANY language is a
  +bad idea, if it can be avoided. Which it can if you use the newer
  +programming stuff. Moving to Java will not solve your problems, it will
  +create 100x worse ones in terms of performance. Moving to c will not solve
  +your problems. Moving to Perl will not solve your problem. Investigating
  +your problem clearly will help eventually solve your problem. (BTW: No CGI
  +request should take 4 seconds to process, unless you are querying a
  +database on the other side of the planet. Unless its some sort of
  +mathematics lab searching for prime numbers or something. I might sound
  +like I'm joking..., but I most certainly am not.)
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -1044,7 +1305,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 03/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  
  1.4       +10 -2     modperl-site/guide/troubleshooting.html
  
  Index: troubleshooting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/troubleshooting.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- troubleshooting.html	2000/02/09 21:11:46	1.3
  +++ troubleshooting.html	2000/04/09 14:19:42	1.4
  @@ -53,6 +53,7 @@
   
   		<LI><A HREF="#Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A>
   		<LI><A HREF="#rwrite_returned_1">rwrite returned -1</A>
  +		<LI><A HREF="#Can_t_upgrade_that_kind_of_scala">Can't upgrade that kind of scalar ...</A>
   		<LI><A HREF="#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>
   		<LI><A HREF="#Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A>
   		<LI><A HREF="#Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A>
  @@ -341,6 +342,13 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Can_t_upgrade_that_kind_of_scala">Can't upgrade that kind of scalar ...</A></H2></CENTER>
  +<P>
  +Fixed in mod_perl 1.22_01-dev (aka in the CVS version following the release
  +of 1.22. Either grab the CVS version or wait for 1.23 to be released.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="caught_SIGPIPE_in_process">caught SIGPIPE in process</A></H2></CENTER>
   <P>
   <PRE>  [modperl] caught SIGPIPE in process 1234
  @@ -454,7 +462,7 @@
   <CODE>$q-&gt;param('test')</CODE> returns some value or <CODE>undef</CODE>.
   
   <P>
  -Also read about <A HREF="././debug.html#Finding_the_Line_Number_the_Erro">finding the Line Number the Error/Warning has been Triggered at</A>.
  +Also read about <A HREF="././debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -717,7 +725,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/04/2000
  +	     <BR>Last Modified at 04/09/2000
         </FONT>
       </B>
     </TD>
  
  
  

Mime
View raw message