]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Always close file handle on descriptor on posix systems before returning from _archiv...
authorSarah Gilmore <sgilmore@mathworks.com>
Fri, 24 Mar 2023 13:44:38 +0000 (09:44 -0400)
committerMartin Matuška <martin@matuska.de>
Thu, 13 Jul 2023 22:50:24 +0000 (00:50 +0200)
libarchive/archive_write_disk_posix.c

index 7aeb920c50004452dde5a5ac5ac67b33bc8dbb4b..7ce25ea6cf958986f1aef61109ef1c6535d2456f 100644 (file)
@@ -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__ */