1
0
Fork 0
mirror of https://github.com/pygos/init.git synced 2024-11-22 03:09:46 +01:00

Don't pre-allocate argument vector for command lines

Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
David Oberhollenzer 2018-04-11 19:45:26 +02:00
parent 71d98c150f
commit 6642b2b2bf
6 changed files with 24 additions and 67 deletions

View file

@ -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)

View file

@ -46,8 +46,8 @@ enum {
typedef struct exec_t {
struct exec_t *next;
char **argv; /* NULL terminated argument vector */
char buffer[]; /* backing store for argv */
int argc; /* number of elements in argument vector */
char args[]; /* argument vectot string blob */
} exec_t;
typedef struct service_t {

View file

@ -112,18 +112,6 @@ int unescape(char *src);
*/
int pack_argv(char *str);
/*
Split a space seperated string into a sequence of null-terminated
strings. Return a NULL terminated array of strings pointing to the
start of each sub string.
It basically runs pack_argv on 'str' and then constructs the argv
vector from that, with each entry pointing into 'str'.
The returned array must be freed with free().
*/
char **split_argv(char *str);
/*
Search through an array of enum_map_t entries to resolve a string to
a numeric value. The end of the map is indicated by a sentinel entry

View file

@ -30,7 +30,6 @@ void delsvc(service_t *svc)
e = svc->exec;
svc->exec = e->next;
free(e->argv);
free(e);
}

View file

@ -38,26 +38,6 @@ static int try_unescape(char *arg, rdline_t *rd)
return 0;
}
static char **try_split_argv(char *str, rdline_t *rd)
{
char **argv = split_argv(str);
if (argv == NULL) {
switch (errno) {
case EINVAL:
fprintf(stderr, "%s: %zu: malformed string constant\n",
rd->filename, rd->lineno);
break;
default:
fprintf(stderr, "%s: %zu: %s\n",
rd->filename, rd->lineno, strerror(errno));
break;
}
}
return argv;
}
static char *try_strdup(const char *str, rdline_t *rd)
{
char *out = strdup(str);
@ -96,11 +76,12 @@ static int svc_exec(service_t *svc, char *arg, rdline_t *rd)
return -1;
}
strcpy(e->buffer, arg);
strcpy(e->args, arg);
e->argv = try_split_argv(e->buffer, rd);
if (e->argv == NULL) {
free(e);
e->argc = pack_argv(e->args);
if (e->argc < 0) {
fprintf(stderr, "%s: %zu: malformed string constant\n",
rd->filename, rd->lineno);
return -1;
}

View file

@ -80,25 +80,3 @@ fail_str:
errno = EINVAL;
return -1;
}
char **split_argv(char *str)
{
char **argv = NULL;
int i, count;
count = pack_argv(str);
if (count <= 0)
return NULL;
argv = malloc(sizeof(argv[0]) * (count + 1));
if (argv == NULL)
return NULL;
for (i = 0; i < count; ++i) {
argv[i] = str;
str += strlen(str) + 1;
}
argv[i] = NULL;
return argv;
}