summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_disk_posix.c
diff options
context:
space:
mode:
authorEugene Grossbein <eugen@freebsd.org>2019-02-02 01:05:18 +0100
committerMartin Matuška <martin@matuska.org>2019-02-10 01:03:04 +0100
commitbd6f56ccda7320e88c10518c4625596a5e043cd7 (patch)
treebe70ec746f47c2986699722f9bf50386ee19309e /libarchive/archive_read_disk_posix.c
parent4bc5892128a042780f167ac35aa72f63c426f3b7 (diff)
downloadlibarchive-bd6f56ccda7320e88c10518c4625596a5e043cd7.tar.gz
POSIX reader: do not fail when tree_current_lstat() fails due to ENOENT
Fixes #1082
Diffstat (limited to 'libarchive/archive_read_disk_posix.c')
-rw-r--r--libarchive/archive_read_disk_posix.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
index cdf75412..e8bbcad3 100644
--- a/libarchive/archive_read_disk_posix.c
+++ b/libarchive/archive_read_disk_posix.c
@@ -856,7 +856,11 @@ next_entry(struct archive_read_disk *a, struct tree *t,
const struct stat *st; /* info to use for this entry */
const struct stat *lst;/* lstat() information */
const char *name;
- int descend, r;
+ int delayed, delayed_errno, descend, r;
+ struct archive_string delayed_str;
+
+ delayed = ARCHIVE_OK;
+ archive_string_init(&delayed_str);
st = NULL;
lst = NULL;
@@ -885,11 +889,19 @@ next_entry(struct archive_read_disk *a, struct tree *t,
case TREE_REGULAR:
lst = tree_current_lstat(t);
if (lst == NULL) {
+ if (errno == ENOENT) {
+ delayed = ARCHIVE_WARN;
+ delayed_errno = errno;
+ archive_string_sprintf(&delayed_str,
+ "%s: File removed before we read it",
+ tree_current_path(t));
+ } else {
archive_set_error(&a->archive, errno,
"%s: Cannot stat",
tree_current_path(t));
tree_enter_initial_dir(t);
return (ARCHIVE_FAILED);
+ }
}
break;
}
@@ -1083,6 +1095,15 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_read_disk_entry_from_file(&(a->archive), entry,
t->entry_fd, st);
+ if (r == ARCHIVE_OK) {
+ r = delayed;
+ if (r != ARCHIVE_OK)
+ archive_set_error(&(a->archive), delayed_errno,
+ "%s", delayed_str.s);
+ }
+ if (!archive_string_empty(&delayed_str))
+ archive_string_free(&delayed_str);
+
return (r);
}