diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-04-14 10:09:57 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-04-14 10:09:57 +0000 |
commit | 1f7c156d56726cdeeadc5983149304f2e3be36ad (patch) | |
tree | 95a0c3632c8c2b20fa6b60f1e1a33e4fc4b24d4f /libbb/vfork_daemon_rexec.c | |
parent | 86b5b2210f0ea0158af81b9da1f6849ea7dcea5d (diff) | |
download | busybox-w32-1f7c156d56726cdeeadc5983149304f2e3be36ad.tar.gz busybox-w32-1f7c156d56726cdeeadc5983149304f2e3be36ad.tar.bz2 busybox-w32-1f7c156d56726cdeeadc5983149304f2e3be36ad.zip |
hush: use NOFORK applets as appropriate. Net reduction of code size.
git-svn-id: svn://busybox.net/trunk/busybox@18436 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb/vfork_daemon_rexec.c')
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 7dbc152e2..78f3c4ad4 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -100,6 +100,52 @@ int wait_pid(int *wstat, int pid) | |||
100 | return r; | 100 | return r; |
101 | } | 101 | } |
102 | 102 | ||
103 | int run_nofork_applet(const struct bb_applet *a, char **argv) | ||
104 | { | ||
105 | int rc, argc; | ||
106 | |||
107 | /* Save some shared globals */ | ||
108 | const struct bb_applet *old_a = current_applet; | ||
109 | int old_x = xfunc_error_retval; | ||
110 | uint32_t old_m = option_mask32; | ||
111 | int old_sleep = die_sleep; | ||
112 | |||
113 | current_applet = a; | ||
114 | applet_name = a->name; | ||
115 | xfunc_error_retval = EXIT_FAILURE; | ||
116 | /*option_mask32 = 0; - not needed */ | ||
117 | /* special flag for xfunc_die(). If xfunc will "die" | ||
118 | * in NOFORK applet, xfunc_die() sees negative | ||
119 | * die_sleep and longjmp here instead. */ | ||
120 | die_sleep = -1; | ||
121 | |||
122 | argc = 1; | ||
123 | while (argv[argc]) | ||
124 | argc++; | ||
125 | |||
126 | rc = setjmp(die_jmp); | ||
127 | if (!rc) { | ||
128 | /* Some callers (xargs) | ||
129 | * need argv untouched because they free argv[i]! */ | ||
130 | char *tmp_argv[argc+1]; | ||
131 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | ||
132 | /* Finally we can call NOFORK applet's main() */ | ||
133 | rc = a->main(argc, tmp_argv); | ||
134 | } else { /* xfunc died in NOFORK applet */ | ||
135 | /* in case they meant to return 0... */ | ||
136 | if (rc == -111) | ||
137 | rc = 0; | ||
138 | } | ||
139 | |||
140 | /* Restoring globals */ | ||
141 | current_applet = old_a; | ||
142 | applet_name = old_a->name; | ||
143 | xfunc_error_retval = old_x; | ||
144 | option_mask32 = old_m; | ||
145 | die_sleep = old_sleep; | ||
146 | return rc; | ||
147 | } | ||
148 | |||
103 | int spawn_and_wait(char **argv) | 149 | int spawn_and_wait(char **argv) |
104 | { | 150 | { |
105 | int rc; | 151 | int rc; |
@@ -111,50 +157,11 @@ int spawn_and_wait(char **argv) | |||
111 | || a->noexec /* NOEXEC trick needs fork() */ | 157 | || a->noexec /* NOEXEC trick needs fork() */ |
112 | #endif | 158 | #endif |
113 | )) { | 159 | )) { |
114 | int argc = 1; | ||
115 | char **pp = argv; | ||
116 | while (*++pp) | ||
117 | argc++; | ||
118 | #if BB_MMU | 160 | #if BB_MMU |
119 | if (a->nofork) | 161 | if (a->nofork) |
120 | #endif | 162 | #endif |
121 | { | 163 | { |
122 | /* Save some shared globals */ | 164 | return run_nofork_applet(a, argv); |
123 | const struct bb_applet *old_a = current_applet; | ||
124 | int old_x = xfunc_error_retval; | ||
125 | uint32_t old_m = option_mask32; | ||
126 | int old_sleep = die_sleep; | ||
127 | |||
128 | current_applet = a; | ||
129 | applet_name = a->name; | ||
130 | xfunc_error_retval = EXIT_FAILURE; | ||
131 | /*option_mask32 = 0; - not needed */ | ||
132 | /* special flag for xfunc_die(). If xfunc will "die" | ||
133 | * in NOFORK applet, xfunc_die() sees negative | ||
134 | * die_sleep and longjmp here instead. */ | ||
135 | die_sleep = -1; | ||
136 | |||
137 | rc = setjmp(die_jmp); | ||
138 | if (!rc) { | ||
139 | /* Some callers (xargs) | ||
140 | * need argv untouched because they free argv[i]! */ | ||
141 | char *tmp_argv[argc+1]; | ||
142 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | ||
143 | /* Finally we can call NOFORK applet's main() */ | ||
144 | rc = a->main(argc, tmp_argv); | ||
145 | } else { /* xfunc died in NOFORK applet */ | ||
146 | /* in case they meant to return 0... */ | ||
147 | if (rc == -111) | ||
148 | rc = 0; | ||
149 | } | ||
150 | |||
151 | /* Restoring globals */ | ||
152 | current_applet = old_a; | ||
153 | applet_name = old_a->name; | ||
154 | xfunc_error_retval = old_x; | ||
155 | option_mask32 = old_m; | ||
156 | die_sleep = old_sleep; | ||
157 | return rc; | ||
158 | } | 165 | } |
159 | #if BB_MMU | 166 | #if BB_MMU |
160 | /* MMU only */ | 167 | /* MMU only */ |
@@ -165,7 +172,7 @@ int spawn_and_wait(char **argv) | |||
165 | /* child */ | 172 | /* child */ |
166 | xfunc_error_retval = EXIT_FAILURE; | 173 | xfunc_error_retval = EXIT_FAILURE; |
167 | current_applet = a; | 174 | current_applet = a; |
168 | run_current_applet_and_exit(argc, argv); | 175 | run_current_applet_and_exit(argv); |
169 | #endif | 176 | #endif |
170 | } | 177 | } |
171 | #endif /* FEATURE_PREFER_APPLETS */ | 178 | #endif /* FEATURE_PREFER_APPLETS */ |