custom-env: Add support for argument array

execve() takes the same form for arguments as environment: an array of
constant pointers to mutable strings, terminated by a NULL.

To make it easier for users who want to build up their own argument
strings to pass to execve, add support for argument arrays to custom_env.

Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
Daniel Stone
2022-07-12 14:46:56 +01:00
committed by Pekka Paalanen
parent 2a9cae17d8
commit e568a025e1
3 changed files with 67 additions and 4 deletions
+37 -1
View File
@@ -78,6 +78,8 @@ custom_env_init_from_environ(struct custom_env *env)
wl_array_init(&env->envp);
env->env_finalized = false;
wl_array_init(&env->argp);
env->arg_finalized = false;
for (it = environ; *it; it++) {
ep = wl_array_add(&env->envp, sizeof *ep);
@@ -94,8 +96,11 @@ custom_env_fini(struct custom_env *env)
wl_array_for_each(p, &env->envp)
free(*p);
wl_array_release(&env->envp);
wl_array_for_each(p, &env->argp)
free(*p);
wl_array_release(&env->argp);
}
static char **
@@ -116,6 +121,20 @@ custom_env_get_env_var(struct custom_env *env, const char *name)
return NULL;
}
void
custom_env_add_arg(struct custom_env *env, const char *arg)
{
char **ap;
assert(!env->arg_finalized);
ap = wl_array_add(&env->argp, sizeof *ap);
assert(ap);
*ap = strdup(arg);
assert(*ap);
}
void
custom_env_set_env_var(struct custom_env *env, const char *name, const char *value)
{
@@ -151,3 +170,20 @@ custom_env_get_envp(struct custom_env *env)
return env->envp.data;
}
char *const *
custom_env_get_argp(struct custom_env *env)
{
char **ap;
assert(!env->arg_finalized);
/* add terminating NULL */
ap = wl_array_add(&env->argp, sizeof *ap);
assert(ap);
*ap = NULL;
env->arg_finalized = true;
return env->argp.data;
}
+11 -3
View File
@@ -61,13 +61,15 @@ fdstr_close_all(struct fdstr *s);
/**
* A container for environment variables, designed to be used when forking child
* processes, as setenv() and anything which allocates memory cannot be used
* between fork() and exec().
* A container for environment variables and/or process arguments, designed to
* be used when forking child processes, as setenv() and anything which
* allocates memory cannot be used between fork() and exec().
*/
struct custom_env {
struct wl_array envp;
bool env_finalized;
struct wl_array argp;
bool arg_finalized;
};
void
@@ -79,5 +81,11 @@ custom_env_fini(struct custom_env *env);
void
custom_env_set_env_var(struct custom_env *env, const char *name, const char *value);
void
custom_env_add_arg(struct custom_env *env, const char *arg);
char *const *
custom_env_get_envp(struct custom_env *env);
char *const *
custom_env_get_argp(struct custom_env *env);