Merge pull request #30974 from poettering/strv-extend-many

strv: add new strv_extend_many() helper
This commit is contained in:
Lennart Poettering
2024-01-17 13:13:30 +01:00
committed by GitHub
24 changed files with 183 additions and 153 deletions
+13 -23
View File
@@ -167,19 +167,13 @@ static char** user_dirs(
return NULL;
/* Now merge everything we found. */
if (strv_extend(&res, persistent_control) < 0)
return NULL;
if (strv_extend(&res, runtime_control) < 0)
return NULL;
if (strv_extend(&res, transient) < 0)
return NULL;
if (strv_extend(&res, generator_early) < 0)
return NULL;
if (strv_extend(&res, persistent_config) < 0)
if (strv_extend_many(
&res,
persistent_control,
runtime_control,
transient,
generator_early,
persistent_config) < 0)
return NULL;
if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
@@ -192,16 +186,12 @@ static char** user_dirs(
if (strv_extend_strv(&res, (char**) user_config_unit_paths, false) < 0)
return NULL;
if (strv_extend(&res, runtime_config) < 0)
return NULL;
if (strv_extend(&res, global_runtime_config) < 0)
return NULL;
if (strv_extend(&res, generator) < 0)
return NULL;
if (strv_extend(&res, data_home) < 0)
if (strv_extend_many(
&res,
runtime_config,
global_runtime_config,
generator,
data_home) < 0)
return NULL;
if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
+57 -31
View File
@@ -505,29 +505,31 @@ int strv_insert(char ***l, size_t position, char *value) {
char **c;
size_t n, m;
assert(l);
if (!value)
return 0;
n = strv_length(*l);
position = MIN(position, n);
/* increase and check for overflow */
m = n + 2;
if (m < n)
/* check for overflow and increase*/
if (n > SIZE_MAX - 2)
return -ENOMEM;
m = n + 2;
c = new(char*, m);
c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(m), sizeof(char*));
if (!c)
return -ENOMEM;
for (size_t i = 0; i < position; i++)
c[i] = (*l)[i];
c[position] = value;
for (size_t i = position; i < n; i++)
c[i+1] = (*l)[i];
c[n+1] = NULL;
if (n > position)
memmove(c + position + 1, c + position, (n - position) * sizeof(char*));
return free_and_replace(*l, c);
c[position] = value;
c[n + 1] = NULL;
*l = c;
return 0;
}
int strv_consume_with_size(char ***l, size_t *n, char *value) {
@@ -588,39 +590,63 @@ int strv_extend_with_size(char ***l, size_t *n, const char *value) {
return strv_consume_with_size(l, n, v);
}
int strv_extend_front(char ***l, const char *value) {
int strv_extend_many_internal(char ***l, const char *value, ...) {
va_list ap;
size_t n, m;
char *v, **c;
int r;
assert(l);
/* Like strv_extend(), but prepends rather than appends the new entry */
m = n = strv_length(*l);
if (!value)
return 0;
r = 0;
va_start(ap, value);
for (const char *s = value; s != POINTER_MAX; s = va_arg(ap, const char*)) {
if (!s)
continue;
n = strv_length(*l);
if (m > SIZE_MAX-1) { /* overflow */
r = -ENOMEM;
break;
}
m++;
}
va_end(ap);
/* Increase and overflow check. */
m = n + 2;
if (m < n)
if (r < 0)
return r;
if (m > SIZE_MAX-1)
return -ENOMEM;
v = strdup(value);
if (!v)
char **c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(m+1), sizeof(char*));
if (!c)
return -ENOMEM;
*l = c;
c = reallocarray(*l, m, sizeof(char*));
if (!c) {
free(v);
return -ENOMEM;
r = 0;
size_t i = n;
va_start(ap, value);
for (const char *s = value; s != POINTER_MAX; s = va_arg(ap, const char*)) {
if (!s)
continue;
c[i] = strdup(s);
if (!c[i]) {
r = -ENOMEM;
break;
}
i++;
}
va_end(ap);
if (r < 0) {
/* rollback on error */
for (size_t j = n; j < i; j++)
c[j] = mfree(c[j]);
return r;
}
memmove(c+1, c, n * sizeof(char*));
c[0] = v;
c[n+1] = NULL;
*l = c;
c[i] = NULL;
return 0;
}
+3 -1
View File
@@ -55,8 +55,10 @@ static inline int strv_extend(char ***l, const char *value) {
return strv_extend_with_size(l, NULL, value);
}
int strv_extend_many_internal(char ***l, const char *value, ...);
#define strv_extend_many(l, ...) strv_extend_many_internal(l, __VA_ARGS__, POINTER_MAX)
int strv_extendf(char ***l, const char *format, ...) _printf_(2,3);
int strv_extend_front(char ***l, const char *value);
int strv_push_with_size(char ***l, size_t *n, char *value);
static inline int strv_push(char ***l, char *value) {
+1 -1
View File
@@ -1517,7 +1517,7 @@ int get_timezones(char ***ret) {
/* Always include UTC */
r = strv_extend(&zones, "UTC");
if (r < 0)
return -ENOMEM;
return r;
strv_sort(zones);
strv_uniq(zones);
+5 -6
View File
@@ -300,12 +300,11 @@ static int parse_argv(int argc, char *argv[]) {
if (strv_isempty(arg_phase)) {
/* If no phases are specifically selected, pick everything from the beginning of the initrd
* to the beginning of shutdown. */
if (strv_extend_strv(&arg_phase,
STRV_MAKE("enter-initrd",
"enter-initrd:leave-initrd",
"enter-initrd:leave-initrd:sysinit",
"enter-initrd:leave-initrd:sysinit:ready"),
/* filter_duplicates= */ false) < 0)
if (strv_extend_many(&arg_phase,
"enter-initrd",
"enter-initrd:leave-initrd",
"enter-initrd:leave-initrd:sysinit",
"enter-initrd:leave-initrd:sysinit:ready") < 0)
return log_oom();
} else {
strv_sort(arg_phase);
+3 -3
View File
@@ -1949,7 +1949,7 @@ int bus_exec_context_set_transient_property(
r = strv_extend_strv(&c->supplementary_groups, l, true);
if (r < 0)
return -ENOMEM;
return r;
joined = strv_join(c->supplementary_groups, " ");
if (!joined)
@@ -3174,7 +3174,7 @@ int bus_exec_context_set_transient_property(
r = strv_extend_strv(dirs, l, true);
if (r < 0)
return -ENOMEM;
return r;
unit_write_settingf(u, flags, name, "%s=%s", name, joined);
}
@@ -3201,7 +3201,7 @@ int bus_exec_context_set_transient_property(
_cleanup_free_ char *joined = NULL;
r = strv_extend_strv(&c->exec_search_path, l, true);
if (r < 0)
return -ENOMEM;
return r;
joined = strv_join(c->exec_search_path, ":");
if (!joined)
return log_oom();
+3 -1
View File
@@ -2271,7 +2271,9 @@ static int bus_unit_set_transient_property(
u->documentation = strv_free(u->documentation);
unit_write_settingf(u, flags, name, "%s=", name);
} else {
strv_extend_strv(&u->documentation, l, false);
r = strv_extend_strv(&u->documentation, l, /* filter_duplicates= */ false);
if (r < 0)
return r;
STRV_FOREACH(p, l)
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
+2 -3
View File
@@ -244,9 +244,8 @@ static char **credential_search_path(const ExecParameters *params, CredentialSea
}
if (IN_SET(path, CREDENTIAL_SEARCH_PATH_TRUSTED, CREDENTIAL_SEARCH_PATH_ALL)) {
if (params->received_credentials_directory)
if (strv_extend(&l, params->received_credentials_directory) < 0)
return NULL;
if (strv_extend(&l, params->received_credentials_directory) < 0)
return NULL;
if (strv_extend_strv(&l, CONF_PATHS_STRV("credstore"), /* filter_duplicates= */ true) < 0)
return NULL;
+4 -5
View File
@@ -2811,11 +2811,10 @@ static int compile_symlinks(
* absolute, when they are processed in namespace.c they will be made relative automatically, i.e.:
* 'os-release -> .os-release-stage/os-release' is what will be created. */
if (setup_os_release_symlink) {
r = strv_extend(&symlinks, "/run/host/.os-release-stage/os-release");
if (r < 0)
return r;
r = strv_extend(&symlinks, "/run/host/os-release");
r = strv_extend_many(
&symlinks,
"/run/host/.os-release-stage/os-release",
"/run/host/os-release");
if (r < 0)
return r;
}
+3 -2
View File
@@ -494,8 +494,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
(void) exec_shared_runtime_deserialize_one(m, val, fds);
else if ((val = startswith(l, "subscribed="))) {
if (strv_extend(&m->deserialized_subscribed, val) < 0)
return -ENOMEM;
r = strv_extend(&m->deserialized_subscribed, val);
if (r < 0)
return r;
} else if ((val = startswith(l, "varlink-server-socket-address="))) {
if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) {
r = manager_varlink_init(m);
+1 -5
View File
@@ -994,11 +994,7 @@ static int activation_details_path_append_pair(ActivationDetails *details, char
if (isempty(p->trigger_path_filename))
return 0;
r = strv_extend(strv, "trigger_path");
if (r < 0)
return r;
r = strv_extend(strv, p->trigger_path_filename);
r = strv_extend_many(strv, "trigger_path", p->trigger_path_filename);
if (r < 0)
return r;
+1 -1
View File
@@ -3098,7 +3098,7 @@ int service_deserialize_exec_command(
case STATE_EXEC_COMMAND_ARGS:
r = strv_extend(&argv, arg);
if (r < 0)
return -ENOMEM;
return r;
break;
default:
assert_not_reached();
+1 -5
View File
@@ -6530,11 +6530,7 @@ int activation_details_append_pair(ActivationDetails *details, char ***strv) {
return 0;
if (!isempty(details->trigger_unit_name)) {
r = strv_extend(strv, "trigger_unit");
if (r < 0)
return r;
r = strv_extend(strv, details->trigger_unit_name);
r = strv_extend_many(strv, "trigger_unit", details->trigger_unit_name);
if (r < 0)
return r;
}
+3 -3
View File
@@ -1242,7 +1242,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
if (r < 0)
return r;
r = strv_extend_strv(&debugger_call, STRV_MAKE(exe, "-c", path), false);
r = strv_extend_many(&debugger_call, exe, "-c", path);
if (r < 0)
return log_oom();
@@ -1251,14 +1251,14 @@ static int run_debug(int argc, char **argv, void *userdata) {
const char *sysroot_cmd;
sysroot_cmd = strjoina("set sysroot ", arg_root);
r = strv_extend_strv(&debugger_call, STRV_MAKE("-iex", sysroot_cmd), false);
r = strv_extend_many(&debugger_call, "-iex", sysroot_cmd);
if (r < 0)
return log_oom();
} else if (streq(arg_debugger, "lldb")) {
const char *sysroot_cmd;
sysroot_cmd = strjoina("platform select --sysroot ", arg_root, " host");
r = strv_extend_strv(&debugger_call, STRV_MAKE("-O", sysroot_cmd), false);
r = strv_extend_many(&debugger_call, "-O", sysroot_cmd);
if (r < 0)
return log_oom();
}
@@ -26,7 +26,7 @@ static int environment_dirs(char ***ret) {
if (r < 0)
return r;
r = strv_extend_front(&dirs, c);
r = strv_consume_prepend(&dirs, TAKE_PTR(c));
if (r < 0)
return r;
+4 -5
View File
@@ -978,11 +978,10 @@ static int context_build_arguments(Context *c) {
return log_oom();
} else if (c->action == ACTION_INSPECT) {
r = strv_extend(&a, c->kernel ?: "[KERNEL_IMAGE]");
if (r < 0)
return log_oom();
r = strv_extend(&a, "[INITRD...]");
r = strv_extend_many(
&a,
c->kernel ?: "[KERNEL_IMAGE]",
"[INITRD...]");
if (r < 0)
return log_oom();
}
+1 -1
View File
@@ -1588,7 +1588,7 @@ static int oci_sysctl(const char *name, JsonVariant *v, JsonDispatchFlags flags,
return json_log(v, flags, SYNTHETIC_ERRNO(EINVAL),
"sysctl key invalid, refusing: %s", k);
r = strv_extend_strv(&s->sysctl, STRV_MAKE(k, m), false);
r = strv_extend_many(&s->sysctl, k, m);
if (r < 0)
return log_oom();
}
+3 -3
View File
@@ -425,7 +425,7 @@ int make_filesystem(
"-T", "default",
node);
if (root && strv_extend_strv(&argv, STRV_MAKE("-d", root), false) < 0)
if (root && strv_extend_many(&argv, "-d", root) < 0)
return log_oom();
if (quiet && strv_extend(&argv, "-q") < 0)
@@ -450,7 +450,7 @@ int make_filesystem(
if (!discard && strv_extend(&argv, "--nodiscard") < 0)
return log_oom();
if (root && strv_extend_strv(&argv, STRV_MAKE("-r", root), false) < 0)
if (root && strv_extend_many(&argv, "-r", root) < 0)
return log_oom();
if (quiet && strv_extend(&argv, "-q") < 0)
@@ -514,7 +514,7 @@ int make_filesystem(
if (!protofile_with_opt)
return -ENOMEM;
if (strv_extend_strv(&argv, STRV_MAKE("-p", protofile_with_opt), false) < 0)
if (strv_extend_many(&argv, "-p", protofile_with_opt) < 0)
return log_oom();
}
+4 -2
View File
@@ -8,6 +8,7 @@
static int denylist_modules(const char *p, char ***denylist) {
_cleanup_strv_free_ char **k = NULL;
int r;
assert(p);
assert(denylist);
@@ -16,8 +17,9 @@ static int denylist_modules(const char *p, char ***denylist) {
if (!k)
return -ENOMEM;
if (strv_extend_strv(denylist, k, true) < 0)
return -ENOMEM;
r = strv_extend_strv(denylist, k, /* filter_duplicates= */ true);
if (r < 0)
return r;
return 0;
}
+1 -5
View File
@@ -932,11 +932,7 @@ static int map_listen(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus
while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
r = strv_extend(p, type);
if (r < 0)
return r;
r = strv_extend(p, path);
r = strv_extend_many(p, type, path);
if (r < 0)
return r;
}
+8 -6
View File
@@ -347,6 +347,7 @@ static int putgrent_with_members(
FILE *group) {
char **a;
int r;
assert(c);
assert(gr);
@@ -365,15 +366,15 @@ static int putgrent_with_members(
if (strv_contains(l, *i))
continue;
if (strv_extend(&l, *i) < 0)
return -ENOMEM;
r = strv_extend(&l, *i);
if (r < 0)
return r;
added = true;
}
if (added) {
struct group t;
int r;
strv_uniq(l);
strv_sort(l);
@@ -396,6 +397,7 @@ static int putsgent_with_members(
FILE *gshadow) {
char **a;
int r;
assert(sg);
assert(gshadow);
@@ -413,15 +415,15 @@ static int putsgent_with_members(
if (strv_contains(l, *i))
continue;
if (strv_extend(&l, *i) < 0)
return -ENOMEM;
r = strv_extend(&l, *i);
if (r < 0)
return r;
added = true;
}
if (added) {
struct sgrp t;
int r;
strv_uniq(l);
strv_sort(l);
+25
View File
@@ -1014,4 +1014,29 @@ TEST(endswith_strv) {
assert_se(streq_ptr(endswith_strv("waldo", STRV_MAKE("knurz", "", "waldo")), ""));
}
TEST(strv_extend_many) {
_cleanup_strv_free_ char **l = NULL;
assert_se(strv_extend_many(&l, NULL) >= 0);
assert_se(strv_isempty(l));
assert_se(strv_extend_many(&l, NULL, NULL, NULL) >= 0);
assert_se(strv_isempty(l));
assert_se(strv_extend_many(&l, "foo") >= 0);
assert_se(strv_equal(l, STRV_MAKE("foo")));
assert_se(strv_extend_many(&l, NULL, "bar", NULL) >= 0);
assert_se(strv_equal(l, STRV_MAKE("foo", "bar")));
assert_se(strv_extend_many(&l, "waldo", "quux") >= 0);
assert_se(strv_equal(l, STRV_MAKE("foo", "bar", "waldo", "quux")));
assert_se(strv_extend_many(&l, "1", "2", "3", "4") >= 0);
assert_se(strv_equal(l, STRV_MAKE("foo", "bar", "waldo", "quux", "1", "2", "3", "4")));
assert_se(strv_extend_many(&l, "yes", NULL, "no") >= 0);
assert_se(strv_equal(l, STRV_MAKE("foo", "bar", "waldo", "quux", "1", "2", "3", "4", "yes", "no")));
}
DEFINE_TEST_MAIN(LOG_INFO);
+11 -15
View File
@@ -355,15 +355,11 @@ static int user_config_paths(char*** ret) {
if (r < 0)
return r;
r = strv_extend(&res, persistent_config);
if (r < 0)
return r;
r = strv_extend(&res, runtime_config);
if (r < 0)
return r;
r = strv_extend(&res, data_home);
r = strv_extend_many(
&res,
persistent_config,
runtime_config,
data_home);
if (r < 0)
return r;
@@ -3983,16 +3979,16 @@ static int exclude_default_prefixes(void) {
* likely over-mounted if the root directory is actually used, and it wouldbe less than ideal to have
* all kinds of files created/adjusted underneath these mount points. */
r = strv_extend_strv(
r = strv_extend_many(
&arg_exclude_prefixes,
STRV_MAKE("/dev",
"/proc",
"/run",
"/sys"),
true);
"/dev",
"/proc",
"/run",
"/sys");
if (r < 0)
return log_oom();
strv_uniq(arg_exclude_prefixes);
return 0;
}
+25 -25
View File
@@ -516,25 +516,25 @@ static int run_virtual_machine(void) {
return log_oom();
}
r = strv_extend_strv(&cmdline, STRV_MAKE("-cpu", "max"), /* filter_duplicates= */ false);
r = strv_extend_many(&cmdline, "-cpu", "max");
if (r < 0)
return log_oom();
if (arg_qemu_gui) {
r = strv_extend_strv(&cmdline, STRV_MAKE("-vga", "virtio"), /* filter_duplicates= */ false);
if (r < 0)
return log_oom();
} else {
r = strv_extend_strv(&cmdline, STRV_MAKE(
"-nographic",
"-nodefaults",
"-chardev", "stdio,mux=on,id=console,signal=off",
"-serial", "chardev:console",
"-mon", "console"
), /* filter_duplicates= */ false);
if (r < 0)
return log_oom();
}
if (arg_qemu_gui)
r = strv_extend_many(
&cmdline,
"-vga",
"virtio");
else
r = strv_extend_many(
&cmdline,
"-nographic",
"-nodefaults",
"-chardev", "stdio,mux=on,id=console,signal=off",
"-serial", "chardev:console",
"-mon", "console");
if (r < 0)
return log_oom();
if (ARCHITECTURE_SUPPORTS_SMBIOS)
FOREACH_ARRAY(cred, arg_credentials.credentials, arg_credentials.n_credentials) {
@@ -588,11 +588,11 @@ static int run_virtual_machine(void) {
(void) copy_access(source_fd, target_fd);
(void) copy_times(source_fd, target_fd, 0);
r = strv_extend_strv(&cmdline, STRV_MAKE(
"-global", "ICH9-LPC.disable_s3=1",
"-global", "driver=cfi.pflash01,property=secure,value=on",
"-drive"
), /* filter_duplicates= */ false);
r = strv_extend_many(
&cmdline,
"-global", "ICH9-LPC.disable_s3=1",
"-global", "driver=cfi.pflash01,property=secure,value=on",
"-drive");
if (r < 0)
return log_oom();
@@ -609,10 +609,10 @@ static int run_virtual_machine(void) {
if (r < 0)
return log_oom();
r = strv_extend_strv(&cmdline, STRV_MAKE(
"-device", "virtio-scsi-pci,id=scsi",
"-device", "scsi-hd,drive=mkosi,bootindex=1"
), /* filter_duplicates= */ false);
r = strv_extend_many(
&cmdline,
"-device", "virtio-scsi-pci,id=scsi",
"-device", "scsi-hd,drive=mkosi,bootindex=1");
if (r < 0)
return log_oom();