aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:33:42 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:33:42 +0100
commitfaac1d3e6e87dc6882e69b62f1c71907d892c876 (patch)
treec9feb257a4d47e71a5555360b0978e22c9e37dbf
parent02c3c3842004d88207b46450dbd19f80e6596c7e (diff)
downloadbusybox-w32-faac1d3e6e87dc6882e69b62f1c71907d892c876.tar.gz
busybox-w32-faac1d3e6e87dc6882e69b62f1c71907d892c876.tar.bz2
busybox-w32-faac1d3e6e87dc6882e69b62f1c71907d892c876.zip
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>
-rw-r--r--archival/libarchive/open_transformer.c26
-rw-r--r--archival/rpm2cpio.c35
-rw-r--r--archival/tar.c38
-rw-r--r--include/bb_archive.h1
4 files changed, 41 insertions, 59 deletions
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index 693ae9995..dae04aa57 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
27 return 0; 27 return 0;
28} 28}
29 29
30void check_errors_in_children(int signo)
31{
32 int status;
33
34 if (!signo) {
35 /* block waiting for any child */
36 if (wait(&status) < 0)
37 return; /* probably there are no children */
38 goto check_status;
39 }
40
41 /* Wait for any child without blocking */
42 for (;;) {
43 if (wait_any_nohang(&status) < 0)
44 /* wait failed?! I'm confused... */
45 return;
46 check_status:
47 if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
48 /* this child exited with 0 */
49 continue;
50 /* Cannot happen?
51 if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */
52 bb_got_signal = 1;
53 }
54}
55
30/* transformer(), more than meets the eye */ 56/* transformer(), more than meets the eye */
31#if BB_MMU 57#if BB_MMU
32void FAST_FUNC open_transformer(int fd, 58void FAST_FUNC open_transformer(int fd,
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c
index 7256aae6b..f3dfa5159 100644
--- a/archival/rpm2cpio.c
+++ b/archival/rpm2cpio.c
@@ -42,26 +42,6 @@ static unsigned skip_header(void)
42 return sizeof(header) + len; 42 return sizeof(header) + len;
43} 43}
44 44
45#if SEAMLESS_COMPRESSION
46static void handle_SIGCHLD(int signo UNUSED_PARAM)
47{
48 int status;
49
50 /* Wait for any child without blocking */
51 for (;;) {
52 if (wait_any_nohang(&status) < 0)
53 /* wait failed?! I'm confused... */
54 return;
55 if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
56 /* this child exited with 0 */
57 continue;
58 /* Cannot happen?
59 if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */
60 bb_got_signal = 1;
61 }
62}
63#endif
64
65/* No getopt required */ 45/* No getopt required */
66int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 46int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
67int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) 47int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
@@ -86,10 +66,9 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
86 /* Skip the main header */ 66 /* Skip the main header */
87 skip_header(); 67 skip_header();
88 68
89#if SEAMLESS_COMPRESSION 69 //if (SEAMLESS_COMPRESSION)
90 /* We need to know whether child (gzip/bzip/etc) exits abnormally */ 70 // /* We need to know whether child (gzip/bzip/etc) exits abnormally */
91 signal(SIGCHLD, handle_SIGCHLD); 71 // signal(SIGCHLD, check_errors_in_children);
92#endif
93 72
94 /* This works, but doesn't report uncompress errors (they happen in child) */ 73 /* This works, but doesn't report uncompress errors (they happen in child) */
95 setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1); 74 setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1);
@@ -100,9 +79,9 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
100 close(rpm_fd); 79 close(rpm_fd);
101 } 80 }
102 81
103#if SEAMLESS_COMPRESSION 82 if (SEAMLESS_COMPRESSION) {
104 return bb_got_signal; 83 check_errors_in_children(0);
105#else 84 return bb_got_signal;
85 }
106 return EXIT_SUCCESS; 86 return EXIT_SUCCESS;
107#endif
108} 87}
diff --git a/archival/tar.c b/archival/tar.c
index af38ac59f..cf972c24c 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -690,29 +690,6 @@ static llist_t *append_file_list_to_list(llist_t *list)
690# define append_file_list_to_list(x) 0 690# define append_file_list_to_list(x) 0
691#endif 691#endif
692 692
693#ifdef CHECK_FOR_CHILD_EXITCODE
694/* Looks like it isn't needed - tar detects malformed (truncated)
695 * archive if e.g. bunzip2 fails */
696static int child_error;
697
698static void handle_SIGCHLD(int status)
699{
700 /* Actually, 'status' is a signo. We reuse it for other needs */
701
702 /* Wait for any child without blocking */
703 if (wait_any_nohang(&status) < 0)
704 /* wait failed?! I'm confused... */
705 return;
706
707 if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
708 /* child exited with 0 */
709 return;
710 /* Cannot happen?
711 if (!WIFSIGNALED(status) && !WIFEXITED(status)) return; */
712 child_error = 1;
713}
714#endif
715
716//usage:#define tar_trivial_usage 693//usage:#define tar_trivial_usage
717//usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" 694//usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt"
718//usage: IF_FEATURE_SEAMLESS_Z("Z") 695//usage: IF_FEATURE_SEAMLESS_Z("Z")
@@ -1059,10 +1036,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1059 if (base_dir) 1036 if (base_dir)
1060 xchdir(base_dir); 1037 xchdir(base_dir);
1061 1038
1062#ifdef CHECK_FOR_CHILD_EXITCODE 1039 //if (SEAMLESS_COMPRESSION || OPT_COMPRESS)
1063 /* We need to know whether child (gzip/bzip/etc) exits abnormally */ 1040 // /* We need to know whether child (gzip/bzip/etc) exits abnormally */
1064 signal(SIGCHLD, handle_SIGCHLD); 1041 // signal(SIGCHLD, check_errors_in_children);
1065#endif
1066 1042
1067 /* Create an archive */ 1043 /* Create an archive */
1068 if (opt & OPT_CREATE) { 1044 if (opt & OPT_CREATE) {
@@ -1118,9 +1094,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1118 if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) 1094 if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */)
1119 close(tar_handle->src_fd); 1095 close(tar_handle->src_fd);
1120 1096
1121#ifdef CHECK_FOR_CHILD_EXITCODE 1097 if (SEAMLESS_COMPRESSION || OPT_COMPRESS) {
1122 return bb_got_signal; 1098 check_errors_in_children(0);
1123#else 1099 return bb_got_signal;
1100 }
1124 return EXIT_SUCCESS; 1101 return EXIT_SUCCESS;
1125#endif
1126} 1102}
diff --git a/include/bb_archive.h b/include/bb_archive.h
index bd08115da..2043d8570 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -224,6 +224,7 @@ int bbunpack(char **argv,
224 const char *expected_ext 224 const char *expected_ext
225) FAST_FUNC; 225) FAST_FUNC;
226 226
227void check_errors_in_children(int signo);
227#if BB_MMU 228#if BB_MMU
228void open_transformer(int fd, 229void open_transformer(int fd,
229 int check_signature, 230 int check_signature,