]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - misc-utils/getopt.c
Merge branch 'PR/libmount-exec-errors' of github.com:karelzak/util-linux-work
[thirdparty/util-linux.git] / misc-utils / getopt.c
index 8150e3c034ee788337f0f85052aded5ca1c15bca..c57dd87377abeafefe24a6f7dc7f906e808cbca1 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);
-       print_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);
 }
 
@@ -379,7 +392,7 @@ int main(int argc, char *argv[])
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
-       atexit(close_stdout);
+       close_stdout_atexit();
 
        if (getenv("GETOPT_COMPATIBLE"))
                ctl.compatible = 1;
@@ -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 */
@@ -413,11 +426,8 @@ int main(int argc, char *argv[])
                case 'a':
                        getopt_long_fp = getopt_long_only;
                        break;
-               case 'h':
-                       usage();
                case 'o':
-                       free(ctl.optstr);
-                       ctl.optstr = xstrdup(optarg);
+                       add_short_options(&ctl, optarg);
                        break;
                case 'l':
                        add_long_options(&ctl, optarg);
@@ -436,17 +446,18 @@ int main(int argc, char *argv[])
                        ctl.shell = shell_type(optarg);
                        break;
                case 'T':
-                       free(ctl.long_options);
                        return TEST_EXIT_CODE;
                case 'u':
                        ctl.quote = 0;
                        break;
+
                case 'V':
-                       printf(UTIL_LINUX_VERSION);
-                       return EXIT_SUCCESS;
+                       print_version(EXIT_SUCCESS);
                case '?':
                case ':':
                        parse_error(NULL);
+               case 'h':
+                       usage();
                default:
                        parse_error(_("internal error, contact the author."));
                }
@@ -455,7 +466,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++;
                }
        }