]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - misc-utils/getopt.c
Merge branch 'PR/libmount-utab-event' of github.com:karelzak/util-linux-work
[thirdparty/util-linux.git] / misc-utils / getopt.c
index 3fa158eb3bed57d78a7a4e1ae487e9ef1b2563a5..f989461a7647bae8d199d88a549068bb326769aa 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
@@ -255,9 +256,9 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
 
        if (ctl->long_options_nr == ctl->long_options_length) {
                ctl->long_options_length += REALLOC_INCREMENT;
-               ctl->long_options = xrealloc(ctl->long_options,
-                                            sizeof(struct option) *
-                                            ctl->long_options_length);
+               ctl->long_options = xreallocarray(ctl->long_options,
+                                                 ctl->long_options_length,
+                                                 sizeof(struct option));
        }
        if (name) {
                /* Not for init! */
@@ -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 = strconcat("+", 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!
@@ -346,8 +359,8 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_(" -T, --test                    test for getopt(1) version\n"), stdout);
        fputs(_(" -u, --unquoted                do not quote the output\n"), stdout);
        fputs(USAGE_SEPARATOR, stdout);
-       printf(USAGE_HELP_OPTIONS(31));
-       printf(USAGE_MAN_TAIL("getopt(1)"));
+       fprintf(stdout, USAGE_HELP_OPTIONS(31));
+       fprintf(stdout, USAGE_MAN_TAIL("getopt(1)"));
        exit(EXIT_SUCCESS);
 }
 
@@ -392,8 +405,8 @@ int main(int argc, char *argv[])
                         */
                        printf(" --\n");
                        return EXIT_SUCCESS;
-               } else
-                       parse_error(_("missing optstring argument"));
+               }
+               parse_error(_("missing optstring argument"));
        }
 
        add_longopt(&ctl, NULL, 0);     /* init */
@@ -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++;
                }
        }