use a file copy rather than a symlink if a hard link fails

This commit is contained in:
Andrew Tridgell 2002-03-27 06:40:28 +01:00
parent b93b8ff936
commit 57088bae34
3 changed files with 38 additions and 1 deletions

View File

@ -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);

View File

@ -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, ...);

31
util.c
View File

@ -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)