fixes for bugs found by make_single_applets.sh
No binary (build failed)
—
(log yok)
| @@ -7,14 +7,19 @@ | |
| #include "libbb.h" | |
| #include "bb_archive.h" | |
| + | //kbuild:lib-$(CONFIG_ZCAT) += bbunzip.o |
| + | //kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o |
| + | //kbuild:lib-$(CONFIG_BZCAT) += bbunzip.o |
| + | //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o |
| + | |
| /* lzop_main() uses bbunpack(), need this: */ | |
| //kbuild:lib-$(CONFIG_LZOP) += bbunzip.o | |
| //kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o | |
| //kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o | |
| /* bzip2_main() too: */ | |
| - | //kbuild:lib-$(CONFIG_FEATURE_BZIP2_DECOMPRESS) += bbunzip.o |
| + | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o |
| /* gzip_main() too: */ | |
| - | //kbuild:lib-$(CONFIG_FEATURE_GZIP_DECOMPRESS) += bbunzip.o |
| + | //kbuild:lib-$(CONFIG_GZIP) += bbunzip.o |
| /* Note: must be kept in sync with archival/lzop.c */ | |
| enum { | |
| @@ -443,7 +448,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |
| //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | |
| // APPLET_ODDNAME:name main location suid_type help | |
| //applet:IF_BZCAT(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | |
| - | #if ENABLE_FEATURE_BZIP2_DECOMPRESS |
| + | #if ENABLE_FEATURE_BZIP2_DECOMPRESS || ENABLE_BUNZIP2 |
| int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| @@ -778,6 +778,8 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags, | |
| uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; | |
| + | /* 0 if argv[0] is NULL: */ |
| + | unsigned string_array_len(char **argv) FAST_FUNC; |
| void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; | |
| char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; | |
| char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; | |
| @@ -78,6 +78,17 @@ | |
| #endif | |
| + | unsigned FAST_FUNC string_array_len(char **argv) |
| + | { |
| + | char **start = argv; |
| + | |
| + | while (*argv) |
| + | argv++; |
| + | |
| + | return argv - start; |
| + | } |
| + | |
| + | |
| #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE | |
| static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | |
| #else | |
| @@ -868,10 +879,7 @@ static int busybox_main(char **argv) | |
| # if NUM_APPLETS > 0 | |
| void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | |
| { | |
| - | int argc = 1; |
| - | |
| - | while (argv[argc]) |
| - | argc++; |
| + | int argc = string_array_len(argv); |
| /* Reinit some shared global data */ | |
| xfunc_error_retval = EXIT_FAILURE; | |
| @@ -993,7 +1001,11 @@ int main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| /* applet_names in this case is just "applet\0\0" */ | |
| lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv)); | |
| + | # if ENABLE_BUILD_LIBBUSYBOX |
| + | return SINGLE_APPLET_MAIN(string_array_len(argv), argv); |
| + | # else |
| return SINGLE_APPLET_MAIN(argc, argv); | |
| + | # endif |
| #elif !ENABLE_BUSYBOX && NUM_APPLETS == 0 | |
| @@ -379,9 +379,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |
| int spec_flgs = 0; | |
| /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ | |
| - | argc = 1; |
| - | while (argv[argc]) |
| - | argc++; |
| + | argc = 1 + string_array_len(argv + 1); |
| va_start(p, applet_opts); | |
| @@ -16,6 +16,7 @@ | |
| */ | |
| #include "busybox.h" /* uses applet tables */ | |
| + | #include "NUM_APPLETS.h" |
| /* This does a fork/exec in one call, using vfork(). Returns PID of new child, | |
| * -1 for failure. Runs argv[0], searching path if that has no / in it. */ | |
| @@ -156,7 +157,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |
| int FAST_FUNC spawn_and_wait(char **argv) | |
| { | |
| int rc; | |
| - | #if ENABLE_FEATURE_PREFER_APPLETS |
| + | #if ENABLE_FEATURE_PREFER_APPLETS && (NUM_APPLETS > 1) |
| int a = find_applet_by_name(argv[0]); | |
| if (a >= 0) { | |
| @@ -1513,8 +1513,11 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |
| } /* for (;;) */ | |
| } | |
| - | #if !BB_MMU |
| + | #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO \ |
| + | || ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD |
| + | # if !BB_MMU |
| static const char *const cat_args[] = { "cat", NULL }; | |
| + | # endif |
| #endif | |
| /* | |
| @@ -1525,14 +1528,14 @@ static const char *const cat_args[] = { "cat", NULL }; | |
| /* ARGSUSED */ | |
| static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) | |
| { | |
| - | #if BB_MMU |
| + | # if BB_MMU |
| while (1) { | |
| ssize_t sz = safe_read(s, line, LINE_SIZE); | |
| if (sz <= 0) | |
| break; | |
| xwrite(s, line, sz); | |
| } | |
| - | #else |
| + | # else |
| /* We are after vfork here! */ | |
| /* move network socket to stdin/stdout */ | |
| xmove_fd(s, STDIN_FILENO); | |
| @@ -1542,7 +1545,7 @@ static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) | |
| xopen(bb_dev_null, O_WRONLY); | |
| BB_EXECVP("cat", (char**)cat_args); | |
| /* on failure we return to main, which does exit(EXIT_FAILURE) */ | |
| - | #endif |
| + | # endif |
| } | |
| static void FAST_FUNC echo_dg(int s, servtab_t *sep) | |
| { | |
| @@ -1566,10 +1569,10 @@ static void FAST_FUNC echo_dg(int s, servtab_t *sep) | |
| /* ARGSUSED */ | |
| static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) | |
| { | |
| - | #if BB_MMU |
| + | # if BB_MMU |
| while (safe_read(s, line, LINE_SIZE) > 0) | |
| continue; | |
| - | #else |
| + | # else |
| /* We are after vfork here! */ | |
| /* move network socket to stdin */ | |
| xmove_fd(s, STDIN_FILENO); | |
| @@ -1580,7 +1583,7 @@ static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) | |
| xdup2(STDOUT_FILENO, STDERR_FILENO); | |
| BB_EXECVP("cat", (char**)cat_args); | |
| /* on failure we return to main, which does exit(EXIT_FAILURE) */ | |
| - | #endif |
| + | # endif |
| } | |
| /* ARGSUSED */ | |
| static void FAST_FUNC discard_dg(int s, servtab_t *sep UNUSED_PARAM) | |
| @@ -1,7 +1,11 @@ | |
| #!/bin/sh | |
| + | run_testsuite=false |
| run_testsuite=true | |
| + | run_single_test=false |
| + | run_single_test=true |
| + | |
| test -d "$1" || { echo "'$1' is not a directory"; exit 1; } | |
| test -x "$1/scripts/randomtest" || { echo "No scripts/randomtest in '$1'"; exit 1; } | |
| @@ -40,6 +44,28 @@ while sleep 1; do | |
| fi | |
| tail -n10 -- "$dir/testsuite/runtest.log" | |
| fi | |
| + | if $run_single_test; then |
| + | ( |
| + | cd -- "$dir" || exit 1 |
| + | echo "Running make_single_applets.sh in $dir..." |
| + | |
| + | if grep -q '# CONFIG_FEATURE_TFTP_GET is not set' .config \ |
| + | && grep -q '# CONFIG_FEATURE_TFTP_PUT is not set' .config \ |
| + | ; then |
| + | # If both off, tftp[d] is ifdefed out and test fails. |
| + | # Enable one: |
| + | sed 's/# CONFIG_FEATURE_TFTP_GET is not set/CONFIG_FEATURE_TFTP_GET=y/' -i .config |
| + | fi |
| + | |
| + | ./make_single_applets.sh |
| + | ) |
| + | if test $? != 0; then |
| + | echo "Failed make_single_applets.sh in $dir" |
| + | exit 1 # you may comment this out... |
| + | let fail++ |
| + | continue |
| + | fi |
| + | fi |
| rm -rf -- "$dir" | |
| let cnt++ | |
| done | |
| @@ -1478,8 +1478,6 @@ typedef struct save_arg_t { | |
| static void save_and_replace_G_args(save_arg_t *sv, char **argv) | |
| { | |
| - | int n; |
| - | |
| sv->sv_argv0 = argv[0]; | |
| sv->sv_g_argv = G.global_argv; | |
| sv->sv_g_argc = G.global_argc; | |
| @@ -1489,10 +1487,7 @@ static void save_and_replace_G_args(save_arg_t *sv, char **argv) | |
| G.global_argv = argv; | |
| IF_HUSH_SET(G.global_args_malloced = 0;) | |
| - | n = 1; |
| - | while (*++argv) |
| - | n++; |
| - | G.global_argc = n; |
| + | G.global_argc = 1 + string_array_len(argv + 1); |
| } | |
| static void restore_G_args(save_arg_t *sv, char **argv) | |
| @@ -6809,13 +6804,11 @@ static void exec_function(char ***to_free, | |
| char **argv) | |
| { | |
| # if BB_MMU | |
| - | int n = 1; |
| + | int n; |
| argv[0] = G.global_argv[0]; | |
| G.global_argv = argv; | |
| - | while (*++argv) |
| - | n++; |
| - | G.global_argc = n; |
| + | G.global_argc = n = 1 + string_array_len(argv + 1); |
| /* On MMU, funcp->body is always non-NULL */ | |
| n = run_list(funcp->body); | |
| fflush_all(); | |
| @@ -8811,12 +8804,8 @@ static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM) | |
| #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL | |
| static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) | |
| { | |
| - | int argc = 0; |
| - | while (*argv) { |
| - | argc++; |
| - | argv++; |
| - | } |
| - | return applet_main_func(argc, argv - argc); |
| + | int argc = string_array_len(argv); |
| + | return applet_main_func(argc, argv); |
| } | |
| #endif | |
| #if ENABLE_HUSH_TEST || BASH_TEST2 | |
| @@ -9363,10 +9352,7 @@ static int FAST_FUNC builtin_set(char **argv) | |
| /* This realloc's G.global_argv */ | |
| G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1); | |
| - | n = 1; |
| - | while (*++pp) |
| - | n++; |
| - | G.global_argc = n; |
| + | G.global_argc = 1 + string_array_len(pp + 1); |
| return EXIT_SUCCESS; | |
| @@ -405,9 +405,7 @@ shell_builtin_ulimit(char **argv) | |
| */ | |
| GETOPT_RESET(); | |
| - | argc = 1; |
| - | while (argv[argc]) |
| - | argc++; |
| + | argc = string_array_len(argv); |
| opts = 0; | |
| while (1) { | |
| @@ -185,6 +185,8 @@ struct hd_geometry { | |
| #define HDIO_GETGEO 0x0301 /* get device geometry */ | |
| + | /* TODO: #if ENABLE_FEATURE_FDISK_WRITABLE */ |
| + | /* (currently fdisk_sun/sgi.c do not have proper WRITABLE #ifs) */ |
| static const char msg_building_new_label[] ALIGN1 = | |
| "Building a new %s. Changes will remain in memory only,\n" | |
| "until you decide to write them. After that the previous content\n" | |
| @@ -192,6 +194,7 @@ static const char msg_building_new_label[] ALIGN1 = | |
| static const char msg_part_already_defined[] ALIGN1 = | |
| "Partition %u is already defined, delete it before re-adding\n"; | |
| + | /* #endif */ |
| struct partition { | |