]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
getopt: explicitly ask for POSIX mode on POSIXLY_CORRECT
authorĐoàn Trần Công Danh <congdanhqx@gmail.com>
Tue, 5 Jan 2021 13:55:46 +0000 (20:55 +0700)
committerĐoàn Trần Công Danh <congdanhqx@gmail.com>
Wed, 6 Jan 2021 13:57:57 +0000 (20:57 +0700)
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>
misc-utils/Makemodule.am
misc-utils/getopt.1.in
misc-utils/getopt.c

index a01ca36bc2af0b147fe9f7bf139ed7408385a2f9..59dea5875836c92a01f04b87e961aadcb1717fb1 100644 (file)
@@ -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 \
index b18d028202c638bfb39179f32ed4a298aed76854..a37cac03c7abe3e8163e1c216ddce2f860bcb56d 100644 (file)
@@ -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
index 01a2df6dd05e4acc0a36340484d615b3d92b3e8d..3fc38c97d3a39c43a75e14af7257dea6566388a4 100644 (file)
@@ -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++;
                }
        }