]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Store file handle to payload file
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 7 Mar 2021 17:05:31 +0000 (17:05 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 7 Mar 2021 17:05:31 +0000 (17:05 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/packager.c

index f7a29ffe89bb8a8c4f74f6a43531c5e5a36ae531..e7e32fbe4df2709dac35beb3ca28a0968aab7b26 100644 (file)
@@ -46,10 +46,12 @@ struct pakfire_packager {
        PakfirePackage pkg;
 
        struct archive* payload;
-       char payload_path[PATH_MAX + 1];
+       FILE* fpayload;
 };
 
 static int pakfire_packager_create_payload(struct pakfire_packager* p, int compress) {
+       char path[] = "/tmp/.pakfire-payload.XXXXXX";
+
        p->payload = archive_write_new();
        if (!p->payload) {
                ERROR(p->pakfire, "archive_write_new() failed\n");
@@ -83,16 +85,26 @@ static int pakfire_packager_create_payload(struct pakfire_packager* p, int compr
                }
        }
 
-       // Allocate a temporary file to write the payload to
-       snprintf(p->payload_path, PATH_MAX, "/tmp/.pakfire-payload.XXXXXX");
-
-       int fd = mkostemp(p->payload_path, O_CLOEXEC);
+       // Create a new temporary file
+       int fd = mkostemp(path, O_CLOEXEC);
        if (fd < 0) {
                ERROR(p->pakfire, "mkostemp() failed: %s\n", strerror(errno));
                return 1;
        }
 
-       r = archive_write_open_fd(p->payload, fd);
+       // Unlink the file straight away
+       unlink(path);
+
+       // Convert the file descriptor into a file handle
+       p->fpayload = fdopen(fd, "w+");
+       if (!p->fpayload) {
+               close(fd);
+
+               return 1;
+       }
+
+       // Write archive to file
+       r = archive_write_open_FILE(p->payload, p->fpayload);
        if (r)
                return r;
 
@@ -103,6 +115,9 @@ static void pakfire_packager_free(struct pakfire_packager* packager) {
        if (packager->payload)
                archive_write_free(packager->payload);
 
+       if (packager->fpayload)
+               fclose(packager->fpayload);
+
        pakfire_package_unref(packager->pkg);
        pakfire_unref(packager->pakfire);
 }
@@ -151,6 +166,32 @@ PAKFIRE_EXPORT struct pakfire_packager* pakfire_packager_unref(
        return NULL;
 }
 
+static int pakfire_packager_copy_data(struct pakfire_packager* packager,
+               struct archive* a, FILE* f) {
+       char buffer[BUFFER_SIZE];
+
+       while (!feof(f)) {
+               // Read a block from file
+               size_t bytes_read = fread(buffer, 1, sizeof(buffer), f);
+
+               // Check if any error occured
+               if (ferror(f)) {
+                       ERROR(packager->pakfire, "Error reading from file: %s\n", strerror(errno));
+                       return 1;
+               }
+
+               // Write the block to the archive
+               ssize_t bytes_written = archive_write_data(a, buffer, bytes_read);
+               if (bytes_written < 0) {
+                       ERROR(packager->pakfire, "Error writing data to archive: %s\n",
+                               archive_error_string(a));
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 static int pakfire_packager_write_format(struct pakfire_packager* packager,
                struct archive* a) {
        const char buffer[] = TO_STRING(PACKAGE_FORMAT) "\n";
@@ -240,12 +281,15 @@ PAKFIRE_EXPORT int pakfire_packager_add(struct pakfire_packager* packager,
                const char* path) {
        FILE* f = NULL;
        struct stat st;
-       char buffer[BUFFER_SIZE];
 
        // Check if path is set
        if (!path)
                return EINVAL;
 
+       // Payload has already been closed
+       if (!packager->payload)
+               return EINVAL;
+
        // Stat the input file
        int r = stat(path, &st);
        if (r) {
@@ -281,26 +325,9 @@ PAKFIRE_EXPORT int pakfire_packager_add(struct pakfire_packager* packager,
                        goto ERROR;
                }
 
-               while (!feof(f)) {
-                       // Read a block from file
-                       size_t bytes_read = fread(buffer, 1, sizeof(buffer), f);
-
-                       if (ferror(f)) {
-                               ERROR(packager->pakfire, "Error reading from file %s: %s\n",
-                                       path, strerror(errno));
-                               r = errno;
-                               goto ERROR;
-                       }
-
-                       // Write the block to the archive
-                       ssize_t bytes_written = archive_write_data(packager->payload, buffer, bytes_read);
-                       if (bytes_written < 0) {
-                               ERROR(packager->pakfire, "Error writing data to archive: %s\n",
-                                       archive_error_string(packager->payload));
-                               r = 1;
-                               goto ERROR;
-                       }
-               }
+               r = pakfire_packager_copy_data(packager, packager->payload, f);
+               if (r)
+                       goto ERROR;
        }
 
        // Successful