Use the following routine to DETACH a program and capture the PID of the detached program.
/* */
/* sample routine to detach a program and return the process */
/* identification number (PID) */
/* */
/* get the parameter */
parse arg progName progParameter
/* detach the program */
thisRC = DetachProgram( progName, progParameter )
/* and process the return code */
if word( thisRC,1 ) = "ERROR:" then
say "DetachProgram returned the error message: " thisRC
else
say "The process identification number of the",
"detached process is <" || thisRC || ">."
exit
/* ------------------------------------------------------------------ */
/* function: detach a program and return the process identification */
/* number */
/* */
/* call: DetachProgram programName {, programParameters} */
/* */
/* where: programName - name of the program */
/* programParameters - parameter for the program */
/* */
/* returns: ERROR n: error n occured */
/* where n is */
/* -255 : unknown error occured */
/* -1 : parameter missing */
/* -2 : program to detach not found */
/* else the process identification number */
/* */
/* Note: This routine uses static names for the temporary files */
/* and thus cannot run in separate programs at the same */
/* time (see below for a solution of this limitation)! */
/* */
/* This routine assumes that the PID is always the last */
/* word in the output of the detach command. */
/* */
/* */
DetachProgram: PROCEDURE
parse arg ProgramName , ProgramParameter
programName = strip( programName )
/* set the necessary ADDRESS environment */
/* Note that the previous ADDRESS environment */
/* is automatically restored after this */
/* routine ends. */
ADDRESS "CMD"
/* init the return code */
thisRC = "ERROR: -255"
if programName <> "" then
do
if stream( programName, "c", "QUERY EXISTS" ) <> "" then
do
/* get the path for the temporary files */
tempPath = value( "TEMP",, "OS2ENVIRONMENT" )
if tempPath = "" then
tempPath = value( "TEMP",, "OS2ENVIRONMENT" )
if tempPath = "" then
tempPath = directory()
if right( tempPath, 1 ) <> "\" then
tempPath = tempPath || "\"
/* Note: */
/* Change the algorithm to get the names for the */
/* logfile and the temporary copy of the logfile */
/* if you want to run this routine in more than */
/* one program at the same time!!! */
/* (e.g. use the routine GetTempFile from RXT&T) */
/* create the name for the STDERR logfile */
/* of the detached program */
STDErrLogFile = tempPath || "$$out$$.ERR"
/* create the name for the temporary copy of the */
/* logfile */
TempLogFile = tempPath || "$$out$$.TMP"
/* detach the program redirecting STDOUT to NUL */
/* and STDERR into the logfile */
/* */
/* The use of another copy of the CMD.EXE is */
/* necessary to handle batch files and REXX */
/* programs correctly */
/* */
"@detach cmd /c " ProgramName ,
ProgramParameter ,
"2>" || STDErrLogFile ,
"1>" || "NUL"
/* because we can't read the logfile in REXX at */
/* this time (it is still opened), we use the */
/* TYPE command to copy the current contents */
/* of the logfile into another file */
/* */
/* Note that you cannot redirect the output of */
/* the TYPE command into RXQUEUE. */
/* You cannot use the COPY command to copy the */
/* file because it is still in use by the */
/* detached program. */
/* */
"@type " STDErrLogFile ">" || TempLogFile
/* and now we read the first line of the */
/* temporary copy of logfile to get the PID */
call stream tempLogfile, "c", "OPEN READ"
if lines( tempLogFile ) >= 1 then
do
curLine = lineIn( tempLogFile )
/* we assume the last word of the output message */
/* from DETACH is the PID */
thisRC = Word( curLine, words( curLine ) )
if right( thisRC,1 ) = "." then
thisRC = dbrright( thisRC, 1 )
end /* if */
/* last thing to do: close temporary copy of */
/* the logfile and delete it */
call stream tempLogfile, "c", "CLOSE"
"@del " tempLogFile "1>NUL 2>NUL"
end /* if stream( programName, "c", "QUERY EXISTS" ) <> "" then */
else
thisRC = "ERROR: -2"
end /* if programName <> "" then */
else
thisRC = "ERROR: -1"
RETURN thisRC