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