- Made conversion-to-bool explicit to avoid build warnings (and potential
runtime errors) on legacy systems.
+- Wait for compiler subprocess (if any) to exit before exiting from a signal.
+ This should fix a race condition (albeit a quite unlikely one) related to
+ removal of the compiler output file(s).
+
ccache 3.2.3
------------
/* Temporary files to remove at program exit. */
static struct pending_tmp_file *pending_tmp_files = NULL;
+/* PID of currently executing compiler that we have started, if any. 0 means no
+ * ongoing compilation. */
+static pid_t compiler_pid = 0;
+
/*
* This is a string that identifies the current "version" of the hash sum
* computed by ccache. If, for any reason, we want to force the hash sum to be
static void
signal_handler(int signo)
{
+ int status;
(void)signo;
clean_up_pending_tmp_files();
+ if (compiler_pid != 0) {
+ /* Wait for compiler subprocess to exit before we snuff it. */
+ waitpid(compiler_pid, &status, 0);
+ }
_exit(1);
}
}
cc_log("Running real compiler");
- status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd);
+ status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
args_pop(args, 3);
if (x_stat(tmp_stdout, &st) != 0) {
args_add(args, "-E");
args_add(args, input_file);
cc_log("Running preprocessor");
- status = execute(args->argv, path_stdout_fd, path_stderr_fd);
+ status = execute(args->argv, path_stdout_fd, path_stderr_fd, &compiler_pid);
args_pop(args, 2);
}
/* ------------------------------------------------------------------------- */
/* execute.c */
-int execute(char **argv, int fd_out, int fd_err);
+int execute(char **argv, int fd_out, int fd_err, pid_t *pid);
char *find_executable(const char *name, const char *exclude_name);
void print_command(FILE *fp, char **argv);
/* Execute a compiler backend, capturing all output to the given paths the full
* path to the compiler to run is in argv[0]. */
int
-execute(char **argv, int fd_out, int fd_err)
+execute(char **argv, int fd_out, int fd_err, pid_t *pid)
{
- pid_t pid;
int status;
cc_log_argv("Executing ", argv);
- pid = fork();
- if (pid == -1) {
+ *pid = fork();
+ if (*pid == -1) {
fatal("Failed to fork: %s", strerror(errno));
}
- if (pid == 0) {
+ if (*pid == 0) {
/* Child. */
dup2(fd_out, 1);
close(fd_out);
close(fd_out);
close(fd_err);
- if (waitpid(pid, &status, 0) != pid) {
+ if (waitpid(*pid, &status, 0) != *pid) {
fatal("waitpid failed: %s", strerror(errno));
}
+ *pid = 0;
if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
return -1;