272 lines
14 KiB
HTML
272 lines
14 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
<!DOCTYPE html
|
|||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|||
|
<html lang="en-us" xml:lang="en-us">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|||
|
<meta name="security" content="public" />
|
|||
|
<meta name="Robots" content="index,follow" />
|
|||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
|||
|
<meta name="DC.Type" content="topic" />
|
|||
|
<meta name="DC.Title" content="CGI Programs and Activation Groups" />
|
|||
|
<meta name="abstract" content="The following section is intended to give a brief overview of Activation Groups." />
|
|||
|
<meta name="description" content="The following section is intended to give a brief overview of Activation Groups." />
|
|||
|
<meta name="DC.Relation" scheme="URI" content="rzaieparcgi.htm" />
|
|||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 2002,2006" />
|
|||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2002,2006" />
|
|||
|
<meta name="DC.Format" content="XHTML" />
|
|||
|
<meta name="DC.Identifier" content="rzag3ch1cgipgmsactgrs" />
|
|||
|
<meta name="DC.Language" content="en-us" />
|
|||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
|||
|
<!-- US Government Users Restricted Rights -->
|
|||
|
<!-- Use, duplication or disclosure restricted by -->
|
|||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
|||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
|||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
|||
|
<title>CGI Programs and Activation Groups</title>
|
|||
|
</head>
|
|||
|
<body id="rzag3ch1cgipgmsactgrs"><a name="rzag3ch1cgipgmsactgrs"><!-- --></a>
|
|||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
|||
|
<h1 class="topictitle1">CGI Programs and Activation Groups</h1>
|
|||
|
<div><p>The following section is intended to give a brief overview of Activation
|
|||
|
Groups.</p>
|
|||
|
<div class="note"><span class="notetitle">Note:</span> It is very important to become familiar with the details of activation
|
|||
|
groups prior to developing or porting a CGI application that will use this
|
|||
|
support.</div>
|
|||
|
</div>
|
|||
|
<div>
|
|||
|
<div class="familylinks">
|
|||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="rzaieparcgi.htm" title="This topic provides information about Common Gateway Interfaces (CGI).">Common Gateway Interface</a></div>
|
|||
|
</div>
|
|||
|
</div><div class="nested1" xml:lang="en-us" id="activationgroups"><a name="activationgroups"><!-- --></a><h2 class="topictitle2">Activation Groups</h2>
|
|||
|
<div><p><dfn class="term">Program activation</dfn> is the process that is used to prepare
|
|||
|
a program to run. The system must activate ILE programs before they can be
|
|||
|
run. Program activation includes the allocation and initialization of static
|
|||
|
storage for the program in addition to completing the binding of programs
|
|||
|
to service programs. Named activation groups must be used when running persistent
|
|||
|
CGI.</p>
|
|||
|
<p>Program activation is not a unique concept. All modern computer operating
|
|||
|
systems must perform program initialization and load. What is unique to CGI
|
|||
|
programs on the iSeries™ server
|
|||
|
is the concept of Activation Groups. All ILE programs and service programs
|
|||
|
are activated within an activation group. This substructure contains the resources
|
|||
|
necessary to run the program. The resources that are contained and are managed
|
|||
|
with an activation group include:</p>
|
|||
|
<ul><li>Static and automatic program variables</li>
|
|||
|
<li>Dynamic storage</li>
|
|||
|
<li>Temporary data management resources (For example, open files and SQL cursors)</li>
|
|||
|
<li>Certain types of exception handlers and ending procedures</li>
|
|||
|
</ul>
|
|||
|
<p>Run-time creation of ILE activation groups is controlled by specifying
|
|||
|
an activation group attribute when your program or service program is created.
|
|||
|
The attribute is specified by using the ACTGRP parameter on the CRTPGM or
|
|||
|
CRTSRVPGM command. The valid options for this attribute include user-named,
|
|||
|
*NEW, and *CALLER. The following is a brief description of these options:</p>
|
|||
|
<dl><dt class="dlterm">user-named</dt>
|
|||
|
<dd>A named activation group allows you to manage a collection of ILE programs
|
|||
|
and ILE service programs as one application. The activation group is created
|
|||
|
when it is first needed. All programs and service programs that specify the
|
|||
|
same activation group name use it then.</dd>
|
|||
|
<dt class="dlterm">*NEW</dt>
|
|||
|
<dd>The name for this activation group is selected by ILE and will always
|
|||
|
be unique. System-named activation groups are always deleted when the high
|
|||
|
level language returns. *NEW is the standard behavior that can be expected
|
|||
|
on other systems such as UNIX<sup>®</sup>.</dd>
|
|||
|
<dt class="dlterm">*CALLER</dt>
|
|||
|
<dd>Specifying *CALLER causes the ILE program or service program to be activated
|
|||
|
within the activation group of the calling program. A new activation group
|
|||
|
is never created with this attribute.</dd>
|
|||
|
</dl>
|
|||
|
<div class="note"><span class="notetitle">Notes:</span> <ol><li>When you create a persistent CGI program, you must specify a named activation
|
|||
|
group.</li>
|
|||
|
<li>CGI programs that are not persistent should not refer to job-level scoped
|
|||
|
resources.</li>
|
|||
|
</ol>
|
|||
|
<p>For additional information about activation groups see the <a href="../books/sc415606.pdf" target="_blank">ILE Concepts</a> ILE Concepts, SC41-5606 book.</p>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="nested1" xml:lang="en-us" id="cgiconsiderations"><a name="cgiconsiderations"><!-- --></a><h2 class="topictitle2">CGI Considerations</h2>
|
|||
|
<div><p>There are advantages to running CGI programs in either a user-named or
|
|||
|
*CALLER activation group. The performance overhead associated with activating
|
|||
|
a CGI every time that is requested can be drastically reduced. It is important
|
|||
|
to understand that because the system does not delete user-named activation
|
|||
|
groups, normal high level language end verbs cannot provide complete end processing.
|
|||
|
For example, the system will not close open files, and the system will not
|
|||
|
return the static and heap storage that are allocated by a program. The program
|
|||
|
must manage these resources explicitly. This will be especially important
|
|||
|
when changing the activation group of CGI programs that rely on their end
|
|||
|
processing functions to run properly.</p>
|
|||
|
<div class="note"><span class="notetitle">Note:</span> When you activate multi-threaded CGI on your web server, you get multiple
|
|||
|
thread support for your CGI application Your CGI application must end all
|
|||
|
of its threads before returning to the server. When using multi-thread capable
|
|||
|
CGI, you need to put the CGI program in a new or named activation group.</div>
|
|||
|
<p>The following section shows examples which will work fine running in a
|
|||
|
*NEW activation group, however will cause problems if run in a user-named
|
|||
|
or *CALLER activation group.</p>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="nested1" xml:lang="en-us" id="activationgroupproblemexamples"><a name="activationgroupproblemexamples"><!-- --></a><h2 class="topictitle2">Activation Group Problem Examples</h2>
|
|||
|
<div><div class="note"><span class="notetitle">Note:</span> The following examples are not general CGI programming examples. For
|
|||
|
general CGI programming examples, see Chapter 7, “Sample programs (in Java™,
|
|||
|
ILE C, and ILE RPG)” on page 49.</div>
|
|||
|
<div class="note"><span class="notetitle">Note:</span> CGI programming examples are also available on the <a href="http://www-03.ibm.com/servers/eserver/iseries/software/http/examples/" target="_blank">IBM<sup>®</sup> HTTP Server for i5/OS™ website</a>.</div>
|
|||
|
<p>In the following example a CGI program when run in a *NEW activation group,
|
|||
|
would write Hello World to the browser. What is important to understand is
|
|||
|
that this application is taking advantage of job end processing to delete
|
|||
|
the stdio buffers that are used to buffer the stdout data.</p>
|
|||
|
<p>You could build the following CGI program to run in either a user-named
|
|||
|
or *CALLER activation group. In such an instance, the server will not process
|
|||
|
the information that was written to stdout. This will cause the web browser
|
|||
|
to display a ″Document Contains No Data″ error message. Another application
|
|||
|
could run again in the same activation group that properly erased stdout.
|
|||
|
In this instance, the data that has been buffered from previous calls would
|
|||
|
be sent.</p>
|
|||
|
<pre>#include <stdio.h>
|
|||
|
void main(void) {
|
|||
|
/***************************************************/
|
|||
|
/* Write header information. */
|
|||
|
/***************************************************/
|
|||
|
printf("Content-type: text/html\n\n");
|
|||
|
/***************************************************/
|
|||
|
/* Write header information. */
|
|||
|
/***************************************************/
|
|||
|
printf("Hello World\n");
|
|||
|
}</pre>
|
|||
|
<p>End processing may not erase stdio buffers so the application must erase
|
|||
|
the stdout with a fflush(stdout) call. The following example will work regardless
|
|||
|
of the activation group specification:</p>
|
|||
|
<pre>#include <stdio.h>
|
|||
|
void main(void) {
|
|||
|
/***************************************************/
|
|||
|
/* Write header information. */
|
|||
|
/***************************************************/
|
|||
|
printf("Content-type: text/html\n\n");
|
|||
|
/***************************************************/
|
|||
|
/* Write header information. */
|
|||
|
/***************************************************/
|
|||
|
printf("Hello World\n");
|
|||
|
/*-------------------------------------------------*/
|
|||
|
/* FIX: Flush stdout. */
|
|||
|
/*-------------------------------------------------*/
|
|||
|
fflush(stdout);
|
|||
|
}</pre>
|
|||
|
<p>When run in a *NEW activation group, this example CGI would read CONTENT_LENGTH
|
|||
|
bytes of data from stdin and write this back out to stdout. The system has
|
|||
|
allocated the buffer that is used to hold the data with a malloc. Like the
|
|||
|
example that is previously shown, this application is relying on several aspects
|
|||
|
of job end processing to function properly.</p>
|
|||
|
<p>If this CGI program were built to run in either a user-named or *CALLER
|
|||
|
activation group, the following problems would occur:</p>
|
|||
|
<ul><li>As with the simple example that is previously shown, the application is
|
|||
|
not erasing stdout. This would cause the web browser to display a ″Document
|
|||
|
Contains No Data″ error message. You could run another application again in
|
|||
|
the same activation group that properly erased stdout. This would send the
|
|||
|
data that has been buffered from previous calls.</li>
|
|||
|
<li>Stdin is buffered similar to stdout. If the contents of stdin are not
|
|||
|
erased, the stdin data on the second and all following calls of the CGI program
|
|||
|
will be unpredictable and the contents may at times contain information from
|
|||
|
subsequent requests.</li>
|
|||
|
<li>The heap storage allocated using malloc is not being freed. Over time,
|
|||
|
a memory leak error like this could use significant amounts of memory. This
|
|||
|
is a common application error that only surfaces when the application is not
|
|||
|
running in a *NEW activation group.</li>
|
|||
|
</ul>
|
|||
|
<pre>/*************************************************************************/
|
|||
|
/* */
|
|||
|
/* CGI Example program. */
|
|||
|
/* */
|
|||
|
/*************************************************************************/
|
|||
|
#include
|
|||
|
void main(void)
|
|||
|
{
|
|||
|
char* stdinBuffer;
|
|||
|
char* contentLength;
|
|||
|
int numBytes;
|
|||
|
int bytesRead;
|
|||
|
FILE* pStdin;
|
|||
|
/**********************************************************************/
|
|||
|
/* Write the header. */
|
|||
|
/**********************************************************************/
|
|||
|
printf("Content-type: text/html\n\n");
|
|||
|
/**********************************************************************/
|
|||
|
/* Get the length of data on stdin. */
|
|||
|
/**********************************************************************/
|
|||
|
contentLength = getenv("CONTENT_LENGTH");
|
|||
|
if (contentLength != NULL) {
|
|||
|
/*******************************************************************/
|
|||
|
/* Allocate storage and clear the storage to hold the data. */
|
|||
|
/*******************************************************************/
|
|||
|
numBytes = atoi(contentLength);
|
|||
|
stdinBuffer = (char*)malloc(numBytes+1);
|
|||
|
if ( stdinBuffer )
|
|||
|
memset(stdinBuffer, 0x00, numBytes+1);
|
|||
|
/*******************************************************************/
|
|||
|
/* Read the data from stdin and write back to stdout. */
|
|||
|
/*******************************************************************/
|
|||
|
bytesRead = fread(stdinBuffer, 1, numBytes, pStdin);
|
|||
|
stdinBuffer[bytesRead+1] = ’\0’;
|
|||
|
printf("%s", stdinBuffer);
|
|||
|
} else
|
|||
|
printf("Error getting content length\n");
|
|||
|
return;
|
|||
|
}</pre>
|
|||
|
<p>The following example shows the changes that would be required to this
|
|||
|
application to allow it to run in a user-named or *CALLER activation group:</p>
|
|||
|
<pre>/*************************************************************************/
|
|||
|
/* */
|
|||
|
/* CGI Example program with changes to support user-named */
|
|||
|
/* and *CALLER ACTGRP. */
|
|||
|
/* */
|
|||
|
/*************************************************************************/
|
|||
|
#include
|
|||
|
void main(void)
|
|||
|
{
|
|||
|
char* stdinBuffer;
|
|||
|
char* contentLength;
|
|||
|
int numBytes;
|
|||
|
int bytesRead;
|
|||
|
FILE* pStdin;
|
|||
|
/**********************************************************************/
|
|||
|
/* Write the header. */
|
|||
|
/**********************************************************************/
|
|||
|
printf("Content-type: text/html\n\n");
|
|||
|
/**********************************************************************/
|
|||
|
/* Get the length of data on stdin. */
|
|||
|
/**********************************************************************/
|
|||
|
contentLength = getenv("CONTENT_LENGTH");
|
|||
|
if (contentLength != NULL) {
|
|||
|
/*******************************************************************/
|
|||
|
/* Allocate storage and clear the storage to hold the data. */
|
|||
|
/*******************************************************************/
|
|||
|
numBytes = atoi(contentLength);
|
|||
|
stdinBuffer = (char*)malloc(numBytes+1);
|
|||
|
if ( stdinBuffer )
|
|||
|
memset(stdinBuffer, 0x00, numBytes+1);
|
|||
|
/*-----------------------------------------------------------------*/
|
|||
|
/* FIX 2: Reset stdin buffers. */
|
|||
|
/*-----------------------------------------------------------------*/
|
|||
|
pStdin = freopen("", "r", stdin);
|
|||
|
/*******************************************************************/
|
|||
|
/* Read the data from stdin and write back to stdout. */
|
|||
|
/*******************************************************************/
|
|||
|
bytesRead = fread(stdinBuffer, 1, numBytes, pStdin);
|
|||
|
stdinBufferþbytesRead+1þ = ’\0’;
|
|||
|
printf("%s", stdinBuffer);
|
|||
|
/*-----------------------------------------------------------------*/
|
|||
|
/* FIX 3: Free allocated memory. */
|
|||
|
/*-----------------------------------------------------------------*/
|
|||
|
free(stdinBuffer);
|
|||
|
} else
|
|||
|
printf("Error getting content length\n");
|
|||
|
/*-------------------------------------------------------------------*/
|
|||
|
/* FIX 1: Flush stdout. */
|
|||
|
/*-------------------------------------------------------------------*/
|
|||
|
fflush(stdout);
|
|||
|
return;
|
|||
|
}</pre>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
</body>
|
|||
|
</html>
|