ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/spawnp.htm

1239 lines
43 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>spawnp()--Spawn Process with Path</title>
<!-- 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. -->
<!-- Begin Header Records ========================================== -->
<!-- UNIX11 SCRIPT A converted by B2H R4.1 (346) (CMS) by V2DCIJB at -->
<!-- RCHVMW2 on 1 Jun 1999 at 16:14:12 -->
<!-- Change History: -->
<!-- 020319 JTROUS Changes for Virus scanner, 98860, V5R3 -->
<!-- 030918 XZY1406: Changes for Job Name and Affinity, 99276 -->
<!-- 030920 XZY1406: Updates for additional inherit.flags, 99454 -->
<!-- This file has undergone html cleanup June 2002 by JET -->
<!-- Edited by Kersten Feb 02 -->
<!--End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<a name="Top_Of_Page"></a>
<!-- Java sync-link -->
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
</script>
<h2>spawnp()--Spawn Process with Path</h2>
<div class="box" style="width: 60%;">
<br>
&nbsp;&nbsp;Syntax<br>
<pre>
#include &lt;spawn.h&gt;
pid_t spawnp(const char <em>*file</em>,
const int <em>fd_count</em>,
const int <em>fd_map[]</em>,
const struct inheritance <em>*inherit</em>,
char * const <em>argv[]</em>,
char * const <em>envp[]</em>);
</pre>
<br>
&nbsp;&nbsp;Service Program Name: QP0ZSPWN<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Conditional; see <a href="#USGNOT">Usage Notes</a>.<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <strong>spawnp()</strong> function creates a child process that inherits
specific attributes from the parent. The attributes inherited by the child
process are file descriptors, the signal mask, the signal action vector, and
environment variables, among others. <strong>spawnp()</strong> takes the
<em>file</em> parameter and searches the environment variable PATH. The
<em>file</em> parameter is concatenated to each path defined in the
PATH environment variable. It uses the first occurrence of the <em>
file</em> parameter that is found with a mode of execute.</p>
<p>If the PATH environment variable does not contain a value, an error occurs.
If the <em>file</em> parameter contains a "/" character, the value of
<em>file</em> is used as a path and a search of the PATH or library
list is not performed. Specifying a <em>file</em> parameter containing
a "/" is the same as calling <strong>spawn()</strong>.</p>
<p>To search the library list, a special value for the PATH environment
variable is used. The string <samp>%LIBL%</samp> can be the entire PATH value
or a component of the PATH value. When the string <samp>%LIBL%</samp> is
encountered, the library list is searched. For example, the following path
searches the directory /usr/bin first, searches the library list next, and then
searches the /tobrien/bin directory for the file:</p>
<pre>
PATH=/usr/bin:%LIBL%:/tobrien/bin
</pre>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong><em>file</em></strong></dt>
<dd>(Input) A file name used with the search path to find an executable file
that will run in the new (child) process. The <samp>file</samp> name is
expected to be in the CCSID of the job.
<p>See <a href="spawnpu.htm">QlgSpawnp()--Spawn Process with Path (using
NLS-enabled file name)</a> for a description and an example of supplying the
<em>file</em> in any CCSID.</p>
</dd>
<dt><strong><em>fd_count</em></strong></dt>
<dd>(Input) The number of file descriptors the child process can inherit. It
can have a value from zero to the value returned from a call to <strong>
sysconf(</strong>_SC_OPEN_MAX<strong>)</strong>.<br>
<br>
</dd>
<dt><strong><em>fd_map[]</em></strong></dt>
<dd>(Input) An array that maps the parent process file descriptor numbers to
the child process file descriptor numbers. If this value is NULL, it indicates
simple inheritance. <strong>Simple inheritance</strong> means that the child
process inherits all eligible open file descriptors of the parent process. In
addition, the file descriptor number in the child process is the same as the
file descriptor number in the parent process. Refer to <a href="#HDRSPWNAT2">
Attributes Inherited</a> for details of file descriptor inheritance.<br>
<br>
</dd>
<dt><strong><em>inherit</em></strong></dt>
<dd>(Input) A pointer to an area of type <samp>struct inheritance</samp>. If
the pointer is NULL, an error occurs. The <samp>inheritance</samp> structure
contains control information to indicate attributes the child process should
inherit from the parent. The following is an example of the <samp>
inheritance</samp> structure, as defined in the <strong>
&lt;spawn.h&gt;</strong> header file:
<pre>
struct inheritance {
flagset_t flags;
int pgroup;
sigset_t sigmask;
sigset_t sigdefault;
};
</pre>
<p>The <samp>flags</samp> field specifies the manner in which the child process
should be created. Only the constants defined in <strong>
&lt;spawn.h&gt;</strong> are allowed; otherwise, <strong>spawnp()</strong> returns -1 with
errno set to EINVAL. The allowed constants follow:</p>
<table cellpadding="5">
<!-- cols="35 65" -->
<tr>
<td align="left" valign="top"><em>SPAWN_SETPGROUP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the process group ID of the child process to the value in <samp>
pgroup</samp>. In this case, the process group field, <samp>pgroup</samp>, must
be valid. If it is not valid, an error occurs. If this flag is set OFF, the
<samp>pgroup</samp> field is checked to determine what the process group ID of
the child process is set to. If the <samp>pgroup</samp> field is set to the
constant SPAWN_NEWPGROUP, the child process group ID is set to the child
process ID. If the <samp>pgroup</samp> field is not set to SPAWN_NEWPGROUP and
the <samp>flags</samp> field is not set to SPAWN_SETPGROUP, the process group
ID of the child process is set to the process group ID of the parent process.
If the <samp>pgroup</samp> field is set to SPAWN_NEWPGROUP and the <samp>
flags</samp> field is set to SPAWN_SETPGROUP, an error occurs.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETSIGMASK</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the signal blocking mask of the child process to the value in <em>
sigmask</em>. In this case, the signal blocking mask must be valid. If it is
not valid, an error occurs. If this flag is set OFF, <strong>spawnp()</strong>
sets the signal blocking mask of the child process to the signal blocking mask
of the calling thread.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETSIGDEF</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the child process' signals identified in <samp>sigdefault</samp> to the
default actions. The <samp>sigdefault</samp> must be valid. If it is not valid,
an error occurs. If this flag is set OFF, <strong>spawnp()</strong> sets the
child process' signal actions to those of the parent process. Any signals of
the parent process that have a catcher specified are set to default in the
child process. The child process' signal actions inherit the parent process'
ignore and default signal actions.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETTHREAD_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
will create the child process as multithread capable. The child process will be
allowed to create threads. If this flag is set OFF, the child process will not
be allowed to create threads.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETPJ_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
attempts to use available i5/OS prestart jobs. The prestart job entries that
may be used follow:
<ul>
<li>QSYS/QP0ZSPWP, if the flag SPAWN_SETTHREAD_NP is set OFF.<br>
<br>
</li>
<li>QSYS/QP0ZSPWT, if the flag SPAWN_SETTHREAD_NP is set ON.<br>
<br>
</li>
</ul>
<p>The i5/OS prestart jobs must have been started using either QSYS/QP0ZSPWP
or QSYS/QP0ZSPWT as the program that identifies a prestart job entry for the
i5/OS subsystem that the parent process is running under. If a prestart job
entry is not defined, the child process will run as a batch immediate job under
the same subsystem as the parent process.</p>
<p>If this flag (SPAWN_SETPJ_NP) is set OFF, the child process will run as a
batch immediate job under the same subsystem as the parent process.</p>
<p><strong>Note:</strong>In order to more closely emulate POSIX semantics,
<strong>spawnp()</strong>
will ignore the Maximum number of uses (MAXUSE) value specified for the
prestart job entry. The prestart job will only be used once, behaving as if
MAXUSE(1) was specified.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETCOMPMSG_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
causes the child process to send a completion message to the user's message
queue when the child process ends. If this flag is set OFF, no completion
message is sent to the user's message queue when the child process ends. If
both the SPAWN_SETCOMPMSG_NP and SPAWN_SETPJ_NP flags are set ON, an error
occurs.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETJOBNAMEPARENT_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the child's i5/OS simple job name to that of the parent's. If this flag is
set OFF, <strong>spawnp()</strong> sets the child's i5/OS simple job name
based on the <em>file</em> parameter.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETJOBNAMEARGV_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the child's i5/OS simple job name to the name found in argv[0] of the
<em>argv[]</em> parameter. If this flag is set OFF,
<strong>spawnp()</strong> sets the child's i5/OS simple job name based
on the <em>file</em> parameter.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETLOGJOBMSGABN_NP</em></td>
<td align="left" valign="top">If this flag is set ON,
the child process does not log the job started (CPF1124) message
and will only log the job ended (CPF1164) message when the job ends abnormally
(job ending code 30 or greater). This applies to the job log as well as
the system history log (QHST). If this flag is set OFF,
the child process logs the job started
(CPF1124) and the job ended (CPF1164) messages.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETLOGJOBMSGNONE_NP</em></td>
<td align="left" valign="top">If this flag is set ON,
the child process does not log the job started (CPF1124) and the
job ended (CPF1164) messages to either the job log or to the system history
log (QHST). If this flag is set OFF,
the child process logs the job started (CPF1124) and the job ended
(CPF1164) messages.
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETAFFINITYID_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the resources affinity identifier of the child process to the 4-byte
integer value, treated as an <samp>unsigned int</samp>, that immediately
follows the <samp>inheritance</samp> structure in memory. A value of 0
indicates i5/OS selects the resources affinity identifier. The
caller must ensure the value immediately follows the <samp>inheritance</samp>
structure. For example:
<pre>
struct extended_inheritance {
struct inheritance inherit;
unsigned int affinityID;
};
struct extended_inheritance extended_inherit;
</pre>
<p>If this flag is set OFF,
i5/OS selects the resources affinity identifier of the child
process.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>SPAWN_SETTHREADRUNPTY_NP</em></td>
<td align="left" valign="top">If this flag is set ON, <strong>spawnp()</strong>
sets the run priority of the child process to the current thread's
run priority. If this flag is set OFF, <strong>spawnp()</strong> sets the run
priority of the child process to the current process' run priority.
</td>
</tr>
</table>
<br>
</dd>
<dt><strong><em>argv[]</em></strong></dt>
<dd>(Input) An array of pointers to strings that contain the argument list for
the executable file. The last element in the array must be the NULL pointer. If
this parameter is NULL, an error occurs.<br>
<br>
</dd>
<dt><strong><em>envp[]</em></strong></dt>
<dd>(Input) An array of pointers to strings that contain the environment
variable lists for the executable file. The last element in the array must be
the NULL pointer. If this parameter is NULL, an error occurs.</dd>
</dl>
<br>
<h3>Authorities</h3>
<p><strong><a name="TBLBSPAWN">Authorization Required for
spawnp()</a></strong></p>
<table border cellpadding="5">
<tr>
<th align="left" valign="bottom">Object Referred to</th>
<th align="center" valign="bottom">Authority<br>
Required</th>
<th align="left" valign="bottom">errno</th>
</tr>
<tr>
<td align="left" valign="top">Each directory in the path name preceding the
executable file that will run in the new process</td>
<td align="center" valign="top">*X</td>
<td align="left" valign="top">EACCES</td>
</tr>
<tr>
<td align="left" valign="top">Executable file that will run in the new
process</td>
<td align="center" valign="top">*X</td>
<td align="left" valign="top">EACCES</td>
</tr>
<tr>
<td align="left" valign="top">If executable file that will run in the new
process is a shell script</td>
<td align="center" valign="top">*RX</td>
<td align="left" valign="top">EACCES</td>
</tr>
</table>
<br>
<br>
<h3>Return Value</h3>
<table cellpadding="5">
<!-- cols="10 90" -->
<tr>
<td align="left" valign="top"><em>value</em></td>
<td align="left" valign="top"><strong>spawnp()</strong> was successful. The
value returned is the process ID of the child process.</td>
</tr>
<tr>
<td align="left" valign="top"><em>-1</em></td>
<td align="left" valign="top"><strong>spawnp()</strong> was not successful. The
<em>errno</em> variable is set to indicate the error.</td>
</tr>
</table>
<br>
<br>
<h3>Error Conditions</h3>
<p>If <strong>spawnp()</strong> is not successful, <em>errno</em> usually
indicates one of the following errors. Under some conditions, <em>errno</em>
could indicate an error other than those listed here.</p>
<dl>
<dt><em>[E2BIG]</em></dt>
<dd>
<p>Argument list too long.</p>
</dd>
<dt><em>[EACCES]</em></dt>
<dd>
<p>Permission denied.</p>
<p>An attempt was made to access an object in a way forbidden by its object
access permissions.</p>
<p>The thread does not have access to the specified file, directory, component,
or path.</p>
<p>If you are accessing a remote file through the Network File System, update
operations to file permissions at the server are not reflected at the client
until updates to data that is stored locally by the Network File System take
place. (Several options on the Add Mounted File System (ADDMFS) command
determine the time between refresh operations of local data.) Access to a
remote file may also fail due to different mappings of user IDs (UID) or group
IDs (GID) on the local and remote systems.</p>
</dd>
<dt><em>[EAPAR]</em></dt>
<dd>
<p>Possible APAR condition or hardware failure.</p>
</dd>
<dt><em>[EBADFUNC]</em></dt>
<dd>
<p>Function parameter in the signal function is not set.</p>
<p>A given file descriptor or directory pointer is not valid for this
operation. The specified descriptor is incorrect, or does not refer to an open
file.</p>
</dd>
<dt><em>[EBADNAME]</em></dt>
<dd>
<p>The object name specified is not correct.</p>
</dd>
<dt><em>[ECANCEL]</em></dt>
<dd>
<p>Operation canceled.</p>
</dd>
<dt><em>[ECONVERT]</em></dt>
<dd>
<p>Conversion error.</p>
<p>One or more characters could not be converted from the source CCSID to the
target CCSID.</p>
<p>The specified path name is not in the CCSID of the job.</p>
</dd>
<dt><em>[EFAULT]</em></dt>
<dd>
<p>The address used for an argument is not correct.</p>
<p>In attempting to use an argument in a call, the system detected an address
that is not valid.</p>
<p>While attempting to access a parameter passed to this function, the system
detected an address that is not valid.</p>
</dd>
<dt><em>[EINVAL]</em></dt>
<dd>
<p>The value specified for the argument is not correct.</p>
<p>A function was passed incorrect argument values, or an operation was
attempted on an object and the operation specified is not supported for that
type of object.</p>
<p>An argument value is not valid, out of range, or NULL.</p>
<p>The <samp>flags</samp> field in the inherit parameter contains an invalid
value.</p>
</dd>
<dt><em>[EIO]</em></dt>
<dd>
<p>Input/output error.</p>
<p>A physical I/O error occurred.</p>
<p>A referenced object may be damaged.</p>
</dd>
<dt><em>[ELOOP]</em></dt>
<dd>
<p>A loop exists in the symbolic links.</p>
<p>This error is issued if the number of symbolic links encountered is more
than POSIX_SYMLOOP (defined in the limits.h header file). Symbolic links are
encountered during resolution of the directory or path name.</p>
</dd>
<dt><em>[ENAMETOOLONG]</em></dt>
<dd>
<p>A path name is too long.</p>
<p>A path name is longer than PATH_MAX characters or some component of the name
is longer than NAME_MAX characters while _POSIX_NO_TRUNC is in effect. For
symbolic links, the length of the name string substituted for a symbolic link
exceeds PATH_MAX. The PATH_MAX and NAME_MAX values can be determined using the
<strong>pathconf()</strong> function.</p>
</dd>
<dt><em>[ENFILE]</em></dt>
<dd>
<p>Too many open files in the system.</p>
<p>A system limit has been reached for the number of files that are allowed to
be concurrently open in the system.</p>
<p>The entire system has too many other file descriptors already open.</p>
</dd>
<dt><em>[ENOENT]</em></dt>
<dd>
<p>No such path or directory.</p>
<p>The directory or a component of the path name specified does not exist.</p>
<p>A named file or directory does not exist or is an empty string.</p>
</dd>
<dt><em>[ENOMEM]</em></dt>
<dd>
<p>Storage allocation request failed.</p>
<p>A function needed to allocate storage, but no storage is available.</p>
<p>There is not enough memory to perform the requested function.</p>
</dd>
<dt><em>[ENOTDIR]</em></dt>
<dd>
<p>Not a directory.</p>
<p>A component of the specified path name existed, but it was not a directory
when a directory was expected.</p>
<p>Some component of the path name is not a directory, or is an empty
string.</p>
</dd>
<dt><em>[ENOTSAFE]</em></dt>
<dd>
<p>Function is not allowed in a job that is running with multiple threads.</p>
</dd>
<dt><em>[ENOTSUP]</em></dt>
<dd>
<p>Operation not supported.</p>
<p>The operation, though supported in general, is not supported for the
requested object or the requested arguments.</p>
</dd>
<dt><em>[ETERM]</em></dt>
<dd>
<p>Operation terminated.</p>
</dd>
<dt><em>[ENOSYSRSC]</em></dt>
<dd>
<p>System resources not available to complete request.</p>
<p>The child process failed to start. The maximum active jobs in a subsystem
may have been reached. CHGSBSD and CHGJOBQE CL commands can be used to change
the maximum active jobs.</p>
</dd>
<dt><em>[EUNKNOWN]</em></dt>
<dd>
<p>Unknown system state.</p>
<p>The operation failed because of an unknown system state. See any messages in
the job log and correct any errors that are indicated, then retry the
operation.</p>
</dd>
</dl>
<br>
<h3><a name="USGNOT">Usage Notes</a></h3>
<ol>
<li><strong>spawnp()</strong> is threadsafe, except this function will fail and
errno ENOTSAFE will be set if it is called in any of the following ways:<br>
<br>
<ul>
<li>From a multithreaded process and <samp>file</samp> refers to a shell script
that does not exist in a threadsafe file system.</li>
<li>From a multithreaded process with a current working directory that is not
in a threadsafe file system, and the PATH environment variable causes <strong>
spawnp()</strong> to check the current working directory.</li>
</ul>
<br>
</li>
<li>There are performance considerations when using <strong>spawn()</strong>
and <strong>spawnp()</strong> concurrently among threads in the same process.
<strong>spawn()</strong> and <strong>spawnp()</strong> serialize against other
<strong>spawn()</strong> and <strong>spawnp()</strong> calls from other threads
in the same process.<br>
<br>
</li>
<li>The child process is enabled for signals. A side effect of this function is
that the parent process is also enabled for signals if it was not enabled for
signals before this function was called.<br>
<br>
</li>
<li>If this function is called from a program running in user state <u>and</u>
it specifies a system-domain program as the executable program for the child
process, an exception occurs. In this case, <strong>spawnp()</strong> returns
the process ID of the child process. On a subsequent call to <strong>
wait()</strong> or <strong>waitpid()</strong>, the status information returned
indicates that an exception occurred in the child process.<br>
<br>
</li>
<li>The program that will be run in the child process must be either a program
object in the QSYS.LIB file system or an independent ASP QSYS.LIB file system
(*PGM object) or a shell script (see <a href="shscript.htm">About Shell
Scripts</a>). The syntax of the name of the file to run must be the proper
syntax for the file system in which the file resides. For example, if the
program MYPROG resides in the QSYS.LIB file system and in library MYLIB, the
specification for <strong>spawnp()</strong>. would be the following:
<pre>
MYPROG.PGM
</pre>
<p>See <a href="spawnu.htm">QlgSpawn()--Spawn Process (using NLS-enabled path
name)</a> for an example specifying the program using the Qlg_Path_Name_T
structure. The Qlg_Path_Name_T structure is supported by <strong>
QlgSpawn()</strong> and allows the program name to be specified in any
CCSID.</p>
<p><strong>Note:</strong> For more information about path syntaxes for the
different file systems, see the
<a href="../ifs/rzaaxkickoff.htm">Integrated file system</a> information
in the Files and file systems topic.</p>
</li>
<li>Spawned child processes are batch jobs or prestart jobs. As such, they do
not have the ability to do 5250-type interactive I/O.<br>
<br>
</li>
<li>Spawned child processes that are i5/OS prestart jobs are similar to batch
jobs. Due to the nature of prestart jobs, only the following i5/OS-specific
attributes are explicitly inherited in a child process when you use prestart
jobs:<br>
<br>
<ul>
<li>Library list</li>
<li>Language identifier</li>
<li>Country or region identifier</li>
<li>Coded character set identifier</li>
<li>Default coded character set identifier</li>
<li>Locale (as specified in the user profile)</li>
</ul>
<p>The child process has the same user profile as the calling thread. However,
the i5/OS job attributes come from the job description specified for the
prestart job entry, and the run attributes come from the class that is
associated with the i5/OS subsystem used for the prestart job entry.</p>
<p><strong>Notes:</strong></p>
<ol>
<li>The prestart job entry QP0ZSPWP is used with prestart jobs that will not be
creating threads. The prestart job entry QP0ZSPWT is used with prestart jobs
that will allow multiple threads. Both types of prestart jobs may be used in
the same subsystem. The prestart job entry must be defined for the subsystem
that the <strong>spawnp()</strong> parent process runs under in order for it to
be used.<br>
<br>
</li>
<li>The following example defines a prestart job entry (QP0ZSPWP) for use by
<strong>spawnp()</strong> under the subsystem QINTER. The <strong>
spawnp()</strong> API must have the SPAWN_SETPJ_NP flag set (but not
SPAWN_SETTHREAD_NP) in order to use these prestart jobs:
<pre>
ADDPJE SBSD(QSYS/QINTER) PGM(QSYS/QP0ZSPWP)
INLJOBS(20) THRESHOLD(5) ADLJOBS(5)
JOBD(QGPL/QDFTJOBD) MAXUSE(1)
CLS(QGPL/QINTER)
</pre>
</li>
<li>The following example defines a prestart job entry (QP0ZSPWT) that will
create prestart jobs that are multithread capable for use by <strong>
spawnp()</strong> under the subsystem QINTER. The <strong>spawnp()</strong> API
must have both SPAWN_SETPJ_NP and SPAWN_SETTHREAD_NP flags set in order to use
these prestart jobs. Also, the JOBD parameter must be a job description that
allows multiple threads as follows:
<pre>
ADDPJE SBSD(QSYS/QINTER) PGM(QSYS/QP0ZSPWT)
INLJOBS(20) THRESHOLD(5) ADLJOBS(5)
JOBD(QSYS/QAMTJOBD) MAXUSE(1)
CLS(QGPL/QINTER)
</pre>
</li>
</ol>
<p>Refer to the <a href="../rzaks/rzaks1.htm">Work Management</a> topic for complete
details on prestart jobs.</p>
</li>
<li>Shell scripts are allowed for the child process. If a shell script is
specified, the appropriate shell interpreter program is called. The shell
script must be a text file and must contain the following format on the first
line of the file:
<pre>
#!interpreter_path &lt;options&gt;
</pre>
<p>where <samp>interpreter_path</samp> is the path to the shell interpreter
program.</p>
<p>If the calling process is multithreaded, <samp>file</samp> (the first
parameter to <strong>spawnp()</strong>) must reference a threadsafe file
system.</p>
<p><strong>spawnp()</strong> calls the shell interpreter, passing in the shell
options and the arguments passed in as a parameter to <strong>spawnp()</strong>.
The argument list passed into the shell interpreter will look like <a href=
"#FIGSHARG2">Arguments to Shell Interpreter</a>.</p>
<p><strong><a name="FIGSHARG2">Arguments to Shell Interpreter</a></strong><br>
<img src="RBAFX601.gif" alt="Arguments to Shell Interpreter"></p>
<p>See <a href="shscript.htm">About Shell Scripts</a> for an example using
<strong>spawn()</strong> and shell scripts.</p>
</li>
<li>Only programs that expect
arguments as null-terminated character strings can be spawned. The program that
is run in the child process is called at it's initial entry point. The
arguments explicitly passed to the program start with element argv[1]
of the <em>argv[]</em> parameter that was specified during the call to
<strong>spawnp()</strong>. The program language type determines how the arguments
passed are seen by that program. For example, if the program language type is
ILE C or ILE C++, the linkage can be described as:
<pre>
int main(int argc, char *argv[])
{
}
</pre>
<p>where the following are true:</p>
<ul>
<li><em>argc</em> is the number of arguments in <em>argv[]</em>.</li>
<li><em>argv[]</em> is an array of arguments represented as null-terminated
character strings.</li>
<li>The last entry in the array is NULL.</li>
<li>The first element in the array, <em>argv[0]</em>, is automatically set to
the name of the program. Any value specified for <em>argv[0]</em> during the
call to <strong>spawnp()</strong> will be overwritten.</li>
<li>The remaining <em>argv[]</em> elements, if any, will correspond directly to
the <em>argv[]</em> elements specified during the call to <strong>spawnp()</strong>.</li>
</ul>
<p>The maximum number of arguments that can be specified is dependent on the
following:</p>
<ul>
<li>The maximum number of parameters allowed for the program that is run in the
child process, as seen by the DSPPGM CL command. Some programs allow up to
65&nbsp;535 parameters, while others may only allow up to 255 parameters. The
value of SPAWN_MAX_NUM_ARGS is 255, in order to maintain compatibility with
programs that only allow up to 255 parameters. If the maximum number is
exceeded, <strong>spawnp()</strong> returns -1 with errno set to E2BIG.</li>
<li>The total size required for containing the arguments, which includes the
array of pointers to strings, and the total size of all the strings. The total
size is limited to approximately 16&nbsp;500&nbsp;000 bytes. If the total size
is exceeded, <strong>spawnp()</strong> returns -1 with errno set to ENOMEM.
</li>
</ul>
<br>
</li>
<li>The child process does not inherit any of the environment variables of the
parent process. That is, the default environment variable environment is empty.
If the child process is to inherit all the parent process' environment
variables, the <samp>extern</samp> variable <em>environ</em> can be used as the
value for <em>envp[]</em> when <strong>spawnp()</strong> is called. If a
specific set of environment variables is required in the child process, the
user must build the <em>envp[]</em> array with the "name=value" strings. In the
child process, <strong>spawnp()</strong> does the equivalent of a <strong>
putenv()</strong> on each element of the <em>envp[]</em> array. Then the <samp>
extern</samp> variable <em>environ</em> will be set and available to the child
process' program.
<p><strong>Note:</strong> If the user of <strong>spawnp()</strong> specifies the
<samp>extern</samp> variable <em>environ</em> as the <em>envp[]</em> parameter,
the user must successfully call one of the following APIs before calling
<strong>spawnp()</strong>:</p>
<ul>
<li>getenv()</li>
<li>putenv()</li>
<li>Qp0zGetEnv()</li>
<li>Qp0zInitEnv()</li>
<li>Qp0zPutEnv()</li>
</ul>
<p>The <samp>extern</samp> variable <em>environ</em> is not initialized until
one of these APIs is called in the current activation group. If <em>
environ</em> is used in a call to <strong>spawnp()</strong> without first
calling one of these APIs, <strong>spawnp()</strong> returns an error.</p>
</li>
<li>i5/OS handles stdin, stdout, and stderr differently than most UNIX
systems. On most UNIX systems, stdin, stdout, and stderr have file descriptors
0, 1, and 2 reserved and allocated for them. On i5/OS, this is not the case.
There are two ramifications of this difference:<br>
<br>
<ol>
<li>File descriptor 0, 1, and 2 are allocated to the first three files that
have descriptors allocated to them. If an application writes to file descriptor
1 assuming it is stdout, the result will not be as expected.<br>
<br>
</li>
<li>Any API that assumes stdin, stdout, and stderr are file descriptors 0, 1,
and 2 will not behave as expected.</li>
</ol>
<p>Users and applications can enable descriptor-based standard I/O for child
processes by setting environment variable QIBM_USE_DESCRIPTOR_STDIO to the
value Y in the child process. This can be accomplished on the call to <strong>
spawnp()</strong> by either of the following:</p>
<ol>
<li>Specifying the <samp>extern</samp> variable <em>environ</em> as the <em>
envp[]</em> parameter. This assumes that the QIBM_USE_DESCRIPTOR_STDIO
environment variable exists in the calling process.
<p>The environment variable can be set by using one of the following:</p>
<ul>
<li>API putenv("QIBM_USE_DESCRIPTOR_STDIO=Y");</li>
<li>Command ADDENVVAR ENVVAR(QIBM_USE_DESCRIPTOR_STDIO) VALUE(Y)</li>
<li>Command CHGENVVAR ENVVAR(QIBM_USE_DESCRIPTOR_STDIO) VALUE(Y)</li>
</ul>
<br>
</li>
<li>Explicitly include "QIBM_USE_DESCRIPTOR_STDIO=Y" in the user-defined <em>
envp[]</em> array with the "name=value" strings.</li>
</ol>
<p>If you enable descriptor-based standard I/O for child processes, file
descriptors 0, 1, and 2 are automatically used for stdin, stdout, and stderr,
respectively. However, <strong>spawnp()</strong> must be called using a <em>
fd_map</em> that has file descriptors 0, 1, and 2 properly allocated. See <a
href="shscript.htm">About Shell Scripts</a> for an example that enables
descriptor-based standard I/O for a child process. Refer to <a href=
"../books/sc092712.pdf" target="_blank">WebSphere Development Studio: ILE
C/C++ Programmer's Guide</a><img src="wbpdf.gif" alt="Link to PDF"> for
complete details on this support.</p>
</li>
<li>Spawn users have a facility to aid in debugging child processes.
<p>To help the user start a debug session (when <strong>spawnp()</strong> is the
mechanism used to start the process), the user sets the environment variable
QIBM_CHILD_JOB_SNDINQMSG.</p>
<p>If the environment variable is assigned a numerical value, it indicates the
number of descendent levels that will be enabled for debugging. This support
can be used to debug applications that create children, grandchildren,
great-grandchildren, and so forth. When the environment variable has a value of
1, it enables debugging of all subsequent child processes. A value of 2 enables
debugging of all subsequent child processes and grandchild processes.</p>
<p>When the environment variable has a value less than or equal to 0, or any
non-numerical value, debugging will not occur.</p>
<p>Here are the steps a user would take to debug an application by using
<strong>spawnp()</strong>:</p>
<p>Assume the user wants to debug child processes in an application called
CHILDAPP found in library MYAPPLIB.</p>
<ul>
<li>Set the QIBM_CHILD_JOB_SNDINQMSG environment variable to 1.
<p>The environment variable can be set by using one of the following:</p>
<ul>
<li>API putenv("QIBM_CHILD_JOB_SNDINQMSG=1");</li>
<li>Command ADDENVVAR ENVVAR(QIBM_CHILD_JOB_SNDINQMSG) VALUE(1)</li>
<li>Command CHGENVVAR ENVVAR(QIBM_CHILD_JOB_SNDINQMSG) VALUE(1)</li>
</ul>
<br>
</li>
<li>Call or run the application that specifies
CHILDAPP.PGM as the <samp>file</samp>on the <strong>
spawnp()</strong> invocation. CHILDAPP will start running, send a CPAA980
*INQUIRY message to the user's message queue, and then will block, waiting for
a reply to the message. Issue a Work with Active Jobs (WRKACTJOB) command and
find the CHILDAPP in a MSGW job status. Option 7 (Display message) performed
against this job will display the CPAA980 *INQUIRY message that was sent. As
part of this message, the Qualified Job Name will be displayed in the proper
format to pass to the Start Service Job (STRSRVJOB) command (for example,
145778/RANDYR/CHILDAPP).
<p><strong>Note:</strong> Alternatively, a Display Messages (DSPMSG) command
can be issued for the user, and the output searched for the specific CPAA980
*INQUIRY message.</p>
<p><strong>Note:</strong> If the job's inquiry message reply specifies using
the default message reply, the child process will not block since the default
reply for the CPAA980 *INQUIRY message is G.</p>
</li>
<li>Issue a Start Service Job against the child process: STRSRVJOB
JOB(145778/RANDYR/CHILDAPP).<br>
<br>
</li>
<li>Issue a Start Debug Command: STRDBG PGM(MYAPPLIB/CHILDAPP).<br>
<br>
</li>
<li>Set whatever breakpoints are needed in CHILDAPP. When ready to continue,
find the CPAA980 message and reply with G. This will unblock CHILDAPP, which
allows it to run until a breakpoint is reached, at which time CHILDAPP will
again stop.
<p><strong>Note:</strong> If you reply with C to the CPAA980 message, the child
process is ended before the child process' program ever receives control. In
this case, on a subsequent call to <strong>wait()</strong> or <strong>
waitpid()</strong>, the status information returned indicates WIFEXCEPTION(),
which evaluates to a nonzero value, and WEXCEPTNUMBER() will evaluate to 0.</p>
</li>
<li>The application is now stopped at a breakpoint and debugging can
proceed.</li>
</ul>
<br>
</li>
<li>By default, the child's i5/OS simple job name is derived directly from the
<em>file</em> parameter. If <em>file</em> is a symbolic link to another
object, the i5/OS simple job name is derived from the symbolic link itself.
For example, if <em>file</em> was set to CHILD.PGM, the
child's i5/OS simple job name would be CHILD. If /usr/bin/daughter was a
symbolic link to /QSYS.LIB/MYLIB.LIB/CHILD.PGM and <em>file</em> was set to
daughter, the child's i5/OS simple job name would be DAUGHTER.
<p>If SPAWN_SETJOBNAMEPARENT_NP is set in <em>inherit.flags</em>, the
child's i5/OS simple job name would be the same as the parent's i5/OS simple
job name.</p>
<p>If SPAWN_SETJOBNAMEARGV_NP is set in <em>inherit.flags</em>, the
null-terminated character string represented by argv[0] of the
<em>argv[]</em> parameter will be used for the child's i5/OS simple job
name. The name can be up to 10 characters, must be uppercase, and must contain
only those characters allowed for an i5/OS job name. For example, if
<em>file</em> was set to CHILD.PGM, SPAWN_SETJOBNAMEARGV_NP
was set ON, and argv[0] was set to SON, the child's i5/OS simple
job name would be SON. If the first character of the name is invalid, the
<em>file</em> will be used. If any of the remaining characters
of the name are invalid, the valid characters up to that point will be used.
</p>
</li>
<li>The _NP used at the end of
certain flag names, that can be specified for the <em>flags</em> field
of the <em>inherit</em> parameter, indicate the flag is a non-standard,
i5/OS-platform-specific extension to the <samp>inheritance</samp> structure.
Applications that wish to avoid using platform-specific extensions should not
use these flags.
</li>
<li>The child process has an
associated process ID, which uses system resources. Those resources will
remain in use, even after the child process has ended. In order to ensure
those resources are reclaimed, the parent process should either successfully
call <strong>wait()</strong> or <strong>waitpid()</strong>, or the parent
process should end.
</li>
</ol>
<br>
<h3><a name="HDRSPWNAT2">Attributes Inherited</a></h3>
<p>The child process inherits the following POSIX attributes from the
parent:</p>
<ol>
<li>File descriptor table (mapped according to <em>fd_map</em>).
<p><strong>Note:</strong> The
following file descriptor table information does <strong>not</strong> apply to
any of the scan descriptors which are created by the thread executing one of
the scan-related exit programs (or any of its created threads). See <a href=
"ifsopenexit.htm">Integrated File System Scan on Open Exit Programs</a> and <a
href="ifscloseexit.htm">Integrated File System Scan on Close Exit Programs</a>
for more information.</p>
<ul>
<li>If <em>fd_map</em> is NULL, all file descriptors are inherited without
being reordered.
<p><strong>Note:</strong> File descriptors that have the FD_CLOEXEC file
descriptor flag set are not inherited. <!-- Refer to for additional information
about the FD_CLOEXEC flag. --> File descriptors that are created as a result of
the <strong>opendir()</strong> API (to implement open directory streams) are
not inherited.</p>
</li>
<li>If <em>fd_map</em> is not NULL, it is a mapping from the file descriptor
table of the parent process to the file descriptor table of the child process.
<em>fd_count</em> specifies the number of file descriptors the child process
will inherit. Except for those file descriptors designated by SPAWN_FDCLOSED,
file descriptor <em>i</em> in the child process is specified by <em>
fd_map[i]</em>. For example, <em>fd_map[5]</em>= 7 sets the child process' file
descriptor 5 to the parent process' file descriptor 7. File descriptors <em>
fd_count</em> through OPEN_MAX are closed in the child process, as are any file
descriptors designated by SPAWN_FDCLOSED.
<p><strong>Note:</strong> File descriptors that are specified in the <em>
fd_map</em> array are inherited even if they have the FD_CLOEXEC file
descriptor flag set. After inheritance, the FD_CLOEXEC flag in the child
process' file descriptor is cleared.</p>
</li>
<li>For files descriptors that remain open, no attributes are changed.<br>
<br>
</li>
<li>If a file descriptor refers to an open instance in a file system that does
not support file descriptors in two different processes pointing to the same
open instance of a file, the file descriptor is closed in the child process.
<p>Only open files managed by the Root, QOpenSys, or user-defined file systems
support inheritance of their file descriptors. All other file systems will have
their file descriptors closed in the child process.</p>
</li>
</ul>
</li>
<li>Process group ID<br>
<br>
<ul>
<li>If <em>inherit.flags</em> is set to SPAWN_SETPGROUP, the child process
group ID is set to the value in <em>inherit.pgroup</em>.
<p><strong>Note:</strong> i5/OS does not support the ability to set the
process group ID for the child process to a user-specified group ID. This is a
deviation from the POSIX standard.</p>
</li>
<li>If <em>inherit.pgroup</em> is set to SPAWN_NEWPGROUP, the child process is
put in a new process group with a process group ID equal to the process ID.<br>
<br>
</li>
<li>If <em>inherit.pgroup</em> is not set to SPAWN_NEWPGROUP, the child process
inherits the process group of the parent process.</li>
</ul>
<p>If the process group that the child process is attempting to join has
received the SIGKILL signal, the child process is ended.</p>
</li>
<li>Real user ID of the calling thread.<br>
<br>
</li>
<li>Real group ID of the calling thread.<br>
<br>
</li>
<li>Supplementary group IDs (group profile list) of the calling thread.<br>
<br>
</li>
<li>Current working directory of the parent process.<br>
<br>
</li>
<li>Root directory of the parent process.<br>
<br>
</li>
<li>File mode creation mask of the parent process.<br>
<br>
</li>
<li>Signal mask of the calling thread, except if the SPAWN_SETSIGMASK flag is
set in <em>inherit.flags</em>. Then the child process will initially have the
signal mask specified in <em>inherit.mask</em>.<br>
<br>
</li>
<li>Signal action vector, as determined by the following:<br>
<br>
<ul>
<li>If the SPAWN_SETSIGDEF flag is set in <em>inherit.flags</em>, the signal
specified in <em>inherit.sigdefault</em> is set to the default actions in the
child process. Signals set to the default action in the parent process are set
to the default action in the child process.<br>
<br>
</li>
<li>Signals set to be caught in the parent process are set to the default
action in the child process.<br>
<br>
</li>
<li>Signals set to be ignored in the parent process are set to ignore in the
child process, unless set to default by the above rules.</li>
</ul>
<br>
</li>
<li>Priority of the parent process.
<p><strong>Note:</strong> i5/OS prestart jobs do not inherit priority.</p>
</li>
<li>Scheduling policy (the i5/OS scheduling policy) of the parent process.<br>
<br>
</li>
<li>i5/OS-specific attributes of the parent, such as job attributes, run
attributes, library list, and user profile.
<p><strong>Note:</strong> i5/OS prestart jobs inherit a subset of
i5/OS-specific attributes.</p>
</li>
<li>Resource limits of the parent process.<br>
<br>
</li>
</ol>
<br>
<h3>Related Information</h3>
<ul>
<li>The &lt;<strong>spawn.h</strong>&gt; file (see <a href="unix13.htm">Header
Files for UNIX-Type Functions</a>)</li>
<li><a href="spawnpu.htm">QlgSpawnp()</a>--Spawn Process with Path (using
NLS-enabled file name)</li>
<li><a href="spawn.htm">spawn()</a>--Spawn Process</li>
<li><a href="sysconf.htm">sysconf()</a>--Get System Configuration
Variables</li>
<li><a href="wait.htm">wait()</a>--Wait for Child Process to End</li>
<li><a href="waitpid.htm">waitpid()</a>--Wait for Specific Child Process</li>
</ul>
<br>
<h3>Example</h3>
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
for information pertaining to code examples.</p>
<p>For an example of using this function, see Using the Spawn Process and Wait
for Child Process APIs in the API <a href="../apiref/apiexmp.htm">Examples</a>.</p>
<hr>
API introduced: V3R6
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> | <a href=
"unix.htm">UNIX-Type APIs</a> | <a href="aplist.htm">APIs by category</a></td>
</tr>
</table>
</center>
</body>
</html>