fixes for bugs found by make_single_applets.sh
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 3 Jul 2017 19:31:16 +0000 (21:31 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 3 Jul 2017 19:31:16 +0000 (21:31 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/bbunzip.c
include/libbb.h
libbb/appletlib.c
libbb/getopt32.c
libbb/vfork_daemon_rexec.c
networking/inetd.c
scripts/randomtest.loop
shell/hush.c
shell/shell_common.c
util-linux/fdisk.c

index c60f6e6df66738371a4ea1ed5b9d7401064da7f3..f7a7ab3544821943469fcc8bc0b6382460c0434e 100644 (file)
@@ -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)
 {
index 9b72c97be28b23748ffbd26691b01038368ebaf3..557978e66be9353cb0950f9a12eac367e83d17e6 100644 (file)
@@ -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;
index 7f0d6206042460c044ee864d4d60ef754a0cf5de..2dea2b43a0e64eca714c202d3dc08b83aa9c885c 100644 (file)
 #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
 
index b87b835386d92fc3b95c3452649b878295ed4fcc..80f4cc060d7ad2d460af2c1c32b3bfd82b1b7568 100644 (file)
@@ -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);
 
index fd481bf6eab7797e1bff367ce5ef0dca1e8f0c98..2695f99eee33e83ada3a2088b1ae728b548fe87c 100644 (file)
@@ -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) {
index 01e659f13d4d7279d86f4b41d934bc5438ecec38..39169a935f52d848481504e738ac57261cc37480 100644 (file)
@@ -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)
index 710f5fd05b2e853c91f99a1978f9ae58589d186a..4d14b652fa2e726a8591d7baebc6425708acb88f 100755 (executable)
@@ -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
index fc6db316e1e46313f1c7a7196f10b8c0a902be96..30add72f01aa6831c55db95ae9f6d4254fd6d2da 100644 (file)
@@ -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;
 
index 03b7d0b7571c11a9fe2fe6f6d1fe3126419d6da8..bf56f3d78b9e4c121d3c7b8d48c879ed4b5bd18f 100644 (file)
@@ -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) {
index 916d4e30e4b15307cbf29af70ec5d825b1c50088..4467525c739d7398552e6ed4a4f3329edcd28ecb 100644 (file)
@@ -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 {