From 442d522f0bc6f29c14a3e54a0af3aac68bb891a1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Jul 2017 21:31:16 +0200 Subject: [PATCH] fixes for bugs found by make_single_applets.sh Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 11 ++++++++--- include/libbb.h | 2 ++ libbb/appletlib.c | 20 ++++++++++++++++---- libbb/getopt32.c | 4 +--- libbb/vfork_daemon_rexec.c | 3 ++- networking/inetd.c | 17 ++++++++++------- scripts/randomtest.loop | 26 ++++++++++++++++++++++++++ shell/hush.c | 26 ++++++-------------------- shell/shell_common.c | 4 +--- util-linux/fdisk.c | 3 +++ 10 files changed, 75 insertions(+), 41 deletions(-) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index c60f6e6df..f7a7ab354 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -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) { diff --git a/include/libbb.h b/include/libbb.h index 9b72c97be..557978e66 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -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; diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 7f0d62060..2dea2b43a 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -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 diff --git a/libbb/getopt32.c b/libbb/getopt32.c index b87b83538..80f4cc060 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -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); diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index fd481bf6e..2695f99ee 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -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) { diff --git a/networking/inetd.c b/networking/inetd.c index 01e659f13..39169a935 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -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) diff --git a/scripts/randomtest.loop b/scripts/randomtest.loop index 710f5fd05..4d14b652f 100755 --- a/scripts/randomtest.loop +++ b/scripts/randomtest.loop @@ -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 diff --git a/shell/hush.c b/shell/hush.c index f5c1e5bc1..db8ca4f97 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1486,8 +1486,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; @@ -1497,10 +1495,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) @@ -6817,13 +6812,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(); @@ -8829,12 +8822,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 @@ -9381,10 +9370,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; diff --git a/shell/shell_common.c b/shell/shell_common.c index 03b7d0b75..bf56f3d78 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -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) { diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 916d4e30e..4467525c7 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -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 { -- 2.25.1