]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Improve temporary file creation functions and usage
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 15 Nov 2014 12:16:40 +0000 (13:16 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 15 Nov 2014 12:30:38 +0000 (13:30 +0100)
ccache.c
ccache.h
conf.c
manifest.c
stats.c
util.c

index dcdb3f430b2ccc98c5c9b5871a435f9e082bef37..0f5ca1f1ae5a070768b2a4b0de722c0ef9570a40 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -736,14 +736,10 @@ to_cache(struct args *args)
        struct stat st;
        int status;
 
-       if (create_parent_dirs(cached_obj) != 0) {
-               fatal("Failed to create parent directory for %s: %s",
-                     cached_obj, strerror(errno));
-       }
-       tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
-       create_empty_file(tmp_stdout);
-       tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
-       create_empty_file(tmp_stderr);
+       tmp_stdout = format("%s.tmp.stdout", cached_obj);
+       create_empty_tmp_file(&tmp_stdout);
+       tmp_stderr = format("%s.tmp.stderr", cached_obj);
+       create_empty_tmp_file(&tmp_stderr);
 
        args_add(args, "-o");
        args_add(args, output_obj);
@@ -974,23 +970,18 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
                input_base[10] = 0;
        }
 
-       path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir(), tmp_string());
-       if (create_parent_dirs(path_stderr) != 0) {
-               fatal("Failed to create parent directory for %s: %s\n",
-                     path_stderr, strerror(errno));
-       }
-       create_empty_file(path_stderr);
+       path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
+       create_empty_tmp_file(&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_file requires the tmp_string() part to
-                * be last, which is why the temporary file is created in two steps. */
-               char *path_stdout_tmp =
-                       format("%s/%s.tmp.%s", temp_dir(), input_base, tmp_string());
-               create_empty_file(path_stdout_tmp);
+                * 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);
index a98bd94e2ea976cffbc48852ada1e8108c253c67..241f6319426ea2ab0b67390186adf5d334405727 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -150,7 +150,9 @@ char *gnu_getcwd(void);
 #ifndef HAVE_STRTOK_R
 char *strtok_r(char *str, const char *delim, char **saveptr);
 #endif
-int create_empty_file(char *fname);
+int create_tmp_fd(char **fname);
+FILE *create_tmp_file(char **fname, const char *mode);
+void create_empty_tmp_file(char **fname);
 const char *get_home_directory(void);
 char *get_cwd(void);
 bool same_executable_name(const char *s1, const char *s2);
diff --git a/conf.c b/conf.c
index 56adb484ecd4079906e50aef03f930c5d98f7b79..92c70c0648d5f5339fc28c889107f32f61c4bbb9 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -474,8 +474,8 @@ conf_set_value_in_file(const char *path, const char *key, const char *value,
                return false;
        }
 
-       outpath = format("%s.tmp.%s", path, tmp_string());
-       outfile = fopen(outpath, "w");
+       outpath = format("%s.tmp", path);
+       outfile = create_tmp_file(&outpath, "w");
        if (!outfile) {
                *errmsg = format("%s: %s", outpath, strerror(errno));
                free(outpath);
index 4d652eedd868054b835a20cb9eaf3734ae0d3f9f..6eb53fd92996ef9f9cff65bf07d9f044be97e47d 100644 (file)
@@ -736,18 +736,8 @@ manifest_put(const char *manifest_path, struct file_hash *object_hash,
                mf = create_empty_manifest();
        }
 
-       tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());
-       fd2 = mkstemp(tmp_file);
-       if (fd2 == -1 && errno == ENOENT) {
-               if (create_parent_dirs(tmp_file) == 0) {
-                       reformat(&tmp_file, "%s.tmp.%s", manifest_path, tmp_string());
-                       fd2 = mkstemp(tmp_file);
-               }
-       }
-       if (fd2 == -1) {
-               cc_log("Failed to open %s", tmp_file);
-               goto out;
-       }
+       tmp_file = format("%s.tmp", manifest_path);
+       fd2 = create_tmp_fd(&tmp_file);
        f2 = gzdopen(fd2, "wb");
        if (!f2) {
                cc_log("Failed to gzdopen %s", tmp_file);
diff --git a/stats.c b/stats.c
index 16aaa9fe312438812a7a2f6700a78ad30a456947..71fbb7af6af14b554bef7dd65836e8df9e56a542 100644 (file)
--- a/stats.c
+++ b/stats.c
@@ -130,35 +130,16 @@ stats_write(const char *path, struct counters *counters)
        size_t i;
        char *tmp_file;
        FILE *f;
-       int fd;
-
-       tmp_file = format("%s.tmp.%s", path, tmp_string());
-       fd = mkstemp(tmp_file);
-       if (fd == -1 && errno == ENOENT) {
-               if (create_parent_dirs(tmp_file) == 0) {
-                       reformat(&tmp_file, "%s.tmp.%s", path, tmp_string());
-                       fd = mkstemp(tmp_file);
-               }
-       }
-       if (fd == -1) {
-               cc_log("Failed to open %s", tmp_file);
-               close(fd);
-               goto end;
-       }
-       f = fdopen(fd, "wb");
-       if (!f) {
-               cc_log("Failed to open %s", tmp_file);
-               goto end;
-       }
+
+       tmp_file = format("%s.tmp", path);
+       f = create_tmp_file(&tmp_file, "wb");
        for (i = 0; i < counters->size; i++) {
                if (fprintf(f, "%u\n", counters->data[i]) < 0) {
                        fatal("Failed to write to %s", tmp_file);
                }
        }
-       fclose(f); /* This also implicitly closes the fd. */
+       fclose(f);
        x_rename(tmp_file, path);
-
-end:
        free(tmp_file);
 }
 
