Merge pull request #20419 from keszybz/setenv-no-value
Allow --setenv=FOO in various programs
This commit is contained in:
+52
-14
@@ -183,39 +183,51 @@ static int env_append(char **r, char ***k, char **a) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **strv_env_merge(size_t n_lists, ...) {
|
||||
_cleanup_strv_free_ char **ret = NULL;
|
||||
size_t n = 0;
|
||||
char **l, **k;
|
||||
char** _strv_env_merge(char **first, ...) {
|
||||
_cleanup_strv_free_ char **merged = NULL;
|
||||
char **k;
|
||||
va_list ap;
|
||||
|
||||
/* Merges an arbitrary number of environment sets */
|
||||
|
||||
va_start(ap, n_lists);
|
||||
for (size_t i = 0; i < n_lists; i++) {
|
||||
size_t n = strv_length(first);
|
||||
|
||||
va_start(ap, first);
|
||||
for (;;) {
|
||||
char **l;
|
||||
|
||||
l = va_arg(ap, char**);
|
||||
if (l == POINTER_MAX)
|
||||
break;
|
||||
|
||||
n += strv_length(l);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
ret = new(char*, n+1);
|
||||
if (!ret)
|
||||
k = merged = new(char*, n + 1);
|
||||
if (!merged)
|
||||
return NULL;
|
||||
merged[0] = NULL;
|
||||
|
||||
if (env_append(merged, &k, first) < 0)
|
||||
return NULL;
|
||||
|
||||
*ret = NULL;
|
||||
k = ret;
|
||||
va_start(ap, first);
|
||||
for (;;) {
|
||||
char **l;
|
||||
|
||||
va_start(ap, n_lists);
|
||||
for (size_t i = 0; i < n_lists; i++) {
|
||||
l = va_arg(ap, char**);
|
||||
if (env_append(ret, &k, l) < 0) {
|
||||
if (l == POINTER_MAX)
|
||||
break;
|
||||
|
||||
if (env_append(merged, &k, l) < 0) {
|
||||
va_end(ap);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
return TAKE_PTR(ret);
|
||||
return TAKE_PTR(merged);
|
||||
}
|
||||
|
||||
static bool env_match(const char *t, const char *pattern) {
|
||||
@@ -409,6 +421,32 @@ int strv_env_replace_strdup(char ***l, const char *assignment) {
|
||||
return strv_env_replace_consume(l, p);
|
||||
}
|
||||
|
||||
int strv_env_replace_strdup_passthrough(char ***l, const char *assignment) {
|
||||
/* Like strv_env_replace_strdup(), but pulls the variable from the environment of
|
||||
* the calling program, if a variable name without value is specified.
|
||||
*/
|
||||
char *p;
|
||||
|
||||
if (strchr(assignment, '=')) {
|
||||
if (!env_assignment_is_valid(assignment))
|
||||
return -EINVAL;
|
||||
|
||||
p = strdup(assignment);
|
||||
} else {
|
||||
if (!env_name_is_valid(assignment))
|
||||
return -EINVAL;
|
||||
|
||||
/* If we can't find the variable in our environment, we will use
|
||||
* the empty string. This way "passthrough" is equivalent to passing
|
||||
* --setenv=FOO=$FOO in the shell. */
|
||||
p = strjoin(assignment, "=", secure_getenv(assignment));
|
||||
}
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
return strv_env_replace_consume(l, p);
|
||||
}
|
||||
|
||||
int strv_env_assign(char ***l, const char *key, const char *value) {
|
||||
if (!env_name_is_valid(key))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -39,13 +39,15 @@ char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const cha
|
||||
bool strv_env_name_is_valid(char **l);
|
||||
bool strv_env_name_or_assignment_is_valid(char **l);
|
||||
|
||||
char **strv_env_merge(size_t n_lists, ...);
|
||||
char** _strv_env_merge(char **first, ...);
|
||||
#define strv_env_merge(first, ...) _strv_env_merge(first, __VA_ARGS__, POINTER_MAX)
|
||||
char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */
|
||||
|
||||
char **strv_env_unset(char **l, const char *p); /* In place ... */
|
||||
char **strv_env_unset_many(char **l, ...) _sentinel_;
|
||||
int strv_env_replace_consume(char ***l, char *p); /* In place ... */
|
||||
int strv_env_replace_strdup(char ***l, const char *assignment);
|
||||
int strv_env_replace_strdup_passthrough(char ***l, const char *assignment);
|
||||
int strv_env_assign(char ***l, const char *key, const char *value);
|
||||
|
||||
char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
|
||||
|
||||
Reference in New Issue
Block a user