aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-02-02 19:05:25 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-02-02 19:05:25 +0100
commit6307357effb79c8fbc6ccc9d4528c8c1c48a4831 (patch)
tree332d6bc33b792407e2d569c6563887b615ef0392
parentb72baeb00328576df415f9a4b4f3d5f202e3be11 (diff)
downloadbusybox-w32-6307357effb79c8fbc6ccc9d4528c8c1c48a4831.tar.gz
busybox-w32-6307357effb79c8fbc6ccc9d4528c8c1c48a4831.tar.bz2
busybox-w32-6307357effb79c8fbc6ccc9d4528c8c1c48a4831.zip
move nofork_save_area from libbb.h to vfork_daemon_rexec.c
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h11
-rw-r--r--libbb/getopt32.c2
-rw-r--r--libbb/vfork_daemon_rexec.c48
3 files changed, 20 insertions, 41 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 88dceb11d..a0e23697c 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -911,19 +911,8 @@ pid_t wait_any_nohang(int *wstat) FAST_FUNC;
911int wait4pid(pid_t pid) FAST_FUNC; 911int wait4pid(pid_t pid) FAST_FUNC;
912/* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ 912/* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */
913int spawn_and_wait(char **argv) FAST_FUNC; 913int spawn_and_wait(char **argv) FAST_FUNC;
914struct nofork_save_area {
915 jmp_buf die_jmp;
916 const char *applet_name;
917 uint32_t option_mask32;
918 int die_sleep;
919 uint8_t xfunc_error_retval;
920 smallint saved;
921};
922void save_nofork_data(struct nofork_save_area *save) FAST_FUNC;
923void restore_nofork_data(struct nofork_save_area *save) FAST_FUNC;
924/* Does NOT check that applet is NOFORK, just blindly runs it */ 914/* Does NOT check that applet is NOFORK, just blindly runs it */
925int run_nofork_applet(int applet_no, char **argv) FAST_FUNC; 915int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
926int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv) FAST_FUNC;
927 916
928/* Helpers for daemonization. 917/* Helpers for daemonization.
929 * 918 *
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 25bae319e..abd412043 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -531,7 +531,7 @@ getopt32(char **argv, const char *applet_opts, ...)
531 531
532 /* In case getopt32 was already called: 532 /* In case getopt32 was already called:
533 * reset the libc getopt() function, which keeps internal state. 533 * reset the libc getopt() function, which keeps internal state.
534 * run_nofork_applet_prime() does this, but we might end up here 534 * run_nofork_applet() does this, but we might end up here
535 * also via gunzip_main() -> gzip_main(). Play safe. 535 * also via gunzip_main() -> gzip_main(). Play safe.
536 */ 536 */
537#ifdef __GLIBC__ 537#ifdef __GLIBC__
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index cb4781a59..af938bed3 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -68,17 +68,22 @@ pid_t FAST_FUNC xspawn(char **argv)
68} 68}
69 69
70#if ENABLE_FEATURE_PREFER_APPLETS 70#if ENABLE_FEATURE_PREFER_APPLETS
71void FAST_FUNC save_nofork_data(struct nofork_save_area *save) 71struct nofork_save_area {
72 jmp_buf die_jmp;
73 const char *applet_name;
74 uint32_t option_mask32;
75 int die_sleep;
76 uint8_t xfunc_error_retval;
77};
78static void save_nofork_data(struct nofork_save_area *save)
72{ 79{
73 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); 80 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
74 save->applet_name = applet_name; 81 save->applet_name = applet_name;
75 save->xfunc_error_retval = xfunc_error_retval; 82 save->xfunc_error_retval = xfunc_error_retval;
76 save->option_mask32 = option_mask32; 83 save->option_mask32 = option_mask32;
77 save->die_sleep = die_sleep; 84 save->die_sleep = die_sleep;
78 save->saved = 1;
79} 85}
80 86static void restore_nofork_data(struct nofork_save_area *save)
81void FAST_FUNC restore_nofork_data(struct nofork_save_area *save)
82{ 87{
83 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); 88 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
84 applet_name = save->applet_name; 89 applet_name = save->applet_name;
@@ -87,19 +92,17 @@ void FAST_FUNC restore_nofork_data(struct nofork_save_area *save)
87 die_sleep = save->die_sleep; 92 die_sleep = save->die_sleep;
88} 93}
89 94
90int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv) 95int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
91{ 96{
92 int rc, argc; 97 int rc, argc;
98 struct nofork_save_area old;
99
100 save_nofork_data(&old);
93 101
94 applet_name = APPLET_NAME(applet_no); 102 applet_name = APPLET_NAME(applet_no);
95 103
96 xfunc_error_retval = EXIT_FAILURE; 104 xfunc_error_retval = EXIT_FAILURE;
97 105
98 /* Special flag for xfunc_die(). If xfunc will "die"
99 * in NOFORK applet, xfunc_die() sees negative
100 * die_sleep and longjmp here instead. */
101 die_sleep = -1;
102
103 /* In case getopt() or getopt32() was already called: 106 /* In case getopt() or getopt32() was already called:
104 * reset the libc getopt() function, which keeps internal state. 107 * reset the libc getopt() function, which keeps internal state.
105 * 108 *
@@ -129,6 +132,11 @@ int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_n
129 while (argv[argc]) 132 while (argv[argc])
130 argc++; 133 argc++;
131 134
135 /* Special flag for xfunc_die(). If xfunc will "die"
136 * in NOFORK applet, xfunc_die() sees negative
137 * die_sleep and longjmp here instead. */
138 die_sleep = -1;
139
132 rc = setjmp(die_jmp); 140 rc = setjmp(die_jmp);
133 if (!rc) { 141 if (!rc) {
134 /* Some callers (xargs) 142 /* Some callers (xargs)
@@ -137,15 +145,6 @@ int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_n
137 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 145 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
138 /* Finally we can call NOFORK applet's main() */ 146 /* Finally we can call NOFORK applet's main() */
139 rc = applet_main[applet_no](argc, tmp_argv); 147 rc = applet_main[applet_no](argc, tmp_argv);
140
141 /* The whole reason behind nofork_save_area is that <applet>_main
142 * may exit non-locally! For example, in hush Ctrl-Z tries
143 * (modulo bugs) to dynamically create a child (backgrounded task)
144 * if it detects that Ctrl-Z was pressed when a NOFORK was running.
145 * Testcase: interactive "rm -i".
146 * Don't fool yourself into thinking "and <applet>_main() returns
147 * quickly here" and removing "useless" nofork_save_area code. */
148
149 } else { /* xfunc died in NOFORK applet */ 148 } else { /* xfunc died in NOFORK applet */
150 /* in case they meant to return 0... */ 149 /* in case they meant to return 0... */
151 if (rc == -2222) 150 if (rc == -2222)
@@ -153,7 +152,7 @@ int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_n
153 } 152 }
154 153
155 /* Restoring some globals */ 154 /* Restoring some globals */
156 restore_nofork_data(old); 155 restore_nofork_data(&old);
157 156
158 /* Other globals can be simply reset to defaults */ 157 /* Other globals can be simply reset to defaults */
159#ifdef __GLIBC__ 158#ifdef __GLIBC__
@@ -164,15 +163,6 @@ int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_n
164 163
165 return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ 164 return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
166} 165}
167
168int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
169{
170 struct nofork_save_area old;
171
172 /* Saving globals */
173 save_nofork_data(&old);
174 return run_nofork_applet_prime(&old, applet_no, argv);
175}
176#endif /* FEATURE_PREFER_APPLETS */ 166#endif /* FEATURE_PREFER_APPLETS */
177 167
178int FAST_FUNC spawn_and_wait(char **argv) 168int FAST_FUNC spawn_and_wait(char **argv)