summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2014-05-10 19:18:49 +0000
committerjilles <jilles@FreeBSD.org>2014-05-10 19:18:49 +0000
commitaa09279cea9f52c37d4c07acd51053f2de726203 (patch)
tree1eb64ce821fdc1b0c352c7e59a44f4087a27f32b /bin/sh
parente86f4c348276e0fec90c66af0830ba55e3df88bd (diff)
downloadFreeBSD-src-aa09279cea9f52c37d4c07acd51053f2de726203.zip
FreeBSD-src-aa09279cea9f52c37d4c07acd51053f2de726203.tar.gz
sh: In getopts, unset OPTARG where POSIX says we should.
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/options.c25
-rw-r--r--bin/sh/tests/builtins/Makefile1
-rw-r--r--bin/sh/tests/builtins/getopts8.08
-rw-r--r--bin/sh/tests/builtins/getopts8.0.stdout5
4 files changed, 26 insertions, 13 deletions
diff --git a/bin/sh/options.c b/bin/sh/options.c
index 8594c57..bf00a4e 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -446,6 +446,7 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
int ind = 0;
int err = 0;
char s[10];
+ const char *optarg = NULL;
if ((p = *optptr) == NULL || *p == '\0') {
/* Current word is done, advance */
@@ -471,14 +472,10 @@ atend:
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
- err |= setvarsafe("OPTARG", s, 0);
+ optarg = s;
}
- else {
+ else
out2fmt_flush("Illegal option -%c\n", c);
- INTOFF;
- (void) unsetvar("OPTARG");
- INTON;
- }
c = '?';
goto out;
}
@@ -491,14 +488,11 @@ atend:
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
- err |= setvarsafe("OPTARG", s, 0);
+ optarg = s;
c = ':';
}
else {
out2fmt_flush("No arg for -%c option\n", c);
- INTOFF;
- (void) unsetvar("OPTARG");
- INTON;
c = '?';
}
goto out;
@@ -506,16 +500,21 @@ atend:
if (p == **optnext)
(*optnext)++;
- setvarsafe("OPTARG", p, 0);
+ optarg = p;
p = NULL;
}
- else
- setvarsafe("OPTARG", "", 0);
out:
if (*optnext != NULL)
ind = *optnext - optfirst + 1;
*optptr = p;
+ if (optarg != NULL)
+ err |= setvarsafe("OPTARG", optarg, 0);
+ else {
+ INTOFF;
+ err |= unsetvar("OPTARG");
+ INTON;
+ }
fmtstr(s, sizeof(s), "%d", ind);
err |= setvarsafe("OPTIND", s, VNOFUNC);
s[0] = c;
diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile
index 054a3b8..7a71318 100644
--- a/bin/sh/tests/builtins/Makefile
+++ b/bin/sh/tests/builtins/Makefile
@@ -85,6 +85,7 @@ FILES+= getopts4.0
FILES+= getopts5.0
FILES+= getopts6.0
FILES+= getopts7.0
+FILES+= getopts8.0 getopts8.0.stdout
FILES+= hash1.0 hash1.0.stdout
FILES+= hash2.0 hash2.0.stdout
FILES+= hash3.0 hash3.0.stdout
diff --git a/bin/sh/tests/builtins/getopts8.0 b/bin/sh/tests/builtins/getopts8.0
new file mode 100644
index 0000000..da4af6b
--- /dev/null
+++ b/bin/sh/tests/builtins/getopts8.0
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+set -- -yz -wx
+opt=wrong1 OPTARG=wrong2
+while getopts :x opt; do
+ echo "$opt:${OPTARG-unset}"
+done
+echo "OPTIND=$OPTIND"
diff --git a/bin/sh/tests/builtins/getopts8.0.stdout b/bin/sh/tests/builtins/getopts8.0.stdout
new file mode 100644
index 0000000..f10cefc
--- /dev/null
+++ b/bin/sh/tests/builtins/getopts8.0.stdout
@@ -0,0 +1,5 @@
+?:y
+?:z
+?:w
+x:unset
+OPTIND=3
OpenPOWER on IntegriCloud