DosExecPgm

From EDM2
Jump to: navigation, search

DosExecPgm creates a child process which can be either synchronous, asynchronous or detached. The child process must of the same type as the parent process (i.e. a PM process can only start another PM process, unless the non-PM process doesn't perform any I/O). If a non-PM process wants to start a PM process, or a PM process wants to start a non-PM process which does I/O, DosStartSession must be used.

Syntax

rc = DosExecPgm( pchProcName, lProcName, ulExecFlag, pszArg, pszEnv, prcRes, pszName );

Parameters

PCHAR pchProcName (output)
This is the address of the buffer which contains the name of the process that is responsible if the DosExecPgm failure is returned. For instance, if the parent process tries to running an program which doesn't exist, the inexistent file name will be put into this buffer.
LONG lProcName (input)
This is the length, in bytes, of the buffer pchProcName
ULONG ulExecFlag (input)
This is the flag which will lead the child process. There are the possible values:
0 EXEC_SYNC The execution will be synchronous to the parent process. The termination code and result code are stored in the RESULTCODES structure of prcRes.
1 EXEC_ASYNC The execution will be asynchronous to the parent process. When the child process execution is over, its result code will be lost. The PID is stored in the codeTerminate field of the RESULTCODES of prcRes.
2 EXEC_ASYNCRESULT The execution will be asynchronous to the parent process. When the child process execution is over, its result code will be saved and will be retrieved by the DosWaitChild function. The PID is stored in the codeTerminate field of the RESULTCODES structure of prcRes.
3 EXEC_TRACE Like EXEC_ASYNCRESULT but for debugging purposes. Only the child process will be concerned by the debugging session.
4 EXEC_BACKGROUND The execution will be asynchronous in background. It is a orphan process and doesn't depend of the parent process termination. A such program shouldn't use any VIO, KDB or MOU functions other than VioPopups.
5 EXEC_LOAD The process is loaded and is ready to execute, but isn't executed until the session manager dispatches the threads belonging to the process.
6 EXEC_ASYNCRESULTDB Like EXEC_ASYNCRESULT, but for debugging purposes. The child process and its descendants will be concerned by the debugging session.

Warning : unless using EXEC_SYNC and EXEC_ASYNC, result codes should be retrieved with DosWaitChild in order to avoid wasting memory, even if the result codes won't be used later.

PSZ pszArg (input)
This is the address of the argument string passed to the process. Example of a such argument string:
"UNZIP\0-l MYARCHIVE.ZIP *.BMP\0"
By default, the file name is searched in the default directory and through the PATH variable. If the program name isn't present into the PATH variable, the comprehensive access path must be present.
There are always a '\0' between the program name and the parameters. Moreover, a second '\0' must also be placed at the end of the argument string.
PSZ pszEnv (input)
This is the address of the environment string passed to the process. When a NULL value is passed into pszEnv, the child process will inherit the environment of its parent.
PSZ pszRes (output)
This is a pointer to the RESULTCODES structure.
PSZ pszName (input)
This is the address of the string which contains the file name of the child process with its extension which must be present.

Returns

APIRET rc
The following values can be returned:
0 NO_ERROR
1 ERROR_INVALID_FUNCTION
2 ERROR_FILE_NOT_FOUND
3 ERROR_PATH_NOT_FOUND
4 ERROR_TOO_MANY_OPEN_FILES
5 ERROR_ACCESS_DENIED
8 ERROR_NOT_ENOUGH_MEMORY
10 ERROR_BAD_ENVIRONMENT
11 ERROR_BAD_FORMAT
13 ERROR_INVALID_DATA
26 ERROR_NOT_DOS_DISK
32 ERROR_SHARING_VIOLATION
33 ERROR_LOCK_VIOLATION
36 ERROR_SHARING_BUFFER_EXCEEDED
89 ERROR_NO_PROC_SLOTS
95 ERROR_INTERRUPT
108 ERROR_DRIVE_LOCKED
127 ERROR_PROC_NOT_FOUND
182 ERROR_INVALID_ORDINAL
190 ERROR_INVALID_MODULETYPE
191 ERROR_INVALID_EXE_SIGNATURE
192 ERROR_EXE_MARKED_INVALID
195 ERROR_INVALID_MINALLOCSIZE
196 ERROR_DYNLINK_FROM_INVALID_RING

Relevant Structures

typedef struct _RESULTCODES {
  /* Termination code or process identifier. */
  ULONG codeTerminate;
  /* Exit code. */
  ULONG codeResult;
} RESULTCODES, *PRESULTCODES;

Gotchas

Do NOT launch a synchronous PM child process from a single-threaded PM process! It will choke the system messaging queue and you will have to do Ctrl-Esc to kill the process. I don't know if this problem will also appear from a multi-threaded PM process.

Sample Code

#define INCL_DOSPROCESS
#include <os2.h>

UCHAR pchProcName[CCHMAXPATH] = {0} ;	/* Error info from DosExecPgm */
UCHAR pszArgString[CCHMAXPATH+41] ;	/* Argument string */
RESULTCODES ChildRC = {0} ;		/* Results from child process */
PID pidChild = 0 ;			/* PID for child process */
APIRET rc = NO_ERROR ; 			/* Return code */

	/* creating the argument string */
	sprintf(pszArgString, "UNZIP MYARCHIVE.ZIP %s\0",
	        pszWhichFilesToBeExtracted) ;
	/* if the 2nd parameter of the sprint would be like : */
	/* "UNZIP\0MYARCHIVE.ZIP %s\0" */
	/* so the %s will never be filled ! */
	/* It is why that we have to set the '\0' after the sprintf */
	pszArgString[5] = '\0' ;

	rc = DosExecPgm(pchProcName, sizeof pchProcName, EXEC_SYNC,
	                pszArgString, NULL, &ChildRC, "UNZIP.EXE") ;

	if (rc != NO_ERROR)
		{
		/* handle the error */
		}
	else
 		{
 		/* The extraction is successful ! */
		/* Handle the resulted files */
		}

See Also