aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--applets/applet_tables.c9
-rw-r--r--coreutils/Kbuild3
-rw-r--r--coreutils/basename.c11
-rw-r--r--coreutils/echo.c4
-rw-r--r--include/busybox.h3
-rw-r--r--include/libbb.h17
-rw-r--r--init/Config.in4
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/appletlib.c42
-rw-r--r--libbb/error_msg_and_die.c27
-rw-r--r--libbb/getopt32.c17
-rw-r--r--procps/kill.c1
-rw-r--r--shell/Config.in11
-rw-r--r--shell/ash.c25
14 files changed, 84 insertions, 91 deletions
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 6c3492b4d..35b099eb4 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -69,9 +69,14 @@ int main(int argc, char **argv)
69 69
70 /* Keep in sync with include/busybox.h! */ 70 /* Keep in sync with include/busybox.h! */
71 71
72 puts("/* This is a generated file, don't edit */"); 72 puts("/* This is a generated file, don't edit */\n");
73 73
74 puts("const char applet_names[] ALIGN1 = \"\"\n"); 74 if (NUM_APPLETS == 1) {
75 printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name);
76 printf("#define SINGLE_APPLET_MAIN %s_main\n\n", applets[0].name);
77 }
78
79 puts("const char applet_names[] ALIGN1 = \"\"");
75 for (i = 0; i < NUM_APPLETS; i++) { 80 for (i = 0; i < NUM_APPLETS; i++) {
76 printf("\"%s\" \"\\0\"\n", applets[i].name); 81 printf("\"%s\" \"\\0\"\n", applets[i].name);
77 } 82 }
diff --git a/coreutils/Kbuild b/coreutils/Kbuild
index b9ed0d79e..253eb6da8 100644
--- a/coreutils/Kbuild
+++ b/coreutils/Kbuild
@@ -30,6 +30,7 @@ lib-$(CONFIG_DOS2UNIX) += dos2unix.o
30lib-$(CONFIG_DU) += du.o 30lib-$(CONFIG_DU) += du.o
31lib-$(CONFIG_ECHO) += echo.o 31lib-$(CONFIG_ECHO) += echo.o
32lib-$(CONFIG_ASH) += echo.o # used by ash 32lib-$(CONFIG_ASH) += echo.o # used by ash
33lib-$(CONFIG_HUSH) += echo.o # used by hush
33lib-$(CONFIG_ENV) += env.o 34lib-$(CONFIG_ENV) += env.o
34lib-$(CONFIG_EXPR) += expr.o 35lib-$(CONFIG_EXPR) += expr.o
35lib-$(CONFIG_EXPAND) += expand.o 36lib-$(CONFIG_EXPAND) += expand.o
@@ -72,6 +73,8 @@ lib-$(CONFIG_TAIL) += tail.o
72lib-$(CONFIG_TEE) += tee.o 73lib-$(CONFIG_TEE) += tee.o
73lib-$(CONFIG_TEST) += test.o 74lib-$(CONFIG_TEST) += test.o
74lib-$(CONFIG_ASH) += test.o # used by ash 75lib-$(CONFIG_ASH) += test.o # used by ash
76lib-$(CONFIG_HUSH) += test.o # used by hush
77lib-$(CONFIG_MSH) += test.o # used by msh
75lib-$(CONFIG_TOUCH) += touch.o 78lib-$(CONFIG_TOUCH) += touch.o
76lib-$(CONFIG_TR) += tr.o 79lib-$(CONFIG_TR) += tr.o
77lib-$(CONFIG_TRUE) += true.o 80lib-$(CONFIG_TRUE) += true.o
diff --git a/coreutils/basename.c b/coreutils/basename.c
index d536a1bf3..ed2377948 100644
--- a/coreutils/basename.c
+++ b/coreutils/basename.c
@@ -37,15 +37,16 @@ int basename_main(int argc, char **argv)
37 /* It should strip slash: /abc/def/ -> def */ 37 /* It should strip slash: /abc/def/ -> def */
38 s = bb_get_last_path_component_strip(*++argv); 38 s = bb_get_last_path_component_strip(*++argv);
39 39
40 m = strlen(s);
40 if (*++argv) { 41 if (*++argv) {
41 n = strlen(*argv); 42 n = strlen(*argv);
42 m = strlen(s);
43 if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { 43 if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) {
44 s[m-n] = '\0'; 44 m -= n;
45 s[m] = '\0';
45 } 46 }
46 } 47 }
47 48
48 puts(s); 49 /* puts(s) will do, but we can do without stdio this way: */
49 50 s[m++] = '\n';
50 return fflush(stdout); 51 return full_write(STDOUT_FILENO, s, m) == m;
51} 52}
diff --git a/coreutils/echo.c b/coreutils/echo.c
index fd6c950ea..6e25db62c 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -27,10 +27,8 @@
27 27
28/* This is a NOFORK applet. Be very careful! */ 28/* This is a NOFORK applet. Be very careful! */
29 29
30/* argc is unused, but removing it precludes compiler from 30/* NB: can be used by shell even if not enabled as applet */
31 * using call -> jump optimization */
32 31
33int echo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
34int echo_main(int argc ATTRIBUTE_UNUSED, char **argv) 32int echo_main(int argc ATTRIBUTE_UNUSED, char **argv)
35{ 33{
36 const char *arg; 34 const char *arg;
diff --git a/include/busybox.h b/include/busybox.h
index cad45ac00..0c44d2f51 100644
--- a/include/busybox.h
+++ b/include/busybox.h
@@ -59,9 +59,6 @@ extern const uint8_t applet_install_loc[];
59/* Length of these names has effect on size of libbusybox 59/* Length of these names has effect on size of libbusybox
60 * and "individual" binaries. Keep them short. 60 * and "individual" binaries. Keep them short.
61 */ 61 */
62void lbb_prepare(const char *applet
63 USE_FEATURE_INDIVIDUAL(, char **argv)
64 ) MAIN_EXTERNALLY_VISIBLE;
65#if ENABLE_BUILD_LIBBUSYBOX 62#if ENABLE_BUILD_LIBBUSYBOX
66#if ENABLE_FEATURE_SHARED_BUSYBOX 63#if ENABLE_FEATURE_SHARED_BUSYBOX
67int lbb_main(char **argv) EXTERNALLY_VISIBLE; 64int lbb_main(char **argv) EXTERNALLY_VISIBLE;
diff --git a/include/libbb.h b/include/libbb.h
index edf27c6d5..202574adb 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -848,23 +848,20 @@ extern void bb_verror_msg(const char *s, va_list p, const char *strerr);
848 848
849/* applets which are useful from another applets */ 849/* applets which are useful from another applets */
850int bb_cat(char** argv); 850int bb_cat(char** argv);
851int echo_main(int argc, char** argv) MAIN_EXTERNALLY_VISIBLE; 851/* If shell needs them, these three "exist" even if not enabled as applets */
852int test_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 852int echo_main(int argc, char** argv) USE_ECHO(MAIN_EXTERNALLY_VISIBLE);
853int kill_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 853int test_main(int argc, char **argv) USE_TEST(MAIN_EXTERNALLY_VISIBLE);
854#if ENABLE_ROUTE 854int kill_main(int argc, char **argv) USE_KILL(MAIN_EXTERNALLY_VISIBLE);
855void bb_displayroutes(int noresolve, int netstatfmt);
856#endif
857int chown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 855int chown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
858#if ENABLE_GUNZIP
859int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 856int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
860#endif
861#if ENABLE_BUNZIP2
862int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 857int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
863#endif
864int bbunpack(char **argv, 858int bbunpack(char **argv,
865 char* (*make_new_name)(char *filename), 859 char* (*make_new_name)(char *filename),
866 USE_DESKTOP(long long) int (*unpacker)(void) 860 USE_DESKTOP(long long) int (*unpacker)(void)
867); 861);
862#if ENABLE_ROUTE
863void bb_displayroutes(int noresolve, int netstatfmt);
864#endif
868 865
869 866
870/* Networking */ 867/* Networking */
diff --git a/init/Config.in b/init/Config.in
index 25f439003..a1684d45d 100644
--- a/init/Config.in
+++ b/init/Config.in
@@ -98,13 +98,13 @@ config FEATURE_INITRD
98 98
99config HALT 99config HALT
100 bool "poweroff, halt, and reboot" 100 bool "poweroff, halt, and reboot"
101 default y 101 default n
102 help 102 help
103 Stop all processes and either halt, reboot, or power off the system. 103 Stop all processes and either halt, reboot, or power off the system.
104 104
105config MESG 105config MESG
106 bool "mesg" 106 bool "mesg"
107 default y 107 default n
108 help 108 help
109 Mesg controls access to your terminal by others. It is typically 109 Mesg controls access to your terminal by others. It is typically
110 used to allow or disallow other users to write to your terminal 110 used to allow or disallow other users to write to your terminal
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 5740d9247..11ae10d7d 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -101,6 +101,7 @@ lib-y += wfopen_input.o
101lib-y += xatonum.o 101lib-y += xatonum.o
102lib-y += xconnect.o 102lib-y += xconnect.o
103lib-y += xfuncs.o 103lib-y += xfuncs.o
104lib-y += xfunc_die.o
104lib-y += xgetcwd.o 105lib-y += xgetcwd.o
105lib-y += xgethostbyname.o 106lib-y += xgethostbyname.o
106lib-y += xreadlink.o 107lib-y += xreadlink.o
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index e2bb37868..a48a26003 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -36,6 +36,13 @@ static const char usage_messages[] ALIGN1 = ""
36 36
37/* Include generated applet names, pointers to <applet>_main, etc */ 37/* Include generated applet names, pointers to <applet>_main, etc */
38#include "applet_tables.h" 38#include "applet_tables.h"
39/* ...and if applet_tables generator says we have only one applet... */
40#ifdef SINGLE_APPLET_MAIN
41#undef ENABLE_FEATURE_INDIVIDUAL
42#define ENABLE_FEATURE_INDIVIDUAL 1
43#undef USE_FEATURE_INDIVIDUAL
44#define USE_FEATURE_INDIVIDUAL(...) __VA_ARGS__
45#endif
39 46
40 47
41#if ENABLE_FEATURE_COMPRESS_USAGE 48#if ENABLE_FEATURE_COMPRESS_USAGE
@@ -77,6 +84,23 @@ static const char *unpack_usage_messages(void)
77void bb_show_usage(void) 84void bb_show_usage(void)
78{ 85{
79 if (ENABLE_SHOW_USAGE) { 86 if (ENABLE_SHOW_USAGE) {
87#ifdef SINGLE_APPLET_STR
88 /* Imagine that this applet is "true". Dont suck in printf! */
89 const char *p;
90 const char *usage_string = p = unpack_usage_messages();
91
92 if (*p == '\b') {
93 write(2, "\nNo help available.\n\n",
94 sizeof("\nNo help available.\n\n") - 1);
95 } else {
96 write(2, "\nUsage: "SINGLE_APPLET_STR" ",
97 sizeof("\nUsage: "SINGLE_APPLET_STR" ") - 1);
98 write(2, p, strlen(p));
99 write(2, "\n\n", 2);
100 }
101 dealloc_usage_messages((char*)usage_string);
102#else
103// TODO: in this case, stdio is sucked in by busybox_main() anyway...
80 const char *format_string; 104 const char *format_string;
81 const char *p; 105 const char *p;
82 const char *usage_string = p = unpack_usage_messages(); 106 const char *usage_string = p = unpack_usage_messages();
@@ -84,18 +108,17 @@ void bb_show_usage(void)
84 108
85 if (ap < 0) /* never happens, paranoia */ 109 if (ap < 0) /* never happens, paranoia */
86 xfunc_die(); 110 xfunc_die();
87
88 while (ap) { 111 while (ap) {
89 while (*p++) continue; 112 while (*p++) continue;
90 ap--; 113 ap--;
91 } 114 }
92
93 fprintf(stderr, "%s multi-call binary\n", bb_banner); 115 fprintf(stderr, "%s multi-call binary\n", bb_banner);
94 format_string = "\nUsage: %s %s\n\n"; 116 format_string = "\nUsage: %s %s\n\n";
95 if (*p == '\b') 117 if (*p == '\b')
96 format_string = "\nNo help available.\n\n"; 118 format_string = "\nNo help available.\n\n";
97 fprintf(stderr, format_string, applet_name, p); 119 fprintf(stderr, format_string, applet_name, p);
98 dealloc_usage_messages((char*)usage_string); 120 dealloc_usage_messages((char*)usage_string);
121#endif
99 } 122 }
100 xfunc_die(); 123 xfunc_die();
101} 124}
@@ -125,6 +148,9 @@ int *const bb_errno __attribute__ ((section (".data")));
125 148
126void lbb_prepare(const char *applet 149void lbb_prepare(const char *applet
127 USE_FEATURE_INDIVIDUAL(, char **argv)) 150 USE_FEATURE_INDIVIDUAL(, char **argv))
151 MAIN_EXTERNALLY_VISIBLE;
152void lbb_prepare(const char *applet
153 USE_FEATURE_INDIVIDUAL(, char **argv))
128{ 154{
129#ifdef __GLIBC__ 155#ifdef __GLIBC__
130 (*(int **)&bb_errno) = __errno_location(); 156 (*(int **)&bb_errno) = __errno_location();
@@ -158,6 +184,9 @@ const char *applet_name;
158bool re_execed; 184bool re_execed;
159#endif 185#endif
160 186
187
188#if !ENABLE_FEATURE_INDIVIDUAL
189
161USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ 190USE_FEATURE_SUID(static uid_t ruid;) /* real uid */
162 191
163#if ENABLE_FEATURE_SUID_CONFIG 192#if ENABLE_FEATURE_SUID_CONFIG
@@ -660,6 +689,9 @@ void run_applet_and_exit(const char *name, char **argv)
660 exit(busybox_main(argv)); 689 exit(busybox_main(argv));
661} 690}
662 691
692#endif /* !ENABLE_FEATURE_INDIVIDUAL */
693
694
663 695
664#if ENABLE_BUILD_LIBBUSYBOX 696#if ENABLE_BUILD_LIBBUSYBOX
665int lbb_main(char **argv) 697int lbb_main(char **argv)
@@ -667,6 +699,11 @@ int lbb_main(char **argv)
667int main(int argc ATTRIBUTE_UNUSED, char **argv) 699int main(int argc ATTRIBUTE_UNUSED, char **argv)
668#endif 700#endif
669{ 701{
702#if ENABLE_FEATURE_INDIVIDUAL
703 /* Only one applet is selected by the user! */
704 lbb_prepare(SINGLE_APPLET_STR USE_FEATURE_INDIVIDUAL(, argv));
705 return SINGLE_APPLET_MAIN(argc, argv);
706#else
670 lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); 707 lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv));
671 708
672#if !BB_MMU 709#if !BB_MMU
@@ -685,4 +722,5 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv)
685 722
686 run_applet_and_exit(applet_name, argv); 723 run_applet_and_exit(applet_name, argv);
687 bb_error_msg_and_die("applet not found"); 724 bb_error_msg_and_die("applet not found");
725#endif
688} 726}
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c
index 0e99a03cf..addd818b7 100644
--- a/libbb/error_msg_and_die.c
+++ b/libbb/error_msg_and_die.c
@@ -9,33 +9,6 @@
9 9
10#include "libbb.h" 10#include "libbb.h"
11 11
12int die_sleep;
13#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
14jmp_buf die_jmp;
15#endif
16
17void xfunc_die(void)
18{
19 if (die_sleep) {
20 if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
21 && die_sleep < 0
22 ) {
23 /* Special case. We arrive here if NOFORK applet
24 * calls xfunc, which then decides to die.
25 * We don't die, but jump instead back to caller.
26 * NOFORK applets still cannot carelessly call xfuncs:
27 * p = xmalloc(10);
28 * q = xmalloc(10); // BUG! if this dies, we leak p!
29 */
30 /* -2222 means "zero" (longjmp can't pass 0)
31 * run_nofork_applet() catches -2222. */
32 longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
33 }
34 sleep(die_sleep);
35 }
36 exit(xfunc_error_retval);
37}
38
39void bb_error_msg_and_die(const char *s, ...) 12void bb_error_msg_and_die(const char *s, ...)
40{ 13{
41 va_list p; 14 va_list p;
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 51e030653..c0d885603 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -285,6 +285,10 @@ const char *const bb_argv_dash[] = { "-", NULL };
285 285
286const char *opt_complementary; 286const char *opt_complementary;
287 287
288/* Many small applets don't want to suck in stdio.h only because
289 * they need to parse options by calling us */
290#define DONT_USE_PRINTF 1
291
288enum { 292enum {
289 PARAM_STRING, 293 PARAM_STRING,
290 PARAM_LIST, 294 PARAM_LIST,
@@ -335,7 +339,8 @@ getopt32(char **argv, const char *applet_opts, ...)
335#define SHOW_USAGE_IF_ERROR 1 339#define SHOW_USAGE_IF_ERROR 1
336#define ALL_ARGV_IS_OPTS 2 340#define ALL_ARGV_IS_OPTS 2
337#define FIRST_ARGV_IS_OPT 4 341#define FIRST_ARGV_IS_OPT 4
338#define FREE_FIRST_ARGV_IS_OPT 8 342#define FREE_FIRST_ARGV_IS_OPT (8 * !DONT_USE_PRINTF)
343
339 int spec_flgs = 0; 344 int spec_flgs = 0;
340 345
341 argc = 0; 346 argc = 0;
@@ -489,10 +494,16 @@ getopt32(char **argv, const char *applet_opts, ...)
489 va_end(p); 494 va_end(p);
490 495
491 if (spec_flgs & FIRST_ARGV_IS_OPT) { 496 if (spec_flgs & FIRST_ARGV_IS_OPT) {
492 if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') { 497 if (argv[1] && argv[1][0] != '-' && argv[1][1] != '\0') {
498#if DONT_USE_PRINTF
499 char *pp = alloca(strlen(argv[1]) + 2);
500 *pp++ = '-';
501 argv[1] = strcpy(pp, argv[1]);
502#else
493 argv[1] = xasprintf("-%s", argv[1]); 503 argv[1] = xasprintf("-%s", argv[1]);
494 if (ENABLE_FEATURE_CLEAN_UP) 504 if (ENABLE_FEATURE_CLEAN_UP)
495 spec_flgs |= FREE_FIRST_ARGV_IS_OPT; 505 spec_flgs |= FREE_FIRST_ARGV_IS_OPT;
506#endif
496 } 507 }
497 } 508 }
498 509
@@ -573,7 +584,7 @@ getopt32(char **argv, const char *applet_opts, ...)
573 } 584 }
574 } 585 }
575 586
576#if (ENABLE_AR || ENABLE_TAR) && ENABLE_FEATURE_CLEAN_UP 587#if ENABLE_FEATURE_CLEAN_UP
577 if (spec_flgs & FREE_FIRST_ARGV_IS_OPT) 588 if (spec_flgs & FREE_FIRST_ARGV_IS_OPT)
578 free(argv[1]); 589 free(argv[1]);
579#endif 590#endif
diff --git a/procps/kill.c b/procps/kill.c
index a77d66e7a..b839b3819 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -24,7 +24,6 @@
24 * This is needed to avoid collision with kill -9 ... syntax 24 * This is needed to avoid collision with kill -9 ... syntax
25 */ 25 */
26 26
27int kill_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
28int kill_main(int argc, char **argv) 27int kill_main(int argc, char **argv)
29{ 28{
30 char *arg; 29 char *arg;
diff --git a/shell/Config.in b/shell/Config.in
index 5ea071c36..40e0217f4 100644
--- a/shell/Config.in
+++ b/shell/Config.in
@@ -36,7 +36,6 @@ endchoice
36config ASH 36config ASH
37 bool "ash" 37 bool "ash"
38 default n 38 default n
39 select TEST
40 help 39 help
41 Tha 'ash' shell adds about 60k in the default configuration and is 40 Tha 'ash' shell adds about 60k in the default configuration and is
42 the most complete and most pedantically correct shell included with 41 the most complete and most pedantically correct shell included with
@@ -111,7 +110,6 @@ config ASH_GETOPTS
111config ASH_BUILTIN_ECHO 110config ASH_BUILTIN_ECHO
112 bool "Builtin version of 'echo'" 111 bool "Builtin version of 'echo'"
113 default y 112 default y
114 select ECHO
115 depends on ASH 113 depends on ASH
116 help 114 help
117 Enable support for echo, builtin to ash. 115 Enable support for echo, builtin to ash.
@@ -119,7 +117,6 @@ config ASH_BUILTIN_ECHO
119config ASH_BUILTIN_TEST 117config ASH_BUILTIN_TEST
120 bool "Builtin version of 'test'" 118 bool "Builtin version of 'test'"
121 default y 119 default y
122 select TEST
123 depends on ASH 120 depends on ASH
124 help 121 help
125 Enable support for test, builtin to ash. 122 Enable support for test, builtin to ash.
@@ -170,10 +167,6 @@ config ASH_EXPAND_PRMT
170config HUSH 167config HUSH
171 bool "hush" 168 bool "hush"
172 default n 169 default n
173 select TRUE
174 select FALSE
175 select TEST
176 select ECHO
177 help 170 help
178 hush is a very small shell (just 18k) and it has fairly complete 171 hush is a very small shell (just 18k) and it has fairly complete
179 Bourne shell grammar. It even handles all the normal flow control 172 Bourne shell grammar. It even handles all the normal flow control
@@ -240,13 +233,9 @@ config LASH
240 help 233 help
241 lash is deprecated and will be removed, please migrate to hush. 234 lash is deprecated and will be removed, please migrate to hush.
242 235
243
244config MSH 236config MSH
245 bool "msh" 237 bool "msh"
246 default n 238 default n
247 select TRUE
248 select FALSE
249 select TEST
250 help 239 help
251 The minix shell (adds just 30k) is quite complete and handles things 240 The minix shell (adds just 30k) is quite complete and handles things
252 like for/do/done, case/esac and all the things you expect a Bourne 241 like for/do/done, case/esac and all the things you expect a Bourne
diff --git a/shell/ash.c b/shell/ash.c
index 3651929c2..360d39b4c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8417,12 +8417,6 @@ returncmd(int argc ATTRIBUTE_UNUSED, char **argv)
8417static int breakcmd(int, char **); 8417static int breakcmd(int, char **);
8418static int dotcmd(int, char **); 8418static int dotcmd(int, char **);
8419static int evalcmd(int, char **); 8419static int evalcmd(int, char **);
8420#if ENABLE_ASH_BUILTIN_ECHO
8421static int echocmd(int, char **);
8422#endif
8423#if ENABLE_ASH_BUILTIN_TEST
8424static int testcmd(int, char **);
8425#endif
8426static int exitcmd(int, char **); 8420static int exitcmd(int, char **);
8427static int exportcmd(int, char **); 8421static int exportcmd(int, char **);
8428#if ENABLE_ASH_GETOPTS 8422#if ENABLE_ASH_GETOPTS
@@ -8464,6 +8458,9 @@ static int ulimitcmd(int, char **);
8464 * Apart from the above, [[ expr ]] should work as [ expr ] 8458 * Apart from the above, [[ expr ]] should work as [ expr ]
8465 */ 8459 */
8466 8460
8461#define testcmd test_main
8462#define echocmd echo_main
8463
8467/* Keep these in proper order since it is searched via bsearch() */ 8464/* Keep these in proper order since it is searched via bsearch() */
8468static const struct builtincmd builtintab[] = { 8465static const struct builtincmd builtintab[] = {
8469 { BUILTIN_SPEC_REG ".", dotcmd }, 8466 { BUILTIN_SPEC_REG ".", dotcmd },
@@ -11506,22 +11503,6 @@ exitcmd(int argc ATTRIBUTE_UNUSED, char **argv)
11506 /* NOTREACHED */ 11503 /* NOTREACHED */
11507} 11504}
11508 11505
11509#if ENABLE_ASH_BUILTIN_ECHO
11510static int
11511echocmd(int argc, char **argv)
11512{
11513 return echo_main(argc, argv);
11514}
11515#endif
11516
11517#if ENABLE_ASH_BUILTIN_TEST
11518static int
11519testcmd(int argc, char **argv)
11520{
11521 return test_main(argc, argv);
11522}
11523#endif
11524
11525/* 11506/*
11526 * Read a file containing shell functions. 11507 * Read a file containing shell functions.
11527 */ 11508 */