From c8fb3e69d0345eb9bd36a945994e50e4792ad773 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 10 May 2014 19:18:49 +0000 Subject: [PATCH] sh: In getopts, unset OPTARG where POSIX says we should. --- bin/sh/options.c | 25 ++++++++++++------------- bin/sh/tests/builtins/Makefile | 1 + bin/sh/tests/builtins/getopts8.0 | 8 ++++++++ bin/sh/tests/builtins/getopts8.0.stdout | 5 +++++ 4 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 bin/sh/tests/builtins/getopts8.0 create mode 100644 bin/sh/tests/builtins/getopts8.0.stdout diff --git a/bin/sh/options.c b/bin/sh/options.c index 8594c5707a4c..bf00a4e7d47e 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 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, 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 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, 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 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, 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 054a3b8fde7c..7a71318c8227 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 000000000000..da4af6bd0b56 --- /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 000000000000..f10cefcd8c1b --- /dev/null +++ b/bin/sh/tests/builtins/getopts8.0.stdout @@ -0,0 +1,5 @@ +?:y +?:z +?:w +x:unset +OPTIND=3