diff options
Diffstat (limited to 'lib/libarchive/test/test_write_disk_hardlink.c')
-rw-r--r-- | lib/libarchive/test/test_write_disk_hardlink.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/lib/libarchive/test/test_write_disk_hardlink.c b/lib/libarchive/test/test_write_disk_hardlink.c index f8197c8..6e38d86 100644 --- a/lib/libarchive/test/test_write_disk_hardlink.c +++ b/lib/libarchive/test/test_write_disk_hardlink.c @@ -61,18 +61,48 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); archive_entry_free(ae); - /* Link. */ + /* Link. Size of zero means this doesn't carry data. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "link1b"); - archive_entry_set_mode(ae, S_IFREG | 0600); + archive_entry_set_mode(ae, S_IFREG | 0642); archive_entry_set_size(ae, 0); archive_entry_copy_hardlink(ae, "link1a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(0, archive_write_data(ad, data, sizeof(data))); + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + /* + * Repeat tar approach test, but use unset to mark the + * hardlink as having no data. + */ + + /* Regular file. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2a"); + archive_entry_set_mode(ae, S_IFREG | 0755); + archive_entry_set_size(ae, sizeof(data)); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + /* Link. Unset size means this doesn't carry data. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2b"); + archive_entry_set_mode(ae, S_IFREG | 0642); + archive_entry_unset_size(ae); + archive_entry_copy_hardlink(ae, "link2a"); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); archive_entry_free(ae); @@ -83,7 +113,7 @@ DEFINE_TEST(test_write_disk_hardlink) /* Regular file. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2a"); + archive_entry_copy_pathname(ae, "link3a"); archive_entry_set_mode(ae, S_IFREG | 0600); archive_entry_set_size(ae, sizeof(data)); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); @@ -93,10 +123,10 @@ DEFINE_TEST(test_write_disk_hardlink) /* Link. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2b"); + archive_entry_copy_pathname(ae, "link3b"); archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link2a"); + archive_entry_copy_hardlink(ae, "link3a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); @@ -109,7 +139,7 @@ DEFINE_TEST(test_write_disk_hardlink) /* Regular file. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3a"); + archive_entry_copy_pathname(ae, "link4a"); archive_entry_set_mode(ae, S_IFREG | 0600); archive_entry_set_size(ae, 0); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); @@ -123,10 +153,10 @@ DEFINE_TEST(test_write_disk_hardlink) /* Link. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3b"); + archive_entry_copy_pathname(ae, "link4b"); archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link3a"); + archive_entry_copy_hardlink(ae, "link4a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); @@ -138,36 +168,63 @@ DEFINE_TEST(test_write_disk_hardlink) #endif /* Test the entries on disk. */ + + /* Test #1 */ assert(0 == stat("link1a", &st)); + /* If the hardlink was successfully created and the archive + * doesn't carry data for it, we consider it to be + * non-authoritive for meta data as well. This is consistent + * with GNU tar and BSD pax. */ assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); assert(0 == stat("link1b", &st2)); - assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st2.st_size, sizeof(data)); - assertEqualInt(st2.st_nlink, 2); + assertEqualInt(st.st_mode, st2.st_mode); + assertEqualInt(st.st_size, st2.st_size); + assertEqualInt(st.st_nlink, st2.st_nlink); assertEqualInt(st.st_ino, st2.st_ino); assertEqualInt(st.st_dev, st2.st_dev); + /* Test #2: Should produce identical results to test #1 */ + /* Note that marking a hardlink with size = 0 is treated the + * same as having an unset size. This is partly for backwards + * compatibility (we used to not have unset tracking, so + * relied on size == 0) and partly to match the model used by + * common file formats that store a size of zero for + * hardlinks. */ assert(0 == stat("link2a", &st)); assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); assert(0 == stat("link2b", &st2)); + assertEqualInt(st.st_mode, st2.st_mode); + assertEqualInt(st.st_size, st2.st_size); + assertEqualInt(st.st_nlink, st2.st_nlink); + assertEqualInt(st.st_ino, st2.st_ino); + assertEqualInt(st.st_dev, st2.st_dev); + + /* Test #3 */ + assert(0 == stat("link3a", &st)); + assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); + assertEqualInt(st.st_size, sizeof(data)); + assertEqualInt(st.st_nlink, 2); + + assert(0 == stat("link3b", &st2)); assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st2.st_size, sizeof(data)); assertEqualInt(st2.st_nlink, 2); assertEqualInt(st.st_ino, st2.st_ino); assertEqualInt(st.st_dev, st2.st_dev); - assert(0 == stat("link3a", &st)); + /* Test #4 */ + assert(0 == stat("link4a", &st)); assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); - assert(0 == stat("link3b", &st2)); + assert(0 == stat("link4b", &st2)); assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st2.st_size, sizeof(data)); assertEqualInt(st2.st_nlink, 2); |