From: Martin Matuška Date: Thu, 12 Jun 2025 08:59:43 +0000 (+0200) Subject: Merge pull request #2659 from stoeckmann/chld X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2aaa3389d1d9967111cf8ac095f492f179db9df3;p=thirdparty%2Flibarchive.git Merge pull request #2659 from stoeckmann/chld Improve filter process handling (cherry picked from commit 6effe2ec6bdc636573f9ea82bff3add632862333) --- diff --git a/cat/bsdcat.c b/cat/bsdcat.c index 731621fa9..40fdd0436 100644 --- a/cat/bsdcat.c +++ b/cat/bsdcat.c @@ -7,6 +7,9 @@ #include "bsdcat_platform.h" +#ifdef HAVE_SIGNAL_H +#include +#endif #include #ifdef HAVE_STDLIB_H #include @@ -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; diff --git a/cpio/cpio.c b/cpio/cpio.c index 2bf1bfa29..cd88d416e 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -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 diff --git a/libarchive/archive_read_support_filter_program.c b/libarchive/archive_read_support_filter_program.c index 9e825223b..2c8e45302 100644 --- a/libarchive/archive_read_support_filter_program.c +++ b/libarchive/archive_read_support_filter_program.c @@ -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); } diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c index 03c9736c0..0ccea0f81 100644 --- a/libarchive/archive_windows.c +++ b/libarchive/archive_windows.c @@ -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); } diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c index c661cc7f4..f12db3373 100644 --- a/libarchive/archive_write_add_filter_program.c +++ b/libarchive/archive_write_add_filter_program.c @@ -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; diff --git a/tar/bsdtar.c b/tar/bsdtar.c index 53ac135f0..c80c1a1b6 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -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 diff --git a/unzip/bsdunzip.c b/unzip/bsdunzip.c index 621afbeb9..0559a0ddc 100644 --- a/unzip/bsdunzip.c +++ b/unzip/bsdunzip.c @@ -29,6 +29,9 @@ #ifdef HAVE_LOCALE_H #include #endif +#ifdef HAVE_SIGNAL_H +#include +#endif #ifdef HAVE_STDARG_H #include #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