| 587 | } |
| 588 | |
| 589 | bool BootApp::QueueRun(const String& fileName, const String& args, const String& workingDir, BfpSpawnFlags extraFlags) |
| 590 | { |
| 591 | OutputLine(StrFormat("EXECUTING: %s %s", fileName.c_str(), args.c_str()), OutputPri_Low); |
| 592 | |
| 593 | BfpSpawnFlags spawnFlags = (BfpSpawnFlags)(BfpSpawnFlag_NoWindow | BfpSpawnFlag_RedirectStdOutput | BfpSpawnFlag_RedirectStdError | extraFlags); |
| 594 | BfpSpawn* spawn = BfpSpawn_Create(fileName.c_str(), args.c_str(), workingDir.c_str(), NULL, spawnFlags, NULL); |
| 595 | if (spawn == NULL) |
| 596 | { |
| 597 | Fail(StrFormat("Failed to execute '%s'", fileName.c_str())); |
| 598 | return false; |
| 599 | } |
| 600 | int exitCode = 0; |
| 601 | |
| 602 | OutputContext outputContext;; |
| 603 | outputContext.mIsError = false; |
| 604 | OutputContext errorContext; |
| 605 | errorContext.mIsError = false; |
| 606 | BfpSpawn_GetStdHandles(spawn, NULL, &outputContext.mFile, &errorContext.mFile); |
| 607 | |
| 608 | BfpThread* outputThread = BfpThread_Create(OutputThread, (void*)&outputContext); |
| 609 | BfpThread* errorThread = BfpThread_Create(OutputThread, (void*)&errorContext); |
| 610 | |
| 611 | BfpSpawn_WaitFor(spawn, -1, &exitCode, NULL); |
| 612 | |
| 613 | if (outputContext.mFile != NULL) |
| 614 | BfpFile_Close(outputContext.mFile, NULL); |
| 615 | if (errorContext.mFile != NULL) |
| 616 | BfpFile_Close(errorContext.mFile, NULL); |
| 617 | |
| 618 | BfpThread_WaitFor(outputThread, -1); |
| 619 | BfpThread_WaitFor(errorThread, -1); |
| 620 | |
| 621 | BfpThread_Release(outputThread); |
| 622 | BfpThread_Release(errorThread); |
| 623 | BfpSpawn_Release(spawn); |
| 624 | |
| 625 | if (exitCode != 0) |
| 626 | { |
| 627 | Fail(StrFormat("Exit code returned: %d", exitCode)); |
| 628 | return false; |
| 629 | } |
| 630 | return true; |
| 631 | } |
| 632 | |
| 633 | bool BootApp::CopyFile(const StringImpl& srcPath, const StringImpl& destPath) |
| 634 | { |
nothing calls this directly
no test coverage detected