getopt bugs

Eric Blake
Tue Dec 1 13:53:00 GMT 2009

According to Corinna Vinschen on 12/1/2009 2:42 AM:
> Well, ok, you have a point there.  We have three choices:
> - Fix the existing OpenBSD code in Cygwin to reevaluate POSIXLY_CORRECT
>   when optind is set to 0.  It's an easy fix, it only requires to
>   reorder the start of the getopt_internal function very slightly.

I'm filing an OpenBSD bug report to tell them to catch up with NetBSD and

> - Switch from the OpenBSD to the NetBSD sources.

Probably not worth it; the tweaks you proposed are simple enough to
understand.  NetBSD gets leading '-' right (look at the definition of
IN_ORDER), but handles POSIXLY_CORRECT differently (it reads the
environment every single time, even if you change the environment
mid-parse; whereas GNU getopt reads the environment only when starting a
new parse).  I think OpenBSD's caching, once fixed to reset correctly, is
the only correct behavior.

> - Keep everything as it is for Cygwin 1.7.1.

Sounds good to me - let's delay this change to post-1.7.1, in particular
so the OpenBSD folks will have time to respond to my bug report (id TBD...).

> One choice we don't have:
> - Switch from the OpenBSD to the FreeBSD sources.  The FreeBSD getopt
>   sources still have the advertisement clause, unfortunately.

Agreed.  Not to mention that FreeBSD has the same POSIXLY_CORRECT
non-caching issue as NetBSD:;content-type=text%2Fx-cvsweb-markup

> I tend to the first choice with a rather strong option to the third.
> A patch for the first choice might look like this (untested):
> 	* libc/getopt.c (getopt_internal): Reevaluate POSIXLY_CORRECT
> 	if optind is set to 0.  Handle a leading '-' in options independently
> 	of posixly_correct.

Looks decent to me, although you might also want to let optreset!=0 cause
a reread (since later on, optind==0 is translated to optreset=1).  But
I'll spend more time actually testing it and report back.  And again, no
rush until after 1.7.1.

> -	if (posixly_correct == -1)
> +	if (posixly_correct == -1 || optind == 0)
>  		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);

Don't work too hard, make some time for fun as well!

Eric Blake   

More information about the Cygwin-developers mailing list