From 48c37b427136529c5a48a1a51922dea06928ec6a Mon Sep 17 00:00:00 2001 From: guenther <> Date: Sat, 5 Mar 2011 22:10:11 +0000 Subject: [PATCH] Fix PR 6267: recheck POSIXLY_CORRECT each time getopt_long() starts a new argv and don't suppress the handling of leading '-' in optstring when POSIXLY_CORRECT is set. Based on patch from Eric Blake. ok and manpage update from millert@, manpage ok jmc@ --- src/lib/libc/stdlib/getopt.3 | 13 ++----------- src/lib/libc/stdlib/getopt_long.3 | 23 ++--------------------- src/lib/libc/stdlib/getopt_long.c | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3 index 82f74c2c..ecdf42ab 100644 --- a/src/lib/libc/stdlib/getopt.3 +++ b/src/lib/libc/stdlib/getopt.3 @@ -25,9 +25,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: getopt.3,v 1.41 2009/04/12 23:13:36 okan Exp $ +.\" $OpenBSD: getopt.3,v 1.42 2011/03/05 22:10:11 guenther Exp $ .\" -.Dd $Mdocdate: April 12 2009 $ +.Dd $Mdocdate: March 5 2011 $ .Dt GETOPT 3 .Os .Sh NAME @@ -158,15 +158,6 @@ is set to the character that caused the error. The .Fn getopt function returns \-1 when the argument list is exhausted. -.Sh ENVIRONMENT -.Bl -tag -width POSIXLY_CORRECTXX -.It Ev POSIXLY_CORRECT -If set, a leading -.Sq - -in -.Ar optstring -is ignored. -.El .Sh EXAMPLES The following code accepts the options .Fl b diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3 index c2b0db64..fe3a54bb 100644 --- a/src/lib/libc/stdlib/getopt_long.3 +++ b/src/lib/libc/stdlib/getopt_long.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: getopt_long.3,v 1.17 2011/01/24 01:50:25 schwarze Exp $ +.\" $OpenBSD: getopt_long.3,v 1.18 2011/03/05 22:10:11 guenther Exp $ .\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $ .\" .\" Copyright (c) 1988, 1991, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 .\" -.Dd $Mdocdate: January 24 2011 $ +.Dd $Mdocdate: March 5 2011 $ .Dt GETOPT_LONG 3 .Os .Sh NAME @@ -211,23 +211,6 @@ found in glibc-2.1.3: .It handling of .Ql - -as the first character of the option string in the presence of the -environment variable -.Ev POSIXLY_CORRECT : -.Bl -tag -width "OpenBSD" -.It GNU -ignores -.Ev POSIXLY_CORRECT -and returns non-options as arguments to option -.Ql \e1 . -.It OpenBSD -honors -.Ev POSIXLY_CORRECT -and stops at the first non-option. -.El -.It -handling of -.Ql - within the option string (not the first character): .Bl -tag -width "OpenBSD" .It GNU @@ -402,8 +385,6 @@ relative to current positions) are the same, though. .It Ev POSIXLY_CORRECT If set, option processing stops when the first non-option is found and a leading -.Sq - -or .Sq + in the .Ar optstring diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c index eb1e3ef4..e149fe0a 100644 --- a/src/lib/libc/stdlib/getopt_long.c +++ b/src/lib/libc/stdlib/getopt_long.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getopt_long.c,v 1.24 2010/07/22 19:31:53 blambert Exp $ */ +/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ /* @@ -284,26 +284,26 @@ getopt_internal(int nargc, char * const *nargv, const char *options, if (options == NULL) return (-1); + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + /* * Disable GNU extensions if POSIXLY_CORRECT is set or options * string begins with a '+'. */ - if (posixly_correct == -1) + if (posixly_correct == -1 || optreset) posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - else if (*options == '-') + if (*options == '-') flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; if (*options == '+' || *options == '-') options++; - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; - optarg = NULL; if (optreset) nonopt_start = nonopt_end = -1;