mirror of git://git.musl-libc.org/musl
fix getopt[_long] clobbering of optopt on success
getopt is only specified to modify optopt on error, and some software apparently infers an error from optopt!=0. getopt_long is changed analogously. the resulting behavior differs slightly from the behavior of the GNU implementation of getopt_long, which keeps an internal shadow copy of optopt and copies it to the public one on return, but since the GNU implementation also exhibits this shadow-copy behavior for plain getopt where is is non-conforming, I think this can reasonably be considered a bug rather than an intentional behavior that merits mimicing.
This commit is contained in:
parent
150747b41e
commit
786fda875a
|
@ -60,7 +60,6 @@ int getopt(int argc, char * const argv[], const char *optstring)
|
|||
c = 0xfffd; /* replacement char */
|
||||
}
|
||||
optchar = argv[optind]+optpos;
|
||||
optopt = c;
|
||||
optpos += k;
|
||||
|
||||
if (!argv[optind][optpos]) {
|
||||
|
@ -79,6 +78,7 @@ int getopt(int argc, char * const argv[], const char *optstring)
|
|||
} while (l && d != c);
|
||||
|
||||
if (d != c) {
|
||||
optopt = c;
|
||||
if (optstring[0] != ':' && opterr)
|
||||
__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
|
||||
return '?';
|
||||
|
@ -86,6 +86,7 @@ int getopt(int argc, char * const argv[], const char *optstring)
|
|||
if (optstring[i] == ':') {
|
||||
if (optstring[i+1] == ':') optarg = 0;
|
||||
else if (optind >= argc) {
|
||||
optopt = c;
|
||||
if (optstring[0] == ':') return ':';
|
||||
if (opterr) __getopt_msg(argv[0],
|
||||
": option requires an argument: ",
|
||||
|
|
|
@ -75,9 +75,9 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring
|
|||
if (cnt==1) {
|
||||
i = match;
|
||||
optind++;
|
||||
optopt = longopts[i].val;
|
||||
if (*opt == '=') {
|
||||
if (!longopts[i].has_arg) {
|
||||
optopt = longopts[i].val;
|
||||
if (colon || !opterr)
|
||||
return '?';
|
||||
__getopt_msg(argv[0],
|
||||
|
@ -89,6 +89,7 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring
|
|||
optarg = opt+1;
|
||||
} else if (longopts[i].has_arg == required_argument) {
|
||||
if (!(optarg = argv[optind])) {
|
||||
optopt = longopts[i].val;
|
||||
if (colon) return ':';
|
||||
if (!opterr) return '?';
|
||||
__getopt_msg(argv[0],
|
||||
|
@ -107,6 +108,7 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring
|
|||
return longopts[i].val;
|
||||
}
|
||||
if (argv[optind][1] == '-') {
|
||||
optopt = 0;
|
||||
if (!colon && opterr)
|
||||
__getopt_msg(argv[0], cnt ?
|
||||
": option is ambiguous: " :
|
||||
|
|
Loading…
Reference in New Issue