summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2012-09-06 18:04:35 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2012-09-06 18:04:35 +0000
commitd64b28c263a0dcc59b4a1a81a5150d0098e37e74 (patch)
tree70bd3860dc8cdcd4029e5631ad7a5ff0935701b7
parente56bdd7429e072ce9df2c105e44852b211ff0b7c (diff)
Avoid modifying argv when building argv for $* and $@ since it will
affect ps output. This can happen when command line options are specified, e.g. "sh -c command". Based on a diff from espie@ OK espie@
-rw-r--r--bin/ksh/main.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/bin/ksh/main.c b/bin/ksh/main.c
index d0714443432..1f232a366e7 100644
--- a/bin/ksh/main.c
+++ b/bin/ksh/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.49 2012/09/05 22:20:25 espie Exp $ */
+/* $OpenBSD: main.c,v 1.50 2012/09/06 18:04:34 millert Exp $ */
/*
* startup, main loop, environments and error handling
@@ -67,6 +67,28 @@ char username[_PW_NAME_LEN + 1];
#define version_param (initcoms[2])
+/* The shell uses its own variation on argv, to build variables like
+ * $0 and $@.
+ * If we need to alter argv, allocate a new array first since
+ * modifying the original argv will modify ps output.
+ */
+static char **
+make_argv(int argc, char *argv[])
+{
+ int i;
+ char **nargv = argv;
+
+ if (strcmp(argv[0], kshname) != 0) {
+ nargv = alloc(sizeof(char *) * (argc + 1), &aperm);
+ nargv[0] = (char *) kshname;
+ for (i = 1; i < argc; i++)
+ nargv[i] = argv[i];
+ nargv[i] = NULL;
+ }
+
+ return nargv;
+}
+
int
main(int argc, char *argv[])
{
@@ -314,9 +336,8 @@ main(int argc, char *argv[])
#endif
l = e->loc;
- l->argv = &argv[argi - 1];
+ l->argv = make_argv(argc - (argi - 1), &argv[argi - 1]);
l->argc = argc - argi;
- l->argv[0] = (char *) kshname;
getopts_reset(1);
/* Disable during .profile/ENV reading */