diff --git a/util.c b/util.c
index 8dbf01a454fadd4dd4b2350e0862062dd4775ee1..072f53b9bf602fab8998768dd4582aa373636b97 100644 (file)
--- a/util.c
+++ b/util.c
@@ -241,15 +241,9 @@ copy_file(const char *src, const char *dest, int compress_level)
        struct stat st;
        int errnum;
 
-       tmp_name = format("%s.%s", dest, tmp_string());
-
        /* open destination file */
-       fd_out = mkstemp(tmp_name);
-       if (fd_out == -1) {
-               cc_log("mkstemp error: %s", strerror(errno));
-               goto error;
-       }
-
+       tmp_name = x_strdup(dest);
+       fd_out = create_tmp_fd(&tmp_name);
        cc_log("Copying %s to %s via %s (%scompressed)",
               src, dest, tmp_name, compress_level > 0 ? "" : "un");
 
@@ -1022,19 +1016,53 @@ strtok_r(char *str, const char *delim, char **saveptr)
 }
 #endif
 
-/* create an empty file */
+/*
+ * Create an empty temporary file. *fname will be reallocated and set to the
+ * resulting filename. Returns an open file descriptor to the file.
+ */
 int
-create_empty_file(char *fname)
+create_tmp_fd(char **fname)
 {
-       int fd;
-
-       fd = mkstemp(fname);
+       char *template = format("%s.%s", *fname, tmp_string());
+       int fd = mkstemp(template);
+       if (fd == -1 && errno == ENOENT) {
+               if (create_parent_dirs(template) != 0) {
+                       fatal("Failed to create directory %s: %s",
+                             dirname(template), strerror(errno));
+               }
+               reformat(&template, "%s.%s", *fname, tmp_string());
+               fd = mkstemp(template);
+       }
        if (fd == -1) {
-               cc_log("Failed to create %s: %s", fname, strerror(errno));
-               return -1;
+               fatal("Failed to create file %s: %s", template, strerror(errno));
        }
-       close(fd);
-       return 0;
+       free(*fname);
+       *fname = template;
+       return fd;
+}
+
+/*
+ * Create an empty temporary file. *fname will be reallocated and set to the
+ * resulting filename. Returns an open FILE*.
+ */
+FILE *
+create_tmp_file(char **fname, const char *mode)
+{
+       FILE *file = fdopen(create_tmp_fd(fname), mode);
+       if (!file) {
+               fatal("Failed to create file %s: %s", *fname, strerror(errno));
+       }
+       return file;
+}
+
+/*
+ * Create an empty temporary file. *fname will be reallocated and set to the
+ * resulting filename.
+ */
+void
+create_empty_tmp_file(char **fname)
+{
+       close(create_tmp_fd(fname));
 }
 
 /*
@@ -1263,7 +1291,7 @@ x_unlink(const char *path)
         * file. We don't care if the temp file is trashed, so it's always safe to
         * unlink it first.
         */
-       char *tmp_name = format("%s.%s.rmXXXXXX", path, tmp_string());
+       char *tmp_name = format("%s.rm.%s", path, tmp_string());
        int result = 0;
        cc_log("Unlink %s via %s", path, tmp_name);
        if (x_rename(path, tmp_name) == -1) {