diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2017-04-12 00:58:46 +0300 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-04-12 20:11:34 +0200 |
commit | 835ad3a984c5590ae4f6c94f2f0781ea049d1ae8 (patch) | |
tree | cb86c5441c258f66358faa93ef899e09a7788de8 | |
parent | c5496d3585bcab3c39f9b10f638ba0c94f5cda3f (diff) | |
download | busybox-w32-835ad3a984c5590ae4f6c94f2f0781ea049d1ae8.tar.gz busybox-w32-835ad3a984c5590ae4f6c94f2f0781ea049d1ae8.tar.bz2 busybox-w32-835ad3a984c5590ae4f6c94f2f0781ea049d1ae8.zip |
libbb: GETOPT_RESET macro
Signed-off-by: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 22 | ||||
-rw-r--r-- | libbb/getopt32.c | 8 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 28 | ||||
-rw-r--r-- | runit/sv.c | 7 | ||||
-rw-r--r-- | shell/shell_common.c | 8 | ||||
-rw-r--r-- | util-linux/getopt.c | 7 |
6 files changed, 28 insertions, 52 deletions
diff --git a/include/libbb.h b/include/libbb.h index 2c30bde6f..11d022fb5 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1178,6 +1178,28 @@ extern uint32_t option_mask32; | |||
1178 | extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; | 1178 | extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; |
1179 | 1179 | ||
1180 | 1180 | ||
1181 | /* BSD-derived getopt() functions require that optind be set to 1 in | ||
1182 | * order to reset getopt() state. This used to be generally accepted | ||
1183 | * way of resetting getopt(). However, glibc's getopt() | ||
1184 | * has additional getopt() state beyond optind (specifically, glibc | ||
1185 | * extensions ('+' and '-' at the start of the string), and requires | ||
1186 | * that optind be set to zero to reset its state. BSD-derived versions | ||
1187 | * of getopt() misbehaved if optind is set to 0 in order to reset getopt(), | ||
1188 | * and glibc's getopt() used to coredump if optind is set 1 in order | ||
1189 | * to reset getopt(). | ||
1190 | * Then BSD introduced additional variable "optreset" which | ||
1191 | * be set to 1 in order to reset getopt(). Sigh. Standards, anyone? | ||
1192 | * | ||
1193 | * By ~2008, OpenBSD 3.4 was changed to survive glibc-like optind = 0 | ||
1194 | * (to interpret it as if optreset was set). | ||
1195 | */ | ||
1196 | #ifdef __GLIBC__ | ||
1197 | #define GETOPT_RESET() (optind = 0) | ||
1198 | #else /* BSD style */ | ||
1199 | #define GETOPT_RESET() (optind = 1) | ||
1200 | #endif | ||
1201 | |||
1202 | |||
1181 | /* Having next pointer as a first member allows easy creation | 1203 | /* Having next pointer as a first member allows easy creation |
1182 | * of "llist-compatible" structs, and using llist_FOO functions | 1204 | * of "llist-compatible" structs, and using llist_FOO functions |
1183 | * on them. | 1205 | * on them. |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 497fc016f..3104826ef 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -576,13 +576,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
576 | * run_nofork_applet() does this, but we might end up here | 576 | * run_nofork_applet() does this, but we might end up here |
577 | * also via gunzip_main() -> gzip_main(). Play safe. | 577 | * also via gunzip_main() -> gzip_main(). Play safe. |
578 | */ | 578 | */ |
579 | #ifdef __GLIBC__ | 579 | GETOPT_RESET(); |
580 | optind = 0; | ||
581 | #else /* BSD style */ | ||
582 | optind = 1; | ||
583 | /* optreset = 1; */ | ||
584 | #endif | ||
585 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
586 | 580 | ||
587 | /* Note: just "getopt() <= 0" will not work well for | 581 | /* Note: just "getopt() <= 0" will not work well for |
588 | * "fake" short options, like this one: | 582 | * "fake" short options, like this one: |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 2e7dc2d9b..fd481bf6e 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -121,28 +121,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
121 | 121 | ||
122 | /* In case getopt() or getopt32() was already called: | 122 | /* In case getopt() or getopt32() was already called: |
123 | * reset the libc getopt() function, which keeps internal state. | 123 | * reset the libc getopt() function, which keeps internal state. |
124 | * | ||
125 | * BSD-derived getopt() functions require that optind be set to 1 in | ||
126 | * order to reset getopt() state. This used to be generally accepted | ||
127 | * way of resetting getopt(). However, glibc's getopt() | ||
128 | * has additional getopt() state beyond optind, and requires that | ||
129 | * optind be set to zero to reset its state. So the unfortunate state of | ||
130 | * affairs is that BSD-derived versions of getopt() misbehave if | ||
131 | * optind is set to 0 in order to reset getopt(), and glibc's getopt() | ||
132 | * will core dump if optind is set 1 in order to reset getopt(). | ||
133 | * | ||
134 | * More modern versions of BSD require that optreset be set to 1 in | ||
135 | * order to reset getopt(). Sigh. Standards, anyone? | ||
136 | */ | 124 | */ |
137 | #ifdef __GLIBC__ | 125 | GETOPT_RESET(); |
138 | optind = 0; | ||
139 | #else /* BSD style */ | ||
140 | optind = 1; | ||
141 | /* optreset = 1; */ | ||
142 | #endif | ||
143 | /* optarg = NULL; opterr = 1; optopt = 63; - do we need this too? */ | ||
144 | /* (values above are what they initialized to in glibc and uclibc) */ | ||
145 | /* option_mask32 = 0; - not needed, no applet depends on it being 0 */ | ||
146 | 126 | ||
147 | argc = 1; | 127 | argc = 1; |
148 | while (argv[argc]) | 128 | while (argv[argc]) |
@@ -167,11 +147,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
167 | restore_nofork_data(&old); | 147 | restore_nofork_data(&old); |
168 | 148 | ||
169 | /* Other globals can be simply reset to defaults */ | 149 | /* Other globals can be simply reset to defaults */ |
170 | #ifdef __GLIBC__ | 150 | GETOPT_RESET(); |
171 | optind = 0; | ||
172 | #else /* BSD style */ | ||
173 | optind = 1; | ||
174 | #endif | ||
175 | 151 | ||
176 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ | 152 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ |
177 | } | 153 | } |
diff --git a/runit/sv.c b/runit/sv.c index 9e2132259..64f1ae395 100644 --- a/runit/sv.c +++ b/runit/sv.c | |||
@@ -688,12 +688,7 @@ int svc_main(int argc UNUSED_PARAM, char **argv) | |||
688 | /* getopt32() was already called: | 688 | /* getopt32() was already called: |
689 | * reset the libc getopt() function, which keeps internal state. | 689 | * reset the libc getopt() function, which keeps internal state. |
690 | */ | 690 | */ |
691 | #ifdef __GLIBC__ | 691 | GETOPT_RESET(); |
692 | optind = 0; | ||
693 | #else /* BSD style */ | ||
694 | optind = 1; | ||
695 | /* optreset = 1; */ | ||
696 | #endif | ||
697 | 692 | ||
698 | do { | 693 | do { |
699 | if (opts & 1) { | 694 | if (opts & 1) { |
diff --git a/shell/shell_common.c b/shell/shell_common.c index 549b17ca1..fb86e680f 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -401,13 +401,7 @@ shell_builtin_ulimit(char **argv) | |||
401 | /* In case getopt was already called: | 401 | /* In case getopt was already called: |
402 | * reset the libc getopt() function, which keeps internal state. | 402 | * reset the libc getopt() function, which keeps internal state. |
403 | */ | 403 | */ |
404 | #ifdef __GLIBC__ | 404 | GETOPT_RESET(); |
405 | optind = 0; | ||
406 | #else /* BSD style */ | ||
407 | optind = 1; | ||
408 | /* optreset = 1; */ | ||
409 | #endif | ||
410 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
411 | 405 | ||
412 | argc = 1; | 406 | argc = 1; |
413 | while (argv[argc]) | 407 | while (argv[argc]) |
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index 63294c520..79d54854b 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -246,12 +246,7 @@ static int generate_output(char **argv, int argc, const char *optstr, const stru | |||
246 | 246 | ||
247 | /* We used it already in main() in getopt32(), | 247 | /* We used it already in main() in getopt32(), |
248 | * we *must* reset getopt(3): */ | 248 | * we *must* reset getopt(3): */ |
249 | #ifdef __GLIBC__ | 249 | GETOPT_RESET(); |
250 | optind = 0; | ||
251 | #else /* BSD style */ | ||
252 | optind = 1; | ||
253 | /* optreset = 1; */ | ||
254 | #endif | ||
255 | 250 | ||
256 | while (1) { | 251 | while (1) { |
257 | #if ENABLE_FEATURE_GETOPT_LONG | 252 | #if ENABLE_FEATURE_GETOPT_LONG |