]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Copy directly from cache to destination file instead of via tmp file
authorJoel Rosdahl <joel@rosdahl.net>
Fri, 22 May 2020 19:16:48 +0000 (21:16 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Fri, 22 May 2020 19:16:48 +0000 (21:16 +0200)
ccache copies files to the cache via a temporary file which is then
renamed into place. For simplicity reasons the same file copy function
is used when copying files from the cache as well. This however makes
ccache fail for very long destination filenames.

Fix this by introducing a “via_tmp_file” parameter to copy_file, similar
to how it works on master.

Closes #593.

src/ccache.c
src/ccache.h
src/util.c

index 54e8f21e08b8a8247115ce6c17c30deb2240efb1..7ad1f3b3433ada61efd748d01d8385844ad6abda 100644 (file)
@@ -1237,7 +1237,7 @@ do_copy_or_move_file_to_cache(const char *source, const char *dest, bool copy)
                        }
                }
                if (!do_link) {
-                       int ret = copy_file(source, dest, compression_level);
+                       int ret = copy_file(source, dest, compression_level, true);
                        if (ret != 0) {
                                cc_log("Failed to copy %s to %s: %s", source, dest, strerror(errno));
                                stats_update(STATS_ERROR);
@@ -1307,7 +1307,7 @@ do_copy_or_link_file_from_cache(const char *source, const char *dest, bool copy)
                x_unlink(dest);
                ret = link(source, dest);
        } else {
-               ret = copy_file(source, dest, 0);
+               ret = copy_file(source, dest, 0, false);
        }
 
        if (ret == -1) {
index 0d6be609a01c4e111aea6b34fad7b268a19e2993..e5524a6dac4cba0d31aa4db921cc485b278a5e67 100644 (file)
@@ -149,7 +149,8 @@ void fatal(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
 void warn(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 
 void copy_fd(int fd_in, int fd_out);
-int copy_file(const char *src, const char *dest, int compress_level);
+int copy_file(const char *src, const char *dest, int compress_level,
+              bool via_tmp_file);
 int move_file(const char *src, const char *dest, int compress_level);
 int move_uncompressed_file(const char *src, const char *dest,
                            int compress_level);
index 0fd3f0fe3b53eb9f9627ca8f3b7879231ca82268..eff2eed02f1ab026c072e1a7aa1307a355eba6d8 100644 (file)
@@ -315,18 +315,34 @@ get_umask(void)
 // whether dest will be compressed, and with which compression level. Returns 0
 // on success and -1 on failure. On failure, errno represents the error.
 int
-copy_file(const char *src, const char *dest, int compress_level)
+copy_file(const char *src,
+          const char *dest,
+          int compress_level,
+          bool via_tmp_file)
 {
        int fd_out;
+       char *tmp_name = NULL;
        gzFile gz_in = NULL;
        gzFile gz_out = NULL;
        int saved_errno = 0;
 
        // Open destination file.
-       char *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");
+       if (via_tmp_file) {
+               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");
+       } else {
+               fd_out = open(dest, O_WRONLY | O_CREAT | O_BINARY, 0666);
+               if (fd_out == -1) {
+                       saved_errno = errno;
+                       close(fd_out);
+                       errno = saved_errno;
+                       return -1;
+               }
+               cc_log("Copying %s to %s (%scompressed)",
+                      src, dest, compress_level > 0 ? "" : "un");
+       }
 
        // Open source file.
        int fd_in = open(src, O_RDONLY | O_BINARY);
@@ -410,8 +426,10 @@ copy_file(const char *src, const char *dest, int compress_level)
                        gzclose(gz_out);
                }
                close(fd_out);
-               tmp_unlink(tmp_name);
-               free(tmp_name);
+               if (via_tmp_file) {
+                       tmp_unlink(tmp_name);
+                       free(tmp_name);
+               }
                return -1;
        }
 
@@ -433,13 +451,15 @@ copy_file(const char *src, const char *dest, int compress_level)
                goto error;
        }
 
-       if (x_rename(tmp_name, dest) == -1) {
-               saved_errno = errno;
-               cc_log("rename error: %s", strerror(saved_errno));
-               goto error;
-       }
+       if (via_tmp_file) {
+               if (x_rename(tmp_name, dest) == -1) {
+                       saved_errno = errno;
+                       cc_log("rename error: %s", strerror(saved_errno));
+                       goto error;
+               }
 
-       free(tmp_name);
+               free(tmp_name);
+       }
 
        return 0;
 
@@ -453,8 +473,10 @@ error:
        if (fd_out != -1) {
                close(fd_out);
        }
-       tmp_unlink(tmp_name);
-       free(tmp_name);
+       if (via_tmp_file) {
+               tmp_unlink(tmp_name);
+               free(tmp_name);
+       }
        errno = saved_errno;
        return -1;
 }
@@ -463,7 +485,7 @@ error:
 int
 move_file(const char *src, const char *dest, int compress_level)
 {
-       int ret = copy_file(src, dest, compress_level);
+       int ret = copy_file(src, dest, compress_level, true);
        if (ret != -1) {
                x_unlink(src);
        }