update dev300-m57
[ooovba.git] / sal / osl / os2 / process.c
blobd903edb68687ac5a1770804245aec5f70cce2c1f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: process.c,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "system.h"
32 #include <osl/thread.h>
34 #include <osl/diagnose.h>
35 //#include <osl/socket.h>
37 #ifndef _OSL_FILE_PATH_HELPER_H_
38 #include "file_path_helper.h"
39 #endif
41 #include "procimpl.h"
42 //#include "sockimpl.h"
43 //#include "secimpl.h"
45 #include <ctype.h>
47 //#ifndef _RTL_USTRING_HXX_
48 #include <rtl/ustring.hxx>
49 //#endif
51 // for exception logging
52 #include <stdio.h>
53 #include <setjmp.h>
54 #include "helpers/except.h"
57 #define MAX_ARGS 255
58 #define PIPENAMEMASK "\\PIPE\\OSL_PIPE_%u"
59 #define SEMNAMEMASK "\\SEM32\\OSL_SEM_%u"
61 typedef enum {
62 MSG_DATA,
63 MSG_END,
64 MSG_ACK,
65 MSG_REL,
66 MSG_UNKNOWN
67 } MessageType;
69 typedef struct {
70 MessageType m_Type;
71 oslDescriptorFlag m_Flags;
72 oslDescriptorType m_Data;
73 HANDLE m_Value;
74 } Message;
76 typedef struct {
77 HPIPE m_hPipe;
78 } Pipe;
80 typedef struct _oslSocketCallbackArg {
81 HANDLE m_socket;
82 Pipe* m_pipe;
83 } oslSocketCallbackArg;
85 /* process termination queue */
86 static sal_Bool bInitSessionTerm = sal_False;
87 static const sal_Char * const SessionTermQueueName = "\\QUEUES\\SESSIONS.QUE";
88 static HQUEUE SessionTermQueue;
90 /******************************************************************************
92 * Function Declarations
94 *****************************************************************************/
96 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
97 sal_Char *pszArguments[],
98 oslProcessOption Options,
99 oslSecurity Security,
100 sal_Char *pszDirectory,
101 sal_Char *pszEnvironments[],
102 oslProcess *pProcess,
103 oslFileHandle *pInputWrite,
104 oslFileHandle *pOutputRead,
105 oslFileHandle *pErrorRead );
107 /* implemented in file.c */
108 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
110 static sal_Bool InitSessionTerm( void )
112 DosCreateQueue( &SessionTermQueue, QUE_FIFO, (PCSZ) SessionTermQueueName );
114 return sal_True;
117 /******************************************************************************
119 * Functions for starting a process
121 *****************************************************************************/
123 /**********************************************
124 osl_executeProcess_WithRedirectedIO
125 *********************************************/
127 oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
128 rtl_uString *ustrImageName,
129 rtl_uString *ustrArguments[],
130 sal_uInt32 nArguments,
131 oslProcessOption Options,
132 oslSecurity Security,
133 rtl_uString *ustrWorkDir,
134 rtl_uString *ustrEnvironment[],
135 sal_uInt32 nEnvironmentVars,
136 oslProcess *pProcess,
137 oslFileHandle *pInputWrite,
138 oslFileHandle *pOutputRead,
139 oslFileHandle *pErrorRead
143 oslProcessError Error;
144 sal_Char* pszWorkDir=0;
145 sal_Char** pArguments=0;
146 sal_Char** pEnvironment=0;
147 unsigned int index;
149 char szImagePath[PATH_MAX] = "";
150 char szWorkDir[PATH_MAX] = "";
152 #if 0
153 if (Options & osl_Process_SEARCHPATH)
155 const rtl::OUString PATH1;
156 OUString PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
158 rtl_uString * pSearchPath = 0;
159 osl_getEnvironment (PATH.pData, &pSearchPath);
160 if (pSearchPath)
162 rtl_uString * pSearchResult = 0;
163 osl_searchPath (ustrImageName, pSearchPath, &pSearchResult);
164 if (pSearchResult)
166 rtl_uString_assign (ustrImageName, pSearchResult);
167 rtl_uString_release (pSearchResult);
169 rtl_uString_release (pSearchPath);
172 #endif
174 if ( ustrImageName && ustrImageName->length )
176 FileURLToPath( szImagePath, PATH_MAX, ustrImageName );
179 if ( ustrWorkDir != 0 && ustrWorkDir->length )
181 FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
182 pszWorkDir = szWorkDir;
185 if ( pArguments == 0 && nArguments > 0 )
187 pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) );
191 for ( index = 0 ; index < nArguments ; ++index )
193 rtl_String* strArg =0;
196 rtl_uString2String( &strArg,
197 rtl_uString_getStr(ustrArguments[index]),
198 rtl_uString_getLength(ustrArguments[index]),
199 osl_getThreadTextEncoding(),
200 OUSTRING_TO_OSTRING_CVTFLAGS );
202 pArguments[index]=strdup(rtl_string_getStr(strArg));
203 rtl_string_release(strArg);
204 pArguments[index+1]=0;
207 for ( index = 0 ; index < nEnvironmentVars ; ++index )
209 rtl_String* strEnv=0;
211 if ( pEnvironment == 0 )
213 pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) );
216 rtl_uString2String( &strEnv,
217 rtl_uString_getStr(ustrEnvironment[index]),
218 rtl_uString_getLength(ustrEnvironment[index]),
219 osl_getThreadTextEncoding(),
220 OUSTRING_TO_OSTRING_CVTFLAGS );
222 pEnvironment[index]=strdup(rtl_string_getStr(strEnv));
223 rtl_string_release(strEnv);
224 pEnvironment[index+1]=0;
227 int rc, pid;
228 int saveOutput = -1, saveInput = -1, saveError = -1;
229 int stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };
230 FILE *i, *o, *e;
232 if (pInputWrite)
233 pipe( stdInput);
234 if (pOutputRead)
235 pipe( stdOutput);
236 if (pErrorRead)
237 pipe( stdError);
239 fcntl( stdInput[0], F_SETFD, FD_CLOEXEC);
240 fcntl( stdInput[1], F_SETFD, FD_CLOEXEC);
241 fcntl( stdOutput[0], F_SETFD, FD_CLOEXEC);
242 fcntl( stdOutput[1], F_SETFD, FD_CLOEXEC);
243 fcntl( stdError[0], F_SETFD, FD_CLOEXEC);
244 fcntl( stdError[1], F_SETFD, FD_CLOEXEC);
246 saveInput = dup( STDIN_FILENO);
247 fcntl( saveInput, F_SETFD, FD_CLOEXEC);
248 dup2( stdInput[0], STDIN_FILENO );
249 close( stdInput[0] );
251 saveOutput = dup( STDOUT_FILENO);
252 fcntl( saveOutput, F_SETFD, FD_CLOEXEC);
253 dup2( stdOutput[1], STDOUT_FILENO );
254 close( stdOutput[1] );
256 saveError = dup( STDERR_FILENO);
257 fcntl( saveError, F_SETFD, FD_CLOEXEC);
258 dup2( stdError[1], STDERR_FILENO );
259 close( stdError[1] );
261 Error = osl_psz_executeProcess(szImagePath,
262 pArguments,
263 Options,
264 Security,
265 pszWorkDir,
266 pEnvironment,
267 pProcess,
268 pInputWrite,
269 pOutputRead,
270 pErrorRead
273 if ( pInputWrite )
274 *(pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
276 if ( pOutputRead )
277 *(pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
279 if ( pErrorRead )
280 *(pErrorRead) = osl_createFileHandleFromFD( stdError[0] );
282 // restore handles
283 dup2( saveInput, STDIN_FILENO);
284 close( saveInput);
285 dup2( saveOutput, STDOUT_FILENO);
286 close( saveOutput);
287 dup2( saveError, STDERR_FILENO);
288 close( saveError);
290 if ( pArguments != 0 )
292 for ( index = 0 ; index < nArguments ; ++index )
294 if ( pArguments[index] != 0 )
296 free(pArguments[index]);
299 free(pArguments);
302 if ( pEnvironment != 0 )
304 for ( index = 0 ; index < nEnvironmentVars ; ++index )
306 if ( pEnvironment[index] != 0 )
308 free(pEnvironment[index]);
311 free(pEnvironment);
314 return Error;
317 /**********************************************
318 osl_executeProcess
319 *********************************************/
321 oslProcessError SAL_CALL osl_executeProcess(
322 rtl_uString *ustrImageName,
323 rtl_uString *ustrArguments[],
324 sal_uInt32 nArguments,
325 oslProcessOption Options,
326 oslSecurity Security,
327 rtl_uString *ustrWorkDir,
328 rtl_uString *ustrEnvironment[],
329 sal_uInt32 nEnvironmentVars,
330 oslProcess *pProcess
333 return osl_executeProcess_WithRedirectedIO(
334 ustrImageName,
335 ustrArguments,
336 nArguments,
337 Options,
338 Security,
339 ustrWorkDir,
340 ustrEnvironment,
341 nEnvironmentVars,
342 pProcess,
343 NULL,
344 NULL,
345 NULL
349 /**********************************************
350 osl_psz_executeProcess
351 *********************************************/
353 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
354 sal_Char *pszArguments[],
355 oslProcessOption Options,
356 oslSecurity Security,
357 sal_Char *pszDirectory,
358 sal_Char *pszEnvironments[],
359 oslProcess *pProcess,
360 oslFileHandle *pInputWrite,
361 oslFileHandle *pOutputRead,
362 oslFileHandle *pErrorRead
365 ULONG ulSessID = 0; /* Session ID returned */
366 PID pidProcess;
367 APIRET rc;
368 sal_Char* pStr;
369 sal_Char* args;
370 sal_Char* envs;
371 int i;
372 int n = 1;
373 oslProcessImpl* pProcImpl;
374 ULONG nAppType, nOwnAppType;
375 ULONG nCurrentDisk, nDriveMap, nBufSize;
376 int first = 0;
377 sal_Char path[ _MAX_PATH ];
378 sal_Char currentDir[ _MAX_PATH ];
379 sal_Char ownfilename[ _MAX_PATH ];
380 RESULTCODES resultCode;
381 char** p;
383 /* get imagename from arg list, if not specified */
384 if (pszImageName == NULL)
385 pszImageName = pszArguments[first++];
387 OSL_ASSERT(pszImageName != NULL);
389 /* check application type */
390 rc = DosQueryAppType( (PCSZ) pszImageName, &nAppType );
391 if( rc != NO_ERROR )
393 if( (rc == ERROR_FILE_NOT_FOUND) || (rc == ERROR_PATH_NOT_FOUND) )
394 return osl_Process_E_NotFound;
395 else
396 return osl_Process_E_Unknown;
399 /* backup current disk information */
400 if(DosQueryCurrentDisk(&nCurrentDisk, &nDriveMap))
402 nCurrentDisk = 0;
405 /* backup current directory information */
406 nBufSize = _MAX_PATH;
407 if(DosQueryCurrentDir(0, (BYTE*)currentDir, &nBufSize))
409 *currentDir = '\0';
412 /* change to working directory */
413 if(pszDirectory && pszDirectory[1] == ':')
415 BYTE nDrive = toupper(pszDirectory[0]) - 'A' + 1;
417 if(NO_ERROR == DosSetDefaultDisk(nDrive))
419 DosSetCurrentDir((PSZ) pszDirectory);
423 /* query current executable filename and application type */
425 CHAR szName[CCHMAXPATH];
426 PPIB ppib;
427 PTIB ptib;
428 APIRET rc;
429 rc = DosGetInfoBlocks(&ptib, &ppib);
430 rc = DosQueryModuleName(ppib->pib_hmte, sizeof(szName), szName);
431 DosQueryAppType( (PCSZ)szName, &nOwnAppType );
434 /* combination of flags WAIT and DETACHED not supported */
435 if( (Options & osl_Process_DETACHED) && (Options & osl_Process_WAIT) )
436 Options &= !osl_Process_DETACHED;
438 /* start in same session if possible and detached flag not set */
439 if( ((nAppType & 0x00000007) == (nOwnAppType & 0x00000007))
440 /* && ((Options & osl_Process_DETACHED) == 0) */ )
442 CHAR szbuf[CCHMAXPATH];
444 /* calculate needed space for arguments */
445 n = strlen( pszImageName ) + 1;
446 if( pszArguments )
447 for (i = first; pszArguments[i] != NULL; i++)
448 n += strlen(pszArguments[i]) + 1;
450 /* allocate space for arguments */
451 args = (sal_Char*)malloc(n + 1);
452 pStr = args;
454 /* add program name as first string to arguments */
455 memcpy(pStr, pszImageName, strlen( pszImageName ) );
456 pStr += strlen( pszImageName );
457 *pStr++ = '\0';
459 /* add given strings to arguments */
460 if( pszArguments )
461 for (i = first; pszArguments[i] != NULL; i++)
463 memcpy(pStr, pszArguments[i], strlen( pszArguments[i] ) );
464 pStr += strlen( pszArguments[i] );
465 if (pszArguments[i+1] != NULL)
466 *pStr++ = ' ';
469 /* set end marker for arguments */
470 *pStr++ = '\0';
471 *pStr = '\0';
473 OSL_TRACE( "osl_executeProcess with DosExecPgm (args: %s)\n", args );
475 /* calculate needed space for environment: since enviroment var search
476 is a linear scan of the current enviroment, we place new variables
477 before existing ones; so the child will find new definitions before
478 olders; this doesn't require us to replace existing vars */
479 // existing enviroment size
480 n = 0;
481 p = environ;
482 while( *p)
484 int l = strlen( *p);
485 n += l + 1;
486 p++;
488 // new env size (if exists)
489 if( pszEnvironments )
491 for (i = 0; pszEnvironments[i] != NULL; i++)
492 n += strlen(pszEnvironments[i]) + 1;
494 /* allocate space for environment */
495 envs = (sal_Char*)malloc(n + 1);
496 pStr = envs;
498 // add new vars
499 if( pszEnvironments )
501 /* add given strings to environment */
502 for (i = 0; pszEnvironments[i] != NULL; i++)
504 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
505 pStr += strlen( pszEnvironments[i] );
506 *pStr++ = '\0';
509 // add existing vars
510 p = environ;
511 while( *p)
513 memcpy(pStr, *p, strlen( *p ) );
514 pStr += strlen( *p );
515 *pStr++ = '\0';
516 p++;
518 /* set end marker for environment */
519 *pStr = '\0';
522 if(Options & osl_Process_DETACHED)
524 rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_BACKGROUND,
525 (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
527 else
529 rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_ASYNCRESULT,
530 (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
533 pidProcess = resultCode.codeTerminate;
535 /* cleanup */
536 free(envs);
537 free(args);
539 /* error handling */
540 if( rc != NO_ERROR )
541 return osl_Process_E_Unknown;
544 else
546 STARTDATA SData = { 0 };
547 UCHAR achObjBuf[ 256 ] = { 0 };
549 /* combine arguments separated by spaces */
550 if( pszArguments )
552 for (i = first; pszArguments[i] != NULL; i++)
553 n += strlen(pszArguments[i]) + 1;
554 args = (sal_Char*)malloc(n);
555 *args = '\0';
556 for (i = first; pszArguments[i] != NULL; i++)
558 strcat(args, pszArguments[i]);
559 strcat(args, " ");
562 else
563 args = NULL;
565 /* combine environment separated by NULL */
566 if( pszEnvironments )
568 for (i = 0; pszEnvironments[i] != NULL; i++)
569 n += strlen(pszEnvironments[i]) + 1;
570 envs = (sal_Char*)malloc(n + 1);
571 pStr = (sal_Char*)envs;
572 for (i = 0; pszEnvironments[i] != NULL; i++)
574 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
575 pStr += strlen( pszEnvironments[i] );
576 *pStr = '\0';
577 pStr++;
579 *pStr = '\0';
581 else
582 envs = NULL;
584 /* initialize data structure */
585 memset( &SData, 0, sizeof( STARTDATA ) );
586 SData.Length = sizeof(STARTDATA);
588 OSL_TRACE( "osl_executeProcess with DosStartSession (args: %s)\n", args );
590 /* OS/2 Application ? */
591 if(nAppType & 0x00000007)
594 /* inherit options from parent */
595 SData.InheritOpt = SSF_INHERTOPT_PARENT;
597 switch (Options & (osl_Process_NORMAL | osl_Process_MINIMIZED |
598 osl_Process_MAXIMIZED | osl_Process_FULLSCREEN))
600 case osl_Process_MINIMIZED:
601 SData.SessionType = SSF_TYPE_DEFAULT;
602 SData.PgmControl |= SSF_CONTROL_MINIMIZE;
603 break;
605 case osl_Process_MAXIMIZED:
606 SData.SessionType = SSF_TYPE_DEFAULT;
607 SData.PgmControl |= SSF_CONTROL_MAXIMIZE;
608 break;
610 case osl_Process_FULLSCREEN:
611 SData.SessionType = SSF_TYPE_FULLSCREEN;
612 break;
614 default:
615 SData.SessionType = SSF_TYPE_DEFAULT;
616 } /* switch */
620 if( Options & osl_Process_DETACHED )
622 /* start an independent session */
623 SData.Related = SSF_RELATED_INDEPENDENT;
624 SData.TermQ = NULL;
626 else
628 /* start a child session and set Termination Queue */
629 SData.Related = SSF_RELATED_CHILD;
631 if(! bInitSessionTerm)
632 bInitSessionTerm = InitSessionTerm();
634 SData.TermQ = (BYTE*) SessionTermQueueName;
637 SData.FgBg = SSF_FGBG_FORE; /* start session in foreground */
638 SData.TraceOpt = SSF_TRACEOPT_NONE; /* No trace */
640 SData.PgmTitle = NULL;
641 SData.PgmInputs = (BYTE*)args;
642 SData.PgmName = (PSZ) pszImageName;
643 SData.Environment = (BYTE*)envs;
645 if( Options & osl_Process_HIDDEN )
646 SData.PgmControl |= SSF_CONTROL_INVISIBLE;
647 else
648 SData.PgmControl |= SSF_CONTROL_VISIBLE;
650 SData.ObjectBuffer = (PSZ) achObjBuf;
651 SData.ObjectBuffLen = (ULONG) sizeof(achObjBuf);
654 /* Start the session */
655 rc = DosStartSession( &SData, &ulSessID, &pidProcess );
657 /* ignore error "session started in background" */
658 if( rc == ERROR_SMG_START_IN_BACKGROUND )
659 rc = NO_ERROR;
662 if(envs)
663 free(envs);
664 if(args)
665 free(args);
667 if( rc != NO_ERROR )
668 return osl_Process_E_Unknown;
670 } /* else */
673 /* restore current disk */
674 if(nCurrentDisk)
676 DosSetDefaultDisk(nCurrentDisk);
679 /* restore current drive information */
680 if(*currentDir)
682 DosSetCurrentDir((PCSZ)currentDir);
685 /* allocate intern process structure and store child process ID */
686 pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
687 pProcImpl->pProcess = pidProcess;
688 pProcImpl->nSessionID = ulSessID;
690 pProcImpl->bResultCodeValid = FALSE;
692 if( Options & osl_Process_WAIT )
693 osl_joinProcess(pProcImpl);
695 *pProcess = (oslProcess)pProcImpl;
697 if( rc == NO_ERROR )
698 return osl_Process_E_None;
699 else
701 return osl_Process_E_Unknown;
704 /*----------------------------------------------------------------------------*/
706 oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
708 if (Process == NULL)
709 return osl_Process_E_Unknown;
711 /* Stop the session */
712 DosStopSession( STOP_SESSION_SPECIFIED, ((oslProcessImpl*)Process)->nSessionID );
714 return osl_Process_E_None;
717 /*----------------------------------------------------------------------------*/
719 oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
721 HANDLE hProcess;
722 oslProcessImpl* pProcImpl;
724 /* check, if given PID is a valid process */
725 if (FALSE)
727 pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
729 pProcImpl->pProcess = pidProcess;
730 pProcImpl->nSessionID = ulSessID;
733 else
734 pProcImpl = NULL;
736 return (pProcImpl);
739 /*----------------------------------------------------------------------------*/
741 void SAL_CALL osl_freeProcessHandle(oslProcess Process)
743 /* free intern process structure */
744 if (Process != NULL)
745 free((oslProcessImpl*)Process);
748 /*----------------------------------------------------------------------------*/
750 oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
752 oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
753 APIRET rc;
755 if (Process == NULL)
756 return osl_Process_E_Unknown;
758 /* process of same session ? */
759 if( pProcImpl->nSessionID == 0 )
761 RESULTCODES resultCode;
762 PID pidEnded;
764 rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
765 &pidEnded, pProcImpl->pProcess );
767 if( rc == NO_ERROR )
769 pProcImpl->nResultCode = resultCode.codeResult;
770 pProcImpl->bResultCodeValid = TRUE;
772 return osl_Process_E_None;
775 else
777 ULONG pcbData, ulElement = 0;
778 REQUESTDATA rdData;
779 BYTE bPriority;
780 struct {
781 USHORT SessionID;
782 USHORT ReturnValue;
783 } *pvBuffer;
785 /* search/wait for the correct entry in termination queue */
786 while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
787 (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
788 &bPriority, NULLHANDLE )) == NO_ERROR )
791 if( pvBuffer->SessionID == pProcImpl->nSessionID )
793 pProcImpl->nResultCode = pvBuffer->ReturnValue;
794 pProcImpl->bResultCodeValid = TRUE;
796 /* remove item from queue */
797 rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
798 (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
799 &bPriority, NULLHANDLE );
801 if( rc == NO_ERROR )
802 return osl_Process_E_None;
803 else
804 return osl_Process_E_Unknown;
806 } /* while */
808 return osl_Process_E_Unknown;
811 /***************************************************************************/
813 //YD FIXME incomplete!
814 oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
816 return osl_joinProcess( Process);
819 /*----------------------------------------------------------------------------*/
821 oslProcessError SAL_CALL osl_getCommandArgs( sal_Char* pszBuffer, sal_uInt32 Max)
824 static int CmdLen = -1;
825 static sal_Char CmdLine[_MAX_CMD];
827 OSL_ASSERT(pszBuffer);
828 OSL_ASSERT(Max > 1);
830 /* Query commandline during first call of function only */
831 if (CmdLen < 0)
833 sal_Bool bEscaped = sal_False;
834 sal_Bool bSeparated = sal_True;
835 sal_Char* pszBufferOrg = pszBuffer;
836 sal_Char* pszCmdLine;
838 /* get pointer to commandline */
840 PTIB pptib = NULL;
841 PPIB pppib = NULL;
843 DosGetInfoBlocks(&pptib, &pppib);
844 pszCmdLine = pppib->pib_pchcmd;
847 /* skip first string */
848 while( *pszCmdLine )
849 pszCmdLine++;
851 /* concatenate commandline arguments for the given string */
852 Max -= 2;
853 while ( !((*pszCmdLine == '\0') && (*(pszCmdLine + 1) == '\0')) && (Max > 0))
856 * C-Runtime expects char to be unsigned and so to be
857 * preceeded with 00 instead of FF when converting to int
859 int n = *((unsigned char *) pszCmdLine);
860 if (! (isspace(n) || (*pszCmdLine == '\0')) )
862 if (*pszCmdLine == '"')
864 if (*(pszCmdLine + 1) != '"')
865 bEscaped = ! bEscaped;
866 else
868 pszCmdLine++;
869 *pszBuffer++ = *pszCmdLine;
870 Max--;
873 else
875 *pszBuffer++ = *pszCmdLine;
876 Max--;
878 bSeparated = sal_False;
880 else
882 if (bEscaped)
883 *pszBuffer++ = *pszCmdLine;
884 else
885 if (! bSeparated)
887 *pszBuffer++ = '\0';
888 bSeparated = sal_True;
890 Max--;
893 pszCmdLine++;
896 *pszBuffer++ = '\0';
897 *pszBuffer++ = '\0';
899 /* restore pointer and save commandline for next query */
900 CmdLen = pszBuffer - pszBufferOrg;
901 pszBuffer = pszBufferOrg;
902 memcpy( CmdLine, pszBuffer, CmdLen );
904 else
905 memcpy( pszBuffer, CmdLine, CmdLen );
907 OSL_TRACE( "osl_getCommandArgs (args: %s)\n", pszBuffer );
909 return osl_Process_E_None;
912 /*----------------------------------------------------------------------------*/
914 oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields,
915 oslProcessInfo* pInfo)
917 if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
918 return osl_Process_E_Unknown;
920 pInfo->Fields = 0;
922 if (Fields & osl_Process_IDENTIFIER)
924 if( Process == NULL )
926 PTIB pptib = NULL;
927 PPIB pppib = NULL;
929 DosGetInfoBlocks( &pptib, &pppib );
930 pInfo->Ident = pppib->pib_ulpid;
932 else
933 pInfo->Ident = ((oslProcessImpl*)Process)->pProcess;
935 pInfo->Fields |= osl_Process_IDENTIFIER;
938 if (Fields & osl_Process_EXITCODE)
940 oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
942 if( pProcImpl->bResultCodeValid )
944 pInfo->Code = pProcImpl->nResultCode;
945 pInfo->Fields |= osl_Process_EXITCODE;
947 else
949 APIRET rc;
951 if( pProcImpl->nSessionID == 0 )
953 RESULTCODES resultCode;
954 PID pidEnded;
956 rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
957 &pidEnded, pProcImpl->pProcess );
959 if( rc == NO_ERROR )
961 pProcImpl->nResultCode = resultCode.codeResult;
962 pProcImpl->bResultCodeValid = TRUE;
964 pInfo->Code = pProcImpl->nResultCode;
965 pInfo->Fields |= osl_Process_EXITCODE;
967 return osl_Process_E_None;
970 else
972 ULONG pcbData, ulElement = 0;
973 REQUESTDATA rdData;
974 BYTE bPriority;
975 struct {
976 USHORT SessionID;
977 USHORT ReturnValue;
978 } *pvBuffer;
980 /* search/wait for the correct entry in termination queue */
981 while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
982 (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
983 &bPriority, NULLHANDLE )) == NO_ERROR )
986 if( pvBuffer->SessionID == pProcImpl->nSessionID )
988 pProcImpl->nResultCode = pvBuffer->ReturnValue;
989 pProcImpl->bResultCodeValid = TRUE;
991 pInfo->Code = pProcImpl->nResultCode;
992 pInfo->Fields |= osl_Process_EXITCODE;
994 /* remove item from queue */
995 rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
996 (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
997 &bPriority, NULLHANDLE );
999 break;
1006 if (Fields & osl_Process_HEAPUSAGE)
1009 if (Fields & osl_Process_CPUTIMES)
1013 return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;