[git commit] tar, rpm2cpio: check that child decompressor did not error out

Denys Vlasenko vda.linux at googlemail.com
Tue Mar 6 15:33:42 UTC 2012


commit: http://git.busybox.net/busybox/commit/?id=faac1d3e6e87dc6882e69b62f1c71907d892c876
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
check_errors_in_children                               -      57     +57
tar_main                                             833     848     +15
get_header_tar                                      1720    1733     +13
rpm2cpio_main                                        147     140      -7
handle_SIGCHLD                                        41       -     -41
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 2/1 up/down: 85/-48)             Total: 37 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 archival/libarchive/open_transformer.c |   26 +++++++++++++++++++++
 archival/rpm2cpio.c                    |   35 ++++++-----------------------
 archival/tar.c                         |   38 ++++++--------------------------
 include/bb_archive.h                   |    1 +
 4 files changed, 41 insertions(+), 59 deletions(-)

diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index 693ae99..dae04aa 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -27,6 +27,32 @@ int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigne
 	return 0;
 }
 
+void check_errors_in_children(int signo)
+{
+	int status;
+
+	if (!signo) {
+		/* block waiting for any child */
+		if (wait(&status) < 0)
+			return; /* probably there are no children */
+		goto check_status;
+	}
+
+	/* Wait for any child without blocking */
+	for (;;) {
+		if (wait_any_nohang(&status) < 0)
+			/* wait failed?! I'm confused... */
+			return;
+ check_status:
+		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+			/* this child exited with 0 */
+			continue;
+		/* Cannot happen?
+		if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */
+		bb_got_signal = 1;
+	}
+}
+
 /* transformer(), more than meets the eye */
 #if BB_MMU
 void FAST_FUNC open_transformer(int fd,
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c
index 7256aae..f3dfa51 100644
--- a/archival/rpm2cpio.c
+++ b/archival/rpm2cpio.c
@@ -42,26 +42,6 @@ static unsigned skip_header(void)
 	return sizeof(header) + len;
 }
 
-#if SEAMLESS_COMPRESSION
-static void handle_SIGCHLD(int signo UNUSED_PARAM)
-{
-	int status;
-
-	/* Wait for any child without blocking */
-	for (;;) {
-		if (wait_any_nohang(&status) < 0)
-			/* wait failed?! I'm confused... */
-			return;
-		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
-			/* this child exited with 0 */
-			continue;
-		/* Cannot happen?
-		if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */
-		bb_got_signal = 1;
-	}
-}
-#endif
-
 /* No getopt required */
 int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
@@ -86,10 +66,9 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
 	/* Skip the main header */
 	skip_header();
 
-#if SEAMLESS_COMPRESSION
-	/* We need to know whether child (gzip/bzip/etc) exits abnormally */
-	signal(SIGCHLD, handle_SIGCHLD);
-#endif
+	//if (SEAMLESS_COMPRESSION)
+	//	/* We need to know whether child (gzip/bzip/etc) exits abnormally */
+	//	signal(SIGCHLD, check_errors_in_children);
 
 	/* This works, but doesn't report uncompress errors (they happen in child) */
 	setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1);
@@ -100,9 +79,9 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
 		close(rpm_fd);
 	}
 
-#if SEAMLESS_COMPRESSION
-	return bb_got_signal;
-#else
+	if (SEAMLESS_COMPRESSION) {
+		check_errors_in_children(0);
+		return bb_got_signal;
+	}
 	return EXIT_SUCCESS;
-#endif
 }
diff --git a/archival/tar.c b/archival/tar.c
index af38ac5..cf972c2 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -690,29 +690,6 @@ static llist_t *append_file_list_to_list(llist_t *list)
 # define append_file_list_to_list(x) 0
 #endif
 
-#ifdef CHECK_FOR_CHILD_EXITCODE
-/* Looks like it isn't needed - tar detects malformed (truncated)
- * archive if e.g. bunzip2 fails */
-static int child_error;
-
-static void handle_SIGCHLD(int status)
-{
-	/* Actually, 'status' is a signo. We reuse it for other needs */
-
-	/* Wait for any child without blocking */
-	if (wait_any_nohang(&status) < 0)
-		/* wait failed?! I'm confused... */
-		return;
-
-	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
-		/* child exited with 0 */
-		return;
-	/* Cannot happen?
-	if (!WIFSIGNALED(status) && !WIFEXITED(status)) return; */
-	child_error = 1;
-}
-#endif
-
 //usage:#define tar_trivial_usage
 //usage:	"-[" IF_FEATURE_TAR_CREATE("c") "xt"
 //usage:	IF_FEATURE_SEAMLESS_Z("Z")
@@ -1059,10 +1036,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
 	if (base_dir)
 		xchdir(base_dir);
 
-#ifdef CHECK_FOR_CHILD_EXITCODE
-	/* We need to know whether child (gzip/bzip/etc) exits abnormally */
-	signal(SIGCHLD, handle_SIGCHLD);
-#endif
+	//if (SEAMLESS_COMPRESSION || OPT_COMPRESS)
+	//	/* We need to know whether child (gzip/bzip/etc) exits abnormally */
+	//	signal(SIGCHLD, check_errors_in_children);
 
 	/* Create an archive */
 	if (opt & OPT_CREATE) {
@@ -1118,9 +1094,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
 	if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */)
 		close(tar_handle->src_fd);
 
-#ifdef CHECK_FOR_CHILD_EXITCODE
-	return bb_got_signal;
-#else
+	if (SEAMLESS_COMPRESSION || OPT_COMPRESS) {
+		check_errors_in_children(0);
+		return bb_got_signal;
+	}
 	return EXIT_SUCCESS;
-#endif
 }
diff --git a/include/bb_archive.h b/include/bb_archive.h
index bd08115..2043d85 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -224,6 +224,7 @@ int bbunpack(char **argv,
 	    const char *expected_ext
 ) FAST_FUNC;
 
+void check_errors_in_children(int signo);
 #if BB_MMU
 void open_transformer(int fd,
 	int check_signature,


More information about the busybox-cvs mailing list