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
|
dist_man_MANS += misc-utils/getopt.1
|
||||||
PATHFILES += misc-utils/getopt.1
|
PATHFILES += misc-utils/getopt.1
|
||||||
getopt_SOURCES = misc-utils/getopt.c
|
getopt_SOURCES = misc-utils/getopt.c
|
||||||
|
getopt_LDADD = $(LDADD) libcommon.la
|
||||||
getoptexampledir = $(docdir)
|
getoptexampledir = $(docdir)
|
||||||
dist_getoptexample_DATA = \
|
dist_getoptexample_DATA = \
|
||||||
misc-utils/getopt-example.bash \
|
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
|
non\-option parameters are output at the end), unless the
|
||||||
environment variable
|
environment variable
|
||||||
.B POSIXLY_CORRECT
|
.B POSIXLY_CORRECT
|
||||||
is set.
|
is set, in which case,
|
||||||
|
.B getopt
|
||||||
|
will prepend a
|
||||||
|
.RB ' + '
|
||||||
|
before short options automatically.
|
||||||
.PP
|
.PP
|
||||||
The environment variable
|
The environment variable
|
||||||
.B GETOPT_COMPATIBLE
|
.B GETOPT_COMPATIBLE
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
|
|
||||||
#include "closestream.h"
|
#include "closestream.h"
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
|
#include "strutils.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
/* NON_OPT is the code that is returned getopt(3) when a non-option is
|
/* 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,
|
* Register several long options. options is a string of long options,
|
||||||
* separated by commas or whitespace. This nukes 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;
|
getopt_long_fp = getopt_long_only;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
free(ctl.optstr);
|
add_short_options(&ctl, optarg);
|
||||||
ctl.optstr = xstrdup(optarg);
|
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
add_long_options(&ctl, optarg);
|
add_long_options(&ctl, optarg);
|
||||||
|
@ -455,7 +467,7 @@ int main(int argc, char *argv[])
|
||||||
if (optind >= argc)
|
if (optind >= argc)
|
||||||
parse_error(_("missing optstring argument"));
|
parse_error(_("missing optstring argument"));
|
||||||
else {
|
else {
|
||||||
ctl.optstr = xstrdup(argv[optind]);
|
add_short_options(&ctl, argv[optind]);
|
||||||
optind++;
|
optind++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue