mirror of
https://github.com/pygos/init.git
synced 2024-12-22 15:20:49 +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:
parent
71d98c150f
commit
6642b2b2bf
6 changed files with 24 additions and 67 deletions
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,7 +30,6 @@ void delsvc(service_t *svc)
|
|||
e = svc->exec;
|
||||
svc->exec = e->next;
|
||||
|
||||
free(e->argv);
|
||||
free(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue