getopt: explicitly ask for POSIX mode on POSIXLY_CORRECT
GNU libc's getopt_long(3) have the tradition of not shuffling arguments to find options when either POSIXLY_CORRECT is defined in environment variables or '+' prepended in short options. Hence, the current code base is fine as is fine as is for util-linux built with GNU libc. However, musl libc only honour POSIX convention when short options prepended with '+'. musl libc doesn't care about POSIXLY_CORRECT. Thus, the behaviour of util-linux's getopt(1) that linked with musl-libc doesn't match with its own documentation. Let's make sure a '+' is always prepended to short options if POSIXLY_CORRECT is defined. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
This commit is contained in:
parent
0d182490e3
commit
27fd7278a1
|
@ -205,6 +205,7 @@ usrbin_exec_PROGRAMS += getopt
|
|||
dist_man_MANS += misc-utils/getopt.1
|
||||
PATHFILES += misc-utils/getopt.1
|
||||
getopt_SOURCES = misc-utils/getopt.c
|
||||
getopt_LDADD = $(LDADD) libcommon.la
|
||||
getoptexampledir = $(docdir)
|
||||
dist_getoptexample_DATA = \
|
||||
misc-utils/getopt-example.bash \
|
||||
|
|
|
@ -382,7 +382,11 @@ will be parsed. It will still do parameter shuffling (i.e., all
|
|||
non\-option parameters are output at the end), unless the
|
||||
environment variable
|
||||
.B POSIXLY_CORRECT
|
||||
is set.
|
||||
is set, in which case,
|
||||
.B getopt
|
||||
will prepend a
|
||||
.RB ' + '
|
||||
before short options automatically.
|
||||
.PP
|
||||
The environment variable
|
||||
.B GETOPT_COMPATIBLE
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
|
||||
#include "closestream.h"
|
||||
#include "nls.h"
|
||||
#include "strutils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
/* NON_OPT is the code that is returned getopt(3) when a non-option is
|
||||
|
@ -275,6 +276,18 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
|
|||
}
|
||||
|
||||
|
||||
static void add_short_options(struct getopt_control *ctl, char *options)
|
||||
{
|
||||
free(ctl->optstr);
|
||||
if (*options != '+' && getenv("POSIXLY_CORRECT"))
|
||||
ctl->optstr = strappend("+", options);
|
||||
else
|
||||
ctl->optstr = xstrdup(options);
|
||||
if (!ctl->optstr)
|
||||
err_oom();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register several long options. options is a string of long options,
|
||||
* separated by commas or whitespace. This nukes options!
|
||||
|
@ -414,8 +427,7 @@ int main(int argc, char *argv[])
|
|||
getopt_long_fp = getopt_long_only;
|
||||
break;
|
||||
case 'o':
|
||||
free(ctl.optstr);
|
||||
ctl.optstr = xstrdup(optarg);
|
||||
add_short_options(&ctl, optarg);
|
||||
break;
|
||||
case 'l':
|
||||
add_long_options(&ctl, optarg);
|
||||
|
@ -455,7 +467,7 @@ int main(int argc, char *argv[])
|
|||
if (optind >= argc)
|
||||
parse_error(_("missing optstring argument"));
|
||||
else {
|
||||
ctl.optstr = xstrdup(argv[optind]);
|
||||
add_short_options(&ctl, argv[optind]);
|
||||
optind++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue