diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-27 22:39:55 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-27 22:39:55 +0000 |
commit | c4e4be9414f8c7318c0f87b0838d88bb9ef75732 (patch) | |
tree | b128e794445db2b6b025963f5857d31b44332667 /libbb/vfork_daemon_rexec.c | |
parent | f470196a4144dd586f8b80efeef4aca39cf11514 (diff) | |
download | busybox-w32-c4e4be9414f8c7318c0f87b0838d88bb9ef75732.tar.gz busybox-w32-c4e4be9414f8c7318c0f87b0838d88bb9ef75732.tar.bz2 busybox-w32-c4e4be9414f8c7318c0f87b0838d88bb9ef75732.zip |
tentatively fix getopt state corruption for NOFORK applets
Diffstat (limited to 'libbb/vfork_daemon_rexec.c')
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 4e6ecde67..3a386c5c9 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -131,12 +131,34 @@ int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char ** | |||
131 | 131 | ||
132 | applet_name = APPLET_NAME(applet_no); | 132 | applet_name = APPLET_NAME(applet_no); |
133 | xfunc_error_retval = EXIT_FAILURE; | 133 | xfunc_error_retval = EXIT_FAILURE; |
134 | /*option_mask32 = 0; - not needed */ | 134 | |
135 | /* special flag for xfunc_die(). If xfunc will "die" | 135 | /* Special flag for xfunc_die(). If xfunc will "die" |
136 | * in NOFORK applet, xfunc_die() sees negative | 136 | * in NOFORK applet, xfunc_die() sees negative |
137 | * die_sleep and longjmp here instead. */ | 137 | * die_sleep and longjmp here instead. */ |
138 | die_sleep = -1; | 138 | die_sleep = -1; |
139 | 139 | ||
140 | /* Reset the libc getopt() function, which keeps internal state. | ||
141 | * | ||
142 | * BSD-derived getopt() functions require that optind be reset to 1 in | ||
143 | * order to reset getopt() state. This used to be generally accepted | ||
144 | * way of resetting getopt(). However, glibc's getopt() | ||
145 | * has additional getopt() state beyond optind, and requires that | ||
146 | * optind be set zero to reset its state. So the unfortunate state of | ||
147 | * affairs is that BSD-derived versions of getopt() misbehave if | ||
148 | * optind is set to 0 in order to reset getopt(), and glibc's getopt() | ||
149 | * will core ump if optind is set 1 in order to reset getopt(). | ||
150 | * | ||
151 | * More modern versions of BSD require that optreset be set to 1 in | ||
152 | * order to reset getopt(). Sigh. Standards, anyone? | ||
153 | */ | ||
154 | #ifdef __GLIBC__ | ||
155 | optind = 0; | ||
156 | #else /* BSD style */ | ||
157 | optind = 1; | ||
158 | /* optreset = 1; */ | ||
159 | #endif | ||
160 | /* option_mask32 = 0; - not needed */ | ||
161 | |||
140 | argc = 1; | 162 | argc = 1; |
141 | while (argv[argc]) | 163 | while (argv[argc]) |
142 | argc++; | 164 | argc++; |