From: Sarah Gilmore Date: Fri, 24 Mar 2023 13:44:38 +0000 (-0400) Subject: Always close file handle on descriptor on posix systems before returning from _archiv... X-Git-Tag: v3.7.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0cb9df7f95959b8dafde8f7899122464df7a1d26;p=thirdparty%2Flibarchive.git Always close file handle on descriptor on posix systems before returning from _archive_write_disk_finish_entry --- diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index 7aeb920c5..7ce25ea6c 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -397,6 +397,7 @@ static int set_times_from_entry(struct archive_write_disk *); static struct fixup_entry *sort_dir_list(struct fixup_entry *p); static ssize_t write_data_block(struct archive_write_disk *, const char *, size_t); +static void close_file_descriptor(struct archive_write_disk *); static int _archive_write_disk_close(struct archive *); static int _archive_write_disk_free(struct archive *); @@ -1731,6 +1732,7 @@ _archive_write_disk_finish_entry(struct archive *_a) r = hfs_write_data_block( a, null_d, a->file_remaining_bytes); if (r < 0) + close_file_descriptor(a->fd); return ((int)r); } #endif @@ -1740,6 +1742,7 @@ _archive_write_disk_finish_entry(struct archive *_a) a->filesize == 0) { archive_set_error(&a->archive, errno, "File size could not be restored"); + close_file_descriptor(a->fd); return (ARCHIVE_FAILED); } #endif @@ -1750,6 +1753,7 @@ _archive_write_disk_finish_entry(struct archive *_a) */ a->pst = NULL; if ((ret = lazy_stat(a)) != ARCHIVE_OK) + close_file_descriptor(a->fd); return (ret); /* We can use lseek()/write() to extend the file if * ftruncate didn't work or isn't available. */ @@ -1758,11 +1762,13 @@ _archive_write_disk_finish_entry(struct archive *_a) if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) { archive_set_error(&a->archive, errno, "Seek failed"); + close_file_descriptor(a->fd); return (ARCHIVE_FATAL); } if (write(a->fd, &nul, 1) < 0) { archive_set_error(&a->archive, errno, "Write to restore size failed"); + close_file_descriptor(a->fd); return (ARCHIVE_FATAL); } a->pst = NULL; @@ -4735,5 +4741,17 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name, } #endif +/* + * Close the file descriptor if one is open. + */ +static void close_file_descriptor(struct archive_write_disk* a) +{ + if (a->fd >= 0) { + close(a->fd); + a->fd = -1; + } +} + + #endif /* !_WIN32 || __CYGWIN__ */