exec functions

Standards

Standards / Extensions C or C++ Dependencies

POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _POSIX_SOURCE
#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, …, NULL);
int execle(const char *path, const char *arg, …, NULL, char *const envp[]);
int execlp(const char *file, const char *arg, …, NULL);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
Note: Although POSIX.1 does not require that the unistd.h include file be included, it is recommended that you include it for portability.

General description

All exec functions run a new program by replacing the current process image with a new process image obtained from a file in the HFS (hierarchical file system).

For information on specifying names for MVS™ data sets and HFS files, see z/OS XL C/C++ Programming Guide.

A successful exec function never returns control because the calling process is overwritten with the new process.

The argument path is a string giving the absolute or relative path name of a file. This file contains the image of the process to be run.

file is a string that is used in determining the path name of the file containing the image of the process to be run. If file contains a slash character (/), it is assumed to be the absolute or relative path name of the file. If file does not contain a slash, the system searches for the given file name under the list of directories given by the PATH environment variable. The system checks under directories in the order they appear in the PATH variable, and executes the first file whose name matches the file string. The file must reside in the HFS.

The exec functions use the following environment variables:
STEPLIB
Supports the creation and propagation of a STEPLIB environment to the new process image. The following are the accepted values for the STEPLIB environment variable and the actions taken for each value:
  • STEPLIB=NONE. No Steplib DD is to be created for the new process image.
  • STEPLIB=CURRENT. The TASKLIB, STEPLIB or JOBLIB DD data set allocations that are active for the calling task at the time of the call to exec() are propagated to the new process image, if they are found to be cataloged. Uncataloged data sets are not propagated to the new process image.
  • STEPLIB=Dsn1:Dsn2:,...DsnN. The specified data sets, Dsn1:Dsn2:...DsnN, are built into a STEPLIB DD in the new process image.
    Note: The actual name of the DD is not STEPLIB, but is a system-generated name that has the same effect as a STEPLIB DD. The data sets are concatenated in the order specified. The specified data sets must follow standard MVS data set naming conventions. Data sets found to be in violation of this standard are ignored. If the data sets do follow the standard, but:
    • The caller does not have the proper security access to a data set
    • A data set is uncataloged or is not in load library format
    then the data set is ignored. Because the data sets in error are ignored, the executable file may run without the proper STEPLIB environment. If a data set is in error due to improper security access, a X'913' abend is generated. The dump for this abend can be suppressed by your installation.

If the STEPLIB environment variable is not specified, the exec() default behavior is the same as if STEPLIB=CURRENT were specified.

If the program to be invoked is a set-user-ID or set-group-ID file and the user-ID or group-ID of the file is different from that of the current process image, the data sets to be built into the STEPLIB environment for the new process image must be found in the system sanction list for set-user-id and set-group-id programs. Only those data sets that are found in the sanction list are built into the STEPLIB environment for the new process image. For detailed information regarding the sanction list, and for information on STEPLIB performance considerations, see z/OS UNIX System Services Planning.

_BPX_JOBNAME
Used to change the jobname of the new process image. The jobname change is allowed only if the invoker has appropriate privileges and is running in an address space created by fork. If these conditions are not met, the environment variable is ignored. Accepted values are strings of 1–8 alphanumeric characters. Incorrect specifications are ignored.
_BPX_ACCT_DATA
Used to change the account data of the new process image. Rules for specifying account data:
  • Up to 142 actual account data characters are allowed, including any commas
  • Sub-parameters must be separated by commas.
  • There is no restriction on the character set.
  • If the account data is greater than 142 characters, the data is ignored.
_BPXK_JOBLOG
The _BPXK_JOBLOG environment variable can be used to specify that WTO messages are to be written to an open HFS job log file. The following are the allowable values:
Value
Description
nn
Job log messages are to be written to open file descriptor nn.
STDERR
Job log messages are to be written to the standard error file descriptor, 2.
None
Job log messages are not to be written. This is the default.

The file that is used to capture messages can be changed at any time by calling the oe_env_np service (BPX1ENV) and specifying _BPXK_JOBLOG with a different file descriptor.

Message capturing is turned off if the specified file descriptor is marked for close on a fork or exec.

Message capturing is process-related. All threads under a given process share the same job log file. Message capturing may be initiated by any thread under that process.

