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=NULL;
137 sal_Char** pArguments=NULL;
138 sal_Char** pEnvironment=NULL;
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 != NULL && ustrWorkDir->length )
172 {
173 FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
174 pszWorkDir = szWorkDir;
175 }
176
177 if ( pArguments == NULL && 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 =NULL;
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]=NULL;
197 }
198
199 for ( index = 0 ; index < nEnvironmentVars ; ++index )
200 {
201 rtl_String* strEnv=NULL;
202
203 if ( pEnvironment == NULL )
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]=NULL;
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 != NULL )
283 {
284 for ( index = 0 ; index < nArguments ; ++index )
285 {
286 if ( pArguments[index] != NULL )
287 {
288 free(pArguments[index]);
289 }
290 }
291 free(pArguments);
292 }
293
294 if ( pEnvironment != NULL )
295 {
296 for ( index = 0 ; index < nEnvironmentVars ; ++index )
297 {
298 if ( pEnvironment[index] != NULL )
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 environment var search
468 is a linear scan of the current environment, 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 environment 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 * preceded 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