aboutsummaryrefslogtreecommitdiff
path: root/initd
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-04-11 19:45:26 +0200
committerDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-04-11 19:45:26 +0200
commit6642b2b2bf3d16e0632989c1e29c672882e0d283 (patch)
treef39581ab909a41fe07c005cbb81f2ec273d057ea /initd
parent71d98c150f6242fcf1b8a5845e46db56caad3885 (diff)
Don't pre-allocate argument vector for command lines
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
Diffstat (limited to 'initd')
-rw-r--r--initd/runlst.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/initd/runlst.c b/initd/runlst.c
index 7840aff..933daeb 100644
--- a/initd/runlst.c
+++ b/initd/runlst.c
@@ -18,6 +18,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include <fcntl.h>
@@ -55,6 +56,20 @@ static int child_setup(const char *ctty)
return 0;
}
+static NORETURN void argv_exec(exec_t *e)
+{
+ char **argv = alloca(e->argc + 1), *ptr;
+ int i;
+
+ for (ptr = e->args, i = 0; i < e->argc; ++i, ptr += strlen(ptr) + 1)
+ argv[i] = ptr;
+
+ argv[i] = NULL;
+ execve(argv[0], argv, environ);
+ perror(argv[0]);
+ exit(EXIT_FAILURE);
+}
+
int runlst_wait(exec_t *list, const char *ctty)
{
pid_t ret, pid;
@@ -66,9 +81,7 @@ int runlst_wait(exec_t *list, const char *ctty)
if (pid == 0) {
if (child_setup(ctty))
exit(EXIT_FAILURE);
- execve(list->argv[0], list->argv, environ);
- perror(list->argv[0]);
- exit(EXIT_FAILURE);
+ argv_exec(list);
}
if (pid == -1) {
@@ -101,9 +114,7 @@ pid_t runlst(exec_t *list, const char *ctty)
if (list->next != NULL)
exit(runlst_wait(list, NULL));
- execve(list->argv[0], list->argv, environ);
- perror(list->argv[0]);
- exit(EXIT_FAILURE);
+ argv_exec(list);
}
if (pid == -1)