]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge pull request #2659 from stoeckmann/chld
authorMartin Matuška <martin@matuska.de>
Thu, 12 Jun 2025 08:59:43 +0000 (10:59 +0200)
committerMartin Matuska <martin@matuska.de>
Wed, 10 Sep 2025 08:15:45 +0000 (10:15 +0200)
Improve filter process handling

(cherry picked from commit 6effe2ec6bdc636573f9ea82bff3add632862333)

cat/bsdcat.c
cpio/cpio.c
libarchive/archive_read_support_filter_program.c
libarchive/archive_windows.c
libarchive/archive_write_add_filter_program.c
tar/bsdtar.c
unzip/bsdunzip.c

index 731621fa9b75a6b788a8199671381d056da618b2..40fdd04363e51bee2d0e0a68706a3373f1a26471 100644 (file)
@@ -7,6 +7,9 @@
 
 #include "bsdcat_platform.h"
 
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -105,6 +108,16 @@ main(int argc, char **argv)
        bsdcat = &bsdcat_storage;
        memset(bsdcat, 0, sizeof(*bsdcat));
 
+#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
+       { /* Do not ignore SIGCHLD. */
+               struct sigaction sa;
+               sa.sa_handler = SIG_DFL;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = 0;
+               sigaction(SIGCHLD, &sa, NULL);
+       }
+#endif
+
        lafe_setprogname(*argv, "bsdcat");
 
        bsdcat->argv = argv;
index 2bf1bfa2985a2c25bd071b6ae55bb340d2228dfb..cd88d416e861d06712348a916f726a917e6c9f95 100644 (file)
@@ -124,13 +124,21 @@ main(int argc, char *argv[])
        cpio->buff_size = sizeof(buff);
 
 
-#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
-       { /* Ignore SIGPIPE signals. */
+#if defined(HAVE_SIGACTION)
+       {
                struct sigaction sa;
                sigemptyset(&sa.sa_mask);
                sa.sa_flags = 0;
+#ifdef SIGPIPE
+               /* Ignore SIGPIPE signals. */
                sa.sa_handler = SIG_IGN;
                sigaction(SIGPIPE, &sa, NULL);
+#endif
+#ifdef SIGCHLD
+               /* Do not ignore SIGCHLD. */
+               sa.sa_handler = SIG_DFL;
+               sigaction(SIGCHLD, &sa, NULL);
+#endif
        }
 #endif
 
index 9e825223b26c0fa3191613b785240514e326f92d..2c8e45302d8eb25d9c37d284e8ffac587ee76c64 100644 (file)
@@ -110,7 +110,7 @@ struct program_filter {
        pid_t            child;
 #endif
        int              exit_status;
-       int              waitpid_return;
+       pid_t            waitpid_return;
        int              child_stdin, child_stdout;
 
        char            *out_buf;
@@ -242,16 +242,13 @@ child_stop(struct archive_read_filter *self, struct program_filter *state)
                        state->waitpid_return
                            = waitpid(state->child, &state->exit_status, 0);
                } while (state->waitpid_return == -1 && errno == EINTR);
-#if defined(_WIN32) && !defined(__CYGWIN__)
-               CloseHandle(state->child);
-#endif
                state->child = 0;
        }
 
        if (state->waitpid_return < 0) {
                /* waitpid() failed?  This is ugly. */
                archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
-                   "Child process exited badly");
+                   "Error closing child process");
                return (ARCHIVE_WARN);
        }
 
index 03c9736c06a2cb484a6b92d4bb570e9ddeac129f..0ccea0f818b90cd4edd185901131fc74223cad23 100644 (file)
@@ -641,13 +641,14 @@ __la_waitpid(HANDLE child, int *status, int option)
        (void)option;/* UNUSED */
        do {
                if (GetExitCodeProcess(child, &cs) == 0) {
-                       CloseHandle(child);
                        la_dosmaperr(GetLastError());
+                       CloseHandle(child);
                        *status = 0;
                        return (-1);
                }
        } while (cs == STILL_ACTIVE);
 
+       CloseHandle(child);
        *status = (int)(cs & 0xff);
        return (0);
 }
index c661cc7f412fc7d42c4842bde413dc80399c8335..f12db33738833d1b85de1e45ac41702e553719e7 100644 (file)
@@ -330,6 +330,7 @@ __archive_write_program_close(struct archive_write_filter *f,
     struct archive_write_program_data *data)
 {
        int ret, status;
+       pid_t pid;
        ssize_t bytes_read;
 
        if (data->child == 0)
@@ -373,14 +374,12 @@ cleanup:
                close(data->child_stdin);
        if (data->child_stdout != -1)
                close(data->child_stdout);
-       while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
-               continue;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-       CloseHandle(data->child);
-#endif
+       do {
+               pid = waitpid(data->child, &status, 0);
+       } while (pid == -1 && errno == EINTR);
        data->child = 0;
 
-       if (status != 0) {
+       if (pid < 0 || status != 0) {
                archive_set_error(f->archive, EIO,
                    "Error closing program: %s", data->program_name);
                ret = ARCHIVE_FATAL;
index 53ac135f01296fe028e6ca022a50140774763a43..c80c1a1b68896b8573b7031e8b1c35f3cbe98820 100644 (file)
@@ -182,6 +182,11 @@ main(int argc, char **argv)
                /* Ignore SIGPIPE signals. */
                sa.sa_handler = SIG_IGN;
                sigaction(SIGPIPE, &sa, NULL);
+#endif
+#ifdef SIGCHLD
+               /* Do not ignore SIGCHLD. */
+               sa.sa_handler = SIG_DFL;
+               sigaction(SIGCHLD, &sa, NULL);
 #endif
        }
 #endif
index 621afbeb9d6a56d9407dc0e701afc17765693a3f..0559a0ddce8b34466075f766eb6a23f98c481b21 100644 (file)
@@ -29,6 +29,9 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
 #ifdef HAVE_STDARG_H
 #include <stdarg.h>
 #endif
@@ -1187,6 +1190,16 @@ main(int argc, char *argv[])
        const char *zipfile;
        int nopts;
 
+#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
+       { /* Do not ignore SIGCHLD. */
+               struct sigaction sa;
+               sa.sa_handler = SIG_DFL;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = 0;
+               sigaction(SIGCHLD, &sa, NULL);
+       }
+#endif
+
        lafe_setprogname(*argv, "bsdunzip");
 
 #if HAVE_SETLOCALE