_exec Functions

Description

Load and execute new child processes.

#include <process.h> Required only for function declarations  

int _execl( char *cmdname, char *arg0,...char *argn, NULL );

int _execle( char *cmdname, char *arg0,...char *argn, NULL, char **envp );

int _execlp( char *cmdname, char *arg0,...char *argn, NULL );

int _execlpe( char *cmdname, char *arg0,...char *argn, NULL, char **envp );

int _execv( char *cmdname, char **argv );

int _execve( char *cmdname, char **argv, char **envp );

int _execvp( char *cmdname, char **argv );

int _execvpe( char *cmdname, char **argv, char **envp );

cmdname Path name of file to be executed  
arg0, ... argn List of pointers to arguments  
argv Array of pointers to arguments  
envp Array of pointers to environment settings  

Remarks

The _exec functions load and execute new child processes. When the call is successful in DOS, the child process is placed in the memory previously occupied by the calling process. Sufficient memory must be available for loading and executing the child process.

All of the _exec functions use the same operating system function. The letter(s) at the end of the function name determine the specific variation, as shown in the following list:

Letter Variation

e An array of pointers to environment arguments is explicitly passed to the child process.
l Command-line arguments are passed individually to the _exec function.
p Uses the PATH environment variable to find the file to be executed.
v Command-line arguments are passed to the _exec function as an array of pointers.

The cmdname argument specifies the file to be executed as the child process. It can specify a full path (from the root), a partial path (from the current working directory), or just a filename. If cmdname does not have a filename extension or does not end with a period (.), the _exec function searches for the named file; if the search is unsuccessful, it tries the same base name, first with the extension .COM, then with the extension .EXE. If cmdname has an extension, only that extension is used in the search. If cmdname ends with a period, the _exec calls search for cmdname with no extension. The _execlp, _execlpe, _execvp, and _execvpe routines search for cmdname (using the same procedures) in the directories specified by the PATH environment variable.

If cmdname contains a drive specifier or any slashes (that is, if it is a relative path name), the _exec call searches only for the specified file; the path is not searched. Note that the DOS APPEND command cannot be used with the _exec functions.

Arguments are passed to the new process by giving one or more pointers to character strings as arguments in the _exec call. These character strings form the argument list for the child process. The combined length of the strings forming the argument list for the new process must not exceed 128 bytes (in real mode only). The terminating null character ('\0') for each string is not included in the count, but space characters (inserted automatically to separate the arguments) are counted.

The argument pointers can be passed as separate arguments (_execl, _execle, _execlp, and _execlpe) or as an array of pointers (_execv, _execve, _execvp, and _execvpe). At least one argument, arg0, must be passed to the child process; this argument is argv[0] of the child process. Usually, this argument is a copy of the cmdname argument. (A different value will not produce an error.) Under versions of DOS earlier than 3.0, the passed value of arg0 is not available for use in the child process. However, with DOS versions 3.0 and later, cmdname is available as arg0.

The _execl, _execle, _execlp, and _execlpe calls are typically used when the number of arguments is known in advance. The argument arg0 is usually a pointer to cmdname. The arguments arg1 through argn point to the character strings forming the new argument list. A null pointer must follow argn to mark the end of the argument list.

The _execv, _execve, _execvp, and _execvpe calls are useful when the number of arguments to the new process is variable. Pointers to the arguments are passed as an array, argv. The argument argv[0] is usually a pointer to cmdname. The arguments argv[1] through argv[n] point to the character strings forming the new argument list. The argument argv[n+1] must be a NULL pointer to mark the end of the argument list.

Files that are open when an _exec call is made remain open in the new process. In the _execl, _execlp, _execv, and _execvp calls, the child process inherits the environment of the parent. The _execle, _execlpe, _execve, and _execvpe calls allow the user to alter the environment for the child process by passing a list of environment settings through the envp argument. The argument envp is an array of character pointers, each element of which (except for the final element) points to a null-terminated string defining an environment variable. Such a string usually has the form

NAME=value

