fix validation, organization, and links
[catagits/fcgi2.git] / doc / fcgi-tcl.htm
index f860fcc..7556ef6 100644 (file)
-<html>
-<head><title>Integrating FastCGI with Tcl</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" 
-vlink="#555555">
-
-<center>
-<a href="http://fastcgi.com">
-    <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
-</center>
-<br clear=all>
-<h3><center>Integrating FastCGI with Tcl</center></h3>
-
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-
-<P ALIGN=CENTER>
-Michael S. Shanzer
-<BR>
-Open Market, Inc.
-<BR>
-<EM>19 January 1995</EM>
-</P>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-$Id: fcgi-tcl.htm,v 1.2 2001/05/14 13:00:30 robs Exp $ <br>
-</h5>
-<hr>
-
-
-<h3><a NAME = "S1">1. Introduction</a></h3>
-
-
-Tcl (tool command language) is an embeddable scripting language
-that's often used for CGI programming.  Tcl is freely available
-as a source kit.<p>
-
-We've built a Tcl interpreter that runs as a FastCGI application.  Our
-purpose in doing so was twofold:
-
-<ul>
-    <li><i>Create a useful artifact.</i>
-        Open Market has written many CGI applications using Tcl.
-        Now we'd like to turn them into FastCGI applications.<p>
-    <li><i>Demonstrate how easy it is to integrate FastCGI with an
-        existing program.</i>
-        The Tcl interpreter is a substantial program, so integrating
-        FastCGI with the Tcl interpreter is a good test of the
-        <tt>fcgi_stdio</tt> compatability library.
-</ul>
-
-We've succeeded on both counts.  We now have a platform for
-migrating our Tcl-based CGI applications to FastCGI.  And
-the integration required a very small effort.  The only source
-code change to the Tcl interpreter was the routine addition of a
-handful of new commands: <tt>FCGI_Accept</tt>, <tt>FCGI_Finish</tt>,
-<tt>FCGI_SetExitStatus</tt>, and <tt>FCGI_StartFilterData</tt>.<p>
-
-The FastCGI-integrated Tcl interpreter works as usual when run
-from a shell or as a CGI program.  You don't need two Tcls,
-one for FastCGI and one for other uses.<p>
-
-The remainder of this document gives a recipe you can follow to
-build FastCGI into Tcl, explains what's happening in the recipe,
-and illustrates the use of FastCGI Tcl with
-an example program.<p>
-
-<h3><a NAME = "S2">2. Recipe</a></h3>
-
-Here are the assumptions embedded in the following recipe:
-<ul>
-    <li>You are building Tcl 7.4p3, the current stable Tcl release
-    as this is written.
-    You unpack the Tcl kit into a directory <tt>tcl7.4</tt>
-    that's a sibling of the FastCGI kit directory
-    <tt>fcgi-devel-kit</tt>.<p>
-
-    <li>You have gcc version 2.7
-    installed on your system, and use it in the build.
-    gcc is convenient because it supports the <tt>-include</tt>
-    command-line option
-    that instructs the C preprocessor to include a specific file before
-    processing any other include files.  This allows you to include
-    <tt>fcgi_stdio.h</tt> without modifying Tcl source files.  (The
-    reason for specifying gcc version 2.7 is that I have
-    experienced bad behavior with an earlier version and the <tt>-include</tt>
-    flag -- the C preprocessor died with SIGABRT.)<p>
-
-    <li>You have GNU autoconf
-    installed on your system.  If you don't have GNU autoconf,
-    you will have to make certain edits by hand and
-    repeat these edits for each build platform.<p>
-</ul>
-
-If those are valid assumptions, follow these steps:
-<ol>
-    <li><i>Build the FastCGI Developer's Kit.</i>
-    Tcl needs to link against <tt>libfcgi.a</tt>, so
-    <a href="fcgi-devel-kit.htm#S2">build
-    the FastCGI Developer's Kit</a>
-    in order to create this library for your platform.<p>
-
-    <li><i>Pull the Tcl 7.4p3 kit.</i>
-    You'll need the files
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4.tar.Z">tcl7.4.tar.Z</a>,
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p1.patch.gz">tcl7.4p1.patch.gz</a>,
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p2.patch.gz">tcl7.4p2.patch.gz</a>,
-    and
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p3.patch.gz">tcl7.4p3.patch.gz</a>.
-    (Some older Netscape browsers can't perform these
-    retrievals because of a protocol conflict between Netscape
-    and Sun's firewall.)<p>
-
-    Unpack the tar file in the parent directory of the
-    FastCGI kit directory you used in the previous step,
-    so that the directories <tt>tcl7.4</tt> and <tt>fcgi-devel-kit</tt>
-    are siblings.  After unpacking the tar file, follow the directions
-    in the <tt>README</tt> to apply the patches.<p>
-
-    The <a href="http://www.sunlabs.com:80/research/tcl/">Sun Labs Tcl/Tk
-    Project Page</a> contains a wealth of information on Tcl, including
-    up to date information on the latest kits.<p>
-
-    <li><i>Copy the files <tt>tclFCGI.c</tt>, <tt>tclAppInit.c</tt>,
-        <tt>Makefile.in</tt>, and <tt>configure.in</tt> from the FastCGI kit.</i>
-    <pre>
-    > cd tcl7.4
-    > mv tclAppInit.c tclAppInit.c.orig
-    > mv Makefile.in.orig Makefile.in.orig.orig
-    > mv Makefile.in Makefile.in.orig
-    > mv configure.in configure.in.orig
-    > cp ../fcgi-devel-kit/tcl/tcl7.4/* .
-    > cp ../fcgi-devel-kit/tcl/common/* .</pre>
-
-    <li><i>Create a new <tt>configure</tt> script.</i>
-    <pre>
-    > autoconf</pre>
-
-    <li><i>Configure and build.</i>
-    <pre>
-    > ./configure
-    > make</pre>
-    The <tt>make</tt> creates the Tcl interpreter <tt>tclsh</tt>
-    and library archive <tt>libtcl.a</tt> (for embedding Tcl in
-    your own C applications).  The Tcl <tt>README</tt> file
-    explains how you can experiment with <tt>tclsh</tt>
-    without installing it in a standard place.<p>
-</ol>
-
-<h3><a NAME = "S3">3. Recipe Explained</a></h3>
-
-The recipe alone is fine if you are using Tcl 7.4p3, you have gcc
-version 2.7, and you have GNU autoconf.  In case one or more of these
-assumptions doesn't hold for you, and to illuminate how little work was
-involved in integrating FastCGI, here's an explanation of how
-and why you would modify the files <tt>tclAppInit.c</tt>,
-<tt>Makefile.in</tt>, and <tt>configure.in</tt> from the Tcl kit.
-
-<ul>
-    <li><tt>tclAppInit.c</tt>:<p>
-    <ul>
-        <li>Add the following three lines of code
-        to the function <tt>Tcl_AppInit</tt> after the call
-        to <tt>Tcl_Init</tt> and after the comment about calling init
-        procedures:
-        <pre>
-    if (FCGI_Init(interp) == TCL_ERROR) {
-        return TCL_ERROR;
-    }</pre>
-        This registers four Tcl commands (<tt>FCGI_Accept</tt>,
-        <tt>FCGI_Finish</tt>, <tt>FCGI_SetExitStatus</tt>, and
-        <tt>FCGI_StartFilterData</tt>), implemented in
-        <tt>tclFCGI.c</tt>, with the Tcl interpreter.<p>
-    </ul>
-
-    <li><tt>Makefile.in</tt>:<p>
-    <ul>
-        <li>Add <tt>tclFCGI.o</tt> to the <tt>GENERIC_OBJS</tt> variable, and
-            add <tt>tclFCGI.c</tt> to the <tt>SRCS</tt> variable.<p>
-
-            This builds the FastCGI Tcl commands and
-            links them into the Tcl interpreter.<p>
-
-        <li>Add <tt>-I../fcgi-devel-kit/include
-                    -include ../fcgi-devel-kit/include/fcgi_stdio.h</tt>
-            to the <tt>CFLAGS</tt> variable.<p>
-
-            This includes <tt>fcgi_stdio.h</tt>
-            when compiling C code for the Tcl interpreter, overriding
-            the normal <tt>stdio</tt> types, variables, and functions.<p>
-
-        <li>Add <tt>../fcgi-devel-kit/libfcgi/libfcgi.a</tt> before the
-            <tt>@LIBS@</tt> part of the <tt>LIBS</tt> variable.<p>
-
-            This links the implementation of <tt>fcgi_stdio.h</tt>
-            into the Tcl interpreter, for use by the <tt>FCGI_accept</tt>
-            command and any code that uses <tt>stdio</tt> variables
-            or calls <tt>stdio</tt> functions.<p>
-    </ul><p>
-
-    The last two edits will vary if you use a compiler other than gcc or
-    install the <tt>tcl7.4</tt> directory
-    somewhere else in relation to the <tt>fcgi-devel-kit</tt> directory.<p>
-
-    <li><tt>configure.in</tt>:<p>
-    <ul>
-        <li>
-        Replace the lines
-        <pre>
-AC_C_CROSS
-CC=${CC-cc}</pre>
-        with the lines
-        <pre>
-AC_PROG_CC
-AC_C_CROSS</pre>
-        This selects gcc in preference to other C compilers.<p>
-         
-        <li>
-        Add the following lines just after the
-        <tt>AC_SUBST(CC)</tt> line:
-        <pre>
-AC_CHECK_LIB(socket, main, [LIBS="$LIBS -lsocket"])
-AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])
-AC_SUBST(LIBS)</pre>
-        This ensures that the socket libraries used by FastCGI
-        are linked into the Tcl interpreter.<p>
-    </ul>
-    If GNU autoconf is not available to you, you'll leave
-    <tt>configure.in</tt> alone and perform the following steps:<p>
-    <ul>
-        <li>
-        Execute
-        <pre>
-    > SETENV CC gcc</pre>
-        before running <tt>configure</tt>.<p>
-
-        <li>
-        If you are running on a SVR4-derived Unix platform,
-        edit <tt>Makefile</tt> to add
-        <tt>-lsocket -lnsl</tt> to the <tt>LIBS</tt> value
-        after running <tt>configure</tt>.<p>
-    </ul>
-    If you ever re-run <tt>configure</tt>, you'll need to repeat
-    these steps.<p>
-
-</ul>
-
-
-<h3><a NAME = "S4">4. Writing FastCGI applications in Tcl</a></h3>
-
-The Tcl program <tt>tcl/tiny-tcl-fcgi</tt> performs the same function as the C 
-program <tt>examples/tiny-fcgi.c</tt> that's used as an example in the <a href="fcgi-devel-kit.htm#S3.1.1">FastCGI 
-Developer's Kit document</a>. Here's what the Tcl version looks like:
-<p>
-
-<pre>
-#!./tclsh
-set count 0 
-while {[FCGI_Accept] &gt;= 0 } {
-    incr count
-    puts -nonewline "Content-type: text/html\r\n\r\n"
-    puts "&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;"
-    puts "&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;"
-    puts "Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;"
-}
-</pre>
-
-If you've built Tcl according to the recipe and you have a Web server
-set up to run FastCGI applications, load the FastCGI Developer's Kit
-Index Page in that server and run this Tcl application now.<p>
-
-The script invokes Tcl indirectly via the symbolic link
-<tt>examples/tclsh</tt>.  It does this because HP-UX has a limit of 32
-characters for the first line of a command-interpreter file such as
-<tt>examples/tiny-tcl-fcgi</tt>.  If you run on HP-UX you won't want
-to sprinkle symbolic links to <tt>tclsh</tt> everywhere, so you should install
-<tt>tclsh</tt> with a shorter pathname than
-<tt>/usr/local/tcl7.4-fcgi/bin/tclsh7.4</tt>.<p>
-
-The Tcl command <tt>FCGI_Accept</tt> treats the initial
-environment differently than the C function <tt>FCGI_Accept</tt>.  The
-first call to the
-C function <tt>FCGI_Accept</tt> replaces the initial environment with
-the environment of the first request.  The first call to the Tcl command
-<tt>FCGI_Accept</tt> adds the variable bindings of the first request
-to the bindings present in the initial environment.  So when the first
-call to <tt>FCGI_Accept</tt> returns, bindings from the initial
-environment are still there (unless, due to naming conflicts, some of
-them have been overwritten by the first request).  The next call to
-<tt>FCGI_Accept</tt> removes the bindings made on the previous call
-before adding a new set for the request just accepted, again preserving
-the initial environment.<p>
-
-The FastCGI-integrated <tt>tclsh</tt> also includes
-commands <tt>FCGI_Finish</tt>, <tt>FCGI_SetExitStatus</tt>,
-and <tt>FCGI_StartFilterData</tt> that correspond to
-C functions in <tt>fcgi_stdio.h</tt>; see the manpages for
-full information.<p>
-
-Converting a Tcl CGI application to FastCGI is not fundamentally
-different from converting a C CGI application.  You separate
-the portion of the application that performs one-time
-initialization from the portion that performs per-request
-processing.  You put the per-request processing into a loop
-controlled by <tt>FCGI_Accept</tt>.<p>
-
-<HR>
-<ADDRESS><A HREF="mailto:shanzer@openmarket.com">Mike Shanzer // shanzer@openmarket.com</A></ADDRESS>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         Integrating FastCGI with Tcl\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ h5.c3 {text-align: center}\r
+ p.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>\r
+      </DIV>\r
+      <BR CLEAR="all">\r
+      <DIV CLASS="c1">\r
+         <H3>\r
+            Integrating FastCGI with Tcl\r
+         </H3>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <P CLASS="c2">\r
+         Michael S. Shanzer<BR>\r
+         Open Market, Inc.<BR>\r
+         <EM>19 January 1995</EM>\r
+      </P>\r
+      <H5 CLASS="c3">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+         $Id: fcgi-tcl.htm,v 1.3 2001/11/27 01:03:47 robs Exp $<BR>\r
+      </H5>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         Tcl (tool command language) is an embeddable scripting language that&#39;s often used for CGI programming. Tcl\r
+         is freely available as a source kit.\r
+      </P>\r
+      <P>\r
+         We&#39;ve built a Tcl interpreter that runs as a FastCGI application. Our purpose in doing so was twofold:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <I>Create a useful artifact.</I> Open Market has written many CGI applications using Tcl. Now we&#39;d like\r
+            to turn them into FastCGI applications.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Demonstrate how easy it is to integrate FastCGI with an existing program.</I> The Tcl interpreter is a\r
+            substantial program, so integrating FastCGI with the Tcl interpreter is a good test of the\r
+            <TT>fcgi_stdio</TT> compatability library.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         We&#39;ve succeeded on both counts. We now have a platform for migrating our Tcl-based CGI applications to\r
+         FastCGI. And the integration required a very small effort. The only source code change to the Tcl interpreter\r
+         was the routine addition of a handful of new commands: <TT>FCGI_Accept</TT>, <TT>FCGI_Finish</TT>,\r
+         <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT>.\r
+      </P>\r
+      <P>\r
+         The FastCGI-integrated Tcl interpreter works as usual when run from a shell or as a CGI program. You don&#39;t\r
+         need two Tcls, one for FastCGI and one for other uses.\r
+      </P>\r
+      <P>\r
+         The remainder of this document gives a recipe you can follow to build FastCGI into Tcl, explains what&#39;s\r
+         happening in the recipe, and illustrates the use of FastCGI Tcl with an example program.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Recipe</A>\r
+      </H3>\r
+      <P>\r
+         Here are the assumptions embedded in the following recipe:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            You are building Tcl 7.4p3, the current stable Tcl release as this is written. You unpack the Tcl kit into\r
+            a directory <TT>tcl7.4</TT> that&#39;s a sibling of the FastCGI kit directory <TT>fcgi-devel-kit</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            You have gcc version 2.7 installed on your system, and use it in the build. gcc is convenient because it\r
+            supports the <TT>-include</TT> command-line option that instructs the C preprocessor to include a specific\r
+            file before processing any other include files. This allows you to include <TT>fcgi_stdio.h</TT> without\r
+            modifying Tcl source files. (The reason for specifying gcc version 2.7 is that I have experienced bad\r
+            behavior with an earlier version and the <TT>-include</TT> flag -- the C preprocessor died with SIGABRT.)\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            You have GNU autoconf installed on your system. If you don&#39;t have GNU autoconf, you will have to make\r
+            certain edits by hand and repeat these edits for each build platform.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         If those are valid assumptions, follow these steps:\r
+      </P>\r
+      <OL>\r
+         <LI>\r
+            <I>Build the FastCGI Developer&#39;s Kit.</I> Tcl needs to link against <TT>libfcgi.a</TT>, so <A HREF=\r
+            "fcgi-devel-kit.htm#S2">build the FastCGI Developer&#39;s Kit</A> in order to create this library for your\r
+            platform.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Pull the Tcl 7.4p3 kit.</I> You&#39;ll need the files <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4.tar.Z">tcl7.4.tar.Z</A>, <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p1.patch.gz">tcl7.4p1.patch.gz</A>, <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p2.patch.gz">tcl7.4p2.patch.gz</A>, and <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p3.patch.gz">tcl7.4p3.patch.gz</A>. (Some older Netscape browsers\r
+            can&#39;t perform these retrievals because of a protocol conflict between Netscape and Sun&#39;s firewall.)\r
+            <P>\r
+               Unpack the tar file in the parent directory of the FastCGI kit directory you used in the previous step,\r
+               so that the directories <TT>tcl7.4</TT> and <TT>fcgi-devel-kit</TT> are siblings. After unpacking the\r
+               tar file, follow the directions in the <TT>README</TT> to apply the patches.\r
+            </P>\r
+            <P>\r
+               The <A HREF="http://www.sunlabs.com:80/research/tcl/">Sun Labs Tcl/Tk Project Page</A> contains a wealth\r
+               of information on Tcl, including up to date information on the latest kits.\r
+            </P>\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Copy the files <TT>tclFCGI.c</TT>, <TT>tclAppInit.c</TT>, <TT>Makefile.in</TT>, and\r
+            <TT>configure.in</TT> from the FastCGI kit.</I> \r
+<PRE>\r
+    &gt; cd tcl7.4\r
+    &gt; mv tclAppInit.c tclAppInit.c.orig\r
+    &gt; mv Makefile.in.orig Makefile.in.orig.orig\r
+    &gt; mv Makefile.in Makefile.in.orig\r
+    &gt; mv configure.in configure.in.orig\r
+    &gt; cp ../fcgi-devel-kit/tcl/tcl7.4/* .\r
+    &gt; cp ../fcgi-devel-kit/tcl/common/* .\r
+</PRE>\r
+         </LI>\r
+         <LI>\r
+            <I>Create a new <TT>configure</TT> script.</I> \r
+<PRE>\r
+    &gt; autoconf\r
+</PRE>\r
+         </LI>\r
+         <LI>\r
+            <I>Configure and build.</I> \r
+<PRE>\r
+    &gt; ./configure\r
+    &gt; make\r
+</PRE>\r
+            The <TT>make</TT> creates the Tcl interpreter <TT>tclsh</TT> and library archive <TT>libtcl.a</TT> (for\r
+            embedding Tcl in your own C applications). The Tcl <TT>README</TT> file explains how you can experiment\r
+            with <TT>tclsh</TT> without installing it in a standard place.<BR>\r
+            <BR>\r
+         </LI>\r
+      </OL>\r
+      <H3>\r
+         <A NAME="S3">3. Recipe Explained</A>\r
+      </H3>\r
+      <P>\r
+         The recipe alone is fine if you are using Tcl 7.4p3, you have gcc version 2.7, and you have GNU autoconf. In\r
+         case one or more of these assumptions doesn&#39;t hold for you, and to illuminate how little work was involved\r
+         in integrating FastCGI, here&#39;s an explanation of how and why you would modify the files\r
+         <TT>tclAppInit.c</TT>, <TT>Makefile.in</TT>, and <TT>configure.in</TT> from the Tcl kit.\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <TT>tclAppInit.c</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Add the following three lines of code to the function <TT>Tcl_AppInit</TT> after the call to\r
+                  <TT>Tcl_Init</TT> and after the comment about calling init procedures: \r
+<PRE>\r
+    if (FCGI_Init(interp) == TCL_ERROR) {\r
+        return TCL_ERROR;\r
+    }\r
+</PRE>\r
+                  This registers four Tcl commands (<TT>FCGI_Accept</TT>, <TT>FCGI_Finish</TT>,\r
+                  <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT>), implemented in <TT>tclFCGI.c</TT>,\r
+                  with the Tcl interpreter.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <TT>Makefile.in</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Add <TT>tclFCGI.o</TT> to the <TT>GENERIC_OBJS</TT> variable, and add <TT>tclFCGI.c</TT> to the\r
+                  <TT>SRCS</TT> variable.\r
+                  <P>\r
+                     This builds the FastCGI Tcl commands and links them into the Tcl interpreter.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add <TT>-I../fcgi-devel-kit/include -include ../fcgi-devel-kit/include/fcgi_stdio.h</TT> to the\r
+                  <TT>CFLAGS</TT> variable.\r
+                  <P>\r
+                     This includes <TT>fcgi_stdio.h</TT> when compiling C code for the Tcl interpreter, overriding the\r
+                     normal <TT>stdio</TT> types, variables, and functions.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add <TT>../fcgi-devel-kit/libfcgi/libfcgi.a</TT> before the <TT>@LIBS@</TT> part of the <TT>LIBS</TT>\r
+                  variable.\r
+                  <P>\r
+                     This links the implementation of <TT>fcgi_stdio.h</TT> into the Tcl interpreter, for use by the\r
+                     <TT>FCGI_accept</TT> command and any code that uses <TT>stdio</TT> variables or calls\r
+                     <TT>stdio</TT> functions.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            <P>\r
+               The last two edits will vary if you use a compiler other than gcc or install the <TT>tcl7.4</TT>\r
+               directory somewhere else in relation to the <TT>fcgi-devel-kit</TT> directory.\r
+            </P>\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>configure.in</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Replace the lines \r
+<PRE>\r
+AC_C_CROSS\r
+CC=${CC-cc}\r
+</PRE>\r
+                  with the lines \r
+<PRE>\r
+AC_PROG_CC\r
+AC_C_CROSS\r
+</PRE>\r
+                  This selects gcc in preference to other C compilers.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add the following lines just after the <TT>AC_SUBST(CC)</TT> line: \r
+<PRE>\r
+AC_CHECK_LIB(socket, main, [LIBS=&quot;$LIBS -lsocket&quot;])\r
+AC_CHECK_LIB(nsl, main, [LIBS=&quot;$LIBS -lnsl&quot;])\r
+AC_SUBST(LIBS)\r
+</PRE>\r
+                  This ensures that the socket libraries used by FastCGI are linked into the Tcl interpreter.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            If GNU autoconf is not available to you, you&#39;ll leave <TT>configure.in</TT> alone and perform the\r
+            following steps:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Execute \r
+<PRE>\r
+    &gt; SETENV CC gcc\r
+</PRE>\r
+                  before running <TT>configure</TT>.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  If you are running on a SVR4-derived Unix platform, edit <TT>Makefile</TT> to add <TT>-lsocket\r
+                  -lnsl</TT> to the <TT>LIBS</TT> value after running <TT>configure</TT>.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            If you ever re-run <TT>configure</TT>, you&#39;ll need to repeat these steps.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+      </UL>\r
+      <H3>\r
+         <A NAME="S4">4. Writing FastCGI applications in Tcl</A>\r
+      </H3>\r
+      <P>\r
+         The Tcl program <TT>tcl/tiny-tcl-fcgi</TT> performs the same function as the C program\r
+         <TT>examples/tiny-fcgi.c</TT> that&#39;s used as an example in the <A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI\r
+         Developer&#39;s Kit document</A>. Here&#39;s what the Tcl version looks like:\r
+      </P>\r
+      <P>\r
+      </P>\r
+<PRE>\r
+#!./tclsh\r
+set count 0 \r
+while {[FCGI_Accept] &gt;= 0 } {\r
+    incr count\r
+    puts -nonewline &quot;Content-type: text/html\r\n\r\n&quot;\r
+    puts &quot;&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;&quot;\r
+    puts &quot;&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;&quot;\r
+    puts &quot;Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;&quot;\r
+}\r
+</PRE>\r
+      <P>\r
+         If you&#39;ve built Tcl according to the recipe and you have a Web server set up to run FastCGI applications,\r
+         load the FastCGI Developer&#39;s Kit Index Page in that server and run this Tcl application now.\r
+      </P>\r
+      <P>\r
+         The script invokes Tcl indirectly via the symbolic link <TT>examples/tclsh</TT>. It does this because HP-UX\r
+         has a limit of 32 characters for the first line of a command-interpreter file such as\r
+         <TT>examples/tiny-tcl-fcgi</TT>. If you run on HP-UX you won&#39;t want to sprinkle symbolic links to\r
+         <TT>tclsh</TT> everywhere, so you should install <TT>tclsh</TT> with a shorter pathname than\r
+         <TT>/usr/local/tcl7.4-fcgi/bin/tclsh7.4</TT>.\r
+      </P>\r
+      <P>\r
+         The Tcl command <TT>FCGI_Accept</TT> treats the initial environment differently than the C function\r
+         <TT>FCGI_Accept</TT>. The first call to the C function <TT>FCGI_Accept</TT> replaces the initial environment\r
+         with the environment of the first request. The first call to the Tcl command <TT>FCGI_Accept</TT> adds the\r
+         variable bindings of the first request to the bindings present in the initial environment. So when the first\r
+         call to <TT>FCGI_Accept</TT> returns, bindings from the initial environment are still there (unless, due to\r
+         naming conflicts, some of them have been overwritten by the first request). The next call to\r
+         <TT>FCGI_Accept</TT> removes the bindings made on the previous call before adding a new set for the request\r
+         just accepted, again preserving the initial environment.\r
+      </P>\r
+      <P>\r
+         The FastCGI-integrated <TT>tclsh</TT> also includes commands <TT>FCGI_Finish</TT>,\r
+         <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT> that correspond to C functions in\r
+         <TT>fcgi_stdio.h</TT>; see the manpages for full information.\r
+      </P>\r
+      <P>\r
+         Converting a Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI\r
+         application. You separate the portion of the application that performs one-time initialization from the\r
+         portion that performs per-request processing. You put the per-request processing into a loop controlled by\r
+         <TT>FCGI_Accept</TT>.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <ADDRESS>\r
+         <A HREF="mailto:shanzer@openmarket.com">Mike Shanzer // shanzer@openmarket.com</A>\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r