summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/eval.c1
-rw-r--r--bin/sh/options.c31
-rw-r--r--bin/sh/options.h1
-rw-r--r--bin/sh/tests/builtins/getopts9.09
-rw-r--r--bin/sh/tests/builtins/getopts9.0.stdout3
5 files changed, 39 insertions, 6 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 38e227c..c1a9cdb 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -1039,6 +1039,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
shellparam.reset = 1;
shellparam.nparam = argc - 1;
shellparam.p = argv + 1;
+ shellparam.optp = NULL;
shellparam.optnext = NULL;
INTOFF;
savelocalvars = localvars;
diff --git a/bin/sh/options.c b/bin/sh/options.c
index bf00a4e..860cf6c 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -325,6 +325,7 @@ setparam(char **argv)
shellparam.malloc = 1;
shellparam.nparam = nparam;
shellparam.p = newparam;
+ shellparam.optp = NULL;
shellparam.reset = 1;
shellparam.optnext = NULL;
}
@@ -344,6 +345,11 @@ freeparam(struct shparam *param)
ckfree(*ap);
ckfree(param->p);
}
+ if (param->optp) {
+ for (ap = param->optp ; *ap ; ap++)
+ ckfree(*ap);
+ ckfree(param->optp);
+ }
}
@@ -417,20 +423,33 @@ getoptsreset(const char *value)
int
getoptscmd(int argc, char **argv)
{
- char **optbase = NULL;
+ char **optbase = NULL, **ap;
+ int i;
if (argc < 3)
error("usage: getopts optstring var [arg]");
- else if (argc == 3)
- optbase = shellparam.p;
- else
- optbase = &argv[3];
if (shellparam.reset == 1) {
+ INTOFF;
+ if (shellparam.optp) {
+ for (ap = shellparam.optp ; *ap ; ap++)
+ ckfree(*ap);
+ ckfree(shellparam.optp);
+ shellparam.optp = NULL;
+ }
+ if (argc > 3) {
+ shellparam.optp = ckmalloc((argc - 2) * sizeof *ap);
+ memset(shellparam.optp, '\0', (argc - 2) * sizeof *ap);
+ for (i = 0; i < argc - 3; i++)
+ shellparam.optp[i] = savestr(argv[i + 3]);
+ }
+ INTON;
+ optbase = argc == 3 ? shellparam.p : shellparam.optp;
shellparam.optnext = optbase;
shellparam.optptr = NULL;
shellparam.reset = 0;
- }
+ } else
+ optbase = shellparam.optp ? shellparam.optp : shellparam.p;
return getopts(argv[1], argv[2], optbase, &shellparam.optnext,
&shellparam.optptr);
diff --git a/bin/sh/options.h b/bin/sh/options.h
index acc2a11..0994862 100644
--- a/bin/sh/options.h
+++ b/bin/sh/options.h
@@ -38,6 +38,7 @@ struct shparam {
unsigned char malloc; /* if parameter list dynamically allocated */
unsigned char reset; /* if getopts has been reset */
char **p; /* parameter list */
+ char **optp; /* parameter list for getopts */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
};
diff --git a/bin/sh/tests/builtins/getopts9.0 b/bin/sh/tests/builtins/getopts9.0
new file mode 100644
index 0000000..d23fc43
--- /dev/null
+++ b/bin/sh/tests/builtins/getopts9.0
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+args='-ab'
+getopts ab opt $args
+echo $?:$opt:$OPTARG
+for dummy in dummy1 dummy2; do
+ getopts ab opt $args
+ echo $?:$opt:$OPTARG
+done
diff --git a/bin/sh/tests/builtins/getopts9.0.stdout b/bin/sh/tests/builtins/getopts9.0.stdout
new file mode 100644
index 0000000..4d32063
--- /dev/null
+++ b/bin/sh/tests/builtins/getopts9.0.stdout
@@ -0,0 +1,3 @@
+0:a:
+0:b:
+1:?:
OpenPOWER on IntegriCloud