diff --git a/hardlink.c b/hardlink.c index a7c7249..3521cb3 100644 --- a/hardlink.c +++ b/hardlink.c @@ -30,6 +30,7 @@ #include #include #include +#include #define NHASH (1<<17) /* Must be a power of 2! */ #define NIOBUF (1<<12) @@ -268,21 +269,22 @@ void rf (const char *name) growstr(&nam2, add2(n2len, suffixlen)); memcpy(nam2.buf, n2, n2len); memcpy(&nam2.buf[n2len], suffix, suffixlen + 1); - if (rename (n2, nam2.buf)) { - fprintf(stderr, "\nFailed to rename %s to %s\n", n2, nam2.buf); + /* First create a temporary link to n1 under a new name */ + if (link(n1, nam2.buf)) { + fprintf(stderr, "\nFailed to hardlink %s to %s (create temporary link as %s failed - %s)\n", n1, n2, nam2.buf, strerror(errno)); free(nam2.buf); continue; } - if (link (n1, n2)) { - fprintf(stderr, "\nFailed to hardlink %s to %s\n", n1, n2); - if (rename (nam2.buf, n2)) { - fprintf(stderr, "\nBad bad - failed to rename back %s to %s\n", nam2.buf, n2); + /* Then rename into place over the existing n2 */ + if (rename (nam2.buf, n2)) { + fprintf(stderr, "\nFailed to hardlink %s to %s (rename temporary link to %s failed - %s)\n", n1, n2, n2, strerror(errno)); + /* Something went wrong, try to remove the now redundant temporary link */ + if (unlink(nam2.buf)) { + fprintf(stderr, "\nFailed to remove temporary link %s - %s\n", nam2.buf, strerror(errno)); } - close(fd); free(nam2.buf); - return; + continue; } - unlink (nam2.buf); free(nam2.buf); } nlinks++;