diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:38:30 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:38:30 +0000 |
commit | 335b63d8d1876ce4e172ebcc9d64544785682244 (patch) | |
tree | 14183fd728ce51ae10baee70f7d8f72c39d30649 | |
parent | 07c394e69b0cfa7cd30e97ffc6edb0d857905f45 (diff) | |
download | busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.tar.gz busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.tar.bz2 busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.zip |
make a few struct bb_applet members conditional
rename sllep_and_die -> xfunc_die
make fflush_stdout_and_exit NOFORK-safe
fix some buglets found by randomconfig
-rw-r--r-- | applets/applets.c | 53 | ||||
-rw-r--r-- | archival/libunarchive/Kbuild | 5 | ||||
-rw-r--r-- | coreutils/cmp.c | 4 | ||||
-rw-r--r-- | coreutils/echo.c | 2 | ||||
-rw-r--r-- | include/applets.h | 14 | ||||
-rw-r--r-- | include/busybox.h | 26 | ||||
-rw-r--r-- | include/libbb.h | 10 | ||||
-rw-r--r-- | libbb/copyfd.c | 4 | ||||
-rw-r--r-- | libbb/error_msg_and_die.c | 21 | ||||
-rw-r--r-- | libbb/fflush_stdout_and_exit.c | 14 | ||||
-rw-r--r-- | libbb/herror_msg_and_die.c | 5 | ||||
-rw-r--r-- | libbb/perror_msg_and_die.c | 6 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 23 | ||||
-rw-r--r-- | libbb/xconnect.c | 2 | ||||
-rw-r--r-- | libbb/xfuncs.c | 2 | ||||
-rw-r--r-- | shell/ash.c | 2 | ||||
-rw-r--r-- | shell/msh.c | 2 | ||||
-rw-r--r-- | util-linux/getopt.c | 2 |
18 files changed, 114 insertions, 83 deletions
diff --git a/applets/applets.c b/applets/applets.c index 66f2b821d..3441a7886 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -43,13 +43,13 @@ static const char usage_messages[] = | |||
43 | #define usage_messages 0 | 43 | #define usage_messages 0 |
44 | #endif /* SHOW_USAGE */ | 44 | #endif /* SHOW_USAGE */ |
45 | 45 | ||
46 | /* Define struct BB_applet applets[] */ | 46 | /* Define struct bb_applet applets[] */ |
47 | #include "applets.h" | 47 | #include "applets.h" |
48 | /* The -1 arises because of the {0,NULL,0,-1} entry. */ | 48 | /* The -1 arises because of the {0,NULL,0,-1} entry. */ |
49 | const unsigned short NUM_APPLETS = sizeof(applets) / sizeof(struct BB_applet) - 1; | 49 | const unsigned short NUM_APPLETS = sizeof(applets) / sizeof(applets[0]) - 1; |
50 | 50 | ||
51 | 51 | ||
52 | const struct BB_applet *current_applet; | 52 | const struct bb_applet *current_applet; |
53 | const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; | 53 | const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; |
54 | #ifdef BB_NOMMU | 54 | #ifdef BB_NOMMU |
55 | bool re_execed; | 55 | bool re_execed; |
@@ -61,7 +61,7 @@ bool re_execed; | |||
61 | 61 | ||
62 | /* applets[] is const, so we have to define this "override" structure */ | 62 | /* applets[] is const, so we have to define this "override" structure */ |
63 | static struct BB_suid_config { | 63 | static struct BB_suid_config { |
64 | const struct BB_applet *m_applet; | 64 | const struct bb_applet *m_applet; |
65 | uid_t m_uid; | 65 | uid_t m_uid; |
66 | gid_t m_gid; | 66 | gid_t m_gid; |
67 | mode_t m_mode; | 67 | mode_t m_mode; |
@@ -130,7 +130,7 @@ static void parse_config_file(void) | |||
130 | { | 130 | { |
131 | struct BB_suid_config *sct_head; | 131 | struct BB_suid_config *sct_head; |
132 | struct BB_suid_config *sct; | 132 | struct BB_suid_config *sct; |
133 | const struct BB_applet *applet; | 133 | const struct bb_applet *applet; |
134 | FILE *f; | 134 | FILE *f; |
135 | const char *errmsg; | 135 | const char *errmsg; |
136 | char *s; | 136 | char *s; |
@@ -329,7 +329,7 @@ static void parse_config_file(void) | |||
329 | 329 | ||
330 | 330 | ||
331 | #if ENABLE_FEATURE_SUID | 331 | #if ENABLE_FEATURE_SUID |
332 | static void check_suid(const struct BB_applet *applet) | 332 | static void check_suid(const struct bb_applet *applet) |
333 | { | 333 | { |
334 | uid_t ruid = getuid(); /* real [ug]id */ | 334 | uid_t ruid = getuid(); /* real [ug]id */ |
335 | uid_t rgid = getgid(); | 335 | uid_t rgid = getgid(); |
@@ -464,45 +464,42 @@ void bb_show_usage(void) | |||
464 | applet_name, usage_string); | 464 | applet_name, usage_string); |
465 | } | 465 | } |
466 | 466 | ||
467 | sleep_and_die(); | 467 | xfunc_die(); |
468 | } | 468 | } |
469 | 469 | ||
470 | 470 | ||
471 | static int applet_name_compare(const void *name, const void *vapplet) | 471 | static int applet_name_compare(const void *name, const void *vapplet) |
472 | { | 472 | { |
473 | const struct BB_applet *applet = vapplet; | 473 | const struct bb_applet *applet = vapplet; |
474 | 474 | ||
475 | return strcmp(name, applet->name); | 475 | return strcmp(name, applet->name); |
476 | } | 476 | } |
477 | 477 | ||
478 | const struct BB_applet *find_applet_by_name(const char *name) | 478 | const struct bb_applet *find_applet_by_name(const char *name) |
479 | { | 479 | { |
480 | /* Do a binary search to find the applet entry given the name. */ | 480 | /* Do a binary search to find the applet entry given the name. */ |
481 | return bsearch(name, applets, NUM_APPLETS, sizeof(struct BB_applet), | 481 | return bsearch(name, applets, NUM_APPLETS, sizeof(applets[0]), |
482 | applet_name_compare); | 482 | applet_name_compare); |
483 | } | 483 | } |
484 | 484 | ||
485 | 485 | ||
486 | #if ENABLE_FEATURE_INSTALLER | 486 | #if ENABLE_FEATURE_INSTALLER |
487 | /* | ||
488 | * directory table | ||
489 | * this should be consistent w/ the enum, busybox.h::Location, | ||
490 | * or else... | ||
491 | */ | ||
492 | static const char usr_bin [] = "/usr/bin"; | ||
493 | static const char usr_sbin[] = "/usr/sbin"; | ||
494 | |||
495 | static const char *const install_dir[] = { | ||
496 | &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */ | ||
497 | &usr_bin [4], /* "/bin" */ | ||
498 | &usr_sbin[4], /* "/sbin" */ | ||
499 | usr_bin, | ||
500 | usr_sbin | ||
501 | }; | ||
502 | |||
503 | /* create (sym)links for each applet */ | 487 | /* create (sym)links for each applet */ |
504 | static void install_links(const char *busybox, int use_symbolic_links) | 488 | static void install_links(const char *busybox, int use_symbolic_links) |
505 | { | 489 | { |
490 | /* directory table | ||
491 | * this should be consistent w/ the enum, | ||
492 | * busybox.h::bb_install_loc_t, or else... */ | ||
493 | static const char usr_bin [] = "/usr/bin"; | ||
494 | static const char usr_sbin[] = "/usr/sbin"; | ||
495 | static const char *const install_dir[] = { | ||
496 | &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */ | ||
497 | &usr_bin [4], /* "/bin" */ | ||
498 | &usr_sbin[4], /* "/sbin" */ | ||
499 | usr_bin, | ||
500 | usr_sbin | ||
501 | }; | ||
502 | |||
506 | int (*lf)(const char *, const char *) = link; | 503 | int (*lf)(const char *, const char *) = link; |
507 | char *fpc; | 504 | char *fpc; |
508 | int i; | 505 | int i; |
@@ -513,7 +510,7 @@ static void install_links(const char *busybox, int use_symbolic_links) | |||
513 | 510 | ||
514 | for (i = 0; applets[i].name != NULL; i++) { | 511 | for (i = 0; applets[i].name != NULL; i++) { |
515 | fpc = concat_path_file( | 512 | fpc = concat_path_file( |
516 | install_dir[applets[i].location], | 513 | install_dir[applets[i].install_loc], |
517 | applets[i].name); | 514 | applets[i].name); |
518 | rc = lf(busybox, fpc); | 515 | rc = lf(busybox, fpc); |
519 | if (rc != 0 && errno != EEXIST) { | 516 | if (rc != 0 && errno != EEXIST) { |
@@ -557,7 +554,7 @@ static int busybox_main(int argc, char **argv) | |||
557 | applet_name = argv[2]; | 554 | applet_name = argv[2]; |
558 | run_applet_by_name(applet_name, 2, argv); | 555 | run_applet_by_name(applet_name, 2, argv); |
559 | } else { | 556 | } else { |
560 | const struct BB_applet *a; | 557 | const struct bb_applet *a; |
561 | int col, output_width; | 558 | int col, output_width; |
562 | 559 | ||
563 | output_width = 80 - sizeof("start-stop-daemon, ") - 8; | 560 | output_width = 80 - sizeof("start-stop-daemon, ") - 8; |
diff --git a/archival/libunarchive/Kbuild b/archival/libunarchive/Kbuild index 010043c4c..412a2332d 100644 --- a/archival/libunarchive/Kbuild +++ b/archival/libunarchive/Kbuild | |||
@@ -35,12 +35,15 @@ DPKG_FILES:= \ | |||
35 | get_header_tar.o \ | 35 | get_header_tar.o \ |
36 | filter_accept_list_reassign.o | 36 | filter_accept_list_reassign.o |
37 | 37 | ||
38 | # open_transformer uses fork. Compile it only if absolutely necessary | 38 | # open_transformer uses fork(). Compile it only if absolutely necessary |
39 | lib-$(CONFIG_RPM) += open_transformer.o | 39 | lib-$(CONFIG_RPM) += open_transformer.o |
40 | lib-$(CONFIG_FEATURE_TAR_BZIP2) += open_transformer.o | 40 | lib-$(CONFIG_FEATURE_TAR_BZIP2) += open_transformer.o |
41 | lib-$(CONFIG_FEATURE_TAR_LZMA) += open_transformer.o | 41 | lib-$(CONFIG_FEATURE_TAR_LZMA) += open_transformer.o |
42 | lib-$(CONFIG_FEATURE_TAR_GZIP) += open_transformer.o | 42 | lib-$(CONFIG_FEATURE_TAR_GZIP) += open_transformer.o |
43 | lib-$(CONFIG_FEATURE_TAR_COMPRESS) += open_transformer.o | 43 | lib-$(CONFIG_FEATURE_TAR_COMPRESS) += open_transformer.o |
44 | lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += open_transformer.o | ||
45 | lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += open_transformer.o | ||
46 | lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += open_transformer.o | ||
44 | 47 | ||
45 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o | 48 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o |
46 | lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o | 49 | lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o |
diff --git a/coreutils/cmp.c b/coreutils/cmp.c index c70f8822d..80fab0b90 100644 --- a/coreutils/cmp.c +++ b/coreutils/cmp.c | |||
@@ -23,14 +23,14 @@ | |||
23 | 23 | ||
24 | #include "busybox.h" | 24 | #include "busybox.h" |
25 | 25 | ||
26 | static FILE *cmp_xfopen_input(const char * const filename) | 26 | static FILE *cmp_xfopen_input(const char *filename) |
27 | { | 27 | { |
28 | FILE *fp; | 28 | FILE *fp; |
29 | 29 | ||
30 | fp = fopen_or_warn_stdin(filename); | 30 | fp = fopen_or_warn_stdin(filename); |
31 | if (fp) | 31 | if (fp) |
32 | return fp; | 32 | return fp; |
33 | sleep_and_die(); /* We already output an error message. */ | 33 | xfunc_die(); /* We already output an error message. */ |
34 | } | 34 | } |
35 | 35 | ||
36 | static const char fmt_eof[] = "cmp: EOF on %s\n"; | 36 | static const char fmt_eof[] = "cmp: EOF on %s\n"; |
diff --git a/coreutils/echo.c b/coreutils/echo.c index 2ee5002ba..2de19c2e3 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c | |||
@@ -107,7 +107,9 @@ int bb_echo(char **argv) | |||
107 | putchar(' '); | 107 | putchar(' '); |
108 | } | 108 | } |
109 | 109 | ||
110 | #if ENABLE_FEATURE_FANCY_ECHO | ||
110 | newline_ret: | 111 | newline_ret: |
112 | #endif | ||
111 | if (nflag) { | 113 | if (nflag) { |
112 | putchar('\n'); | 114 | putchar('\n'); |
113 | } | 115 | } |
diff --git a/include/applets.h b/include/applets.h index b59d33183..d05299b69 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -52,12 +52,12 @@ s - suid type: | |||
52 | # define APPLET_NOFORK(name,main,l,s,name2) LINK l name | 52 | # define APPLET_NOFORK(name,main,l,s,name2) LINK l name |
53 | 53 | ||
54 | #else | 54 | #else |
55 | const struct BB_applet applets[] = { /* name,main,location,need_suid */ | 55 | const struct bb_applet applets[] = { /* name, main, location, need_suid */ |
56 | # define APPLET(name,l,s) {#name,name##_main,l,s}, | 56 | # define APPLET(name,l,s) { #name, name##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, |
57 | # define APPLET_NOUSAGE(name,main,l,s) {#name,main##_main,l,s}, | 57 | # define APPLET_NOUSAGE(name,main,l,s) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, |
58 | # define APPLET_ODDNAME(name,main,l,s,name2) {#name,main##_main,l,s}, | 58 | # define APPLET_ODDNAME(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, |
59 | # define APPLET_NOEXEC(name,main,l,s,name2) {#name,main##_main,l,s,1}, | 59 | # define APPLET_NOEXEC(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_EXEC_PREFER_APPLETS(,1) }, |
60 | # define APPLET_NOFORK(name,main,l,s,name2) {#name,main##_main,l,s,1,1}, | 60 | # define APPLET_NOFORK(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_EXEC_PREFER_APPLETS(,1 ,1) }, |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #if ENABLE_INSTALL_NO_USR | 63 | #if ENABLE_INSTALL_NO_USR |
@@ -355,7 +355,7 @@ USE_GUNZIP(APPLET_ODDNAME(zcat, gunzip, _BB_DIR_BIN, _BB_SUID_NEVER, zcat)) | |||
355 | USE_ZCIP(APPLET(zcip, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 355 | USE_ZCIP(APPLET(zcip, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
356 | 356 | ||
357 | #if !defined(PROTOTYPES) && !defined(MAKE_USAGE) | 357 | #if !defined(PROTOTYPES) && !defined(MAKE_USAGE) |
358 | { 0, NULL, 0, 0 } | 358 | { NULL } |
359 | }; | 359 | }; |
360 | #endif | 360 | #endif |
361 | 361 | ||
diff --git a/include/busybox.h b/include/busybox.h index 6f4808778..380de9ab8 100644 --- a/include/busybox.h +++ b/include/busybox.h | |||
@@ -9,26 +9,35 @@ | |||
9 | 9 | ||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | #if ENABLE_FEATURE_INSTALLER | ||
12 | /* order matters: used as index into "install_dir[]" in busybox.c */ | 13 | /* order matters: used as index into "install_dir[]" in busybox.c */ |
13 | enum Location { | 14 | typedef enum bb_install_loc_t { |
14 | _BB_DIR_ROOT = 0, | 15 | _BB_DIR_ROOT = 0, |
15 | _BB_DIR_BIN, | 16 | _BB_DIR_BIN, |
16 | _BB_DIR_SBIN, | 17 | _BB_DIR_SBIN, |
17 | _BB_DIR_USR_BIN, | 18 | _BB_DIR_USR_BIN, |
18 | _BB_DIR_USR_SBIN | 19 | _BB_DIR_USR_SBIN |
19 | }; | 20 | } bb_install_loc_t; |
21 | #endif | ||
20 | 22 | ||
21 | enum SUIDRoot { | 23 | #if ENABLE_FEATURE_SUID |
24 | typedef enum bb_suid_t { | ||
22 | _BB_SUID_NEVER = 0, | 25 | _BB_SUID_NEVER = 0, |
23 | _BB_SUID_MAYBE, | 26 | _BB_SUID_MAYBE, |
24 | _BB_SUID_ALWAYS | 27 | _BB_SUID_ALWAYS |
25 | }; | 28 | } bb_suid_t; |
29 | #endif | ||
26 | 30 | ||
27 | struct BB_applet { | 31 | struct bb_applet { |
28 | const char *name; | 32 | const char *name; |
29 | int (*main) (int argc, char **argv); | 33 | int (*main) (int argc, char **argv); |
30 | __extension__ enum Location location:8; | 34 | #if ENABLE_FEATURE_INSTALLER |
31 | __extension__ enum SUIDRoot need_suid:8; | 35 | __extension__ enum bb_install_loc_t install_loc:8; |
36 | #endif | ||
37 | #if ENABLE_FEATURE_SUID | ||
38 | __extension__ enum bb_suid_t need_suid:8; | ||
39 | #endif | ||
40 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS | ||
32 | /* true if instead if fork(); exec("applet"); waitpid(); | 41 | /* true if instead if fork(); exec("applet"); waitpid(); |
33 | * one can do fork(); exit(applet_main(argc,argv)); waitpid(); */ | 42 | * one can do fork(); exit(applet_main(argc,argv)); waitpid(); */ |
34 | unsigned char noexec; | 43 | unsigned char noexec; |
@@ -36,10 +45,11 @@ struct BB_applet { | |||
36 | /* true if instead if fork(); exec("applet"); waitpid(); | 45 | /* true if instead if fork(); exec("applet"); waitpid(); |
37 | * one can simply call applet_main(argc,argv); */ | 46 | * one can simply call applet_main(argc,argv); */ |
38 | unsigned char nofork; | 47 | unsigned char nofork; |
48 | #endif | ||
39 | }; | 49 | }; |
40 | 50 | ||
41 | /* Defined in applet.c */ | 51 | /* Defined in applet.c */ |
42 | extern const struct BB_applet applets[]; | 52 | extern const struct bb_applet applets[]; |
43 | extern const unsigned short NUM_APPLETS; | 53 | extern const unsigned short NUM_APPLETS; |
44 | 54 | ||
45 | #endif /* _BB_INTERNAL_H_ */ | 55 | #endif /* _BB_INTERNAL_H_ */ |
diff --git a/include/libbb.h b/include/libbb.h index 3919524bc..6fff441c5 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -608,7 +608,7 @@ llist_t *llist_rev(llist_t *list); | |||
608 | int write_pidfile(const char *path); | 608 | int write_pidfile(const char *path); |
609 | #define remove_pidfile(f) ((void)unlink(f)) | 609 | #define remove_pidfile(f) ((void)unlink(f)) |
610 | #else | 610 | #else |
611 | #define write_pidfile(f) 1 | 611 | #define write_pidfile(f) TRUE |
612 | #define remove_pidfile(f) ((void)0) | 612 | #define remove_pidfile(f) ((void)0) |
613 | #endif | 613 | #endif |
614 | 614 | ||
@@ -623,7 +623,7 @@ extern smallint logmode; | |||
623 | extern int die_sleep; | 623 | extern int die_sleep; |
624 | extern int xfunc_error_retval; | 624 | extern int xfunc_error_retval; |
625 | extern jmp_buf die_jmp; | 625 | extern jmp_buf die_jmp; |
626 | extern void sleep_and_die(void) ATTRIBUTE_NORETURN; | 626 | extern void xfunc_die(void) ATTRIBUTE_NORETURN; |
627 | extern void bb_show_usage(void) ATTRIBUTE_NORETURN ATTRIBUTE_EXTERNALLY_VISIBLE; | 627 | extern void bb_show_usage(void) ATTRIBUTE_NORETURN ATTRIBUTE_EXTERNALLY_VISIBLE; |
628 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); | 628 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); |
629 | extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); | 629 | extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); |
@@ -670,8 +670,8 @@ const struct hwtype *get_hwntype(int type); | |||
670 | 670 | ||
671 | 671 | ||
672 | #ifndef BUILD_INDIVIDUAL | 672 | #ifndef BUILD_INDIVIDUAL |
673 | struct BB_applet; | 673 | struct bb_applet; |
674 | extern const struct BB_applet *find_applet_by_name(const char *name); | 674 | extern const struct bb_applet *find_applet_by_name(const char *name); |
675 | /* Returns only if applet is not found. */ | 675 | /* Returns only if applet is not found. */ |
676 | extern void run_applet_by_name(const char *name, int argc, char **argv); | 676 | extern void run_applet_by_name(const char *name, int argc, char **argv); |
677 | extern void run_current_applet_and_exit(int argc, char **argv) ATTRIBUTE_NORETURN; | 677 | extern void run_current_applet_and_exit(int argc, char **argv) ATTRIBUTE_NORETURN; |
@@ -880,7 +880,7 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ | |||
880 | }; | 880 | }; |
881 | 881 | ||
882 | #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c") | 882 | #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c") |
883 | extern const struct BB_applet *current_applet; | 883 | extern const struct bb_applet *current_applet; |
884 | extern const char *applet_name; | 884 | extern const char *applet_name; |
885 | extern const char BB_BANNER[]; | 885 | extern const char BB_BANNER[]; |
886 | 886 | ||
diff --git a/libbb/copyfd.c b/libbb/copyfd.c index e0596d5f6..aa8fbb967 100644 --- a/libbb/copyfd.c +++ b/libbb/copyfd.c | |||
@@ -74,7 +74,7 @@ void complain_copyfd_and_die(off_t sz) | |||
74 | if (sz != -1) | 74 | if (sz != -1) |
75 | bb_error_msg_and_die("short read"); | 75 | bb_error_msg_and_die("short read"); |
76 | /* if sz == -1, bb_copyfd_XX already complained */ | 76 | /* if sz == -1, bb_copyfd_XX already complained */ |
77 | sleep_and_die(); | 77 | xfunc_die(); |
78 | } | 78 | } |
79 | #endif | 79 | #endif |
80 | 80 | ||
@@ -94,7 +94,7 @@ void bb_copyfd_exact_size(int fd1, int fd2, off_t size) | |||
94 | if (sz != -1) | 94 | if (sz != -1) |
95 | bb_error_msg_and_die("short read"); | 95 | bb_error_msg_and_die("short read"); |
96 | /* if sz == -1, bb_copyfd_XX already complained */ | 96 | /* if sz == -1, bb_copyfd_XX already complained */ |
97 | sleep_and_die(); | 97 | xfunc_die(); |
98 | } | 98 | } |
99 | 99 | ||
100 | off_t bb_copyfd_eof(int fd1, int fd2) | 100 | off_t bb_copyfd_eof(int fd1, int fd2) |
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c index 39178a3ce..4a9049364 100644 --- a/libbb/error_msg_and_die.c +++ b/libbb/error_msg_and_die.c | |||
@@ -10,14 +10,25 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | int die_sleep; | 12 | int die_sleep; |
13 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS | ||
13 | jmp_buf die_jmp; | 14 | jmp_buf die_jmp; |
15 | #endif | ||
14 | 16 | ||
15 | void sleep_and_die(void) | 17 | void xfunc_die(void) |
16 | { | 18 | { |
17 | if (die_sleep) { | 19 | if (die_sleep) { |
18 | /* Special case: don't die, but jump */ | 20 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { |
19 | if (die_sleep < 0) | 21 | /* Special case. We arrive here if NOFORK applet |
20 | longjmp(die_jmp, xfunc_error_retval); | 22 | * calls xfunc, which then decides to die. |
23 | * We don't die, but jump instead back to caller. | ||
24 | * NOFORK applets still cannot carelessly call xfuncs: | ||
25 | * p = xmalloc(10); | ||
26 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
27 | */ | ||
28 | /* -111 means "zero" (longjmp can't pass 0) | ||
29 | * spawn_and_wait() catches -111. */ | ||
30 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -111); | ||
31 | } | ||
21 | sleep(die_sleep); | 32 | sleep(die_sleep); |
22 | } | 33 | } |
23 | exit(xfunc_error_retval); | 34 | exit(xfunc_error_retval); |
@@ -30,5 +41,5 @@ void bb_error_msg_and_die(const char *s, ...) | |||
30 | va_start(p, s); | 41 | va_start(p, s); |
31 | bb_verror_msg(s, p, NULL); | 42 | bb_verror_msg(s, p, NULL); |
32 | va_end(p); | 43 | va_end(p); |
33 | sleep_and_die(); | 44 | xfunc_die(); |
34 | } | 45 | } |
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index ae68222b4..d79827f45 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c | |||
@@ -13,13 +13,17 @@ | |||
13 | 13 | ||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | 15 | ||
16 | // TODO: make it safe to call from NOFORK applets | ||
17 | // Currently, it can exit(0). Even if it is made to do longjmp trick | ||
18 | // (see sleep_and_die internals), zero cannot be passed thru this way! | ||
19 | |||
20 | void fflush_stdout_and_exit(int retval) | 16 | void fflush_stdout_and_exit(int retval) |
21 | { | 17 | { |
22 | if (fflush(stdout)) | 18 | if (fflush(stdout)) |
23 | sleep_and_die(); | 19 | xfunc_die(); |
20 | |||
21 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { | ||
22 | /* We are in NOFORK applet. Do not exit() directly, | ||
23 | * but use xfunc_die() */ | ||
24 | xfunc_error_retval = retval; | ||
25 | xfunc_die(); | ||
26 | } | ||
27 | |||
24 | exit(retval); | 28 | exit(retval); |
25 | } | 29 | } |
diff --git a/libbb/herror_msg_and_die.c b/libbb/herror_msg_and_die.c index a7a22caf7..8c77378d7 100644 --- a/libbb/herror_msg_and_die.c +++ b/libbb/herror_msg_and_die.c | |||
@@ -7,9 +7,6 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <stdarg.h> | ||
11 | #include <stdlib.h> | ||
12 | |||
13 | #include "libbb.h" | 10 | #include "libbb.h" |
14 | 11 | ||
15 | void bb_herror_msg_and_die(const char *s, ...) | 12 | void bb_herror_msg_and_die(const char *s, ...) |
@@ -19,5 +16,5 @@ void bb_herror_msg_and_die(const char *s, ...) | |||
19 | va_start(p, s); | 16 | va_start(p, s); |
20 | bb_vherror_msg(s, p); | 17 | bb_vherror_msg(s, p); |
21 | va_end(p); | 18 | va_end(p); |
22 | sleep_and_die(); | 19 | xfunc_die(); |
23 | } | 20 | } |
diff --git a/libbb/perror_msg_and_die.c b/libbb/perror_msg_and_die.c index 7521e7157..3a06b654b 100644 --- a/libbb/perror_msg_and_die.c +++ b/libbb/perror_msg_and_die.c | |||
@@ -7,10 +7,6 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <stdio.h> | ||
11 | #include <errno.h> | ||
12 | #include <string.h> | ||
13 | #include <stdlib.h> | ||
14 | #include "libbb.h" | 10 | #include "libbb.h" |
15 | 11 | ||
16 | void bb_perror_msg_and_die(const char *s, ...) | 12 | void bb_perror_msg_and_die(const char *s, ...) |
@@ -20,5 +16,5 @@ void bb_perror_msg_and_die(const char *s, ...) | |||
20 | va_start(p, s); | 16 | va_start(p, s); |
21 | bb_vperror_msg(s, p); | 17 | bb_vperror_msg(s, p); |
22 | va_end(p); | 18 | va_end(p); |
23 | sleep_and_die(); | 19 | xfunc_die(); |
24 | } | 20 | } |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 286ee2678..dabd1a6d6 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <paths.h> | 18 | #include <paths.h> |
19 | #include "busybox.h" /* for struct BB_applet */ | 19 | #include "busybox.h" /* for struct bb_applet */ |
20 | 20 | ||
21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, | 21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, |
22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ | 22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ |
@@ -104,8 +104,9 @@ int spawn_and_wait(char **argv) | |||
104 | { | 104 | { |
105 | int rc; | 105 | int rc; |
106 | 106 | ||
107 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS) { | 107 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS |
108 | const struct BB_applet *a = find_applet_by_name(argv[0]); | 108 | { |
109 | const struct bb_applet *a = find_applet_by_name(argv[0]); | ||
109 | if (a && (a->nofork | 110 | if (a && (a->nofork |
110 | #ifndef BB_NOMMU | 111 | #ifndef BB_NOMMU |
111 | || a->noexec /* NOEXEC cannot be used on NOMMU */ | 112 | || a->noexec /* NOEXEC cannot be used on NOMMU */ |
@@ -120,19 +121,27 @@ int spawn_and_wait(char **argv) | |||
120 | #endif | 121 | #endif |
121 | { | 122 | { |
122 | int old_sleep = die_sleep; | 123 | int old_sleep = die_sleep; |
124 | int old_x = xfunc_error_retval; | ||
123 | die_sleep = -1; /* special flag */ | 125 | die_sleep = -1; /* special flag */ |
124 | /* sleep_and_die() checks for it */ | 126 | /* xfunc_die() checks for it */ |
127 | |||
125 | rc = setjmp(die_jmp); | 128 | rc = setjmp(die_jmp); |
126 | if (!rc) { | 129 | if (!rc) { |
127 | const struct BB_applet *old_a = current_applet; | 130 | const struct bb_applet *old_a = current_applet; |
128 | current_applet = a; | 131 | current_applet = a; |
129 | applet_name = a->name; | 132 | applet_name = a->name; |
130 | // what else should we save/restore? | 133 | // what else should we save/restore? |
131 | rc = a->main(argc, argv); | 134 | rc = a->main(argc, argv); |
132 | current_applet = old_a; | 135 | current_applet = old_a; |
133 | applet_name = old_a->name; | 136 | applet_name = old_a->name; |
137 | } else { | ||
138 | /* xfunc died in NOFORK applet */ | ||
139 | if (rc == -111) | ||
140 | rc = 0; | ||
134 | } | 141 | } |
142 | |||
135 | die_sleep = old_sleep; | 143 | die_sleep = old_sleep; |
144 | xfunc_error_retval = old_x; | ||
136 | return rc; | 145 | return rc; |
137 | } | 146 | } |
138 | #ifndef BB_NOMMU /* MMU only */ | 147 | #ifndef BB_NOMMU /* MMU only */ |
@@ -145,9 +154,13 @@ int spawn_and_wait(char **argv) | |||
145 | run_current_applet_and_exit(argc, argv); | 154 | run_current_applet_and_exit(argc, argv); |
146 | #endif | 155 | #endif |
147 | } | 156 | } |
157 | |||
148 | } | 158 | } |
149 | rc = spawn(argv); | 159 | rc = spawn(argv); |
150 | w: | 160 | w: |
161 | #else /* !FEATURE_EXEC_PREFER_APPLETS */ | ||
162 | rc = spawn(argv); | ||
163 | #endif /* FEATURE_EXEC_PREFER_APPLETS */ | ||
151 | return wait4pid(rc); | 164 | return wait4pid(rc); |
152 | } | 165 | } |
153 | 166 | ||
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 8466325c7..e7d510678 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -166,7 +166,7 @@ USE_FEATURE_IPV6(sa_family_t af,) | |||
166 | if (rc || !result) { | 166 | if (rc || !result) { |
167 | bb_error_msg("bad address '%s'", org_host); | 167 | bb_error_msg("bad address '%s'", org_host); |
168 | if (ai_flags & DIE_ON_ERROR) | 168 | if (ai_flags & DIE_ON_ERROR) |
169 | sleep_and_die(); | 169 | xfunc_die(); |
170 | goto ret; | 170 | goto ret; |
171 | } | 171 | } |
172 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 172 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index fa4a15236..b9d013a24 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -476,7 +476,7 @@ void xprint_and_close_file(FILE *file) | |||
476 | fflush(stdout); | 476 | fflush(stdout); |
477 | // copyfd outputs error messages for us. | 477 | // copyfd outputs error messages for us. |
478 | if (bb_copyfd_eof(fileno(file), 1) == -1) | 478 | if (bb_copyfd_eof(fileno(file), 1) == -1) |
479 | sleep_and_die(); | 479 | xfunc_die(); |
480 | 480 | ||
481 | fclose(file); | 481 | fclose(file); |
482 | } | 482 | } |
diff --git a/shell/ash.c b/shell/ash.c index f98fc4178..b4278424a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6533,7 +6533,7 @@ tryexec(char *cmd, char **argv, char **envp) | |||
6533 | 6533 | ||
6534 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL | 6534 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
6535 | if (strchr(cmd, '/') == NULL) { | 6535 | if (strchr(cmd, '/') == NULL) { |
6536 | const struct BB_applet *a; | 6536 | const struct bb_applet *a; |
6537 | 6537 | ||
6538 | a = find_applet_by_name(cmd); | 6538 | a = find_applet_by_name(cmd); |
6539 | if (a) { | 6539 | if (a) { |
diff --git a/shell/msh.c b/shell/msh.c index 3a5c85050..23a7c0498 100644 --- a/shell/msh.c +++ b/shell/msh.c | |||
@@ -3197,7 +3197,7 @@ static int dohelp(struct op *t) | |||
3197 | } | 3197 | } |
3198 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL | 3198 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3199 | { | 3199 | { |
3200 | const struct BB_applet *applet = applets; | 3200 | const struct bb_applet *applet = applets; |
3201 | 3201 | ||
3202 | while (applet->name) { | 3202 | while (applet->name) { |
3203 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), applet->name); | 3203 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), applet->name); |
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index fefa02206..85a1d4410 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -51,10 +51,8 @@ enum { | |||
51 | OPT_s = 0x10, // -s | 51 | OPT_s = 0x10, // -s |
52 | OPT_T = 0x20, // -T | 52 | OPT_T = 0x20, // -T |
53 | OPT_u = 0x40, // -u | 53 | OPT_u = 0x40, // -u |
54 | #if ENABLE_GETOPT_LONG | ||
55 | OPT_a = 0x80, // -a | 54 | OPT_a = 0x80, // -a |
56 | OPT_l = 0x100, // -l | 55 | OPT_l = 0x100, // -l |
57 | #endif | ||
58 | SHELL_IS_TCSH = 0x8000, /* hijack this bit for other purposes */ | 56 | SHELL_IS_TCSH = 0x8000, /* hijack this bit for other purposes */ |
59 | }; | 57 | }; |
60 | 58 | ||