Changeset 93120 in vbox for trunk/src/VBox/Main/src-helper-apps
- Timestamp:
- Jan 4, 2022 2:54:28 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 149134
- Location:
- trunk/src/VBox/Main/src-helper-apps/os2
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-helper-apps/os2/Makefile.kmk
r93116 r93120 23 23 # This is checked in as a binary, this is just the makefile for re-builting it. 24 24 # 25 override DEFS.os2 = RT_OS_OS2 # HACK ALERT! 26 PROGRAMS += os2_util 27 os2_util_TOOL = OPENWATCOM-16 28 os2_util_ASTOOL = OPENWATCOM-16 29 os2_util_LDTOOL = OPENWATCOM-WL 30 os2_util_BLD_TRG = os2 31 os2_util_BLD_TRG_ARCH = x86 32 os2_util_INST = $(INST_UNATTENDED_TEMPLATES) 33 os2_util_MODE = a+r,u+w 34 os2_util_DEFS = IN_RING3 35 os2_util_CFLAGS = -zl -s -ml 36 os2_util_LDFLAGS = \ 25 ifdef VBOX_WITH_OPEN_WATCOM 26 PROGRAMS += os2_util 27 endif 28 os2_util_TOOL = OPENWATCOM-16 29 os2_util_ASTOOL = OPENWATCOM-16 30 os2_util_LDTOOL = OPENWATCOM-WL 31 os2_util_BLD_TRG = os2 32 os2_util_BLD_TRG_ARCH = x86 33 os2_util_INST = $(INST_UNATTENDED_TEMPLATES) 34 os2_util_MODE = a+r,u+w 35 os2_util_DEFS = IN_RING3 36 os2_util_CFLAGS = -zl -s -ml -os 37 os2_util_LDFLAGS = \ 37 38 SYSTEM os2 \ 38 39 OPTION START=_Os2UtilMain \ … … 41 42 OPTION MANYAUTODATA \ 42 43 SEGMENT IOPL IOPL EXECUTEREAD 43 os2_util_INCS = $(PATH_TOOL_OPENWATCOM)/h/os21x 44 os2_util_SOURCES = os2_util.c os2_utilA.asm 44 if 0 45 os2_util_LDFLAGS += Debug Watcom All 46 os2_util_CFLAGS += -d2 -hw 47 endif 48 49 os2_util_INCS = $(PATH_TOOL_OPENWATCOM)/h/os21x 50 os2_util_SOURCES = os2_util.c os2_utilA.asm 45 51 46 52 include $(FILE_KBUILD_SUB_FOOTER) -
trunk/src/VBox/Main/src-helper-apps/os2/os2_util.c
r93116 r93120 28 28 #include <VBox/log.h> 29 29 30 #include "VBox/version.h" 31 30 32 31 33 /********************************************************************************************************************************* … … 79 81 80 82 83 /** strchr-like function. */ 84 static char __far *MyStrChr(const char __far *psz, char chNeedle) 85 { 86 char ch; 87 while ((ch = *psz) != '\0') 88 { 89 if (ch == chNeedle) 90 return (char __far *)psz; 91 psz++; 92 } 93 return NULL; 94 } 95 96 81 97 /** memcpy-like function. */ 82 98 static void *MyMemCopy(void __far *pvDst, void const __far *pvSrc, USHORT cb) … … 134 150 MyOutNum(rc); 135 151 MyOutStr("\r\n"); 136 DosExit(EXIT_PROCESS, 0); 152 DosExit(EXIT_PROCESS, 1); 153 } 154 155 156 static void MyApiError3AndQuit(PSZ pszOperation, PSZ psz2, PSZ psz3, USHORT rc) 157 { 158 MyOutStr("Os2Util: error: "); 159 MyOutStr(pszOperation); 160 MyOutStr(psz2); 161 MyOutStr(psz3); 162 MyOutStr(" failed: "); 163 MyOutNum(rc); 164 MyOutStr("\r\n"); 165 DosExit(EXIT_PROCESS, 1); 166 } 167 168 169 static void MySyntaxErrorAndQuit(PSZ pszMsg) 170 { 171 MyOutStr("Os2Util: syntax error: "); 172 MyOutStr(pszMsg); 173 MyOutStr("\r\n"); 174 DosExit(EXIT_PROCESS, 1); 137 175 } 138 176 … … 160 198 * Write out buffered data 161 199 */ 200 /** @todo this does not seem to work. */ 162 201 pBuf = g_pBufferHead; 163 202 while (pBuf) … … 234 273 235 274 275 /** 276 * Waits for the child progress to complete, returning it's status code. 277 */ 278 static void DoWait(PID pidChild, USHORT idSession, HQUEUE hQueue, PRESULTCODES pResultCodes) 279 { 280 /* 281 * Can we use DosCwait? 282 */ 283 if (idSession == 0 && hQueue == NULL) 284 { 285 for (;;) 286 { 287 PID pidIgnored; 288 USHORT rc = DosCwait(DCWA_PROCESS, DCWW_WAIT, pResultCodes, &pidIgnored, pidChild); 289 if (rc == NO_ERROR) 290 break; 291 if (rc != ERROR_INTERRUPT) 292 { 293 MyOutStr("Os2Util: error: DosCwait(DCWA_PROCESS,DCWW_WAIT,,,"); 294 MyOutNum(pidChild); 295 MyOutStr(") failed: "); 296 MyOutNum(rc); 297 MyOutStr("\r\n"); 298 } 299 } 300 } 301 else 302 { 303 /* 304 * No we have to use the queue interface to the session manager. 305 */ 306 for (;;) 307 { 308 ULONG ulAdderPidAndEvent = 0; 309 PUSHORT pausData = NULL; 310 USHORT cbData = 0; 311 BYTE bPriority = 0; 312 HSEM hSem = NULL; 313 USHORT rc = DosReadQueue(hQueue, &ulAdderPidAndEvent, &cbData, (PULONG)&pausData, 314 0 /*uElementCode*/, 0 /* fNoWait */, &bPriority, &hSem); 315 if (rc == NO_ERROR) 316 { 317 if (cbData >= sizeof(USHORT) * 2) 318 { 319 USHORT idTermSession = pausData[0]; 320 USHORT uExitCode = pausData[1]; 321 if (idTermSession == idSession) 322 { 323 pResultCodes->codeTerminate = 0; 324 pResultCodes->codeResult = uExitCode; 325 break; 326 } 327 if (1) 328 { 329 MyOutStr("OutUtil: info: idTermSession="); 330 MyOutNum(idTermSession); 331 MyOutStr(" uExitCode="); 332 MyOutNum(uExitCode); 333 MyOutStr("\r\n"); 334 } 335 } 336 else 337 { 338 MyOutStr("OutUtil: warning: bogus queue element size: cbData="); 339 MyOutNum(cbData); 340 MyOutStr("\r\n"); 341 } 342 DosFreeSeg((__segment)pausData); 343 } 344 else if (rc != ERROR_INTERRUPT) 345 { 346 DosCloseQueue(hQueue); 347 MyApiErrorAndQuit("DosReadQueue", rc); 348 } 349 } 350 } 351 } 352 353 354 /** Displays version string and quits. */ 355 static void ShowVersionAndQuit(void) 356 { 357 CHAR szVer[] = "$Rev$\r\n"; 358 USHORT usIgnored; 359 DosWrite(g_hStdOut, szVer, sizeof(szVer) - 1, &usIgnored); 360 DosExit(EXIT_PROCESS, 0); 361 } 362 363 364 /** Displays usage info and quits. */ 236 365 static void ShowUsageAndQuit(void) 237 366 { 238 367 static char s_szHelp[] = 239 "Os2Util.exe is tiny helper utility that implements TEE'ing to the VBox release log,\r\n" 240 "files and shows the actual exit code of a program. Standard error and output will\r\n" 241 "be merged into one for simplicity reasons.\r\n" 368 VBOX_PRODUCT " OS/2 Unattended Helper Version " VBOX_VERSION_STRING "\r\n" 369 "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\r\n" 242 370 "\r\n" 243 "usage: Os2Util.exe [-a|--append] [-f<filename>|--tee-to-file <filename>] \\\r\n" 244 " [-b|--tee-to-backdoor] -- <prog> [args]\r\n" 245 " or Os2Util.exe <-w<msg>|--write-backdoor <msg>> \r\n"; 371 "Os2Util.exe is tiny helper utility that implements TEE'ing to the VBox release\r\n" 372 "log, files and shows the actual exit code of a program. Standard error and\r\n" 373 "output will be merged into one for simplicity reasons.\r\n" 374 "\r\n" 375 "Usage: Os2Util.exe [-a|--append] [-f<filename>|--tee-to-file <filename>] \\\r\n" 376 " [-b|--tee-to-backdoor] [-z<exit>|--as-zero <exit> [..]] \\\r\n" 377 " -- <prog> [args]\r\n" 378 " or Os2Util.exe <-w<msg>|--write-backdoor <msg>>\r\n" 379 "\r\n" 380 "Note! Does not supported any kind of quoting before the child arguments.\r\n" 381 ; 246 382 USHORT usIgnored; 247 DosWrite(g_hStd Err, s_szHelp, sizeof(s_szHelp) - 1, &usIgnored);383 DosWrite(g_hStdOut, s_szHelp, sizeof(s_szHelp) - 1, &usIgnored); 248 384 DosExit(EXIT_PROCESS, 0); 249 385 } … … 262 398 if (*psz == '\0') 263 399 { 264 USHORT usIgnored; 265 DosWrite(g_hStdErr, RT_STR_TUPLE("Os2Util: syntax error: Option '"), &usIgnored); 266 DosWrite(g_hStdErr, pszOption, MyStrLen(pszOption), &usIgnored); 267 DosWrite(g_hStdErr, RT_STR_TUPLE("' takes a value\r\n"), &usIgnored); 400 MyOutStr("Os2Util: syntax error: Option '"); 401 MyOutStr(pszOption); 402 MyOutStr("' takes a value\r\n"); 268 403 DosExit(EXIT_PROCESS, 2); 269 404 } … … 275 410 if (ch != '\0') 276 411 *psz++ = '\0'; 412 return psz; 413 } 414 415 416 /** 417 * Gets the an numeric option value. 418 */ 419 static PSZ MyGetOptNum(PSZ psz, PSZ pszOption, PUSHORT puValue) 420 { 421 PSZ pszError = NULL; 422 PSZ pszValueStart = NULL; 423 PSZ pszValue; 424 CHAR ch; 425 USHORT uValue; 426 psz = MyGetOptValue(psz, pszOption, &pszValueStart); 427 428 pszValue = pszValueStart; 429 uValue = 0; 430 if (pszValue[0] == '0' && ((ch = pszValue[1]) == 'x' || ch == 'X')) 431 { 432 pszValue += 2; 433 while ((ch = *pszValue++) != '\0') 434 { 435 BYTE bDigit; 436 if (ch <= '9' && ch >= '0') 437 bDigit = ch - '0'; 438 else if (ch <= 'f' && ch >= 'a') 439 bDigit = ch - 'a' + 10; 440 else if (ch <= 'F' && ch >= 'A') 441 bDigit = ch - 'A' + 10; 442 else 443 { 444 pszError = "': invalid hex value\r\n"; 445 break; 446 } 447 if (uValue >> 12) 448 { 449 pszError = "': hex value out of range\r\n"; 450 break; 451 } 452 uValue <<= 4; 453 uValue |= bDigit; 454 } 455 } 456 else 457 { 458 while ((ch = *pszValue++) != '\0') 459 { 460 BYTE bDigit; 461 if (ch <= '9' && ch >= '0') 462 bDigit = ch - '0'; 463 else 464 { 465 pszError = "': invalid decimal value\r\n"; 466 break; 467 } 468 if (uValue * 10 / 10 != uValue) 469 { 470 pszError = "': decimal value out of range\r\n"; 471 break; 472 } 473 uValue *= 10; 474 uValue += bDigit; 475 } 476 } 477 478 if (pszError) 479 { 480 MyOutStr("Os2Util: syntax error: Option '"); 481 MyOutStr(pszOption); 482 MyOutStr("' with value '"); 483 MyOutStr(pszValueStart); 484 MyOutStr(pszError); 485 DosExit(EXIT_PROCESS, 2); 486 } 487 488 *puValue = uValue; 277 489 return psz; 278 490 } … … 326 538 RESULTCODES ResultCodes = { 0xffff, 0xffff }; 327 539 CHAR szBuf[512]; 540 CHAR szExeFull[CCHMAXPATH]; 541 PSZ pszExe; 542 USHORT uExeType; 543 USHORT idSession = 0; 544 PID pidChild = 0; 545 HQUEUE hQueue = ~(HQUEUE)0; 546 CHAR szQueueName[64]; 547 unsigned cAsZero; 548 USHORT auAsZero[16]; 328 549 329 550 /* … … 359 580 if (ch == 'a' && MyMatchLongOption(&psz, RT_STR_TUPLE("append"))) 360 581 fAppend = TRUE; 582 else if (ch == 'a' && MyMatchLongOption(&psz, RT_STR_TUPLE("as-zero"))) 583 { 584 if (cAsZero > RT_ELEMENTS(auAsZero)) 585 MySyntaxErrorAndQuit("Too many --as-zero/-z options"); 586 psz = MyGetOptNum(psz + 1, "--as-zero", &auAsZero[cAsZero]); 587 cAsZero++; 588 } 361 589 else if (ch == 'h' && MyMatchLongOption(&psz, RT_STR_TUPLE("help"))) 362 590 ShowUsageAndQuit(); … … 365 593 else if (ch == 't' && MyMatchLongOption(&psz, RT_STR_TUPLE("tee-to-file"))) 366 594 psz = MyGetOptValue(psz, "--tee-to-file", &pszTeeToFile); 595 else if (ch == 'v' && MyMatchLongOption(&psz, RT_STR_TUPLE("version"))) 596 ShowVersionAndQuit(); 367 597 else if (ch == 'w' && MyMatchLongOption(&psz, RT_STR_TUPLE("write-backdoor"))) 368 598 { … … 373 603 else 374 604 { 375 DosWrite(g_hStdErr, RT_STR_TUPLE("Os2util: syntax error: "), &usIgnored);376 DosWrite(g_hStdErr, pszOptStart, MyStrLen(pszOptStart), &usIgnored);377 DosWrite(g_hStdErr, RT_STR_TUPLE("\r\n"), &usIgnored);605 MyOutStr("Os2util: syntax error: "); 606 MyOutStr(pszOptStart); 607 MyOutStr("\r\n"); 378 608 DosExit(EXIT_PROCESS, 2); 379 609 } … … 399 629 DosExit(EXIT_PROCESS, 0); 400 630 } 631 else if (ch == 'z') 632 { 633 if (cAsZero > RT_ELEMENTS(auAsZero)) 634 MySyntaxErrorAndQuit("Too many --as-zero/-z options"); 635 psz = MyGetOptNum(psz + 1, "-z", &auAsZero[cAsZero]); 636 cAsZero++; 637 } 401 638 else if (ch == '?' || ch == 'h' || ch == 'H') 402 639 ShowUsageAndQuit(); 640 else if (ch == 'V') 641 ShowVersionAndQuit(); 403 642 else 404 643 { 405 DosWrite(g_hStdErr, RT_STR_TUPLE("Os2util: syntax error: "), &usIgnored);644 MyOutStr("Os2util: syntax error: "); 406 645 if (ch) 407 646 DosWrite(g_hStdErr, &ch, 1, &usIgnored); 408 647 else 409 DosWrite(g_hStdErr, RT_STR_TUPLE("lone dash"), &usIgnored);410 DosWrite(g_hStdErr, RT_STR_TUPLE(" ("), &usIgnored);411 DosWrite(g_hStdErr, pszOptStart, MyStrLen(pszOptStart), &usIgnored);412 DosWrite(g_hStdErr, RT_STR_TUPLE(")\r\n"), &usIgnored);648 MyOutStr("lone dash"); 649 MyOutStr(" ("); 650 MyOutStr(pszOptStart); 651 MyOutStr(")\r\n"); 413 652 DosExit(EXIT_PROCESS, 2); 414 653 } … … 425 664 if (ch == '\0') 426 665 { 427 DosWrite(g_hStdErr, RT_STR_TUPLE("Os2Util: syntax error: No program specified\r\n"), &usIgnored);666 MyOutStr("Os2Util: syntax error: No program specified\r\n"); 428 667 DosExit(EXIT_PROCESS, 2); 429 668 } … … 434 673 435 674 /* 675 * Find the executable and check its type. 676 */ 677 if ( pszzNewCmdLine[1] == ':' 678 || MyStrChr(pszzNewCmdLine, '\\') 679 || MyStrChr(pszzNewCmdLine, '/')) 680 pszExe = pszzNewCmdLine; 681 else 682 { 683 rc = DosSearchPath(SEARCH_CUR_DIRECTORY | SEARCH_ENVIRONMENT | SEARCH_IGNORENETERRS, "PATH", 684 pszzNewCmdLine, szExeFull, sizeof(szExeFull)); 685 if (rc != NO_ERROR) 686 MyApiError3AndQuit("DosSearchPath(7, \"PATH\", \"", pszzNewCmdLine, "\",,)", rc); 687 pszExe = &szExeFull[0]; 688 } 689 690 /* Perhapse we should use WinQueryProgramType here instead? */ 691 rc = DosQAppType(pszExe, &uExeType); 692 if (rc != NO_ERROR) 693 MyApiErrorAndQuit("DosQAppType(pszExe, &uExeType)", rc); 694 #ifdef DEBUG 695 MyOutStr("Os2Util: debug: uExeType="); MyOutNum(uExeType); MyOutStr("\r\n"); 696 #endif 697 /** @todo deal with launching winos2 programs too... */ 698 699 /* 436 700 * Prepare redirection. 437 701 */ … … 445 709 rc = DosDupHandle(g_hStdErr, &hDup); 446 710 if (rc != NO_ERROR) 447 MyApiErrorAndQuit("DosDupHandle(g_hStdErr, &hDup) ;", rc);711 MyApiErrorAndQuit("DosDupHandle(g_hStdErr, &hDup)", rc); 448 712 g_hStdErr = hDup; 449 713 DosSetFHandState(hDup, OPEN_FLAGS_NOINHERIT); /* not strictly necessary, so ignore errors */ … … 452 716 rc = DosDupHandle(g_hStdOut, &hDup); 453 717 if (rc != NO_ERROR) 454 MyApiErrorAndQuit("DosDupHandle(g_hStdOut, &hDup) ;", rc);718 MyApiErrorAndQuit("DosDupHandle(g_hStdOut, &hDup)", rc); 455 719 g_hStdOut = hDup; 456 720 DosSetFHandState(hDup, OPEN_FLAGS_NOINHERIT); /* not strictly necessary, so ignore errors */ … … 469 733 rc = DosDupHandle(hPipeWrite, &hDup); 470 734 if (rc != NO_ERROR) 471 MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=1]) ;", rc);735 MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=1])", rc); 472 736 473 737 hDup = 2; 474 738 rc = DosDupHandle(hPipeWrite, &hDup); 475 739 if (rc != NO_ERROR) 476 MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=2]) ;", rc);740 MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=2])", rc); 477 741 478 742 /* We can close the write end of the pipe as we don't need the original handle any more. */ … … 484 748 */ 485 749 szBuf[0] = '\0'; 486 rc = DosExecPgm(szBuf, sizeof(szBuf), hPipeRead == -1 ? EXEC_SYNC : EXEC_ASYNCRESULT, 487 pszzNewCmdLine, pszzEnv, &ResultCodes, pszzNewCmdLine); 488 if (rc != NO_ERROR) 489 { 490 MyOutStr("Os2Util: error: DosExecPgm failed for \""); 491 MyOutStr(pszzNewCmdLine); 492 MyOutStr("\": "); 493 MyOutNum(rc); 494 if (szBuf[0]) 495 { 496 MyOutStr(" ErrObj="); 497 szBuf[sizeof(szBuf) - 1] = '\0'; 498 MyOutStr(szBuf); 499 } 500 MyOutStr("\r\n"); 501 DosExit(EXIT_PROCESS, 1); 750 #define FAPPTYP_TYPE_MASK 7 751 if ((uExeType & FAPPTYP_TYPE_MASK) == PT_WINDOWABLEVIO) /** @todo what if we're in fullscreen ourselves? */ 752 { 753 /* For same type programs we can use DosExecPgm: */ 754 rc = DosExecPgm(szBuf, sizeof(szBuf), hPipeRead == -1 ? EXEC_SYNC : EXEC_ASYNCRESULT, 755 pszzNewCmdLine, pszzEnv, &ResultCodes, pszExe); 756 if (rc != NO_ERROR) 757 { 758 MyOutStr("Os2Util: error: DosExecPgm failed for \""); 759 MyOutStr(pszzNewCmdLine); 760 MyOutStr("\": "); 761 MyOutNum(rc); 762 if (szBuf[0]) 763 { 764 MyOutStr(" ErrObj="); 765 szBuf[sizeof(szBuf) - 1] = '\0'; 766 MyOutStr(szBuf); 767 } 768 MyOutStr("\r\n"); 769 DosExit(EXIT_PROCESS, 1); 770 } 771 if (hPipeRead != -1) 772 pidChild = ResultCodes.codeTerminate; 773 } 774 else 775 { 776 /* For different typed programs we have to use DosStartSession, which 777 is a lot more tedious to use. */ 778 static const char s_szQueueBase[] = "\\QUEUES\\OS2_UTIL-"; 779 union 780 { 781 STARTDATA StartData; 782 BYTE abPadding[sizeof(STARTDATA) + 64]; 783 struct 784 { 785 STARTDATA Core; 786 ULONG ulReserved; 787 PSZ pszBuf; 788 USHORT cbBuf; 789 } s; 790 } u; 791 PIDINFO PidInfo = {0, 0, 0}; 792 793 /* Create the wait queue first. */ 794 DosGetPID(&PidInfo); 795 MyMemCopy(szQueueName, s_szQueueBase, sizeof(s_szQueueBase)); 796 MyNumToString(&szQueueName[sizeof(s_szQueueBase) - 1], PidInfo.pid); 797 798 rc = DosCreateQueue(&hQueue, 0 /*FIFO*/, szQueueName); 799 if (rc != NO_ERROR) 800 MyApiError3AndQuit("DosCreateQueue(&hQueue, 0, \"", szQueueName, "\")", rc); 801 802 u.StartData.Length = sizeof(u.StartData); 803 u.StartData.Related = 1 /* SSF_RELATED_CHILD */; 804 u.StartData.FgBg = 0 /* SSF_FGBG_FORE */; 805 u.StartData.TraceOpt = 0 /* SSF_TRACEOPT_NONE */; 806 u.StartData.PgmTitle = NULL; 807 u.StartData.PgmName = pszExe; 808 u.StartData.PgmInputs = psz; /* just arguments, not exec apparently.*/ 809 u.StartData.TermQ = szQueueName; 810 u.StartData.Environment = NULL; /* Inherit our env. Note! Using pszzEnv causes it to be freed 811 and we'll crash reporting the error. */ 812 u.StartData.InheritOpt = 1 /* SSF_INHERTOPT_PARENT */; 813 u.StartData.SessionType = uExeType & FAPPTYP_TYPE_MASK; 814 if (uExeType & 0x20 /*FAPPTYP_DOS*/) 815 u.StartData.SessionType = 4 /* SSF_TYPE_VDM */; 816 u.StartData.IconFile = NULL; 817 u.StartData.PgmHandle = 0; 818 u.StartData.PgmControl = 0 /* SSF_CONTROL_VISIBLE */; 819 u.StartData.InitXPos = 0; 820 u.StartData.InitYPos = 0; 821 u.StartData.InitXSize = 0; 822 u.StartData.InitYSize = 0; 823 u.s.ulReserved = 0; 824 u.s.pszBuf = NULL; 825 u.s.cbBuf = 0; 826 827 rc = DosStartSession(&u.StartData, &idSession, &pidChild); 828 if (rc != NO_ERROR) 829 { 830 DosCloseQueue(hQueue); 831 MyApiError3AndQuit("DosStartSession for \"", pszExe, "\"", rc); 832 } 502 833 } 503 834 … … 507 838 if (hPipeRead != -1) 508 839 { 509 /* Save the child pid. */510 PID const pidChild = ResultCodes.codeTerminate;511 PID pidIgnored;512 840 513 841 /* Close the write handles or we'll hang in the read loop. */ … … 517 845 /* Disable hard error popups (file output to unformatted disks). */ 518 846 DosError(2 /* only exceptions */); 519 520 847 521 848 /* … … 538 865 /* Backdoor: */ 539 866 if (fTeeToBackdoor) 540 VBoxBackdoorPrint( psz, cbRead);867 VBoxBackdoorPrint(szBuf, cbRead); 541 868 542 869 /* File: */ … … 560 887 561 888 DosClose(hPipeRead); 562 rc = DosCwait(DCWA_PROCESS, DCWW_WAIT, &ResultCodes, &pidIgnored, pidChild); 563 if (rc != NO_ERROR) 564 { 565 MyOutStr("Os2Util: error: DosCwait(DCWA_PROCESS,DCWW_WAIT,,,"); 566 MyOutNum(pidChild); 567 MyOutStr(") failed: "); 568 MyOutNum(rc); 569 MyOutStr("\r\n"); 570 } 571 } 889 890 /* 891 * Wait for the process to complete. 892 */ 893 DoWait(pidChild, idSession, hQueue, &ResultCodes); 894 } 895 /* 896 * Must wait for the session completion too. 897 */ 898 else if (idSession != 0) 899 DoWait(pidChild, idSession, hQueue, &ResultCodes); 572 900 573 901 /* … … 585 913 MyOutStr("\r\n"); 586 914 915 /* Treat it as zero? */ 916 if (ResultCodes.codeTerminate == 0) 917 { 918 unsigned i = cAsZero; 919 while (i-- > 0) 920 if (auAsZero[i] == ResultCodes.codeResult) 921 { 922 MyOutStr("Os2Util: info: treating status as zero\r\n"); 923 ResultCodes.codeResult = 0; 924 break; 925 } 926 } 927 928 if (idSession != 0) 929 DosCloseQueue(hQueue); 587 930 for (;;) 588 931 DosExit(EXIT_PROCESS, ResultCodes.codeTerminate == 0 ? ResultCodes.codeResult : 127);
Note:
See TracChangeset
for help on using the changeset viewer.