blob: 6be6884cfd3a564adeb84fba5e11f740288ce590 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "system.h"
#include <osl/thread.h>
#include <osl/diagnose.h>
//#include <osl/socket.h>
#ifndef _OSL_FILE_PATH_HELPER_H_
#include "file_path_helper.h"
#endif
#include "procimpl.h"
//#include "sockimpl.h"
//#include "secimpl.h"
#include <ctype.h>
//#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
//#endif
// for exception logging
#include <stdio.h>
#include <setjmp.h>
#define MAX_ARGS 255
#define PIPENAMEMASK "\\PIPE\\OSL_PIPE_%u"
#define SEMNAMEMASK "\\SEM32\\OSL_SEM_%u"
typedef enum {
MSG_DATA,
MSG_END,
MSG_ACK,
MSG_REL,
MSG_UNKNOWN
} MessageType;
typedef struct {
MessageType m_Type;
oslDescriptorFlag m_Flags;
oslDescriptorType m_Data;
HANDLE m_Value;
} Message;
typedef struct {
HPIPE m_hPipe;
} Pipe;
typedef struct _oslSocketCallbackArg {
HANDLE m_socket;
Pipe* m_pipe;
} oslSocketCallbackArg;
/* process termination queue */
static sal_Bool bInitSessionTerm = sal_False;
static const sal_Char * const SessionTermQueueName = "\\QUEUES\\SESSIONS.QUE";
static HQUEUE SessionTermQueue;
/******************************************************************************
*
* Function Declarations
*
*****************************************************************************/
oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
sal_Char *pszArguments[],
oslProcessOption Options,
oslSecurity Security,
sal_Char *pszDirectory,
sal_Char *pszEnvironments[],
oslProcess *pProcess,
oslFileHandle *pInputWrite,
oslFileHandle *pOutputRead,
oslFileHandle *pErrorRead );
/* implemented in file.c */
extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
static sal_Bool InitSessionTerm( void )
{
DosCreateQueue( &SessionTermQueue, QUE_FIFO, (PCSZ) SessionTermQueueName );
return sal_True;
}
/******************************************************************************
*
* Functions for starting a process
*
*****************************************************************************/
/**********************************************
osl_executeProcess_WithRedirectedIO
*********************************************/
oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
rtl_uString *ustrImageName,
rtl_uString *ustrArguments[],
sal_uInt32 nArguments,
oslProcessOption Options,
oslSecurity Security,
rtl_uString *ustrWorkDir,
rtl_uString *ustrEnvironment[],
sal_uInt32 nEnvironmentVars,
oslProcess *pProcess,
oslFileHandle *pInputWrite,
oslFileHandle *pOutputRead,
oslFileHandle *pErrorRead
)
{
oslProcessError Error;
sal_Char* pszWorkDir=0;
sal_Char** pArguments=0;
sal_Char** pEnvironment=0;
unsigned int index;
char szImagePath[PATH_MAX] = "";
char szWorkDir[PATH_MAX] = "";
#if 0
if (Options & osl_Process_SEARCHPATH)
{
const rtl::OUString PATH1;
OUString PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
rtl_uString * pSearchPath = 0;
osl_getEnvironment (PATH.pData, &pSearchPath);
if (pSearchPath)
{
rtl_uString * pSearchResult = 0;
osl_searchPath (ustrImageName, pSearchPath, &pSearchResult);
if (pSearchResult)
{
rtl_uString_assign (ustrImageName, pSearchResult);
rtl_uString_release (pSearchResult);
}
rtl_uString_release (pSearchPath);
}
}
#endif
if ( ustrImageName && ustrImageName->length )
{
FileURLToPath( szImagePath, PATH_MAX, ustrImageName );
}
if ( ustrWorkDir != 0 && ustrWorkDir->length )
{
FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
pszWorkDir = szWorkDir;
}
if ( pArguments == 0 && nArguments > 0 )
{
pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) );
}
for ( index = 0 ; index < nArguments ; ++index )
{
rtl_String* strArg =0;
rtl_uString2String( &strArg,
rtl_uString_getStr(ustrArguments[index]),
rtl_uString_getLength(ustrArguments[index]),
osl_getThreadTextEncoding(),
OUSTRING_TO_OSTRING_CVTFLAGS );
pArguments[index]=strdup(rtl_string_getStr(strArg));
rtl_string_release(strArg);
pArguments[index+1]=0;
}
for ( index = 0 ; index < nEnvironmentVars ; ++index )
{
rtl_String* strEnv=0;
if ( pEnvironment == 0 )
{
pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) );
}
rtl_uString2String( &strEnv,
rtl_uString_getStr(ustrEnvironment[index]),
rtl_uString_getLength(ustrEnvironment[index]),
osl_getThreadTextEncoding(),
OUSTRING_TO_OSTRING_CVTFLAGS );
pEnvironment[index]=strdup(rtl_string_getStr(strEnv));
rtl_string_release(strEnv);
pEnvironment[index+1]=0;
}
int rc, pid;
int saveOutput = -1, saveInput = -1, saveError = -1;
int stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };
FILE *i, *o, *e;
if (pInputWrite)
pipe( stdInput);
if (pOutputRead)
pipe( stdOutput);
if (pErrorRead)
pipe( stdError);
fcntl( stdInput[0], F_SETFD, FD_CLOEXEC);
fcntl( stdInput[1], F_SETFD, FD_CLOEXEC);
fcntl( stdOutput[0], F_SETFD, FD_CLOEXEC);
fcntl( stdOutput[1], F_SETFD, FD_CLOEXEC);
fcntl( stdError[0], F_SETFD, FD_CLOEXEC);
fcntl( stdError[1], F_SETFD, FD_CLOEXEC);
saveInput = dup( STDIN_FILENO);
fcntl( saveInput, F_SETFD, FD_CLOEXEC);
dup2( stdInput[0], STDIN_FILENO );
close( stdInput[0] );
saveOutput = dup( STDOUT_FILENO);
fcntl( saveOutput, F_SETFD, FD_CLOEXEC);
dup2( stdOutput[1], STDOUT_FILENO );
close( stdOutput[1] );
saveError = dup( STDERR_FILENO);
fcntl( saveError, F_SETFD, FD_CLOEXEC);
dup2( stdError[1], STDERR_FILENO );
close( stdError[1] );
Error = osl_psz_executeProcess(szImagePath,
pArguments,
Options,
Security,
pszWorkDir,
pEnvironment,
pProcess,
pInputWrite,
pOutputRead,
pErrorRead
);
if ( pInputWrite )
*(pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
if ( pOutputRead )
*(pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
if ( pErrorRead )
*(pErrorRead) = osl_createFileHandleFromFD( stdError[0] );
// restore handles
dup2( saveInput, STDIN_FILENO);
close( saveInput);
dup2( saveOutput, STDOUT_FILENO);
close( saveOutput);
dup2( saveError, STDERR_FILENO);
close( saveError);
if ( pArguments != 0 )
{
for ( index = 0 ; index < nArguments ; ++index )
{
if ( pArguments[index] != 0 )
{
free(pArguments[index]);
}
}
free(pArguments);
}
if ( pEnvironment != 0 )
{
for ( index = 0 ; index < nEnvironmentVars ; ++index )
{
if ( pEnvironment[index] != 0 )
{
free(pEnvironment[index]);
}
}
free(pEnvironment);
}
return Error;
}
/**********************************************
osl_executeProcess
*********************************************/
oslProcessError SAL_CALL osl_executeProcess(
rtl_uString *ustrImageName,
rtl_uString *ustrArguments[],
sal_uInt32 nArguments,
oslProcessOption Options,
oslSecurity Security,
rtl_uString *ustrWorkDir,
rtl_uString *ustrEnvironment[],
sal_uInt32 nEnvironmentVars,
oslProcess *pProcess
)
{
return osl_executeProcess_WithRedirectedIO(
ustrImageName,
ustrArguments,
nArguments,
Options,
Security,
ustrWorkDir,
ustrEnvironment,
nEnvironmentVars,
pProcess,
NULL,
NULL,
NULL
);
}
/**********************************************
osl_psz_executeProcess
*********************************************/
oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
sal_Char *pszArguments[],
oslProcessOption Options,
oslSecurity Security,
sal_Char *pszDirectory,
sal_Char *pszEnvironments[],
oslProcess *pProcess,
oslFileHandle *pInputWrite,
oslFileHandle *pOutputRead,
oslFileHandle *pErrorRead
)
{
ULONG ulSessID = 0; /* Session ID returned */
PID pidProcess;
APIRET rc;
sal_Char* pStr;
sal_Char* args;
sal_Char* envs;
int i;
int n = 1;
oslProcessImpl* pProcImpl;
ULONG nAppType, nOwnAppType;
ULONG nCurrentDisk, nDriveMap, nBufSize;
int first = 0;
sal_Char path[ _MAX_PATH ];
sal_Char currentDir[ _MAX_PATH ];
sal_Char ownfilename[ _MAX_PATH ];
RESULTCODES resultCode;
char** p;
/* get imagename from arg list, if not specified */
if (pszImageName == NULL)
pszImageName = pszArguments[first++];
OSL_ASSERT(pszImageName != NULL);
/* check application type */
rc = DosQueryAppType( (PCSZ) pszImageName, &nAppType );
if( rc != NO_ERROR )
{
if( (rc == ERROR_FILE_NOT_FOUND) || (rc == ERROR_PATH_NOT_FOUND) )
return osl_Process_E_NotFound;
else
return osl_Process_E_Unknown;
}
/* backup current disk information */
if(DosQueryCurrentDisk(&nCurrentDisk, &nDriveMap))
{
nCurrentDisk = 0;
}
/* backup current directory information */
nBufSize = _MAX_PATH;
if(DosQueryCurrentDir(0, (BYTE*)currentDir, &nBufSize))
{
*currentDir = '\0';
}
/* change to working directory */
if(pszDirectory && pszDirectory[1] == ':')
{
BYTE nDrive = toupper(pszDirectory[0]) - 'A' + 1;
if(NO_ERROR == DosSetDefaultDisk(nDrive))
{
DosSetCurrentDir((PSZ) pszDirectory);
}
}
/* query current executable filename and application type */
{
CHAR szName[CCHMAXPATH];
PPIB ppib;
PTIB ptib;
APIRET rc;
rc = DosGetInfoBlocks(&ptib, &ppib);
rc = DosQueryModuleName(ppib->pib_hmte, sizeof(szName), szName);
DosQueryAppType( (PCSZ)szName, &nOwnAppType );
}
/* combination of flags WAIT and DETACHED not supported */
if( (Options & osl_Process_DETACHED) && (Options & osl_Process_WAIT) )
Options &= !osl_Process_DETACHED;
/* start in same session if possible and detached flag not set */
if( ((nAppType & 0x00000007) == (nOwnAppType & 0x00000007))
/* && ((Options & osl_Process_DETACHED) == 0) */ )
{
CHAR szbuf[CCHMAXPATH];
/* calculate needed space for arguments */
n = strlen( pszImageName ) + 1;
if( pszArguments )
for (i = first; pszArguments[i] != NULL; i++)
n += strlen(pszArguments[i]) + 1;
/* allocate space for arguments */
args = (sal_Char*)malloc(n + 1);
pStr = args;
/* add program name as first string to arguments */
memcpy(pStr, pszImageName, strlen( pszImageName ) );
pStr += strlen( pszImageName );
*pStr++ = '\0';
/* add given strings to arguments */
if( pszArguments )
for (i = first; pszArguments[i] != NULL; i++)
{
memcpy(pStr, pszArguments[i], strlen( pszArguments[i] ) );
pStr += strlen( pszArguments[i] );
if (pszArguments[i+1] != NULL)
*pStr++ = ' ';
}
/* set end marker for arguments */
*pStr++ = '\0';
*pStr = '\0';
OSL_TRACE( "osl_executeProcess with DosExecPgm (args: %s)\n", args );
/* calculate needed space for environment: since enviroment var search
is a linear scan of the current enviroment, we place new variables
before existing ones; so the child will find new definitions before
olders; this doesn't require us to replace existing vars */
// existing enviroment size
n = 0;
p = environ;
while( *p)
{
int l = strlen( *p);
n += l + 1;
p++;
}
// new env size (if exists)
if( pszEnvironments )
{
for (i = 0; pszEnvironments[i] != NULL; i++)
n += strlen(pszEnvironments[i]) + 1;
}
/* allocate space for environment */
envs = (sal_Char*)malloc(n + 1);
pStr = envs;
// add new vars
if( pszEnvironments )
{
/* add given strings to environment */
for (i = 0; pszEnvironments[i] != NULL; i++)
{
memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
pStr += strlen( pszEnvironments[i] );
*pStr++ = '\0';
}
}
// add existing vars
p = environ;
while( *p)
{
memcpy(pStr, *p, strlen( *p ) );
pStr += strlen( *p );
*pStr++ = '\0';
p++;
}
/* set end marker for environment */
*pStr = '\0';
if(Options & osl_Process_DETACHED)
{
rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_BACKGROUND,
(PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
}
else
{
rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_ASYNCRESULT,
(PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
}
pidProcess = resultCode.codeTerminate;
/* cleanup */
free(envs);
free(args);
/* error handling */
if( rc != NO_ERROR )
return osl_Process_E_Unknown;
}
else
{
STARTDATA SData = { 0 };
UCHAR achObjBuf[ 256 ] = { 0 };
/* combine arguments separated by spaces */
if( pszArguments )
{
for (i = first; pszArguments[i] != NULL; i++)
n += strlen(pszArguments[i]) + 1;
// YD DosStartSession requires low-mem buffers!
args = (sal_Char*)_tmalloc(n);
*args = '\0';
for (i = first; pszArguments[i] != NULL; i++)
{
strcat(args, pszArguments[i]);
strcat(args, " ");
}
}
else
args = NULL;
/* combine environment separated by NULL */
if( pszEnvironments )
{
for (i = 0; pszEnvironments[i] != NULL; i++)
n += strlen(pszEnvironments[i]) + 1;
// YD DosStartSession requires low-mem buffers!
envs = (sal_Char*)_tmalloc(n + 1);
pStr = (sal_Char*)envs;
for (i = 0; pszEnvironments[i] != NULL; i++)
{
memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
pStr += strlen( pszEnvironments[i] );
*pStr = '\0';
pStr++;
}
*pStr = '\0';
}
else
envs = NULL;
/* initialize data structure */
memset( &SData, 0, sizeof( STARTDATA ) );
SData.Length = sizeof(STARTDATA);
OSL_TRACE( "osl_executeProcess with DosStartSession (args: %s)\n", args );
/* OS/2 Application ? */
if(nAppType & 0x00000007)
{
/* inherit options from parent */
SData.InheritOpt = SSF_INHERTOPT_PARENT;
switch (Options & (osl_Process_NORMAL | osl_Process_MINIMIZED |
osl_Process_MAXIMIZED | osl_Process_FULLSCREEN))
{
case osl_Process_MINIMIZED:
SData.SessionType = SSF_TYPE_DEFAULT;
SData.PgmControl |= SSF_CONTROL_MINIMIZE;
break;
case osl_Process_MAXIMIZED:
SData.SessionType = SSF_TYPE_DEFAULT;
SData.PgmControl |= SSF_CONTROL_MAXIMIZE;
break;
case osl_Process_FULLSCREEN:
SData.SessionType = SSF_TYPE_FULLSCREEN;
break;
default:
SData.SessionType = SSF_TYPE_DEFAULT;
} /* switch */
}
if( Options & osl_Process_DETACHED )
{
/* start an independent session */
SData.Related = SSF_RELATED_INDEPENDENT;
SData.TermQ = NULL;
}
else
{
/* start a child session and set Termination Queue */
SData.Related = SSF_RELATED_CHILD;
if(! bInitSessionTerm)
bInitSessionTerm = InitSessionTerm();
SData.TermQ = (BYTE*) SessionTermQueueName;
}
SData.FgBg = SSF_FGBG_FORE; /* start session in foreground */
SData.TraceOpt = SSF_TRACEOPT_NONE; /* No trace */
SData.PgmTitle = NULL;
SData.PgmInputs = (BYTE*)args;
SData.PgmName = (PSZ) pszImageName;
SData.Environment = (BYTE*)envs;
if( Options & osl_Process_HIDDEN )
SData.PgmControl |= SSF_CONTROL_INVISIBLE;
else
SData.PgmControl |= SSF_CONTROL_VISIBLE;
SData.ObjectBuffer = (PSZ) achObjBuf;
SData.ObjectBuffLen = (ULONG) sizeof(achObjBuf);
/* Start the session */
rc = DosStartSession( &SData, &ulSessID, &pidProcess );
/* ignore error "session started in background" */
if( rc == ERROR_SMG_START_IN_BACKGROUND )
rc = NO_ERROR;
if(envs)
_tfree(envs);
if(args)
_tfree(args);
if( rc != NO_ERROR )
return osl_Process_E_Unknown;
} /* else */
/* restore current disk */
if(nCurrentDisk)
{
DosSetDefaultDisk(nCurrentDisk);
}
/* restore current drive information */
if(*currentDir)
{
DosSetCurrentDir((PCSZ)currentDir);
}
/* allocate intern process structure and store child process ID */
pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
pProcImpl->pProcess = pidProcess;
pProcImpl->nSessionID = ulSessID;
pProcImpl->bResultCodeValid = FALSE;
if( Options & osl_Process_WAIT )
osl_joinProcess(pProcImpl);
*pProcess = (oslProcess)pProcImpl;
if( rc == NO_ERROR )
return osl_Process_E_None;
else
return osl_Process_E_Unknown;
}
/*----------------------------------------------------------------------------*/
oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
{
if (Process == NULL)
return osl_Process_E_Unknown;
/* Stop the session */
DosStopSession( STOP_SESSION_SPECIFIED, ((oslProcessImpl*)Process)->nSessionID );
return osl_Process_E_None;
}
/*----------------------------------------------------------------------------*/
oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
{
HANDLE hProcess;
oslProcessImpl* pProcImpl;
/* check, if given PID is a valid process */
if (FALSE)
{
pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
/*
pProcImpl->pProcess = pidProcess;
pProcImpl->nSessionID = ulSessID;
*/
}
else
pProcImpl = NULL;
return (pProcImpl);
}
/*----------------------------------------------------------------------------*/
void SAL_CALL osl_freeProcessHandle(oslProcess Process)
{
/* free intern process structure */
if (Process != NULL)
free((oslProcessImpl*)Process);
}
/*----------------------------------------------------------------------------*/
oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
{
oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
APIRET rc;
if (Process == NULL)
return osl_Process_E_Unknown;
/* process of same session ? */
if( pProcImpl->nSessionID == 0 )
{
RESULTCODES resultCode;
PID pidEnded;
rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
&pidEnded, pProcImpl->pProcess );
if( rc == NO_ERROR )
{
pProcImpl->nResultCode = resultCode.codeResult;
pProcImpl->bResultCodeValid = TRUE;
return osl_Process_E_None;
}
}
else
{
ULONG pcbData, ulElement = 0;
REQUESTDATA rdData;
BYTE bPriority;
struct {
USHORT SessionID;
USHORT ReturnValue;
} *pvBuffer;
/* search/wait for the correct entry in termination queue */
while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
(PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
&bPriority, NULLHANDLE )) == NO_ERROR )
{
if( pvBuffer->SessionID == pProcImpl->nSessionID )
{
pProcImpl->nResultCode = pvBuffer->ReturnValue;
pProcImpl->bResultCodeValid = TRUE;
/* remove item from queue */
rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
(PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
&bPriority, NULLHANDLE );
if( rc == NO_ERROR )
return osl_Process_E_None;
else
return osl_Process_E_Unknown;
}
} /* while */
}
return osl_Process_E_Unknown;
}
/***************************************************************************/
//YD FIXME incomplete!
oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
{
return osl_joinProcess( Process);
}
/*----------------------------------------------------------------------------*/
oslProcessError SAL_CALL osl_getCommandArgs( sal_Char* pszBuffer, sal_uInt32 Max)
{
static int CmdLen = -1;
static sal_Char CmdLine[_MAX_CMD];
OSL_ASSERT(pszBuffer);
OSL_ASSERT(Max > 1);
/* Query commandline during first call of function only */
if (CmdLen < 0)
{
sal_Bool bEscaped = sal_False;
sal_Bool bSeparated = sal_True;
sal_Char* pszBufferOrg = pszBuffer;
sal_Char* pszCmdLine;
/* get pointer to commandline */
{
PTIB pptib = NULL;
PPIB pppib = NULL;
DosGetInfoBlocks(&pptib, &pppib);
pszCmdLine = pppib->pib_pchcmd;
}
/* skip first string */
while( *pszCmdLine )
pszCmdLine++;
/* concatenate commandline arguments for the given string */
Max -= 2;
while ( !((*pszCmdLine == '\0') && (*(pszCmdLine + 1) == '\0')) && (Max > 0))
{
/*
* C-Runtime expects char to be unsigned and so to be
* preceeded with 00 instead of FF when converting to int
*/
int n = *((unsigned char *) pszCmdLine);
if (! (isspace(n) || (*pszCmdLine == '\0')) )
{
if (*pszCmdLine == '"')
{
if (*(pszCmdLine + 1) != '"')
bEscaped = ! bEscaped;
else
{
pszCmdLine++;
*pszBuffer++ = *pszCmdLine;
Max--;
}
}
else
{
*pszBuffer++ = *pszCmdLine;
Max--;
}
bSeparated = sal_False;
}
else
{
if (bEscaped)
*pszBuffer++ = *pszCmdLine;
else
if (! bSeparated)
{
*pszBuffer++ = '\0';
bSeparated = sal_True;
}
Max--;
}
pszCmdLine++;
}
*pszBuffer++ = '\0';
*pszBuffer++ = '\0';
/* restore pointer and save commandline for next query */
CmdLen = pszBuffer - pszBufferOrg;
pszBuffer = pszBufferOrg;
memcpy( CmdLine, pszBuffer, CmdLen );
}
else
memcpy( pszBuffer, CmdLine, CmdLen );
OSL_TRACE( "osl_getCommandArgs (args: %s)\n", pszBuffer );
return osl_Process_E_None;
}
/*----------------------------------------------------------------------------*/
oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields,
oslProcessInfo* pInfo)
{
if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
return osl_Process_E_Unknown;
pInfo->Fields = 0;
if (Fields & osl_Process_IDENTIFIER)
{
if( Process == NULL )
{
PTIB pptib = NULL;
PPIB pppib = NULL;
DosGetInfoBlocks( &pptib, &pppib );
pInfo->Ident = pppib->pib_ulpid;
}
else
pInfo->Ident = ((oslProcessImpl*)Process)->pProcess;
pInfo->Fields |= osl_Process_IDENTIFIER;
}
if (Fields & osl_Process_EXITCODE)
{
oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
if( pProcImpl->bResultCodeValid )
{
pInfo->Code = pProcImpl->nResultCode;
pInfo->Fields |= osl_Process_EXITCODE;
}
else
{
APIRET rc;
if( pProcImpl->nSessionID == 0 )
{
RESULTCODES resultCode;
PID pidEnded;
rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
&pidEnded, pProcImpl->pProcess );
if( rc == NO_ERROR )
{
pProcImpl->nResultCode = resultCode.codeResult;
pProcImpl->bResultCodeValid = TRUE;
pInfo->Code = pProcImpl->nResultCode;
pInfo->Fields |= osl_Process_EXITCODE;
return osl_Process_E_None;
}
}
else
{
ULONG pcbData, ulElement = 0;
REQUESTDATA rdData;
BYTE bPriority;
struct {
USHORT SessionID;
USHORT ReturnValue;
} *pvBuffer;
/* search/wait for the correct entry in termination queue */
while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
(PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
&bPriority, NULLHANDLE )) == NO_ERROR )
{
if( pvBuffer->SessionID == pProcImpl->nSessionID )
{
pProcImpl->nResultCode = pvBuffer->ReturnValue;
pProcImpl->bResultCodeValid = TRUE;
pInfo->Code = pProcImpl->nResultCode;
pInfo->Fields |= osl_Process_EXITCODE;
/* remove item from queue */
rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
(PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
&bPriority, NULLHANDLE );
break;
}
}
}
}
}
if (Fields & osl_Process_HEAPUSAGE)
{
}
if (Fields & osl_Process_CPUTIMES)
{
}
return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
}