From: Martin Matuska Date: Sat, 25 May 2019 21:46:59 +0000 (+0200) Subject: archive_write_disk_posix: open a fd when processing fixup entries X-Git-Tag: v3.4.0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b837c72c423b744a2e6c554742877173406dbfa0;p=thirdparty%2Flibarchive.git archive_write_disk_posix: open a fd when processing fixup entries --- diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index 70b27b503..0583fbd13 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -182,6 +182,7 @@ struct fixup_entry { void *mac_metadata; int fixup; /* bitmask of what needs fixing */ char *name; + int fd; }; /* @@ -2354,20 +2355,31 @@ _archive_write_disk_close(struct archive *_a) while (p != NULL) { a->pst = NULL; /* Mark stat cache as out-of-date. */ + if (p->fd < 0 && p->fixup & + (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) { + p->fd = open(p->name, + O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC); + } if (p->fixup & TODO_TIMES) { - set_times(a, -1, p->mode, p->name, + set_times(a, p->fd, p->mode, p->name, p->atime, p->atime_nanos, p->birthtime, p->birthtime_nanos, p->mtime, p->mtime_nanos, p->ctime, p->ctime_nanos); } - if (p->fixup & TODO_MODE_BASE) + if (p->fixup & TODO_MODE_BASE) { +#ifdef HAVE_FCHMOD + if (p->fd >= 0) + fchmod(p->fd, p->mode); + else +#endif chmod(p->name, p->mode); + } if (p->fixup & TODO_ACLS) - archive_write_disk_set_acls(&a->archive, -1, p->name, - &p->acl, p->mode); + archive_write_disk_set_acls(&a->archive, p->fd, + p->name, &p->acl, p->mode); if (p->fixup & TODO_FFLAGS) - set_fflags_platform(a, -1, p->name, + set_fflags_platform(a, p->fd, p->name, p->mode, p->fflags_set, 0); if (p->fixup & TODO_MAC_METADATA) set_mac_metadata(a, p->name, p->mac_metadata, @@ -2376,6 +2388,8 @@ _archive_write_disk_close(struct archive *_a) archive_acl_clear(&p->acl); free(p->mac_metadata); free(p->name); + if (p->fd >= 0) + close(p->fd); free(p); p = next; } @@ -2510,6 +2524,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname) a->fixup_list = fe; fe->fixup = 0; fe->name = strdup(pathname); + fe->fd = -1; return (fe); }