From c5552d3f757b00212e35eeafd033e1343f46b5ce Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 15 Nov 2014 13:50:49 +0100 Subject: [PATCH] Improve execute() to take FDs instead of filenames This means that execute() no longer needs to recreate the temporary stdout/stderr files needlessly. Note: ccache will no longer build on win32 after this change, but I don't know what needs to be done to win32execute(). I leave that to those who know. --- ccache.c | 56 +++++++++++++++++++++++++++---------------------------- ccache.h | 5 ++--- execute.c | 17 ++--------------- 3 files changed, 32 insertions(+), 46 deletions(-) diff --git a/ccache.c b/ccache.c index 0f5ca1f1a..0da051391 100644 --- a/ccache.c +++ b/ccache.c @@ -734,12 +734,12 @@ to_cache(struct args *args) { char *tmp_stdout, *tmp_stderr, *tmp_dia; struct stat st; - int status; + int status, tmp_stdout_fd, tmp_stderr_fd; tmp_stdout = format("%s.tmp.stdout", cached_obj); - create_empty_tmp_file(&tmp_stdout); + tmp_stdout_fd = create_tmp_fd(&tmp_stdout); tmp_stderr = format("%s.tmp.stderr", cached_obj); - create_empty_tmp_file(&tmp_stderr); + tmp_stderr_fd = create_tmp_fd(&tmp_stderr); args_add(args, "-o"); args_add(args, output_obj); @@ -766,7 +766,7 @@ to_cache(struct args *args) } cc_log("Running real compiler"); - status = execute(args->argv, tmp_stdout, tmp_stderr); + status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd); args_pop(args, 3); if (stat(tmp_stdout, &st) != 0) { @@ -954,7 +954,7 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) char *input_base; char *tmp; char *path_stdout, *path_stderr; - int status; + int status, path_stderr_fd; struct file_hash *result; /* ~/hello.c -> tmp.hello.123.i @@ -971,34 +971,28 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) } path_stderr = format("%s/tmp.cpp_stderr", temp_dir()); - create_empty_tmp_file(&path_stderr); + path_stderr_fd = create_tmp_fd(&path_stderr); add_pending_tmp_file(path_stderr); time_of_compilation = time(NULL); - if (!direct_i_file) { - /* The temporary file needs the proper i_extension for the compiler to do - * its thing. However, create_empty_tmp_file appends a suffix to the - * filename, which is why the temporary file is created in two steps. */ - char *path_stdout_tmp = format("%s/%s.tmp", temp_dir(), input_base); - create_empty_tmp_file(&path_stdout_tmp); - path_stdout = format("%s.%s", path_stdout_tmp, conf->cpp_extension); - x_rename(path_stdout_tmp, path_stdout); - free(path_stdout_tmp); + if (direct_i_file) { + /* We are compiling a .i or .ii file - that means we can skip the cpp stage + * and directly form the correct i_tmpfile. */ + path_stdout = input_file; + status = 0; + } else { + /* Run cpp on the input file to obtain the .i. */ + int path_stdout_fd; + path_stdout = format("%s/%s.stdout", temp_dir(), input_base); + path_stdout_fd = create_tmp_fd(&path_stdout); add_pending_tmp_file(path_stdout); - /* run cpp on the input file to obtain the .i */ args_add(args, "-E"); args_add(args, input_file); cc_log("Running preprocessor"); - status = execute(args->argv, path_stdout, path_stderr); + status = execute(args->argv, path_stdout_fd, path_stderr_fd); args_pop(args, 2); - } else { - /* we are compiling a .i or .ii file - that means we - can skip the cpp stage and directly form the - correct i_tmpfile */ - path_stdout = input_file; - status = 0; } if (status != 0) { @@ -1008,10 +1002,8 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) } if (conf->unify) { - /* - * When we are doing the unifying tricks we need to include the - * input file name in the hash to get the warnings right. - */ + /* When we are doing the unifying tricks we need to include the input file + * name in the hash to get the warnings right. */ hash_delimiter(hash, "unifyfilename"); hash_string(hash, input_file); @@ -1034,7 +1026,15 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) fatal("Failed to open %s: %s", path_stderr, strerror(errno)); } - i_tmpfile = path_stdout; + if (direct_i_file) { + i_tmpfile = input_file; + } else { + /* i_tmpfile needs the proper cpp_extension for the compiler to do its + * thing correctly. */ + i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension); + x_rename(path_stdout, i_tmpfile); + add_pending_tmp_file(i_tmpfile); + } if (conf->run_second_cpp) { free(path_stderr); diff --git a/ccache.h b/ccache.h index 241f63194..6fdd55f6c 100644 --- a/ccache.h +++ b/ccache.h @@ -209,9 +209,7 @@ void wipe_all(struct conf *conf); /* ------------------------------------------------------------------------- */ /* execute.c */ -int execute(char **argv, - const char *path_stdout, - const char *path_stderr); +int execute(char **argv, int fd_out, int fd_err); char *find_executable(const char *name, const char *exclude_name); void print_command(FILE *fp, char **argv); @@ -262,6 +260,7 @@ int win32execute(char *path, char **argv, int doreturn, # define link(src,dst) (CreateHardLink(dst,src,NULL) ? 0 : -1) # define lstat(a,b) stat(a,b) # define execv(a,b) win32execute(a,b,0,NULL,NULL) +#error TODO: Adapt win32execute to new execute API # define execute(a,b,c) win32execute(*(a),a,1,b,c) # define PATH_DELIM ";" # define F_RDLCK 0 diff --git a/execute.c b/execute.c index 9f7dbe97b..7bc86f06c 100644 --- a/execute.c +++ b/execute.c @@ -175,25 +175,12 @@ win32execute(char *path, char **argv, int doreturn, the full path to the compiler to run is in argv[0] */ int -execute(char **argv, const char *path_stdout, const char *path_stderr) +execute(char **argv, int fd_out, int fd_err) { pid_t pid; - int status, fd_out, fd_err; + int status; cc_log_argv("Executing ", argv); - - tmp_unlink(path_stdout); - fd_out = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); - if (fd_out == -1) { - fatal("Error creating %s: %s", path_stdout, strerror(errno)); - } - - tmp_unlink(path_stderr); - fd_err = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); - if (fd_err == -1) { - fatal("Error creating %s: %s", path_stderr, strerror(errno)); - } - pid = fork(); if (pid == -1) fatal("Failed to fork: %s", strerror(errno)); -- 2.47.2