| @@ -27,6 +27,15 @@ void check_rc(bool b, std::string_view s) { | |||
| ::pid_t | |||
| spawn_child(const std::vector<std::string>& command, int stdout_pipe, int close_me) noexcept { | |||
| // We must allocate BEFORE fork(), since the CRT might stumble with malloc()-related locks that | |||
| // are held during the fork(). | |||
| std::vector<const char*> strings; | |||
| strings.reserve(command.size() + 1); | |||
| for (auto& s : command) { | |||
| strings.push_back(s.data()); | |||
| } | |||
| strings.push_back(nullptr); | |||
| auto child_pid = ::fork(); | |||
| if (child_pid != 0) { | |||
| return child_pid; | |||
| @@ -38,25 +47,19 @@ spawn_child(const std::vector<std::string>& command, int stdout_pipe, int close_ | |||
| rc = dup2(stdout_pipe, STDERR_FILENO); | |||
| check_rc(rc != -1, "Failed to dup2 stderr"); | |||
| std::vector<const char*> strings; | |||
| strings.reserve(command.size() + 1); | |||
| for (auto& s : command) { | |||
| strings.push_back(s.data()); | |||
| } | |||
| strings.push_back(nullptr); | |||
| ::execvp(strings[0], (char* const*)strings.data()); | |||
| if (errno == ENOENT) { | |||
| std::cerr | |||
| << fmt::format("[dds child executor] The requested executable ({}) could not be found.", | |||
| strings[0]); | |||
| std::exit(-1); | |||
| std::quick_exit(-1); | |||
| } | |||
| std::cerr << "[dds child executor] execvp returned! This is a fatal error: " | |||
| << std::system_category().message(errno) << '\n'; | |||
| std::terminate(); | |||
| std::quick_exit(-1); | |||
| } | |||
| } // namespace | |||