| 479 | } |
| 480 | |
| 481 | int ExecuteCommand(const Command &Cmd) { |
| 482 | zx_status_t rc; |
| 483 | |
| 484 | // Convert arguments to C array |
| 485 | auto Args = Cmd.getArguments(); |
| 486 | size_t Argc = Args.size(); |
| 487 | assert(Argc != 0); |
| 488 | std::unique_ptr<const char *[]> Argv(new const char *[Argc + 1]); |
| 489 | for (size_t i = 0; i < Argc; ++i) |
| 490 | Argv[i] = Args[i].c_str(); |
| 491 | Argv[Argc] = nullptr; |
| 492 | |
| 493 | // Determine output. On Fuchsia, the fuzzer is typically run as a component |
| 494 | // that lacks a mutable working directory. Fortunately, when this is the case |
| 495 | // a mutable output directory must be specified using "-artifact_prefix=...", |
| 496 | // so write the log file(s) there. |
| 497 | // However, we don't want to apply this logic for absolute paths. |
| 498 | int FdOut = STDOUT_FILENO; |
| 499 | bool discardStdout = false; |
| 500 | bool discardStderr = false; |
| 501 | |
| 502 | if (Cmd.hasOutputFile()) { |
| 503 | std::string Path = Cmd.getOutputFile(); |
| 504 | if (Path == getDevNull()) { |
| 505 | // On Fuchsia, there's no "/dev/null" like-file, so we |
| 506 | // just don't copy the FDs into the spawned process. |
| 507 | discardStdout = true; |
| 508 | } else { |
| 509 | bool IsAbsolutePath = Path.length() > 1 && Path[0] == '/'; |
| 510 | if (!IsAbsolutePath && Cmd.hasFlag("artifact_prefix")) |
| 511 | Path = Cmd.getFlagValue("artifact_prefix") + "/" + Path; |
| 512 | |
| 513 | FdOut = open(Path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0); |
| 514 | if (FdOut == -1) { |
| 515 | Printf("libFuzzer: failed to open %s: %s\n", Path.c_str(), |
| 516 | strerror(errno)); |
| 517 | return ZX_ERR_IO; |
| 518 | } |
| 519 | } |
| 520 | } |
| 521 | auto CloseFdOut = at_scope_exit([FdOut]() { |
| 522 | if (FdOut != STDOUT_FILENO) |
| 523 | close(FdOut); |
| 524 | }); |
| 525 | |
| 526 | // Determine stderr |
| 527 | int FdErr = STDERR_FILENO; |
| 528 | if (Cmd.isOutAndErrCombined()) { |
| 529 | FdErr = FdOut; |
| 530 | if (discardStdout) |
| 531 | discardStderr = true; |
| 532 | } |
| 533 | |
| 534 | // Clone the file descriptors into the new process |
| 535 | std::vector<fdio_spawn_action_t> SpawnActions; |
| 536 | SpawnActions.push_back(clone_fd_action(STDIN_FILENO, STDIN_FILENO)); |
| 537 | |
| 538 | if (!discardStdout) |
nothing calls this directly
no test coverage detected