From: Brendan Shanks Date: Sun, 30 Jun 2024 12:41:31 +0000 (-0700) Subject: perf: Use posix_spawn to execute the compiler (#1471) X-Git-Tag: v4.11~138 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1eb0aa5b9bcf74bd2ca6f161e406da64ccd349af;p=thirdparty%2Fccache.git perf: Use posix_spawn to execute the compiler (#1471) --- diff --git a/src/ccache/execute.cpp b/src/ccache/execute.cpp index 198fbe5e..ac875e72 100644 --- a/src/ccache/execute.cpp +++ b/src/ccache/execute.cpp @@ -41,6 +41,10 @@ #include +#ifdef HAVE_SPAWN_H +# include +#endif + #ifdef HAVE_UNISTD_H # include #endif @@ -299,30 +303,47 @@ execute(Context& ctx, { LOG("Executing {}", util::format_argv_for_logging(argv)); - { - SignalHandlerBlocker signal_handler_blocker; - ctx.compiler_pid = fork(); + int result; + posix_spawn_file_actions_t file_actions; + if ((result = posix_spawn_file_actions_init(&file_actions))) { + throw core::Fatal( + FMT("posix_spawn_file_actions_init failed: {}", strerror(result))); } - if (ctx.compiler_pid == -1) { - throw core::Fatal(FMT("Failed to fork: {}", strerror(errno))); + if ((result = posix_spawn_file_actions_adddup2( + &file_actions, *fd_out, STDOUT_FILENO)) + || (result = posix_spawn_file_actions_addclose(&file_actions, *fd_out)) + || (result = posix_spawn_file_actions_adddup2( + &file_actions, *fd_err, STDERR_FILENO)) + || (result = posix_spawn_file_actions_addclose(&file_actions, *fd_err))) { + throw core::Fatal(FMT("posix_spawn_file_actions_addclose/dup2 failed: {}", + strerror(result))); } - if (ctx.compiler_pid == 0) { - // Child. - dup2(*fd_out, STDOUT_FILENO); - fd_out.close(); - dup2(*fd_err, STDERR_FILENO); - fd_err.close(); - exit(execv(argv[0], const_cast(argv))); + { + SignalHandlerBlocker signal_handler_blocker; + pid_t pid; + extern char** environ; + result = posix_spawn(&pid, + argv[0], + &file_actions, + nullptr, + const_cast(argv), + environ); + if (!result) { + ctx.compiler_pid = pid; + } } + posix_spawn_file_actions_destroy(&file_actions); fd_out.close(); fd_err.close(); - int status; - int result; + if (result) { + return -1; + } + int status; while ((result = waitpid(ctx.compiler_pid, &status, 0)) != ctx.compiler_pid) { if (result == -1 && errno == EINTR) { continue;