execute: support minimal environment variable replacement when executing processes
This commit is contained in:
parent
1e3ad081ef
commit
fab56fc541
|
@ -943,7 +943,7 @@ int exec_spawn(ExecCommand *command,
|
||||||
const char *username = NULL, *home = NULL;
|
const char *username = NULL, *home = NULL;
|
||||||
uid_t uid = (uid_t) -1;
|
uid_t uid = (uid_t) -1;
|
||||||
gid_t gid = (gid_t) -1;
|
gid_t gid = (gid_t) -1;
|
||||||
char **our_env = NULL, **pam_env = NULL, **final_env = NULL;
|
char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
|
||||||
unsigned n_env = 0;
|
unsigned n_env = 0;
|
||||||
int saved_stdout = -1, saved_stdin = -1;
|
int saved_stdout = -1, saved_stdin = -1;
|
||||||
bool keep_stdout = false, keep_stdin = false;
|
bool keep_stdout = false, keep_stdin = false;
|
||||||
|
@ -1260,13 +1260,19 @@ int exec_spawn(ExecCommand *command,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
execve(command->path, argv, final_env);
|
if (!(final_argv = replace_env_argv(argv, final_env))) {
|
||||||
|
r = EXIT_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
execve(command->path, final_argv, final_env);
|
||||||
r = EXIT_EXEC;
|
r = EXIT_EXEC;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
strv_free(our_env);
|
strv_free(our_env);
|
||||||
strv_free(final_env);
|
strv_free(final_env);
|
||||||
strv_free(pam_env);
|
strv_free(pam_env);
|
||||||
|
strv_free(final_argv);
|
||||||
|
|
||||||
if (saved_stdin >= 0)
|
if (saved_stdin >= 0)
|
||||||
close_nointr_nofail(saved_stdin);
|
close_nointr_nofail(saved_stdin);
|
||||||
|
|
17
src/strv.c
17
src/strv.c
|
@ -539,3 +539,20 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *strv_env_get_with_length(char **l, const char *name, size_t k) {
|
||||||
|
char **i;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
STRV_FOREACH(i, l)
|
||||||
|
if (strncmp(*i, name, k) == 0 &&
|
||||||
|
(*i)[k] == '=')
|
||||||
|
return *i + k + 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strv_env_get(char **l, const char *name) {
|
||||||
|
return strv_env_get_with_length(l, name, strlen(name));
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ char **strv_env_delete(char **x, unsigned n_lists, ...);
|
||||||
|
|
||||||
char **strv_env_set(char **x, const char *p);
|
char **strv_env_set(char **x, const char *p);
|
||||||
|
|
||||||
|
char *strv_env_get_with_length(char **l, const char *name, size_t k);
|
||||||
|
char *strv_env_get(char **x, const char *n);
|
||||||
|
|
||||||
#define STRV_FOREACH(s, l) \
|
#define STRV_FOREACH(s, l) \
|
||||||
for ((s) = (l); (s) && *(s); (s)++)
|
for ((s) = (l); (s) && *(s); (s)++)
|
||||||
|
|
||||||
|
|
112
src/util.c
112
src/util.c
|
@ -613,15 +613,23 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strappend(const char *s, const char *suffix) {
|
char *strnappend(const char *s, const char *suffix, size_t b) {
|
||||||
size_t a, b;
|
size_t a;
|
||||||
char *r;
|
char *r;
|
||||||
|
|
||||||
|
if (!s && !suffix)
|
||||||
|
return strdup("");
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return strndup(suffix, b);
|
||||||
|
|
||||||
|
if (!suffix)
|
||||||
|
return strdup(s);
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(suffix);
|
assert(suffix);
|
||||||
|
|
||||||
a = strlen(s);
|
a = strlen(s);
|
||||||
b = strlen(suffix);
|
|
||||||
|
|
||||||
if (!(r = new(char, a+b+1)))
|
if (!(r = new(char, a+b+1)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -633,6 +641,10 @@ char *strappend(const char *s, const char *suffix) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *strappend(const char *s, const char *suffix) {
|
||||||
|
return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
int readlink_malloc(const char *p, char **r) {
|
int readlink_malloc(const char *p, char **r) {
|
||||||
size_t l = 100;
|
size_t l = 100;
|
||||||
|
|
||||||
|
@ -2692,6 +2704,100 @@ void status_welcome(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *replace_env(const char *format, char **env) {
|
||||||
|
enum {
|
||||||
|
WORD,
|
||||||
|
DOLLAR,
|
||||||
|
VARIABLE
|
||||||
|
} state = WORD;
|
||||||
|
|
||||||
|
const char *e, *word = format;
|
||||||
|
char *r = NULL, *k;
|
||||||
|
|
||||||
|
assert(format);
|
||||||
|
|
||||||
|
for (e = format; *e; e ++) {
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
|
||||||
|
case WORD:
|
||||||
|
if (*e == '$')
|
||||||
|
state = DOLLAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOLLAR:
|
||||||
|
if (*e == '(') {
|
||||||
|
if (!(k = strnappend(r, word, e-word-1)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
r = k;
|
||||||
|
|
||||||
|
word = e-1;
|
||||||
|
state = VARIABLE;
|
||||||
|
|
||||||
|
} else if (*e == '$') {
|
||||||
|
if (!(k = strnappend(r, word, e-word)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
r = k;
|
||||||
|
|
||||||
|
word = e+1;
|
||||||
|
state = WORD;
|
||||||
|
} else
|
||||||
|
state = WORD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VARIABLE:
|
||||||
|
if (*e == ')') {
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if ((t = strv_env_get_with_length(env, word+2, e-word-2))) {
|
||||||
|
if (!(k = strappend(r, t)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
r = k;
|
||||||
|
|
||||||
|
word = e+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = WORD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(k = strnappend(r, word, e-word)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
return k;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **replace_env_argv(char **argv, char **env) {
|
||||||
|
char **r, **i;
|
||||||
|
unsigned k;
|
||||||
|
|
||||||
|
if (!(r = new(char*, strv_length(argv)+1)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
STRV_FOREACH(i, argv) {
|
||||||
|
if (!(r[k++] = replace_env(*i, env))) {
|
||||||
|
strv_free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r[k] = NULL;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const ioprio_class_table[] = {
|
static const char *const ioprio_class_table[] = {
|
||||||
[IOPRIO_CLASS_NONE] = "none",
|
[IOPRIO_CLASS_NONE] = "none",
|
||||||
[IOPRIO_CLASS_RT] = "realtime",
|
[IOPRIO_CLASS_RT] = "realtime",
|
||||||
|
|
|
@ -183,6 +183,10 @@ int write_one_line_file(const char *fn, const char *line);
|
||||||
int read_one_line_file(const char *fn, char **line);
|
int read_one_line_file(const char *fn, char **line);
|
||||||
|
|
||||||
char *strappend(const char *s, const char *suffix);
|
char *strappend(const char *s, const char *suffix);
|
||||||
|
char *strnappend(const char *s, const char *suffix, size_t length);
|
||||||
|
|
||||||
|
char *replace_env(const char *format, char **env);
|
||||||
|
char **replace_env_argv(char **argv, char **env);
|
||||||
|
|
||||||
int readlink_malloc(const char *p, char **r);
|
int readlink_malloc(const char *p, char **r);
|
||||||
int readlink_and_make_absolute(const char *p, char **r);
|
int readlink_and_make_absolute(const char *p, char **r);
|
||||||
|
|
Loading…
Reference in a new issue