LibC: Correctly reset the getopt state on optind = 0

515f31339c incorrectly made getopt only reset its state when `optind`
is set to 1. However, the Linux man page says that setting it to 0 also
reinitializes its state and additionally checks for some GNU extensions.
stress-ng relies on this behavior.

The POSIX man page only says that setting it to 0 results in undefined
behavior.
This commit is contained in:
Sönke Holz
2025-05-21 21:44:06 +02:00
committed by Nico Weber
parent bbdbdabff8
commit 2f2a06d925
2 changed files with 4 additions and 3 deletions

View File

@@ -17,7 +17,8 @@ extern int optopt;
// Index of the next argument to process upon a getopt*() call.
extern int optind;
// If set, reset the internal state kept by getopt*(). You may also want to set
// optind to 1 in that case.
// optind to 1 in that case. Alternatively, setting optind to 0 is treated like
// doing both of the above.
extern int optreset;
// After parsing an option that accept an argument, set to point to the argument
// value.

View File

@@ -33,7 +33,7 @@ int getopt(int argc, char* const* argv, char const* short_options)
for (auto i = 1; i < argc; ++i)
s_args.append({ argv[i], strlen(argv[i]) });
if (optind == 1 || optreset == 1) {
if (optind <= 1 || optreset == 1) {
s_parser.reset_state();
optind = 1;
optreset = 0;
@@ -75,7 +75,7 @@ int getopt_long(int argc, char* const* argv, char const* short_options, const st
});
}
if (optind == 1 || optreset == 1) {
if (optind <= 1 || optreset == 1) {
s_parser.reset_state();
optind = 1;
optreset = 0;