where NAME is the name of an environment variable and value is the string value to which that variable is set. (Note that value is not enclosed in double quotation marks.) The final element of the envp array should be NULL. When envp itself is NULL, the child process inherits the environment settings of the parent process.

A program executed with one of the _exec family of functions is always loaded into memory as if the “maximum allocation” field in the program's .EXE file header is set to the default value of 0xFFFFH. You can use the EXEHDR utility to change the maximum allocation field of a program; however, such a program invoked with one of the _exec functions may behave differently from a program invoked directly from the operating-system command line or with one of the _spawn functions.

Note that COMMAND.COM checks the first two bytes of a file to determine whether it is an .EXE file or a .COM file—you can execute a file named by any extension, as long as its content is truly executable.

The _exec calls do not preserve the translation modes of open files. If the child process must use files inherited from the parent, the _setmode routine should be used to set the translation mode of these files to the desired mode.

You must explicitly flush (using fflush or _flushall) or close any stream prior to the _exec function call.

Signal settings are not preserved in child processes that are created by calls to _exec routines. The signal settings are reset to the default in the child process.

Return Value

The _exec functions do not normally return to the calling process. If an _exec function returns, an error has occurred and the return value is –1. The errno variable is set to one of the following values:

Value Meaning

E2BIG The argument list exceeds 128 bytes, or the space required for the environment information exceeds 32K.
EACCES The specified file has a locking or sharing violation (DOS version 3.0 or later).
EMFILE Too many files open (the specified file must be opened to determine whether it is executable).
ENOENT File or path name not found.
ENOEXEC The specified file is not executable or has an invalid executable-file format.
ENOMEM Not enough memory is available to execute the child process; or the available memory has been corrupted; or an invalid block exists, indicating that the parent process was not allocated properly.

Compatibility

Standards:UNIX

16-Bit:DOS

32-Bit:DOS32X

Use _exec for compatibility with ANSI naming conventions of non-ANSI functions. Use exec and link with OLDNAMES.LIB for UNIX compatibility.

Because of differences in DOS versions 2.0 and 2.1, child processes generated by the _exec family of functions (or by the equivalent _spawn functions with the _P_OVERLAY argument) may cause fatal system errors when they exit. If you are running DOS 2.0 or 2.1, you must upgrade to DOS version 3.0 or later to use these functions.

Bound programs cannot use the _exec family of functions in real mode.

See Also

abort, atexit, exit, _exit, _onexit, _spawn functions, system

Example

/* EXEC.C: This program accepts a number in the range 1 through 8 from the

* command line. Based on the number it receives, it executes one of the

* eight different procedures that spawn the process named child. For

* some of these procedures, the child.exe file must be in the same

* directory; for others, it need only be in the same path.

*/

#include <stdio.h>

#include <process.h>

char *my_env[] = {

"THIS=environment will be",

"PASSED=to child.exe by the",

"_EXECLE=and",

"_EXECLPE=and",

"_EXECVE=and",

"_EXECVPE=functions",

NULL

};

void main( int argc, char *argv[] )

{

char *args[4];

int result;

args[0] = "child"; /* Set up parameters to send */

args[1] = "_execv??";

args[2] = "two";

args[3] = NULL;

switch( argv[1][0] ) /* Based on first letter of argument */

{

case '1':

_execl( argv[2], argv[2], "_execl", "two", NULL );

break;

case '2':

_execle( argv[2], argv[2], "_execle", "two", NULL, my_env );

break;

case '3':

_execlp( argv[2], argv[2], "_execlp", "two", NULL );

break;

case '4':

_execlpe( argv[2], argv[2], "_execlpe", "two", NULL, my_env );

break;

case '5':

_execv( argv[2], args );

break;

case '6':

_execve( argv[2], args, my_env );

break;

case '7':

_execvp( argv[2], args );

break;

case '8':

_execvpe( argv[2], args, my_env );

break;

default:

printf( "SYNTAX: EXEC <1-8> <childprogram>\n" );

exit( 1 );

}

printf( "Process was not spawned.\n" );

printf( "Program 'child' was not found." );

}