]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
use a file copy rather than a symlink if a hard link fails
authorAndrew Tridgell <tridge@samba.org>
Wed, 27 Mar 2002 05:40:28 +0000 (06:40 +0100)
committerAndrew Tridgell <tridge@samba.org>
Wed, 27 Mar 2002 05:40:28 +0000 (06:40 +0100)
ccache.c
ccache.h
util.c

index c250640ee47f6e58b906fdf3e7e319be946f551a..13fa21da20bbfc8cbc585dd95e609a6abf298bc6 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -237,7 +237,12 @@ static void from_cache(int first)
        unlink(output_file);
        ret = link(hashname, output_file);
        if (ret == -1 && errno != ENOENT) {
-               ret = symlink(hashname, output_file);
+               ret = copy_file(hashname, output_file);
+               if (ret == -1 && errno != ENOENT) {
+                       cc_log("failed to copy %s -> %s (%s)\n", 
+                              hashname, output_file, strerror(errno));
+                       failed();
+               }
        }
        if (ret == 0) {
                utime(output_file, NULL);
index a9dbb23c6f98c1e8fa48a18a6a95209a38f59021..99ea571701faafc5764b47b05f09df5c5e7bc963 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -34,6 +34,7 @@ void cc_log(const char *format, ...);
 void fatal(const char *msg);
 
 void copy_fd(int fd_in, int fd_out);
+int copy_file(const char *src, const char *dest);
 
 int create_dir(const char *dir);
 void x_asprintf(char **ptr, const char *format, ...);
diff --git a/util.c b/util.c
index 0db5f62e375bdfebd0c2f5ccb6e557a693eaf5eb..ed5b72dcc0f653ff4986bc6d0ca627cce54b64cd 100644 (file)
--- a/util.c
+++ b/util.c
@@ -58,6 +58,37 @@ void copy_fd(int fd_in, int fd_out)
        }
 }
 
+/* copy a file - used when hard links don't work */
+int copy_file(const char *src, const char *dest)
+{
+       int fd1, fd2;
+       char buf[10240];
+       int n;
+
+       fd1 = open(src, O_RDONLY);
+       if (fd1 == -1) return -1;
+
+       unlink(dest);
+       fd2 = open(dest, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0666);
+       if (fd2 == -1) {
+               close(fd1);
+               return -1;
+       }
+
+       while ((n = read(fd1, buf, sizeof(buf))) > 0) {
+               if (write(fd2, buf, n) != n) {
+                       close(fd2);
+                       close(fd1);
+                       unlink(dest);
+                       return -1;
+               }
+       }
+
+       close(fd2);
+       close(fd1);
+       return 0;
+}
+
 
 /* make sure a directory exists */
 int create_dir(const char *dir)