Multiple processes in a single address space can each have different files active as the JOBLOG file; some or all of them can share the same file; and some processes can have message capturing active while others do not.

Only files that can be represented by file descriptors may be used as job log files; MVS data sets are not supported.

Message capturing will be propagated on a fork() or spawn(). In the case where a file descriptor was specified, the physical file must be the same for message capturing to continue in the forked or spawned process. If STDERR was specified, the file descriptor may be re-mapped to a different physical file.

Message capturing may be overridden on exec() or spawn() by specifying the _BPXK_JOBLOG environment variable as a parameter to the exec() or spawn().

Message capturing will only work in forked (BPXAS) address spaces.
Note: This is not true joblog support, messages that would normally go to the JESYSMSG data set are captured, but messages that go to JESMSGLG are not captured.
Special behavior for XPG4: If this file is not a valid executable object, the execlp() and execvp() functions invoke /bin/sh with the invoker's path name and the rest of the input arguments. It is similar to invoking:
execl("/bin/sh",
      "sh",
      "--",
      fully_expanded_pathname,
      arg1, arg2, ..., argn,
      NULL
     );
where arg1, arg2, ..., argn are the caller's arguments to execlp() or execvp(), and fully_expanded_pathname is the path name of the shell script found by searching the directories in the current PATH.

arg, …, NULL is a series of pointers to NULL-terminated character strings specifying arguments for the process being invoked. If the new process is a main(), these strings are stored in an array, and a pointer to the array is passed in the argv parameter. The first argument is required, and it should point to a string containing the name of the file that is associated with the process that exec is starting. A NULL pointer must follow the last argument string pointer.

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 invoked. argv[0] should point to a string containing the name of a file associated with the process being started by exec. 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.

All the forms of exec functions provide a way to locate the file containing the new process you want to run and a collection of arguments that should be passed to the new process. Each form of exec has its own method for specifying this information.

Some exec calls explicitly pass an environment using an envp argument. In versions where an environment is not passed explicitly—execl(), execlp(), execv(), and execvp()—the system uses the entire environment of the caller. The caller's environment is assumed to be the environment variables that the external variable **environ points to.

The variable ARG_MAX, obtained from z/OS® UNIX services by an invocation of sysconf(_SC_ARG_MAX), specifies the maximum number of bytes that can be used for arguments and environment variables passed to the process being invoked. The number of bytes includes the NULL terminator on each string.

A process started by an exec function has all of the open file descriptors that were present in the caller, except for those files opened with the close-on-exec flag FD_CLOEXEC. See fcntl() — Control open file descriptors for more information about this flag. In file descriptors that remain open, all attributes remain unchanged (including file locks).

Directory streams that are open in the calling process image are closed in the new process image.

The state of conversion descriptors and message catalog descriptors is undefined.

Signals set to be ignored in the caller, SIG_IGN, are set to be ignored in the new process image. Be careful to take care of signals that are being ignored. Although sigaction() specifying a handler is not passed by, SIG_IGN is. Blocking of signals is also passed by. All other signals are set to the default action, SIG_DFL, in the new process image, no matter how the caller handled such signals.

The real user ID (UID), real group ID (GID), and supplementary group IDs of the new process are the same as those of the caller. If the set-user-ID mode bit of the program file is on, the effective user ID of the new process is set to the file's owner. Similarly, if the set-group-ID mode bit of the program file is on, the effective group ID of the new process is set to the file's group. The effective user ID of the new process image is saved as the saved set-user-ID, and the effective group ID of the new process image is saved as the saved set-group-ID.

Any shared memory segments attached to the calling process image will not be attached to the new process image, see shmat() — Shared memory attach operation. Any shared memory segments attached to the calling process image will be detached (that is, the value of shm_nattch decremented by one). If this is the last thread attached to the shared memory segment and a shmctl() RMID has been issued, the segment will be removed from the system.

Special behavior for XPG4.2: Interval timers are preserved across an exec.

The new process also inherits the following from the caller:

A successful exec function automatically opens the specified program file, and updates the access time st_atime for that file. The program file is closed automatically after the program has been read from the file. The precise time of this close operation is undefined.

