From d9ceae7315298445c975f571f0417a4553e0ae32 Mon Sep 17 00:00:00 2001 From: Oliver Reiche Date: Wed, 31 May 2023 12:14:57 +0200 Subject: Avoid potential malloc between fork/exec --- src/buildtool/system/system_command.hpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/buildtool/system/system_command.hpp') diff --git a/src/buildtool/system/system_command.hpp b/src/buildtool/system/system_command.hpp index 5bec9ad1..13655730 100644 --- a/src/buildtool/system/system_command.hpp +++ b/src/buildtool/system/system_command.hpp @@ -155,6 +155,15 @@ class SystemCommand { int out_fd, int err_fd) const noexcept -> std::optional { + auto const* cwd_cstr = cwd.c_str(); + + // some executables require an open (possibly seekable) stdin, and + // therefore, we use an open temporary file that does not appear on the + // file system and will be removed automatically once the descriptor is + // closed. + gsl::owner in_file = std::tmpfile(); + auto in_fd = fileno(in_file); + // fork child process pid_t pid = ::fork(); if (-1 == pid) { @@ -166,12 +175,7 @@ class SystemCommand { // dispatch child/parent process if (pid == 0) { - // some executables require an open (possibly seekable) stdin, and - // therefore, we use an open temporary file that does not appear - // on the file system and will be removed automatically once the - // descriptor is closed. - gsl::owner in_file = std::tmpfile(); - auto in_fd = fileno(in_file); + ::chdir(cwd_cstr); // redirect and close fds ::dup2(in_fd, STDIN_FILENO); @@ -181,24 +185,24 @@ class SystemCommand { ::close(out_fd); ::close(err_fd); - [[maybe_unused]] auto anchor = - FileSystemManager::ChangeDirectory(cwd); - // execute command in child process and exit ::execvpe(*cmd, cmd, envp); // report error and terminate child process if ::execvp did not exit - std::cerr << fmt::format("Failed to execute '{}' with error: {}", - *cmd, - strerror(errno)) - << std::endl; + // NOLINTNEXTLINE + printf("Failed to execute '%s' with error: %s\n", + *cmd, + strerror(errno)); System::ExitWithoutCleanup(EXIT_FAILURE); } + ::close(in_fd); + // wait for child to finish and obtain return value int status{}; ::waitpid(pid, &status, 0); + // NOLINTNEXTLINE(hicpp-signed-bitwise) return WEXITSTATUS(status); } -- cgit v1.2.3