xref: /AOO41X/main/sal/osl/os2/process.c (revision 1a6da4ce8c047845eeeaec2dcb6a8b9276848791)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "system.h"
25 #include <osl/thread.h>
26 
27 #include <osl/diagnose.h>
28 //#include <osl/socket.h>
29 
30 #ifndef _OSL_FILE_PATH_HELPER_H_
31 #include "file_path_helper.h"
32 #endif
33 
34 #include "procimpl.h"
35 //#include "sockimpl.h"
36 //#include "secimpl.h"
37 
38 #include <ctype.h>
39 
40 //#ifndef _RTL_USTRING_HXX_
41 #include <rtl/ustring.hxx>
42 //#endif
43 
44 // for exception logging
45 #include <stdio.h>
46 #include <setjmp.h>
47 
48 
49 #define MAX_ARGS 255
50 #define PIPENAMEMASK  "\\PIPE\\OSL_PIPE_%u"
51 #define SEMNAMEMASK   "\\SEM32\\OSL_SEM_%u"
52 
53 typedef enum {
54     MSG_DATA,
55     MSG_END,
56     MSG_ACK,
57     MSG_REL,
58     MSG_UNKNOWN
59 } MessageType;
60 
61 typedef struct {
62     MessageType       m_Type;
63     oslDescriptorFlag m_Flags;
64     oslDescriptorType m_Data;
65     HANDLE            m_Value;
66 } Message;
67 
68 typedef struct {
69     HPIPE   m_hPipe;
70 } Pipe;
71 
72 typedef struct _oslSocketCallbackArg {
73     HANDLE  m_socket;
74     Pipe*   m_pipe;
75 } oslSocketCallbackArg;
76 
77 /* process termination queue */
78 static sal_Bool            bInitSessionTerm = sal_False;
79 static const sal_Char * const SessionTermQueueName = "\\QUEUES\\SESSIONS.QUE";
80 static HQUEUE             SessionTermQueue;
81 
82 /******************************************************************************
83  *
84  *                  Function Declarations
85  *
86  *****************************************************************************/
87 
88 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
89                                                 sal_Char *pszArguments[],
90                                                 oslProcessOption Options,
91                                                 oslSecurity Security,
92                                                 sal_Char *pszDirectory,
93                                                 sal_Char *pszEnvironments[],
94                                                 oslProcess *pProcess,
95                                                 oslFileHandle *pInputWrite,
96                                                 oslFileHandle *pOutputRead,
97                                                 oslFileHandle *pErrorRead );
98 
99 /* implemented in file.c */
100 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
101 
InitSessionTerm(void)102 static sal_Bool InitSessionTerm( void )
103 {
104     DosCreateQueue( &SessionTermQueue, QUE_FIFO, (PCSZ) SessionTermQueueName );
105 
106     return sal_True;
107 }
108 
109 /******************************************************************************
110  *
111  *                  Functions for starting a process
112  *
113  *****************************************************************************/
114 
115 /**********************************************
116  osl_executeProcess_WithRedirectedIO
117  *********************************************/
118 
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)119 oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
120                                             rtl_uString *ustrImageName,
121                                             rtl_uString *ustrArguments[],
122                                             sal_uInt32   nArguments,
123                                             oslProcessOption Options,
124                                             oslSecurity Security,
125                                             rtl_uString *ustrWorkDir,
126                                             rtl_uString *ustrEnvironment[],
127                                             sal_uInt32   nEnvironmentVars,
128                                             oslProcess *pProcess,
129                                             oslFileHandle   *pInputWrite,
130                                             oslFileHandle   *pOutputRead,
131                                             oslFileHandle   *pErrorRead
132                                             )
133 {
134 
135     oslProcessError Error;
136     sal_Char* pszWorkDir=0;
137     sal_Char** pArguments=0;
138     sal_Char** pEnvironment=0;
139     unsigned int index;
140 
141     char szImagePath[PATH_MAX] = "";
142     char szWorkDir[PATH_MAX] = "";
143 
144 #if 0
145     if (Options & osl_Process_SEARCHPATH)
146     {
147         const rtl::OUString PATH1;
148         OUString PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
149 
150         rtl_uString * pSearchPath = 0;
151         osl_getEnvironment (PATH.pData, &pSearchPath);
152         if (pSearchPath)
153         {
154             rtl_uString * pSearchResult = 0;
155             osl_searchPath (ustrImageName, pSearchPath, &pSearchResult);
156             if (pSearchResult)
157             {
158                 rtl_uString_assign (ustrImageName, pSearchResult);
159                 rtl_uString_release (pSearchResult);
160             }
161             rtl_uString_release (pSearchPath);
162         }
163     }
164 #endif
165 
166     if ( ustrImageName && ustrImageName->length )
167     {
168         FileURLToPath( szImagePath, PATH_MAX, ustrImageName );
169     }
170 
171     if ( ustrWorkDir != 0 && ustrWorkDir->length )
172     {
173         FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
174         pszWorkDir = szWorkDir;
175     }
176 
177     if ( pArguments == 0 && nArguments > 0 )
178     {
179         pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) );
180     }
181 
182 
183     for ( index = 0 ; index < nArguments ; ++index )
184     {
185         rtl_String* strArg =0;
186 
187 
188         rtl_uString2String( &strArg,
189                             rtl_uString_getStr(ustrArguments[index]),
190                             rtl_uString_getLength(ustrArguments[index]),
191                             osl_getThreadTextEncoding(),
192                             OUSTRING_TO_OSTRING_CVTFLAGS );
193 
194         pArguments[index]=strdup(rtl_string_getStr(strArg));
195         rtl_string_release(strArg);
196         pArguments[index+1]=0;
197     }
198 
199     for ( index = 0 ; index < nEnvironmentVars ; ++index )
200     {
201         rtl_String* strEnv=0;
202 
203         if ( pEnvironment == 0 )
204         {
205             pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) );
206         }
207 
208         rtl_uString2String( &strEnv,
209                             rtl_uString_getStr(ustrEnvironment[index]),
210                             rtl_uString_getLength(ustrEnvironment[index]),
211                             osl_getThreadTextEncoding(),
212                             OUSTRING_TO_OSTRING_CVTFLAGS );
213 
214         pEnvironment[index]=strdup(rtl_string_getStr(strEnv));
215         rtl_string_release(strEnv);
216         pEnvironment[index+1]=0;
217     }
218 
219     int     rc, pid;
220     int     saveOutput = -1, saveInput = -1, saveError = -1;
221     int     stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };
222     FILE    *i, *o, *e;
223 
224     if (pInputWrite)
225         pipe( stdInput);
226     if (pOutputRead)
227         pipe( stdOutput);
228     if (pErrorRead)
229         pipe( stdError);
230 
231     fcntl( stdInput[0], F_SETFD, FD_CLOEXEC);
232     fcntl( stdInput[1], F_SETFD, FD_CLOEXEC);
233     fcntl( stdOutput[0], F_SETFD, FD_CLOEXEC);
234     fcntl( stdOutput[1], F_SETFD, FD_CLOEXEC);
235     fcntl( stdError[0], F_SETFD, FD_CLOEXEC);
236     fcntl( stdError[1], F_SETFD, FD_CLOEXEC);
237 
238     saveInput = dup( STDIN_FILENO);
239     fcntl( saveInput, F_SETFD, FD_CLOEXEC);
240     dup2( stdInput[0], STDIN_FILENO );
241     close( stdInput[0] );
242 
243     saveOutput = dup( STDOUT_FILENO);
244     fcntl( saveOutput, F_SETFD, FD_CLOEXEC);
245     dup2( stdOutput[1], STDOUT_FILENO );
246     close( stdOutput[1] );
247 
248     saveError = dup( STDERR_FILENO);
249     fcntl( saveError, F_SETFD, FD_CLOEXEC);
250     dup2( stdError[1], STDERR_FILENO );
251     close( stdError[1] );
252 
253     Error = osl_psz_executeProcess(szImagePath,
254                                    pArguments,
255                                    Options,
256                                    Security,
257                                    pszWorkDir,
258                                    pEnvironment,
259                                    pProcess,
260                                    pInputWrite,
261                                    pOutputRead,
262                                    pErrorRead
263                                    );
264 
265     if ( pInputWrite )
266         *(pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
267 
268     if ( pOutputRead )
269         *(pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
270 
271     if ( pErrorRead )
272         *(pErrorRead) = osl_createFileHandleFromFD( stdError[0] );
273 
274     // restore handles
275     dup2( saveInput, STDIN_FILENO);
276     close( saveInput);
277     dup2( saveOutput, STDOUT_FILENO);
278     close( saveOutput);
279     dup2( saveError, STDERR_FILENO);
280     close( saveError);
281 
282     if ( pArguments != 0 )
283     {
284         for ( index = 0 ; index < nArguments ; ++index )
285         {
286             if ( pArguments[index] != 0 )
287             {
288                 free(pArguments[index]);
289             }
290         }
291         free(pArguments);
292     }
293 
294     if ( pEnvironment != 0 )
295     {
296         for ( index = 0 ; index < nEnvironmentVars ; ++index )
297         {
298             if ( pEnvironment[index] != 0 )
299             {
300                 free(pEnvironment[index]);
301             }
302         }
303         free(pEnvironment);
304     }
305 
306     return Error;
307 }
308 
309 /**********************************************
310  osl_executeProcess
311  *********************************************/
312 
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)313 oslProcessError SAL_CALL osl_executeProcess(
314                                             rtl_uString *ustrImageName,
315                                             rtl_uString *ustrArguments[],
316                                             sal_uInt32   nArguments,
317                                             oslProcessOption Options,
318                                             oslSecurity Security,
319                                             rtl_uString *ustrWorkDir,
320                                             rtl_uString *ustrEnvironment[],
321                                             sal_uInt32   nEnvironmentVars,
322                                             oslProcess *pProcess
323                                             )
324 {
325     return osl_executeProcess_WithRedirectedIO(
326         ustrImageName,
327         ustrArguments,
328         nArguments,
329         Options,
330         Security,
331         ustrWorkDir,
332         ustrEnvironment,
333         nEnvironmentVars,
334         pProcess,
335         NULL,
336         NULL,
337         NULL
338         );
339 }
340 
341 /**********************************************
342  osl_psz_executeProcess
343  *********************************************/
344 
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)345 oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
346                                                 sal_Char *pszArguments[],
347                                                 oslProcessOption Options,
348                                                 oslSecurity Security,
349                                                 sal_Char *pszDirectory,
350                                                 sal_Char *pszEnvironments[],
351                                                 oslProcess *pProcess,
352                                                 oslFileHandle   *pInputWrite,
353                                                 oslFileHandle   *pOutputRead,
354                                                 oslFileHandle   *pErrorRead
355                                                 )
356 {
357     ULONG ulSessID  = 0;          /* Session ID returned          */
358     PID pidProcess;
359     APIRET rc;
360     sal_Char* pStr;
361     sal_Char*        args;
362     sal_Char*        envs;
363     int i;
364     int n = 1;
365     oslProcessImpl* pProcImpl;
366     ULONG nAppType, nOwnAppType;
367     ULONG nCurrentDisk, nDriveMap, nBufSize;
368     int  first = 0;
369     sal_Char path[ _MAX_PATH ];
370     sal_Char currentDir[ _MAX_PATH ];
371     sal_Char ownfilename[ _MAX_PATH ];
372     RESULTCODES resultCode;
373     char** p;
374 
375     /* get imagename from arg list, if not specified */
376     if (pszImageName == NULL)
377         pszImageName = pszArguments[first++];
378 
379     OSL_ASSERT(pszImageName != NULL);
380 
381     /* check application type */
382     rc = DosQueryAppType( (PCSZ) pszImageName, &nAppType );
383     if( rc != NO_ERROR )
384     {
385         if( (rc == ERROR_FILE_NOT_FOUND) || (rc == ERROR_PATH_NOT_FOUND) )
386             return osl_Process_E_NotFound;
387         else
388             return osl_Process_E_Unknown;
389     }
390 
391     /* backup current disk information */
392     if(DosQueryCurrentDisk(&nCurrentDisk, &nDriveMap))
393     {
394         nCurrentDisk = 0;
395     }
396 
397     /* backup current directory information */
398     nBufSize = _MAX_PATH;
399     if(DosQueryCurrentDir(0, (BYTE*)currentDir, &nBufSize))
400     {
401         *currentDir = '\0';
402     }
403 
404     /* change to working directory */
405     if(pszDirectory && pszDirectory[1] == ':')
406     {
407         BYTE nDrive = toupper(pszDirectory[0]) - 'A' + 1;
408 
409         if(NO_ERROR == DosSetDefaultDisk(nDrive))
410         {
411             DosSetCurrentDir((PSZ) pszDirectory);
412         }
413     }
414 
415     /* query current executable filename and application type */
416     {
417         CHAR    szName[CCHMAXPATH];
418         PPIB    ppib;
419         PTIB    ptib;
420         APIRET  rc;
421         rc = DosGetInfoBlocks(&ptib, &ppib);
422         rc = DosQueryModuleName(ppib->pib_hmte, sizeof(szName), szName);
423         DosQueryAppType( (PCSZ)szName, &nOwnAppType );
424     }
425 
426     /* combination of flags WAIT and DETACHED not supported */
427     if( (Options & osl_Process_DETACHED) && (Options & osl_Process_WAIT) )
428         Options &= !osl_Process_DETACHED;
429 
430     /* start in same session if possible and detached flag not set */
431     if( ((nAppType & 0x00000007) == (nOwnAppType & 0x00000007))
432 /*      && ((Options & osl_Process_DETACHED) == 0) */ )
433     {
434         CHAR szbuf[CCHMAXPATH];
435 
436         /* calculate needed space for arguments */
437         n = strlen( pszImageName ) + 1;
438         if( pszArguments )
439             for (i = first; pszArguments[i] != NULL; i++)
440                 n += strlen(pszArguments[i]) + 1;
441 
442         /* allocate space for arguments */
443         args = (sal_Char*)malloc(n + 1);
444         pStr = args;
445 
446         /* add program name as first string to arguments */
447         memcpy(pStr, pszImageName, strlen( pszImageName ) );
448         pStr += strlen( pszImageName );
449         *pStr++ = '\0';
450 
451         /* add given strings to arguments */
452         if( pszArguments )
453             for (i = first; pszArguments[i] != NULL; i++)
454             {
455                 memcpy(pStr, pszArguments[i], strlen( pszArguments[i] ) );
456                 pStr += strlen( pszArguments[i] );
457                 if (pszArguments[i+1] != NULL)
458                     *pStr++ = ' ';
459             }
460 
461         /* set end marker for arguments */
462         *pStr++ = '\0';
463         *pStr = '\0';
464 
465         OSL_TRACE( "osl_executeProcess with DosExecPgm (args: %s)\n", args );
466 
467         /* calculate needed space for environment: since enviroment var search
468            is a linear scan of the current enviroment, we place new variables
469            before existing ones; so the child will find new definitions before
470            olders; this doesn't require us to replace existing vars */
471         // existing enviroment size
472         n = 0;
473         p = environ;
474         while( *p)
475         {
476             int l = strlen( *p);
477             n += l + 1;
478             p++;
479         }
480         // new env size (if exists)
481         if( pszEnvironments )
482         {
483             for (i = 0; pszEnvironments[i] != NULL; i++)
484                 n += strlen(pszEnvironments[i]) + 1;
485         }
486         /* allocate space for environment */
487         envs = (sal_Char*)malloc(n + 1);
488         pStr = envs;
489 
490         // add new vars
491         if( pszEnvironments )
492         {
493             /* add given strings to environment */
494             for (i = 0; pszEnvironments[i] != NULL; i++)
495             {
496                 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
497                 pStr += strlen( pszEnvironments[i] );
498                 *pStr++ = '\0';
499             }
500         }
501         // add existing vars
502         p = environ;
503         while( *p)
504         {
505             memcpy(pStr, *p, strlen( *p ) );
506             pStr += strlen( *p );
507             *pStr++ = '\0';
508             p++;
509         }
510         /* set end marker for environment */
511         *pStr = '\0';
512 
513 
514         if(Options & osl_Process_DETACHED)
515         {
516             rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_BACKGROUND,
517                              (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
518         }
519         else
520         {
521             rc = DosExecPgm( szbuf, sizeof( szbuf ), EXEC_ASYNCRESULT,
522                              (PSZ) args, (PSZ) envs, &resultCode, (PSZ) pszImageName );
523         }
524 
525         pidProcess = resultCode.codeTerminate;
526 
527         /* cleanup */
528         free(envs);
529         free(args);
530 
531         /* error handling */
532         if( rc != NO_ERROR )
533             return osl_Process_E_Unknown;
534     }
535 
536     else
537     {
538         STARTDATA SData = { 0 };
539         UCHAR achObjBuf[ 256 ] = { 0 };
540 
541         /* combine arguments separated by spaces */
542         if( pszArguments )
543         {
544             for (i = first; pszArguments[i] != NULL; i++)
545                 n += strlen(pszArguments[i]) + 1;
546             // YD DosStartSession requires low-mem buffers!
547             args = (sal_Char*)_tmalloc(n);
548             *args = '\0';
549             for (i = first; pszArguments[i] != NULL; i++)
550             {
551                 strcat(args, pszArguments[i]);
552                 strcat(args, " ");
553             }
554         }
555         else
556             args = NULL;
557 
558         /* combine environment separated by NULL */
559         if( pszEnvironments )
560         {
561             for (i = 0; pszEnvironments[i] != NULL; i++)
562                 n += strlen(pszEnvironments[i]) + 1;
563             // YD DosStartSession requires low-mem buffers!
564             envs = (sal_Char*)_tmalloc(n + 1);
565             pStr = (sal_Char*)envs;
566             for (i = 0; pszEnvironments[i] != NULL; i++)
567             {
568                 memcpy(pStr, pszEnvironments[i], strlen( pszEnvironments[i] ) );
569                 pStr += strlen( pszEnvironments[i] );
570                 *pStr = '\0';
571                 pStr++;
572             }
573             *pStr = '\0';
574         }
575         else
576             envs = NULL;
577 
578         /* initialize data structure */
579         memset( &SData, 0, sizeof( STARTDATA ) );
580         SData.Length  = sizeof(STARTDATA);
581 
582         OSL_TRACE( "osl_executeProcess with DosStartSession (args: %s)\n", args );
583 
584         /* OS/2 Application ? */
585         if(nAppType & 0x00000007)
586         {
587 
588             /* inherit options from parent */
589             SData.InheritOpt = SSF_INHERTOPT_PARENT;
590 
591             switch (Options & (osl_Process_NORMAL | osl_Process_MINIMIZED |
592                             osl_Process_MAXIMIZED | osl_Process_FULLSCREEN))
593             {
594                 case osl_Process_MINIMIZED:
595                     SData.SessionType = SSF_TYPE_DEFAULT;
596                     SData.PgmControl |= SSF_CONTROL_MINIMIZE;
597                     break;
598 
599                 case osl_Process_MAXIMIZED:
600                     SData.SessionType = SSF_TYPE_DEFAULT;
601                     SData.PgmControl |= SSF_CONTROL_MAXIMIZE;
602                     break;
603 
604                 case osl_Process_FULLSCREEN:
605                     SData.SessionType = SSF_TYPE_FULLSCREEN;
606                     break;
607 
608                 default:
609                     SData.SessionType = SSF_TYPE_DEFAULT;
610             } /* switch */
611         }
612 
613 
614         if( Options & osl_Process_DETACHED )
615         {
616             /* start an independent session */
617             SData.Related = SSF_RELATED_INDEPENDENT;
618             SData.TermQ = NULL;
619         }
620         else
621         {
622             /* start a child session and set Termination Queue */
623             SData.Related = SSF_RELATED_CHILD;
624 
625             if(! bInitSessionTerm)
626                 bInitSessionTerm = InitSessionTerm();
627 
628             SData.TermQ = (BYTE*) SessionTermQueueName;
629         }
630 
631         SData.FgBg  = SSF_FGBG_FORE;      /* start session in foreground  */
632         SData.TraceOpt = SSF_TRACEOPT_NONE;   /* No trace                */
633 
634         SData.PgmTitle = NULL;
635         SData.PgmInputs = (BYTE*)args;
636         SData.PgmName = (PSZ) pszImageName;
637         SData.Environment = (BYTE*)envs;
638 
639         if( Options & osl_Process_HIDDEN )
640             SData.PgmControl |= SSF_CONTROL_INVISIBLE;
641         else
642             SData.PgmControl |= SSF_CONTROL_VISIBLE;
643 
644         SData.ObjectBuffer  = (PSZ) achObjBuf;
645         SData.ObjectBuffLen = (ULONG) sizeof(achObjBuf);
646 
647 
648         /* Start the session */
649         rc = DosStartSession( &SData, &ulSessID, &pidProcess );
650 
651         /* ignore error "session started in background" */
652         if( rc == ERROR_SMG_START_IN_BACKGROUND )
653             rc = NO_ERROR;
654 
655 
656         if(envs)
657             _tfree(envs);
658         if(args)
659             _tfree(args);
660 
661         if( rc != NO_ERROR )
662             return osl_Process_E_Unknown;
663 
664     } /* else */
665 
666 
667     /* restore current disk */
668     if(nCurrentDisk)
669     {
670         DosSetDefaultDisk(nCurrentDisk);
671     }
672 
673     /* restore current drive information */
674     if(*currentDir)
675     {
676         DosSetCurrentDir((PCSZ)currentDir);
677     }
678 
679     /* allocate intern process structure and store child process ID */
680     pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
681     pProcImpl->pProcess = pidProcess;
682     pProcImpl->nSessionID = ulSessID;
683 
684     pProcImpl->bResultCodeValid = FALSE;
685 
686     if( Options & osl_Process_WAIT )
687         osl_joinProcess(pProcImpl);
688 
689     *pProcess = (oslProcess)pProcImpl;
690 
691     if( rc == NO_ERROR )
692         return osl_Process_E_None;
693     else
694 
695         return osl_Process_E_Unknown;
696 }
697 
698 /*----------------------------------------------------------------------------*/
699 
osl_terminateProcess(oslProcess Process)700 oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
701 {
702     if (Process == NULL)
703         return osl_Process_E_Unknown;
704 
705     /* Stop the session */
706     DosStopSession( STOP_SESSION_SPECIFIED, ((oslProcessImpl*)Process)->nSessionID );
707 
708     return osl_Process_E_None;
709 }
710 
711 /*----------------------------------------------------------------------------*/
712 
osl_getProcess(oslProcessIdentifier Ident)713 oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
714 {
715     HANDLE        hProcess;
716     oslProcessImpl* pProcImpl;
717 
718     /* check, if given PID is a valid process */
719     if (FALSE)
720     {
721         pProcImpl = (oslProcessImpl*)malloc(sizeof(oslProcessImpl));
722 /*
723         pProcImpl->pProcess = pidProcess;
724         pProcImpl->nSessionID = ulSessID;
725 */
726     }
727     else
728         pProcImpl = NULL;
729 
730     return (pProcImpl);
731 }
732 
733 /*----------------------------------------------------------------------------*/
734 
osl_freeProcessHandle(oslProcess Process)735 void SAL_CALL osl_freeProcessHandle(oslProcess Process)
736 {
737     /* free intern process structure */
738     if (Process != NULL)
739         free((oslProcessImpl*)Process);
740 }
741 
742 /*----------------------------------------------------------------------------*/
743 
osl_joinProcess(oslProcess Process)744 oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
745 {
746     oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
747     APIRET rc;
748 
749     if (Process == NULL)
750         return osl_Process_E_Unknown;
751 
752     /* process of same session ? */
753     if( pProcImpl->nSessionID == 0 )
754     {
755         RESULTCODES resultCode;
756         PID pidEnded;
757 
758         rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
759                 &pidEnded, pProcImpl->pProcess );
760 
761         if( rc == NO_ERROR )
762         {
763             pProcImpl->nResultCode = resultCode.codeResult;
764             pProcImpl->bResultCodeValid = TRUE;
765 
766             return osl_Process_E_None;
767         }
768     }
769     else
770     {
771         ULONG pcbData, ulElement = 0;
772         REQUESTDATA rdData;
773         BYTE bPriority;
774         struct {
775             USHORT SessionID;
776             USHORT ReturnValue;
777         } *pvBuffer;
778 
779         /* search/wait for the correct entry in termination queue */
780         while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
781                         (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
782                         &bPriority, NULLHANDLE )) == NO_ERROR )
783         {
784 
785             if( pvBuffer->SessionID == pProcImpl->nSessionID )
786             {
787                 pProcImpl->nResultCode = pvBuffer->ReturnValue;
788                 pProcImpl->bResultCodeValid = TRUE;
789 
790                 /* remove item from queue */
791                 rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
792                        (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
793                        &bPriority, NULLHANDLE );
794 
795                 if( rc == NO_ERROR )
796                     return osl_Process_E_None;
797                 else
798                     return osl_Process_E_Unknown;
799             }
800         } /* while */
801     }
802     return osl_Process_E_Unknown;
803 }
804 
805 /***************************************************************************/
806 
807 //YD FIXME incomplete!
osl_joinProcessWithTimeout(oslProcess Process,const TimeValue * pTimeout)808 oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
809 {
810     return osl_joinProcess( Process);
811 }
812 
813 /*----------------------------------------------------------------------------*/
814 
osl_getCommandArgs(sal_Char * pszBuffer,sal_uInt32 Max)815 oslProcessError SAL_CALL osl_getCommandArgs( sal_Char* pszBuffer, sal_uInt32 Max)
816 {
817 
818     static int  CmdLen = -1;
819     static sal_Char CmdLine[_MAX_CMD];
820 
821     OSL_ASSERT(pszBuffer);
822     OSL_ASSERT(Max > 1);
823 
824     /* Query commandline during first call of function only */
825     if (CmdLen < 0)
826     {
827         sal_Bool bEscaped = sal_False;
828         sal_Bool bSeparated = sal_True;
829         sal_Char* pszBufferOrg = pszBuffer;
830         sal_Char* pszCmdLine;
831 
832         /* get pointer to commandline */
833         {
834             PTIB pptib = NULL;
835             PPIB pppib = NULL;
836 
837             DosGetInfoBlocks(&pptib, &pppib);
838             pszCmdLine = pppib->pib_pchcmd;
839         }
840 
841         /* skip first string */
842         while( *pszCmdLine )
843             pszCmdLine++;
844 
845         /* concatenate commandline arguments for the given string */
846         Max -= 2;
847         while ( !((*pszCmdLine == '\0') && (*(pszCmdLine + 1) == '\0')) && (Max > 0))
848         {
849             /*
850              *  C-Runtime expects char to be unsigned and so to be
851              *  preceeded with 00 instead of FF when converting to int
852              */
853             int n = *((unsigned char *) pszCmdLine);
854             if (! (isspace(n) || (*pszCmdLine == '\0')) )
855             {
856                 if (*pszCmdLine == '"')
857                 {
858                     if (*(pszCmdLine + 1) != '"')
859                         bEscaped = ! bEscaped;
860                     else
861                     {
862                         pszCmdLine++;
863                         *pszBuffer++ = *pszCmdLine;
864                         Max--;
865                     }
866                 }
867                 else
868                 {
869                     *pszBuffer++ = *pszCmdLine;
870                     Max--;
871                 }
872                 bSeparated = sal_False;
873             }
874             else
875             {
876                 if (bEscaped)
877                     *pszBuffer++ = *pszCmdLine;
878                 else
879                     if (! bSeparated)
880                     {
881                         *pszBuffer++ = '\0';
882                         bSeparated = sal_True;
883                     }
884                 Max--;
885             }
886 
887             pszCmdLine++;
888         }
889 
890         *pszBuffer++ = '\0';
891         *pszBuffer++ = '\0';
892 
893         /* restore pointer and save commandline for next query */
894         CmdLen = pszBuffer - pszBufferOrg;
895         pszBuffer = pszBufferOrg;
896         memcpy( CmdLine, pszBuffer, CmdLen );
897     }
898     else
899        memcpy( pszBuffer, CmdLine, CmdLen );
900 
901     OSL_TRACE( "osl_getCommandArgs (args: %s)\n", pszBuffer );
902 
903     return osl_Process_E_None;
904 }
905 
906 /*----------------------------------------------------------------------------*/
907 
osl_getProcessInfo(oslProcess Process,oslProcessData Fields,oslProcessInfo * pInfo)908 oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields,
909                                    oslProcessInfo* pInfo)
910 {
911     if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
912         return osl_Process_E_Unknown;
913 
914     pInfo->Fields = 0;
915 
916     if (Fields & osl_Process_IDENTIFIER)
917     {
918         if( Process == NULL )
919         {
920             PTIB pptib = NULL;
921             PPIB pppib = NULL;
922 
923             DosGetInfoBlocks( &pptib, &pppib );
924             pInfo->Ident = pppib->pib_ulpid;
925         }
926         else
927             pInfo->Ident = ((oslProcessImpl*)Process)->pProcess;
928 
929         pInfo->Fields |= osl_Process_IDENTIFIER;
930     }
931 
932     if (Fields & osl_Process_EXITCODE)
933     {
934         oslProcessImpl* pProcImpl = (oslProcessImpl*) Process;
935 
936         if( pProcImpl->bResultCodeValid )
937         {
938             pInfo->Code = pProcImpl->nResultCode;
939             pInfo->Fields |= osl_Process_EXITCODE;
940         }
941         else
942         {
943             APIRET rc;
944 
945             if( pProcImpl->nSessionID == 0 )
946             {
947                 RESULTCODES resultCode;
948                 PID pidEnded;
949 
950                 rc = DosWaitChild( DCWA_PROCESS, DCWW_WAIT, &resultCode,
951                         &pidEnded, pProcImpl->pProcess );
952 
953                 if( rc == NO_ERROR )
954                 {
955                     pProcImpl->nResultCode = resultCode.codeResult;
956                     pProcImpl->bResultCodeValid = TRUE;
957 
958                     pInfo->Code = pProcImpl->nResultCode;
959                     pInfo->Fields |= osl_Process_EXITCODE;
960 
961                     return osl_Process_E_None;
962                 }
963             }
964             else
965             {
966                 ULONG pcbData, ulElement = 0;
967                 REQUESTDATA rdData;
968                 BYTE bPriority;
969                 struct {
970                     USHORT SessionID;
971                     USHORT ReturnValue;
972                 } *pvBuffer;
973 
974                 /* search/wait for the correct entry in termination queue */
975                 while( ( rc = DosPeekQueue( SessionTermQueue, &rdData, &pcbData,
976                                 (PPVOID) &pvBuffer, &ulElement, DCWW_WAIT,
977                                 &bPriority, NULLHANDLE )) == NO_ERROR )
978                 {
979 
980                     if( pvBuffer->SessionID == pProcImpl->nSessionID )
981                     {
982                         pProcImpl->nResultCode = pvBuffer->ReturnValue;
983                         pProcImpl->bResultCodeValid = TRUE;
984 
985                         pInfo->Code = pProcImpl->nResultCode;
986                         pInfo->Fields |= osl_Process_EXITCODE;
987 
988                         /* remove item from queue */
989                         rc = DosReadQueue( SessionTermQueue, &rdData, &pcbData,
990                             (PPVOID)&pvBuffer, ulElement, DCWW_WAIT,
991                                &bPriority, NULLHANDLE );
992 
993                         break;
994                     }
995                 }
996             }
997         }
998     }
999 
1000     if (Fields & osl_Process_HEAPUSAGE)
1001     {
1002     }
1003     if (Fields & osl_Process_CPUTIMES)
1004     {
1005     }
1006 
1007     return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
1008 }
1009