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