merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / os2 / process.c
blobe83552192bfb10c43aa696e36d90baf4d3f681c7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "system.h"
29 #include <osl/thread.h>
31 #include <osl/diagnose.h>
32 //#include <osl/socket.h>
34 #ifndef _OSL_FILE_PATH_HELPER_H_
35 #include "file_path_helper.h"
36 #endif
38 #include "procimpl.h"
39 //#include "sockimpl.h"
40 //#include "secimpl.h"
42 #include <ctype.h>
44 //#ifndef _RTL_USTRING_HXX_
45 #include <rtl/ustring.hxx>
46 //#endif
48 // for exception logging
49 #include <stdio.h>
50 #include <setjmp.h>
51 #include "helpers/except.h"
54 #define MAX_ARGS 255
55 #define PIPENAMEMASK "\\PIPE\\OSL_PIPE_%u"
56 #define SEMNAMEMASK "\\SEM32\\OSL_SEM_%u"
58 typedef enum {
59 MSG_DATA,
60 MSG_END,
61 MSG_ACK,
62 MSG_REL,
63 MSG_UNKNOWN
64 } MessageType;
66 typedef struct {
67 MessageType m_Type;
68 oslDescriptorFlag m_Flags;
69 oslDescriptorType m_Data;
70 HANDLE m_Value;
71 } Message;
73 typedef struct {
74 HPIPE m_hPipe;
75 } Pipe;
77 typedef struct _oslSocketCallbackArg {
78 HANDLE m_socket;
79 Pipe* m_pipe;
80 } oslSocketCallbackArg;
82 /* process termination queue */
83 static sal_Bool bInitSessionTerm = sal_False;
84 static const sal_Char * const SessionTermQueueName = "\\QUEUES\\SESSIONS.QUE";
85 static HQUEUE SessionTermQueue;
87 /******************************************************************************
89 * Function Declarations
91 *****************************************************************************/
93 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
94 sal_Char *pszArguments[],
95 oslProcessOption Options,
96 oslSecurity Security,
97 sal_Char *pszDirectory,
98 sal_Char *pszEnvironments[],
99 oslProcess *pProcess,
100 oslFileHandle *pInputWrite,
101 oslFileHandle *pOutputRead,
102 oslFileHandle *pErrorRead );
104 /* implemented in file.c */
105 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
107 static sal_Bool InitSessionTerm( void )
109 DosCreateQueue( &SessionTermQueue, QUE_FIFO, (PCSZ) SessionTermQueueName );
111 return sal_True;
114 /******************************************************************************
116 * Functions for starting a process
118 *****************************************************************************/
120 /**********************************************
121 osl_executeProcess_WithRedirectedIO
122 *********************************************/
124 oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
125 rtl_uString *ustrImageName,
126 rtl_uString *ustrArguments[],
127 sal_uInt32 nArguments,
128 oslProcessOption Options,
129 oslSecurity Security,
130 rtl_uString *ustrWorkDir,
131 rtl_uString *ustrEnvironment[],
132 sal_uInt32 nEnvironmentVars,
133 oslProcess *pProcess,
134 oslFileHandle *pInputWrite,
135 oslFileHandle *pOutputRead,
136 oslFileHandle *pErrorRead
140 oslProcessError Error;
141 sal_Char* pszWorkDir=0;
142 sal_Char** pArguments=0;
143 sal_Char** pEnvironment=0;
144 unsigned int index;
146 char szImagePath[PATH_MAX] = "";
147 char szWorkDir[PATH_MAX] = "";
149 #if 0
150 if (Options & osl_Process_SEARCHPATH)
152 const rtl::OUString PATH1;
153 OUString PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
155 rtl_uString * pSearchPath = 0;
156 osl_getEnvironment (PATH.pData, &pSearchPath);
157 if (pSearchPath)
159 rtl_uString * pSearchResult = 0;
160 osl_searchPath (ustrImageName, pSearchPath, &pSearchResult);
161 if (pSearchResult)
163 rtl_uString_assign (ustrImageName, pSearchResult);
164 rtl_uString_release (pSearchResult);
166 rtl_uString_release (pSearchPath);
169 #endif
171 if ( ustrImageName && ustrImageName->length )
173 FileURLToPath( szImagePath, PATH_MAX, ustrImageName );
176 if ( ustrWorkDir != 0 && ustrWorkDir->length )
178 FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
179 pszWorkDir = szWorkDir;
182 if ( pArguments == 0 && nArguments > 0 )
184 pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) );
188 for ( index = 0 ; index < nArguments ; ++index )
190 rtl_String* strArg =0;
193 rtl_uString2String( &strArg,
194 rtl_uString_getStr(ustrArguments[index]),
195 rtl_uString_getLength(ustrArguments[index]),
196 osl_getThreadTextEncoding(),
197 OUSTRING_TO_OSTRING_CVTFLAGS );
199 pArguments[index]=strdup(rtl_string_getStr(strArg));
200 rtl_string_release(strArg);
201 pArguments[index+1]=0;
204 for ( index = 0 ; index < nEnvironmentVars ; ++index )
206 rtl_String* strEnv=0;
208 if ( pEnvironment == 0 )
210 pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) );
213 rtl_uString2String( &strEnv,
214 rtl_uString_getStr(ustrEnvironment[index]),
215 rtl_uString_getLength(ustrEnvironment[index]),
216 osl_getThreadTextEncoding(),
217 OUSTRING_TO_OSTRING_CVTFLAGS );
219 pEnvironment[index]=strdup(rtl_string_getStr(strEnv));
220 rtl_string_release(strEnv);
221 pEnvironment[index+1]=0;
224 int rc, pid;
225 int saveOutput = -1, saveInput = -1, saveError = -1;
226 int stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };
227 FILE *i, *o, *e;
229 if (pInputWrite)
230 pipe( stdInput);
231 if (pOutputRead)
232 pipe( stdOutput);
233 if (pErrorRead)
234 pipe( stdError);
236 fcntl( stdInput[0], F_SETFD, FD_CLOEXEC);
237 fcntl( stdInput[1], F_SETFD, FD_CLOEXEC);
238 fcntl( stdOutput[0], F_SETFD, FD_CLOEXEC);
239 fcntl( stdOutput[1], F_SETFD, FD_CLOEXEC);
240 fcntl( stdError[0], F_SETFD, FD_CLOEXEC);
241 fcntl( stdError[1], F_SETFD, FD_CLOEXEC);
243 saveInput = dup( STDIN_FILENO);
244 fcntl( saveInput, F_SETFD, FD_CLOEXEC);
245 dup2( stdInput[0], STDIN_FILENO );
246 close( stdInput[0] );
248 saveOutput = dup( STDOUT_FILENO);
249 fcntl( saveOutput, F_SETFD, FD_CLOEXEC);
250 dup2( stdOutput[1], STDOUT_FILENO );
251 close( stdOutput[1] );
253 saveError = dup( STDERR_FILENO);
254 fcntl( saveError, F_SETFD, FD_CLOEXEC);
255 dup2( stdError[1], STDERR_FILENO );
256 close( stdError[1] );
258 Error = osl_psz_executeProcess(szImagePath,
259 pArguments,
260 Options,
261 Security,
262 pszWorkDir,
263 pEnvironment,
264 pProcess,
265 pInputWrite,
266 pOutputRead,
267 pErrorRead
270 if ( pInputWrite )
271 *(pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
273 if ( pOutputRead )
274 *(pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
276 if ( pErrorRead )
277 *(pErrorRead) = osl_createFileHandleFromFD( stdError[0] );
279 // restore handles
280 dup2( saveInput, STDIN_FILENO);
281 close( saveInput);
282 dup2( saveOutput, STDOUT_FILENO);
283 close( saveOutput);
284 dup2( saveError, STDERR_FILENO);
285 close( saveError);
287 if ( pArguments != 0 )
289 for ( index = 0 ; index < nArguments ; ++index )
291 if ( pArguments[index] != 0 )
293 free(pArguments[index]);
296 free(pArguments);
299 if ( pEnvironment != 0 )
301 for ( index = 0 ; index < nEnvironmentVars ; ++index )
303 if ( pEnvironment[index] != 0 )
305 free(pEnvironment[index]);
308 free(pEnvironment);
311 return Error;
314 /**********************************************
315 osl_executeProcess
316 *********************************************/
318 oslProcessError SAL_CALL osl_executeProcess(
319 rtl_uString *ustrImageName,
320 rtl_uString *ustrArguments[],
321 sal_uInt32 nArguments,
322 oslProcessOption Options,
323 oslSecurity Security,
324 rtl_uString *ustrWorkDir,
325 rtl_uString *ustrEnvironment[],
326 sal_uInt32 nEnvironmentVars,
327 oslProcess *pProcess
330 return osl_executeProcess_WithRedirectedIO(
331 ustrImageName,
332 ustrArguments,
333 nArguments,
334 Options,
335 Security,
336 ustrWorkDir,
337 ustrEnvironment,
338 nEnvironmentVars,
339 pProcess,
340 NULL,
341 NULL,
342 NULL
346 /**********************************************
347 osl_psz_executeProcess
348 *********************************************/
350 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
351 sal_Char *pszArguments[],
352 oslProcessOption Options,
353 oslSecurity Security,
354 sal_Char *pszDirectory,
355 sal_Char *pszEnvironments[],
356 oslProcess *pProcess,
357 oslFileHandle *pInputWrite,
358 oslFileHandle *pOutputRead,
359 oslFileHandle *pErrorRead
362 ULONG ulSessID = 0; /* Session ID returned */
363 PID pidProcess;
364 APIRET rc;
365 sal_Char* pStr;
366 sal_Char* args;
367 sal_Char* envs;
368 int i;
369 int n = 1;
370 oslProcessImpl* pProcImpl;
371 ULONG nAppType, nOwnAppType;
372 ULONG nCurrentDisk, nDriveMap, nBufSize;
373 int first = 0;
374 sal_Char path[ _MAX_PATH ];
375 sal_Char currentDir[ _MAX_PATH ];
376 sal_Char ownfilename[ _MAX_PATH ];
377 RESULTCODES resultCode;
378 char** p;
380 /* get imagename from arg list, if not specified */
381 if (pszImageName == NULL)
382 pszImageName = pszArguments[first++];
384 OSL_ASSERT(pszImageName != NULL);
386 /* check application type */
387 rc = DosQueryAppType( (PCSZ) pszImageName, &nAppType );
388 if( rc != NO_ERROR )
390 if( (rc == ERROR_FILE_NOT_FOUND) || (rc == ERROR_PATH_NOT_FOUND) )
391 return osl_Process_E_NotFound;
392 else
393 return osl_Process_E_Unknown;
396 /* backup current disk information */
397 if(DosQueryCurrentDisk(&nCurrentDisk, &nDriveMap))
399 nCurrentDisk = 0;
402 /* backup current directory information */
403 nBufSize = _MAX_PATH;
404 if(DosQueryCurrentDir(0, (BYTE*)currentDir, &nBufSize))
406 *currentDir = '\0';
409 /* change to working directory */
410 if(pszDirectory && pszDirectory[1] == ':')
412 BYTE nDrive = toupper(pszDirectory[0]) - 'A' + 1;
414 if(NO_ERROR == DosSetDefaultDisk(nDrive))
416 DosSetCurrentDir((PSZ) pszDirectory);
420 /* query current executable filename and application type */
422 CHAR szName[CCHMAXPATH];
423 PPIB ppib;
424 PTIB ptib;
425 APIRET rc;
426 rc = DosGetInfoBlocks(&ptib, &ppib);
427 rc = DosQueryModuleName(ppib->pib_hmte, sizeof(szName), szName);
428 DosQueryAppType( (PCSZ)szName, &nOwnAppType );
431 /* combination of flags WAIT and DETACHED not supported */
432 if( (Options & osl_Process_DETACHED) && (Options & osl_Process_WAIT) )
433 Options &= !osl_Process_DETACHED;
435 /* start in same session if possible and detached flag not set */
436 if( ((nAppType & 0x00000007) == (nOwnAppType & 0x00000007))
437 /* && ((Options & osl_Process_DETACHED) == 0) */ )
439 CHAR szbuf[CCHMAXPATH];
441 /* calculate needed space for arguments */
442 n = strlen( pszImageName ) + 1;
443 if( pszArguments )
444 for (i = first; pszArguments[i] != NULL; i++)
445 n += strlen(pszArguments[i]) + 1;
447 /* allocate space for arguments */
448 args = (sal_Char*)malloc(n + 1);
449 pStr = args;
451 /* add program name as first string to arguments */
452 memcpy(pStr, pszImageName, strlen( pszImageName ) );
453 pStr += strlen( pszImageName );
454 *pStr++ = '\0';
456 /* add given strings to arguments */
457 if( pszArguments )
458 for (i = first; pszArguments[i] != NULL; i++)
460 memcpy(pStr, pszArguments[i], strlen( pszArguments[i] ) );
461 pStr += strlen( pszArguments[i] );
462 if (pszArguments[i+1] != NULL)
463 *pStr++ = ' ';
466 /* set end marker for arguments */
467 *pStr++ = '\0';
468 *pStr = '\0';
470 OSL_TRACE( "osl_executeProcess with DosExecPgm (args: %s)\n", args );
472 /* calculate needed space for environment: since enviroment var search
473 is a linear scan of the current enviroment, we place new variables
474 before existing ones; so the child will find new definitions before
475 olders; this doesn't require us to replace existing vars */
476 // existing enviroment size
477 n = 0;
478 p = environ;
479 while( *p)
481 int l = strlen( *p);
482 n += l + 1;
483 p++;
485 // new env size (if exists)
486 if( pszEnvironments )
488 for (i = 0; pszEnvironments[i] != NULL; i++)
489 n += strlen(pszEnvironments[i]) + 1;
491 /* allocate space for environment */
492 envs = (sal_Char*)malloc(n + 1);
493 pStr = envs;
495 // add new vars
496 if( pszEnvironments )
498 /* add given strings to environment */
499 for (i = 0; pszEnvironments[i] != NULL; i++)
501 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
502 pStr += strlen( pszEnvironments[i] );
503 *pStr++ = '\0';
506 // add existing vars
507 p = environ;
508 while( *p)
510 memcpy(pStr, *p, strlen( *p ) );
511 pStr += strlen( *p );
512 *pStr++ = '\0';
513 p++;
515 /* set end marker for environment */
516 *pStr = '\0';
519 if(Options & osl_Process_DETACHED)
521 rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_BACKGROUND,
522 (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
524 else
526 rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_ASYNCRESULT,
527 (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
530 pidProcess = resultCode.codeTerminate;
532 /* cleanup */
533 free(envs);
534 free(args);
536 /* error handling */
537 if( rc != NO_ERROR )
538 return osl_Process_E_Unknown;
541 else
543 STARTDATA SData = { 0 };
544 UCHAR achObjBuf[ 256 ] = { 0 };
546 /* combine arguments separated by spaces */
547 if( pszArguments )
549 for (i = first; pszArguments[i] != NULL; i++)
550 n += strlen(pszArguments[i]) + 1;
551 // YD DosStartSession requires low-mem buffers!
552 args = (sal_Char*)_tmalloc(n);
553 *args = '\0';
554 for (i = first; pszArguments[i] != NULL; i++)
556 strcat(args, pszArguments[i]);
557 strcat(args, " ");
560 else
561 args = NULL;
563 /* combine environment separated by NULL */
564 if( pszEnvironments )
566 for (i = 0; pszEnvironments[i] != NULL; i++)
567 n += strlen(pszEnvironments[i]) + 1;
568 // YD DosStartSession requires low-mem buffers!
569 envs = (sal_Char*)_tmalloc(n + 1);
570 pStr = (sal_Char*)envs;
571 for (i = 0; pszEnvironments[i] != NULL; i++)
573 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
574 pStr += strlen( pszEnvironments[i] );
575 *pStr = '\0';
576 pStr++;
578 *pStr = '\0';
580 else
581 envs = NULL;
583 /* initialize data structure */
584 memset( &SData, 0, sizeof( STARTDATA ) );
585 SData.Length = sizeof(STARTDATA);
587 OSL_TRACE( "osl_executeProcess with DosStartSession (args: %s)\n", args );
589 /* OS/2 Application ? */
590 if(nAppType & 0x00000007)
593 /* inherit options from parent */
594 SData.InheritOpt = SSF_INHERTOPT_PARENT;
596 switch (Options & (osl_Process_NORMAL | osl_Process_MINIMIZED |
597 osl_Process_MAXIMIZED | osl_Process_FULLSCREEN))
599 case osl_Process_MINIMIZED:
600 SData.SessionType = SSF_TYPE_DEFAULT;
601 SData.PgmControl |= SSF_CONTROL_MINIMIZE;
602 break;
604 case osl_Process_MAXIMIZED:
605 SData.SessionType = SSF_TYPE_DEFAULT;
606 SData.PgmControl |= SSF_CONTROL_MAXIMIZE;
607 break;
609 case osl_Process_FULLSCREEN:
610 SData.SessionType = SSF_TYPE_FULLSCREEN;
611 break;
613 default:
614 SData.SessionType = SSF_TYPE_DEFAULT;
615 } /* switch */
619 if( Options & osl_Process_DETACHED )
621 /* start an independent session */
622 SData.Related = SSF_RELATED_INDEPENDENT;
623 SData.TermQ = NULL;
625 else
627 /* start a child session and set Termination Queue */
628 SData.Related = SSF_RELATED_CHILD;
630 if(! bInitSessionTerm)
631 bInitSessionTerm = InitSessionTerm();
633 SData.TermQ = (BYTE*) SessionTermQueueName;
636 SData.FgBg = SSF_FGBG_FORE; /* start session in foreground */
637 SData.TraceOpt = SSF_TRACEOPT_NONE; /* No trace */
639 SData.PgmTitle = NULL;
640 SData.PgmInputs = (BYTE*)args;
641 SData.PgmName = (PSZ) pszImageName;
642 SData.Environment = (BYTE*)envs;
644 if( Options & osl_Process_HIDDEN )
645 SData.PgmControl |= SSF_CONTROL_INVISIBLE;
646 else
647 SData.PgmControl |= SSF_CONTROL_VISIBLE;
649 SData.ObjectBuffer = (PSZ) achObjBuf;
650 SData.ObjectBuffLen = (ULONG) sizeof(achObjBuf);
653 /* Start the session */
654 rc = DosStartSession( &SData, &ulSessID, &pidProcess );
656 /* ignore error "session started in background" */
657 if( rc == ERROR_SMG_START_IN_BACKGROUND )
658 rc = NO_ERROR;
661 if(envs)
662 _tfree(envs);
663 if(args)
664 _tfree(args);
666 if( rc != NO_ERROR )
667 return osl_Process_E_Unknown;
669 } /* else */
672 /* restore current disk */
673 if(nCurrentDisk)
675 DosSetDefaultDisk(nCurrentDisk);
678 /* restore current drive information */
679 if(*currentDir)
681 DosSetCurrentDir((PCSZ)currentDir);
684 /* allocate intern process structure and store child process ID */
685 pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
686 pProcImpl->pProcess = pidProcess;
687 pProcImpl->nSessionID = ulSessID;
689 pProcImpl->bResultCodeValid = FALSE;
691 if( Options & osl_Process_WAIT )
692 osl_joinProcess(pProcImpl);
694 *pProcess = (oslProcess)pProcImpl;
696 if( rc == NO_ERROR )
697 return osl_Process_E_None;
698 else
700 return osl_Process_E_Unknown;
703 /*----------------------------------------------------------------------------*/
705 oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
707 if (Process == NULL)
708 return osl_Process_E_Unknown;
710 /* Stop the session */
711 DosStopSession( STOP_SESSION_SPECIFIED, ((oslProcessImpl*)Process)->nSessionID );
713 return osl_Process_E_None;
716 /*----------------------------------------------------------------------------*/
718 oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
720 HANDLE hProcess;
721 oslProcessImpl* pProcImpl;
723 /* check, if given PID is a valid process */
724 if (FALSE)
726 pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
728 pProcImpl->pProcess = pidProcess;
729 pProcImpl->nSessionID = ulSessID;
732 else
733 pProcImpl = NULL;
735 return (pProcImpl);
738 /*----------------------------------------------------------------------------*/
740 void SAL_CALL osl_freeProcessHandle(oslProcess Process)
742 /* free intern process structure */
743 if (Process != NULL)
744 free((oslProcessImpl*)Process);
747 /*----------------------------------------------------------------------------*/
749 oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
751 oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
752 APIRET rc;
754 if (Process == NULL)
755 return osl_Process_E_Unknown;
757 /* process of same session ? */
758 if( pProcImpl->nSessionID == 0 )
760 RESULTCODES resultCode;
761 PID pidEnded;
763 rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
764 &pidEnded, pProcImpl->pProcess );
766 if( rc == NO_ERROR )
768 pProcImpl->nResultCode = resultCode.codeResult;
769 pProcImpl->bResultCodeValid = TRUE;
771 return osl_Process_E_None;
774 else
776 ULONG pcbData, ulElement = 0;
777 REQUESTDATA rdData;
778 BYTE bPriority;
779 struct {
780 USHORT SessionID;
781 USHORT ReturnValue;
782 } *pvBuffer;
784 /* search/wait for the correct entry in termination queue */
785 while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
786 (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
787 &bPriority, NULLHANDLE )) == NO_ERROR )
790 if( pvBuffer->SessionID == pProcImpl->nSessionID )
792 pProcImpl->nResultCode = pvBuffer->ReturnValue;
793 pProcImpl->bResultCodeValid = TRUE;
795 /* remove item from queue */
796 rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
797 (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
798 &bPriority, NULLHANDLE );
800 if( rc == NO_ERROR )
801 return osl_Process_E_None;
802 else
803 return osl_Process_E_Unknown;
805 } /* while */
807 return osl_Process_E_Unknown;
810 /***************************************************************************/
812 //YD FIXME incomplete!
813 oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
815 return osl_joinProcess( Process);
818 /*----------------------------------------------------------------------------*/
820 oslProcessError SAL_CALL osl_getCommandArgs( sal_Char* pszBuffer, sal_uInt32 Max)
823 static int CmdLen = -1;
824 static sal_Char CmdLine[_MAX_CMD];
826 OSL_ASSERT(pszBuffer);
827 OSL_ASSERT(Max > 1);
829 /* Query commandline during first call of function only */
830 if (CmdLen < 0)
832 sal_Bool bEscaped = sal_False;
833 sal_Bool bSeparated = sal_True;
834 sal_Char* pszBufferOrg = pszBuffer;
835 sal_Char* pszCmdLine;
837 /* get pointer to commandline */
839 PTIB pptib = NULL;
840 PPIB pppib = NULL;
842 DosGetInfoBlocks(&pptib, &pppib);
843 pszCmdLine = pppib->pib_pchcmd;
846 /* skip first string */
847 while( *pszCmdLine )
848 pszCmdLine++;
850 /* concatenate commandline arguments for the given string */
851 Max -= 2;
852 while ( !((*pszCmdLine == '\0') && (*(pszCmdLine + 1) == '\0')) && (Max > 0))
855 * C-Runtime expects char to be unsigned and so to be
856 * preceeded with 00 instead of FF when converting to int
858 int n = *((unsigned char *) pszCmdLine);
859 if (! (isspace(n) || (*pszCmdLine == '\0')) )
861 if (*pszCmdLine == '"')
863 if (*(pszCmdLine + 1) != '"')
864 bEscaped = ! bEscaped;
865 else
867 pszCmdLine++;
868 *pszBuffer++ = *pszCmdLine;
869 Max--;
872 else
874 *pszBuffer++ = *pszCmdLine;
875 Max--;
877 bSeparated = sal_False;
879 else
881 if (bEscaped)
882 *pszBuffer++ = *pszCmdLine;
883 else
884 if (! bSeparated)
886 *pszBuffer++ = '\0';
887 bSeparated = sal_True;
889 Max--;
892 pszCmdLine++;
895 *pszBuffer++ = '\0';
896 *pszBuffer++ = '\0';
898 /* restore pointer and save commandline for next query */
899 CmdLen = pszBuffer - pszBufferOrg;
900 pszBuffer = pszBufferOrg;
901 memcpy( CmdLine, pszBuffer, CmdLen );
903 else
904 memcpy( pszBuffer, CmdLine, CmdLen );
906 OSL_TRACE( "osl_getCommandArgs (args: %s)\n", pszBuffer );
908 return osl_Process_E_None;
911 /*----------------------------------------------------------------------------*/
913 oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields,
914 oslProcessInfo* pInfo)
916 if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
917 return osl_Process_E_Unknown;
919 pInfo->Fields = 0;
921 if (Fields & osl_Process_IDENTIFIER)
923 if( Process == NULL )
925 PTIB pptib = NULL;
926 PPIB pppib = NULL;
928 DosGetInfoBlocks( &pptib, &pppib );
929 pInfo->Ident = pppib->pib_ulpid;
931 else
932 pInfo->Ident = ((oslProcessImpl*)Process)->pProcess;
934 pInfo->Fields |= osl_Process_IDENTIFIER;
937 if (Fields & osl_Process_EXITCODE)
939 oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
941 if( pProcImpl->bResultCodeValid )
943 pInfo->Code = pProcImpl->nResultCode;
944 pInfo->Fields |= osl_Process_EXITCODE;
946 else
948 APIRET rc;
950 if( pProcImpl->nSessionID == 0 )
952 RESULTCODES resultCode;
953 PID pidEnded;
955 rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
956 &pidEnded, pProcImpl->pProcess );
958 if( rc == NO_ERROR )
960 pProcImpl->nResultCode = resultCode.codeResult;
961 pProcImpl->bResultCodeValid = TRUE;
963 pInfo->Code = pProcImpl->nResultCode;
964 pInfo->Fields |= osl_Process_EXITCODE;
966 return osl_Process_E_None;
969 else
971 ULONG pcbData, ulElement = 0;
972 REQUESTDATA rdData;
973 BYTE bPriority;
974 struct {
975 USHORT SessionID;
976 USHORT ReturnValue;
977 } *pvBuffer;
979 /* search/wait for the correct entry in termination queue */
980 while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
981 (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
982 &bPriority, NULLHANDLE )) == NO_ERROR )
985 if( pvBuffer->SessionID == pProcImpl->nSessionID )
987 pProcImpl->nResultCode = pvBuffer->ReturnValue;
988 pProcImpl->bResultCodeValid = TRUE;
990 pInfo->Code = pProcImpl->nResultCode;
991 pInfo->Fields |= osl_Process_EXITCODE;
993 /* remove item from queue */
994 rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
995 (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
996 &bPriority, NULLHANDLE );
998 break;
1005 if (Fields & osl_Process_HEAPUSAGE)
1008 if (Fields & osl_Process_CPUTIMES)
1012 return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;