tar,rpm2cpio: check that child decompressor did not error out
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@googlemail.com>
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user