Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Marshall <keithmarshall@@users.sf.net>2009-01-04 20:35:36 +0300
committerKeith Marshall <keithmarshall@@users.sf.net>2009-01-04 20:35:36 +0300
commitf1170e02f2463a0a296f9d3199bb7e6e8257d2ab (patch)
tree49a26f5f696a935035d66994bb44cbc825c5fee5 /winsup/mingw/mingwex
parent952783ba77512e36857a6179da8cada9367ef3cc (diff)
Fix MinGW-Bug [2445962]; (reported by Keishi Suenaga).
Diffstat (limited to 'winsup/mingw/mingwex')
-rw-r--r--winsup/mingw/mingwex/getopt.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/winsup/mingw/mingwex/getopt.c b/winsup/mingw/mingwex/getopt.c
index 081cc56e1..29753caf1 100644
--- a/winsup/mingw/mingwex/getopt.c
+++ b/winsup/mingw/mingwex/getopt.c
@@ -87,6 +87,14 @@ enum
int optopt = getopt_unknown; /* return value for option being evaluated */
+/* Some BSD applications expect to be able to reinitialise `getopt' parsing
+ * by setting a global variable called `optreset'. We provide an obfuscated
+ * API, which allows applications to emulate this brain damage; however, any
+ * use of this is non-portable, and is strongly discouraged.
+ */
+#define optreset __mingw_optreset
+int optreset = 0;
+
static __inline__
int getopt_missing_arg( const CHAR *optstring )
{
@@ -313,7 +321,7 @@ int getopt_parse( int mode, getopt_std_args, ... )
static const CHAR *nextchar = NULL;
static int optmark = 0;
- if( optind < optbase )
+ if( (optreset |= (optind < 1)) || (optind < optbase) )
{
/* POSIX does not prescribe any definitive mechanism for restarting
* a `getopt' scan, but some applications may require such capability.
@@ -325,7 +333,25 @@ int getopt_parse( int mode, getopt_std_args, ... )
* adjusting all of the internal placeholders to one less than the
* adjusted `optind' value, (but never to less than zero).
*/
- optmark = optbase = argind = (optind > 0) ? optind - 1 : 0;
+ if( optreset )
+ {
+ /* User has explicitly requested reinitialisation...
+ * We need to reset `optind' to it's normal initial value of 1,
+ * to avoid a potential infinitely recursive loop; by doing this
+ * up front, we also ensure that the remaining placeholders will
+ * be correctly reinitialised to no less than zero.
+ */
+ optind = 1;
+
+ /* We also need to clear the `optreset' request...
+ */
+ optreset = 0;
+ }
+
+ /* Now, we may safely reinitialise the internal placeholders, to
+ * one less than `optind', without fear of making them negative.
+ */
+ optmark = optbase = argind = optind - 1;
nextchar = NULL;
}