diff options
author | kientzle <kientzle@FreeBSD.org> | 2008-06-21 17:47:56 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2008-06-21 17:47:56 +0000 |
commit | c0709d3e410563b2a2e5a24d2d62213ae61db682 (patch) | |
tree | 9968edc22732384ed881ec64c5fb63ffcae7b263 /usr.bin | |
parent | d3bd62e8051581bfc33d309594ddb5c7cf8e2c79 (diff) | |
download | FreeBSD-src-c0709d3e410563b2a2e5a24d2d62213ae61db682.zip FreeBSD-src-c0709d3e410563b2a2e5a24d2d62213ae61db682.tar.gz |
If we're using -l and can't hardlink the file because of a cross-device
link, just ignore the -l option and copy the file instead.
In particular, this should fix the COPYTREE_* macros used in the
ports infrastructure which use -l to preserve space but often get
used for cross-device copies.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/cpio/cpio.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/usr.bin/cpio/cpio.c b/usr.bin/cpio/cpio.c index 715fb95..e6904a5 100644 --- a/usr.bin/cpio/cpio.c +++ b/usr.bin/cpio/cpio.c @@ -537,14 +537,28 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry) * Obviously, this only gets invoked in pass mode. */ if (cpio->option_link) { - /* Note: link(2) doesn't create parent directories. */ - archive_entry_set_hardlink(entry, srcpath); - r = archive_write_header(cpio->archive, entry); + struct archive_entry *t; + /* Save the original entry in case we need it later. */ + t = archive_entry_clone(entry); + if (t == NULL) + cpio_errc(1, ENOMEM, "Can't create link"); + /* Note: link(2) doesn't create parent directories, + * so we use archive_write_header() instead. */ + archive_entry_set_hardlink(t, srcpath); + r = archive_write_header(cpio->archive, t); + archive_entry_free(t); if (r != ARCHIVE_OK) cpio_warnc(archive_errno(cpio->archive), archive_error_string(cpio->archive)); if (r == ARCHIVE_FATAL) exit(1); +#ifdef EXDEV + if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { + /* Cross-device link: Just fall through and use + * the original entry to copy the file over. */ + cpio_warnc(0, "Copying file instead"); + } else +#endif return (0); } |