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 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 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 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 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 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 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 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 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! 808 oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout) 809 { 810 return osl_joinProcess( Process); 811 } 812 813 /*----------------------------------------------------------------------------*/ 814 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 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