ibm-information-center/dist/eclipse/plugins/i5OS.ic.rzaie_5.4.0.1/rzag3ch1cgipgmsactgrs.htm

272 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 &lt;stdio.h&gt;
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 &lt;stdio.h&gt;
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>