diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-06 16:33:42 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-06 16:33:42 +0100 |
commit | faac1d3e6e87dc6882e69b62f1c71907d892c876 (patch) | |
tree | c9feb257a4d47e71a5555360b0978e22c9e37dbf | |
parent | 02c3c3842004d88207b46450dbd19f80e6596c7e (diff) | |
download | busybox-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.c | 26 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 35 | ||||
-rw-r--r-- | archival/tar.c | 38 | ||||
-rw-r--r-- | 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 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 | ||
30 | void 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 |
32 | void FAST_FUNC open_transformer(int fd, | 58 | void 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 | ||
46 | static 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 */ |
66 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 46 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
67 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | 47 | int 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 */ | ||
696 | static int child_error; | ||
697 | |||
698 | static 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 | ||
227 | void check_errors_in_children(int signo); | ||
227 | #if BB_MMU | 228 | #if BB_MMU |
228 | void open_transformer(int fd, | 229 | void open_transformer(int fd, |
229 | int check_signature, | 230 | int check_signature, |