Special behavior for z/OS UNIX Services:
  1. A prior loaded copy of an HFS program in the same address space is reused under the same circumstances that apply to the reuse of a prior loaded MVS unauthorized program from an unauthorized library by the MVS XCTL service with the following exceptions:
    • If the calling process is in Ptrace debug mode, a prior loaded copy is not reused.
    • If the calling process is not in Ptrace debug mode, but the only prior loaded usable copy found of the HFS program is in storage modifiable by the caller, the prior copy is not reused.
  2. If the specified file name represents an external link or a sticky bit file, the program is loaded from the caller's MVS load library search order. For an external link, the external name is only used if the name is eight characters or less, otherwise the caller receives an error from the loadhfs service. For a sticky bit program, the file name is used if it is eight characters or less. Otherwise, the program is loaded from the HFS.
  3. If the calling task is in a WLM enclave, the resulting task in the new process image is joined to the same WLM enclave. This allows WLM to manage the old and new process images as one ‘business unit of work’ entity for system accounting and management purposes.
Note: If you are expecting this function to take advantage of the z/OS UNIX magic number support, the Language Environment® runtime option to POSIX(ON) must have been set when the process was initialized. Attempting to use magic number support with a process initialized with POSIX(OFF) may produce undesirable effects. See z/OS UNIX System Services Planning and z/OS UNIX System Services User's Guide for details and uses of the z/OS UNIX magic number.

Returned value

If successful, an exec function never returns control because the calling process is overwritten with the new process.

If unsuccessful, an exec function returns -1 and sets errno to one of the following values:
Error Code
Description
E2BIG
The combined argument list and environment list of the new process has more bytes than the system-defined length. See sysconf() — Determine system configuration options for information about the system-defined length.
EACCES
The process did not have appropriate permissions to run the specified file, for one of these reasons:
  • The process did not have permission to search a directory named in your path.
  • The process did not have execute permission for the file to be run.
  • The system cannot run files of this type.
EFAULT
A bad address was received as an argument of the call, or the user exit program checked.

Consult Reason Code to determine the exact reason the error occurred. The following reason code can accompany the return code: JRExecParmErr and JRExitRtnError.

EINVAL
The new process image file has the appropriate permission and has a recognized format, but the system does not support execution of a file with this format.
ELOOP
A loop exists in symbolic links. This error is issued if the number of symbolic links detected in the resolution of the path or file argument is greater than POSIX_SYMLOOP (a value defined in the limits.h header file)
ELEMULTITHREAD
The exec function was invoked from a multithreaded environment.
EMVSSAF2ERR
The executable file is a set-user-ID or set-group-ID file, and the file owner's UID or GID is not defined to RACF®.
ENAMETOOLONG
All or part of the file name is too long. This can happen if:
  • A path or file argument exceeds the value of PATH_MAX, or an element of your path exceeds PATH_MAX.
  • Any pathname component is greater than NAME_MAX, and _POSIX_NO_TRUNC is in effect.
  • The length of a path name string substituted for a symbolic link in the path argument exceeds PATH_MAX.
The PATH_MAX and NAME_MAX values are determined with pathconf().
ENOENT
One or more pathname components in path or file does not exist. This error is also issued if path or file is a NULL string.
ENOEXEC
The new process image file has the appropriate access permission but has an unrecognized format. This errno can be returned from any one of the exec family of functions, except for execlp() and execvp().
Note: Reason codes further qualify the errno. For most of the reason codes, see z/OS UNIX System Services Messages and Codes.
For ENOEXEC, the reason codes are:
Reason Code Explanation
X'xxxx0C27' The target HFS file is not in the correct format to be an executable file.
X'xxxx0C31' The target HFS file is built at a level that is higher than that supported by the running system.
ENOMEM
The new process requires more memory than is permitted by the operating system.
ENOTDIR
A directory component of path or file is not really a directory.

Example

CELEBE03
⁄* CELEBE03

   This example runs a program, using the execl() function.

 *⁄
#define _POSIX_SOURCE
#include <stdio.h>
#include <sys⁄wait.h>            ⁄*FIX: used be <wait.h>*⁄
#include <sys⁄types.h>
#include <unistd.h>

main() {
  pid_t pid;
  int status;

  if ((pid = fork()) == 0) {
    execl("⁄bin⁄false", NULL);
    perror("The execl() call must have failed");
    exit(255);
  }
  else {
    wait(&status);
    if (WIFEXITED(status))
      printf("child exited with status of %d\n", WEXITSTATUS(status));
    else
      puts("child did not exit successfully\n");
  }
}
Output
child exited with status of 1

Related information