]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
POSIX reader: do not fail when tree_current_lstat() fails due to ENOENT
authorEugene Grossbein <eugen@freebsd.org>
Sat, 2 Feb 2019 00:05:18 +0000 (01:05 +0100)
committerMartin Matuška <martin@matuska.org>
Sun, 10 Feb 2019 00:03:04 +0000 (01:03 +0100)
Fixes #1082

libarchive/archive_read_disk_posix.c

index cdf7541238cf9fdc462226d1fc0af7bf226b2f7a..e8bbcad3c2b25a6ce6ec70fdb79eb7e4199d648e 100644 (file)
@@ -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);
 }