From: Tim Kientzle Date: Sat, 21 Jun 2008 10:56:12 +0000 (-0400) Subject: When using -l, if a link fails because of a cross-device link, X-Git-Tag: v2.6.0~156 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ab209592500284f49f86bcc60da8560d1f5ce2a;p=thirdparty%2Flibarchive.git When using -l, if a link fails because of a cross-device link, ignore the -l for this entry and copy instead. SVN-Revision: 136 --- diff --git a/cpio/cpio.c b/cpio/cpio.c index 3788611ca..1012f74c1 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -26,7 +26,7 @@ #include "cpio_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $"); #include #include @@ -537,9 +537,16 @@ 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)); @@ -547,8 +554,9 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry) 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"); - archive_entry_set_hardlink(entry, NULL); } else #endif return (0);