sh: Don't discard getopts state on unknown option or missing argument.

When getopts finds an invalid option or a missing option-argument, it should
not reset its state and should set OPTIND as normal. This is an old ash bug
that was fixed long ago in dash. Our behaviour now matches most other
shells.
This commit is contained in:
Jilles Tjoelker 2014-05-10 17:42:21 +00:00
parent 0973283d6e
commit 6e76445cf7
3 changed files with 17 additions and 8 deletions

View File

@ -480,7 +480,7 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
INTON;
}
c = '?';
goto bad;
goto out;
}
if (*++q == ':')
q++;
@ -501,7 +501,7 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
INTON;
c = '?';
}
goto bad;
goto out;
}
if (p == **optnext)
@ -511,14 +511,10 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
}
else
setvarsafe("OPTARG", "", 0);
ind = *optnext - optfirst + 1;
goto out;
bad:
ind = 1;
*optnext = NULL;
p = NULL;
out:
if (*optnext != NULL)
ind = *optnext - optfirst + 1;
*optptr = p;
fmtstr(s, sizeof(s), "%d", ind);
err |= setvarsafe("OPTIND", s, VNOFUNC);

View File

@ -0,0 +1,7 @@
# $FreeBSD$
set -- -x -y
getopts :x var || echo "First getopts bad: $?"
getopts :x var
r=$?
[ r != 0 ] && [ "$OPTIND" = 3 ]

View File

@ -0,0 +1,6 @@
# $FreeBSD$
set -- -x
getopts :x: var
r=$?
[ r != 0 ] && [ "$OPTIND" = 2 ]