gtpc2m86 | C/C++ Language Support User's Guide |
This function creates a child process on a specified I-stream. The
caller is called the parent process and the created entry control
block (ECB) is called the child process. The process
identifier (ID) of the child process is returned by this function, while the
process ID of the caller is used as the parent process ID of the
child process. Using process IDs, the parent and child processes can
use the kill function to send signals to each other.
Additionally, when the child process exits, a SIGCHLD signal is sent to the
parent process automatically.
Format
#define TPF_FORK_EXTENDED
#include <sysapi.h>
pid_t tpf_fork (const struct tpf_fork_input *create_parameters,
const char *argv[ ], const char *envp[ ]);
or
#include <sysapi.h>
pid_t tpf_fork(const struct tpf_fork_input *create_parameters);
- create_parameters
- A pointer to a fully initialized tpf_fork_input
structure. The following fields are defined in the
tpf_fork_input structure:
- program
- A pointer to the name of the first program to be called by the created
ECB. The program must be a dynamic load module (DLM) and its entry
point must be a main function. It can be specified in the
following ways:
- If prog_type is TPF_FORK_NAME, program
points to a 4-character TPF program name.
- If prog_type is TPF_FORK_FILE, program
points to the path name of a file system executable file that contains a
reference to a TPF program. This path name can specify a relative path
or an absolute path, which is indicated by a preceding slash. The file
must contain one of the following:
- #!nnnn, where nnnn is the 4-character name of a TPF
program to be run
- #!pathname, where pathname is the path to the file
that contains #!nnnn.
- If prog_type is TPF_FORK_AND_SEARCH,
program points to the path name of a file system executable file
that contains a reference to a TPF program. This path name can specify
a relative path or an absolute path that is indicated by a preceding
slash. Otherwise, the directories specified by the PATH environment
variable are searched for the file system executable file. The file
must contain one of the following:
- #!nnnn, where nnnn is the 4-character name of a TPF
program to be run
- #!pathname, where pathname is the path to the file
that contains #!nnnn.
- If prog_type is TPF_FORK_FILE or TPF_FORK_AND
SEARCH and program points to the path name of a file system
executable file that does not contain a reference to a TPF program in the form
#!nnnn, the tpf_fork function calls segment CFIX, which
is the default executable ZFILE parser, by using the path name of the caller
and the remaining input arguments. This is similar to the
following:
struct tpf_fork_input create_parameters;
create_parameters.program = "CFIX";
create_parameters.prog_type = TPF_FORK_NAME;
create_parameters.istream = TPF_FORK_IS_BALANCE;
create_parameters.ebw_data = NULL;
create_parameters.ebw_data_length = 0;
create_parameters.parm_data = NULL;
argvar[0] = "sh";
argvar[1] = "-c";
argvar[2] = fully_expanded_pathname;
for ( i=3; argv[3-i] != NULL; ++i)
argvar[i] = argv[3-i];
argvar[i] = NULL;
tpf_fork( &create_parameters, argvar, NULL );
where argvar is an array containing all the caller's
arguments to tpf_fork, and fully_expanded_pathname is
the path name of the script found by searching the directories in the current
path.
- prog_type
- One of the following:
- TPF_FORK_NAME, if program specifies a 4-character
TPF program name.
- TPF_FORK_FILE, if program specifies the path name of
a file system executable file that refers to a TPF program. This path
name can specify a relative path or an absolute path, which is indicated by a
preceding slash.
- TPF_FORK_AND_SEARCH, if program specifies the path
name of a file system executable file that refers to a TPF program.
This path name can specify a relative path or an absolute path, which is
indicated by a preceding slash. Otherwise, the file system executable
is searched in the directories specified by the PATH environment
variable.
- istream
- The I-stream where the asynchronous entry is created; specify either
the I-stream number (1-based ordinal) or one of the following:
- TPF_FORK_IS_MAIN
- Create the asynchronous entry on the main I-stream. Specify either
this option or the I-stream number (1-based ordinal).
- TPF_FORK_IS_MPIF
- Create the asynchronous entry on the Multi-Processor Interconnect Facility
(MPIF) I-stream. Specify either this option or the I-stream number
(1-based ordinal).
- TPF_FORK_IS_BALANCE
- Create the asynchronous entry on the least busy I-stream. Specify
either this option or the I-stream number (1-based ordinal).
- ebw_data_length
- The number of bytes of data (0-104 bytes) to be passed to the child
process.
- ebw_data
- A pointer to void containing the address of data to be passed
to the child process beginning at EBW000.
- parm_data
- A pointer to additional data to be passed to program.
The data is passed to the main function in program in
the argv array. The total length of the program
and parm_data strings must be less than 4094 bytes.If
argv is supplied, parm_data must equal NULL.
Otherwise, an error is returned.
- argv
- is a pointer to an array of pointers to null-terminated character
strings. There must be a NULL pointer after the last character string
to mark the end of the array. These strings are used as arguments for
the process being called. argv[0] should point to
a string containing the name of a file (program name) associated with the
process being started by tpf_fork. If parm_data
is supplied, argv must equal NULL. Otherwise, an error is
returned.
- envp
- is a pointer to an array of pointers to null-terminated character
strings. There must be a NULL pointer after the last character string
to mark the end of the array. The strings of envp provide
the environment variables for the new process.
Normal Return
The process ID of the created child process is returned.
Error Return
A value of -1 and errno is set to one of the
following:
- EACCESS
- The program does not have permission to run the specified file system path
name.
- EINVAL
- The create_parameters parameter is a NULL pointer, or one or
more of the members of the referenced struct tpf_fork_input object
are not valid:
- The program member is a NULL pointer.
- The ebw_data_length member is less than zero or greater than
104.
- The ebw_data_length member is greater than zero and less than
or equal to 104, and the ebw_data member is a NULL pointer.
- The prog_type member is not TPF_FORK_NAME,
TPF_FORK_FILE, or TPF_FORK_AND_SEARCH.
- ELOOP
- A loop exists in the symbolic links. This error occurs if the
number of symbolic links detected in the resolution is greater than
POSIX_SYMLOOP (a value defined in the limits.h header
file).
- ENAMETOOLONG
- The program field is longer than PATH_MAX characters or some
component of program is longer than NAME_MAX.
- ENOENT
- One or more components of the path name specified by program do
not exist or program points to a NULL string.
- ENOEXEC
- The contents of the program file are not of the form
#!uaaa (where u is an uppercase letter and a
is an uppercase letter or a digit), or the 4-character TPF program name is not
of the form uaaa.
- ENOTDIR
- A component of the path prefix specified by program is not a
directory.
- ETPFFSNOTRDY
- The TPF file system has not been initialized or cannot be used by the
process.
- E2BIG
- The length of the program string plus the length of the
parm_data string is greater than or equal to 4094 bytes.
Programming Considerations
- You must have authorization to use a restricted macro to call this
function.
- This function performs system resource checks that may cause the calling
ECB to give up control.
- If istream is set to FORK_IS_BALANCE, the TPF
scheduler will be called.
- ECBs may or may not be started on the same I-stream where they are created
depending on the options you set and whether the scheduler is called.
- The following information is inherited by the created child process from
the calling parent process:
- Environment list
- Real user ID (UID) and real group ID (GID)
- Process group ID
- Current working directory
- File mode creation mask
- Open file descriptors that do not have the FD_CLOEXEC file
descriptor flag set to 1. The file descriptors must also be able to be
inherited, that is, the device driver must specify that file descriptors that
use it can be inherited.
- The effective UID and effective GID of the child process are initialized
to the effective UID and effective GID of the parent process with the
following exceptions:
- If TPF_FORK_FILE is specified and if the file specified by
program has the set-user-ID (S_ISUID) flag
set, the effective user ID is set to the user ID of the owner of the
file.
- If TPF_FORK_FILE is specified and if the file specified by
program has the set-group-ID (S_ISGID) flag
set, the effective group ID is set to the group ID of the owner of the
file.
- The saved set-user-ID and saved set-group-ID of the child process are
initialized to the same values as the effective user ID and effective group
ID, respectively.
- Each time a process that has a parent process exits, a SIGCHLD signal is
sent to the parent process. Unless the parent process has set its
SIGCHLD signal disposition to SIG_IGN using the signal function,
termination status for each exiting child process is saved until the parent
process calls the wait or waitpid function.
Examples
The following example creates an asynchronous entry and adds it to the
ready list for the application I-stream that is least active. No data
is passed to the EBW work area of the asynchronous entry. When the
asynchronous entry gets control of the selected I-stream, it enters the TPF
program segment specified by "/bin/usr/usr1/app1.exe", which
contains the string #!QZZ2. The program-defined
environment variable MYPATH is passed from QZZ1 to QZZ2.
/***************************************/
/* Sample program QZZ1 */
/***************************************/
#define TPF_FORK_EXTENDED
#include <sysapi.h>
int main(int argc, char **argv) {
char *args[] = { "/bin/usr/usr1/app1.exe", "0", "0", "100", "ADD", NULL };
char *envp[] = {"MYPATH=/usr/bin:/bin", NULL };
struct tpf_fork_input create_parameters;
pid_t child_pid;
create_parameters.program = "/bin/usr/usr1/app1.exe"
/***************************************/
/* call program QZZ2 specified by */
/* "/bin/usr/usr1/app1.exe" */
/***************************************/
create_parameters.prog_type = TPF_FORK_FILE;
create_parameters.istream = TPF_FORK_IS_BALANCE;
create_parameters.ebw_data_length = 0;
create_parameters.ebw_data = NULL;
create_parameters.parm_data = NULL;
child_pid = tpf_fork(&create_parameters, (const char **)args, (const char **)envp);
}
/**************************************/
/* End of QZZ1 */
/**************************************/
/**************************************/
/* Sample program QZZ2 */
/**************************************/
#include <sysapi.h>
int main(int argc, char **argv)
{
int i;
for (i=0; i<=argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
}
/**************************************/
/* End of QZZ1 */
/**************************************/
The output of QZZ2 is:
argv[0]=/bin/usr/usr1/app1.exe"
argv[1]=0
argv[2]=0
argv[3]=100
argv[4]=ADD
Related Information
See the ZFILE export command in TPF Operations
for more information about the PATH environment variable.