]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Improve execute() to take FDs instead of filenames
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 15 Nov 2014 12:50:49 +0000 (13:50 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 15 Nov 2014 14:23:44 +0000 (15:23 +0100)
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
ccache.h
execute.c

index 0f5ca1f1ae5a070768b2a4b0de722c0ef9570a40..0da05139165c9d82633d9d4a9048cfff1a56bcc8 100644 (file)
--- 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);
index 241f6319426ea2ab0b67390186adf5d334405727..6fdd55f6c88e7f1e33275e92a40aa971d2a5109d 100644 (file)
--- 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
index 9f7dbe97b9ded5c1e464699dd359e322dae90c05..7bc86f06c94f510ca4cfb86f7cb4455904cad17c 100644 (file)
--- 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));