getopt: update optarg and optind correctly on missing argument
authorRich Felker <dalias@aerifal.cx>
Wed, 22 Aug 2018 23:29:56 +0000 (19:29 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 22 Aug 2018 23:29:56 +0000 (19:29 -0400)
the text of the specification for getopt's handling of options that
require an argument, which requires updating optarg and optind, does
not exclude the error case where the end of the argument list has been
reached. in that case, it is expected that optarg be assigned
argv[argc] (normally null) and optind be incremented by 2, resulting
in a value of argc+1.

src/misc/getopt.c

index e921a60ed9997ac0634f1a4c819ce55c7b18714d..cd1f292fb56718e23d1aba6c0a2be2c3a0dc5d30 100644 (file)
@@ -84,8 +84,12 @@ int getopt(int argc, char * const argv[], const char *optstring)
                return '?';
        }
        if (optstring[i] == ':') {
-               if (optstring[i+1] == ':') optarg = 0;
-               else if (optind >= argc) {
+               optarg = 0;
+               if (optstring[i+1] != ':' || optpos) {
+                       optarg = argv[optind++] + optpos;
+                       optpos = 0;
+               }
+               if (optind > argc) {
                        optopt = c;
                        if (optstring[0] == ':') return ':';
                        if (opterr) __getopt_msg(argv[0],
@@ -93,10 +97,6 @@ int getopt(int argc, char * const argv[], const char *optstring)
                                optchar, k);
                        return '?';
                }
-               if (optstring[i+1] != ':' || optpos) {
-                       optarg = argv[optind++] + optpos;
-                       optpos = 0;
-               }
        }
        return c;
 }