Compare commits

...

9 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek ed0c57c6da gpt-auto-generator: improve log message
We said "exiting", but then the program continues to do other operations
and log additional messages.
2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek 0f99304e11 shared/exec-util: fix logging of the args of an executed program
The debug logs has lots of "About to execute /some/path (null)". This
occurs when the args array is empty. Instead, only print "(null)" if
we failed with oom.

Having strv_skip() return NULL makes this pleasant to write without repeating
strv_isempty() a few times.
2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek ee0d84bff6 test-execve: minor simplification 2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek 14ded07623 various: handle the positive condition after strv_skip() first 2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek 7764746336 busctl: use RET_GATHER 2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek 17d702393b busctl: use STRV_FOREACH in the usual fashion
Also put positive branch first, do not use 'i' as a char** variable name.
2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek a573879ac1 analyze: use STRV_FOREACH in consistent fashion
Also put positive condition first.
2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek e30467cea0 basic/strv: return NULL from strv_skip
strv_skip was written to carefully return the original array, but this turns
out to be an unnecessary complication. After the previous patch, no caller
cares about the distinction between NULL and { NULL }, but various callers need
to wrap the process the returned value with strv_isempty(), sometimes more than
once. Let's always return NULL for an empty result to allow callers to be
simplified.
2024-11-19 17:18:14 +01:00
Zbigniew Jędrzejewski-Szmek 5fb5bbfdea homectl: do not rely on strv_skip() returning an empty list
mangle_user_list() was doing a microoptimization of avoiding of
copying of a single string by constructing the strv object manually.
This seems like more trouble than it's worth, considering that this
is called once in the program's life.

Simplify that code and always return an array constructed with strv_copy()
or strv_new().
2024-11-19 17:18:14 +01:00
18 changed files with 190 additions and 205 deletions

View File

@ -47,30 +47,25 @@ int verb_architectures(int argc, char *argv[], void *userdata) {
(void) table_hide_column_from_display(table, (size_t) 0);
if (strv_isempty(strv_skip(argv, 1)))
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++) {
r = add_arch(table, a);
if (r < 0)
return r;
}
else {
STRV_FOREACH(as, strv_skip(argv, 1)) {
char **args = strv_skip(argv, 1);
if (args) {
STRV_FOREACH(arg, args) {
Architecture a;
if (streq(*as, "native"))
if (streq(*arg, "native"))
a = native_architecture();
else if (streq(*as, "uname"))
else if (streq(*arg, "uname"))
a = uname_architecture();
else if (streq(*as, "secondary")) {
else if (streq(*arg, "secondary")) {
#ifdef ARCHITECTURE_SECONDARY
a = ARCHITECTURE_SECONDARY;
#else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No secondary architecture.");
#endif
} else
a = architecture_from_string(*as);
a = architecture_from_string(*arg);
if (a < 0)
return log_error_errno(a, "Architecture \"%s\" not known.", *as);
return log_error_errno(a, "Architecture \"%s\" not known.", *arg);
r = add_arch(table, a);
if (r < 0)
@ -78,6 +73,11 @@ int verb_architectures(int argc, char *argv[], void *userdata) {
}
(void) table_set_sort(table, (size_t) 0);
} else
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++) {
r = add_arch(table, a);
if (r < 0)
return r;
}
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);

View File

@ -9,12 +9,11 @@
#include "strv.h"
int verb_cat_config(int argc, char *argv[], void *userdata) {
char **list;
int r;
pager_open(arg_pager_flags);
list = strv_skip(argv, 1);
char **list = strv_skip(argv, 1);
STRV_FOREACH(arg, list) {
const char *t = NULL;

View File

@ -17,7 +17,24 @@ int verb_exit_status(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to right-align status: %m");
if (strv_isempty(strv_skip(argv, 1)))
char **args = strv_skip(argv, 1);
if (args)
STRV_FOREACH(arg, args) {
int status;
status = exit_status_from_string(*arg);
if (status < 0)
return log_error_errno(status, "Invalid exit status \"%s\".", *arg);
assert(status >= 0 && (size_t) status < ELEMENTSOF(exit_status_mappings));
r = table_add_many(table,
TABLE_STRING, exit_status_mappings[status].name ?: "-",
TABLE_INT, status,
TABLE_STRING, exit_status_class(status) ?: "-");
if (r < 0)
return table_log_add_error(r);
}
else
for (size_t i = 0; i < ELEMENTSOF(exit_status_mappings); i++) {
if (!exit_status_mappings[i].name)
continue;
@ -29,22 +46,6 @@ int verb_exit_status(int argc, char *argv[], void *userdata) {
if (r < 0)
return table_log_add_error(r);
}
else
for (int i = 1; i < argc; i++) {
int status;
status = exit_status_from_string(argv[i]);
if (status < 0)
return log_error_errno(status, "Invalid exit status \"%s\".", argv[i]);
assert(status >= 0 && (size_t) status < ELEMENTSOF(exit_status_mappings));
r = table_add_many(table,
TABLE_STRING, exit_status_mappings[status].name ?: "-",
TABLE_INT, status,
TABLE_STRING, exit_status_class(status) ?: "-");
if (r < 0)
return table_log_add_error(r);
}
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
if (r < 0)

View File

@ -106,15 +106,30 @@ static void dump_filesystem_set(const FilesystemSet *set) {
}
int verb_filesystems(int argc, char *argv[], void *userdata) {
bool first = true;
#if ! HAVE_LIBBPF
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not compiled with libbpf support, sorry.");
#endif
pager_open(arg_pager_flags);
if (strv_isempty(strv_skip(argv, 1))) {
char **args = strv_skip(argv, 1);
if (args)
STRV_FOREACH(name, args) {
if (name != args)
puts("");
const FilesystemSet *set = filesystem_set_find(*name);
if (!set) {
/* make sure the error appears below normal output */
fflush(stdout);
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"Filesystem set \"%s\" not found.", *name);
}
dump_filesystem_set(set);
}
else {
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
int k;
@ -126,27 +141,24 @@ int verb_filesystems(int argc, char *argv[], void *userdata) {
for (FilesystemGroups i = 0; i < _FILESYSTEM_SET_MAX; i++) {
const FilesystemSet *set = filesystem_sets + i;
if (!first)
if (i > 0)
puts("");
dump_filesystem_set(set);
filesystem_set_remove(kernel, set);
if (i != FILESYSTEM_SET_KNOWN)
filesystem_set_remove(known, set);
first = false;
}
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
return 0;
if (!set_isempty(known)) {
_cleanup_free_ char **l = NULL;
printf("\n"
"# %sUngrouped filesystems%s (known but not included in any of the groups except @known):\n",
ansi_highlight(), ansi_normal());
l = set_get_strv(known);
_cleanup_free_ char **l = set_get_strv(known);
if (!l)
return log_oom();
@ -197,24 +209,6 @@ int verb_filesystems(int argc, char *argv[], void *userdata) {
STRV_FOREACH(filesystem, l)
printf("# %s\n", *filesystem);
}
} else
STRV_FOREACH(name, strv_skip(argv, 1)) {
const FilesystemSet *set;
if (!first)
puts("");
set = filesystem_set_find(*name);
if (!set) {
/* make sure the error appears below normal output */
fflush(stdout);
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"Filesystem set \"%s\" not found.", *name);
}
dump_filesystem_set(set);
first = false;
}
return EXIT_SUCCESS;

View File

@ -35,11 +35,12 @@ int verb_malloc(int argc, char *argv[], void *userdata) {
char **services = STRV_MAKE("org.freedesktop.systemd1");
int r;
if (!strv_isempty(strv_skip(argv, 1))) {
services = strv_skip(argv, 1);
STRV_FOREACH(service, services)
char **args = strv_skip(argv, 1);
if (args) {
STRV_FOREACH(service, args)
if (!service_name_is_valid(*service))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "D-Bus service name '%s' is not valid.", *service);
services = args;
}
r = acquire_bus(&bus, NULL);

View File

@ -114,19 +114,14 @@ int verb_pcrs(int argc, char *argv[], void *userdata) {
if (!alg) /* hide hash column if we couldn't acquire it */
(void) table_set_display(table, 0, 1);
if (strv_isempty(strv_skip(argv, 1)))
for (uint32_t pi = 0; pi < _TPM2_PCR_INDEX_MAX_DEFINED; pi++) {
r = add_pcr_to_table(table, alg, pi);
if (r < 0)
return r;
}
else {
for (int i = 1; i < argc; i++) {
char **args = strv_skip(argv, 1);
if (args) {
STRV_FOREACH(arg, args) {
int pi;
pi = tpm2_pcr_index_from_string(argv[i]);
pi = tpm2_pcr_index_from_string(*arg);
if (pi < 0)
return log_error_errno(pi, "PCR index \"%s\" not known.", argv[i]);
return log_error_errno(pi, "PCR index \"%s\" not known.", *arg);
r = add_pcr_to_table(table, alg, pi);
if (r < 0)
@ -134,6 +129,11 @@ int verb_pcrs(int argc, char *argv[], void *userdata) {
}
(void) table_set_sort(table, (size_t) 0);
} else
for (uint32_t pi = 0; pi < _TPM2_PCR_INDEX_MAX_DEFINED; pi++) {
r = add_pcr_to_table(table, alg, pi);
if (r < 0)
return r;
}
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, /* show_header= */true);

View File

@ -103,12 +103,30 @@ static void dump_syscall_filter(const SyscallFilterSet *set) {
}
int verb_syscall_filters(int argc, char *argv[], void *userdata) {
bool first = true;
int r;
pager_open(arg_pager_flags);
if (strv_isempty(strv_skip(argv, 1))) {
char **args = strv_skip(argv, 1);
if (args)
STRV_FOREACH(name, args) {
const SyscallFilterSet *set;
if (name != args)
puts("");
set = syscall_filter_set_find(*name);
if (!set) {
/* make sure the error appears below normal output */
fflush(stdout);
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"Filter set \"%s\" not found.", *name);
}
dump_syscall_filter(set);
}
else {
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
int k = 0; /* explicit initialization to appease gcc */
@ -121,27 +139,24 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
for (int i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
const SyscallFilterSet *set = syscall_filter_sets + i;
if (!first)
if (i > 0)
puts("");
dump_syscall_filter(set);
syscall_set_remove(kernel, set);
if (i != SYSCALL_FILTER_SET_KNOWN)
syscall_set_remove(known, set);
first = false;
}
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
return 0;
if (!set_isempty(known)) {
_cleanup_free_ char **l = NULL;
printf("\n"
"# %sUngrouped System Calls%s (known but not included in any of the groups except @known):\n",
ansi_highlight(), ansi_normal());
l = set_get_strv(known);
_cleanup_free_ char **l = set_get_strv(known);
if (!l)
return log_oom();
@ -157,13 +172,11 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
if (!arg_quiet)
log_notice_errno(k, "# Not showing unlisted system calls, couldn't retrieve kernel system call list: %m");
} else if (!set_isempty(kernel)) {
_cleanup_free_ char **l = NULL;
printf("\n"
"# %sUnlisted System Calls%s (supported by the local kernel, but not included in any of the groups listed above):\n",
ansi_highlight(), ansi_normal());
l = set_get_strv(kernel);
_cleanup_free_ char **l = set_get_strv(kernel);
if (!l)
return log_oom();
@ -172,24 +185,6 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
STRV_FOREACH(syscall, l)
printf("# %s\n", *syscall);
}
} else
STRV_FOREACH(name, strv_skip(argv, 1)) {
const SyscallFilterSet *set;
if (!first)
puts("");
set = syscall_filter_set_find(*name);
if (!set) {
/* make sure the error appears below normal output */
fflush(stdout);
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"Filter set \"%s\" not found.", *name);
}
dump_syscall_filter(set);
first = false;
}
return EXIT_SUCCESS;

View File

@ -75,11 +75,12 @@ static int test_timestamp_one(const char *p) {
int verb_timestamp(int argc, char *argv[], void *userdata) {
int r = 0;
STRV_FOREACH(p, strv_skip(argv, 1)) {
RET_GATHER(r, test_timestamp_one(*p));
char **args = strv_skip(argv, 1);
STRV_FOREACH(arg, args) {
if (arg != args)
puts("");
if (p[1])
putchar('\n');
RET_GATHER(r, test_timestamp_one(*arg));
}
return r;

View File

@ -956,14 +956,16 @@ bool strv_fnmatch_full(
}
char** strv_skip(char **l, size_t n) {
while (n > 0) {
if (strv_isempty(l))
return l;
return NULL;
l++, n--;
}
/* To simplify callers, always return NULL instead of a zero-item array. */
if (strv_isempty(l))
return NULL;
return l;
}

View File

@ -547,9 +547,21 @@ static int tree(int argc, char **argv, void *userdata) {
if (r < 0)
return r;
if (argc <= 1) {
char **args = strv_skip(argv, 1);
if (args)
STRV_FOREACH(arg, args) {
if (arg != args)
puts("");
if (args[1]) {
pager_open(arg_pager_flags);
printf("Service %s%s%s:\n", ansi_highlight(), *arg, ansi_normal());
}
RET_GATHER(r, tree_one(bus, *arg));
}
else {
_cleanup_strv_free_ char **names = NULL;
bool not_first = false;
r = sd_bus_list_names(bus, &names, NULL);
if (r < 0)
@ -557,41 +569,20 @@ static int tree(int argc, char **argv, void *userdata) {
pager_open(arg_pager_flags);
STRV_FOREACH(i, names) {
int q;
if (!arg_unique && (*i)[0] == ':')
STRV_FOREACH(name, names) {
if (!arg_unique && (*name)[0] == ':')
continue;
if (!arg_acquired && (*i)[0] == ':')
if (!arg_acquired && (*name)[0] == ':')
continue;
if (not_first)
printf("\n");
if (name != names)
puts("");
printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
printf("Service %s%s%s:\n", ansi_highlight(), *name, ansi_normal());
q = tree_one(bus, *i);
if (q < 0 && r >= 0)
r = q;
not_first = true;
RET_GATHER(r, tree_one(bus, *name));
}
} else
STRV_FOREACH(i, strv_skip(argv, 1)) {
int q;
if (i > argv+1)
printf("\n");
if (argv[2]) {
pager_open(arg_pager_flags);
printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
}
q = tree_one(bus, *i);
if (q < 0 && r >= 0)
r = q;
}
return r;

View File

@ -663,8 +663,9 @@ static int add_root_mount(void) {
r = efi_loader_get_device_part_uuid(NULL);
if (r == -ENOENT) {
log_notice("EFI loader partition unknown, exiting.\n"
"(The boot loader did not set EFI variable LoaderDevicePartUUID.)");
log_notice("EFI loader partition unknown, not processing %s.\n"
"(The boot loader did not set EFI variable LoaderDevicePartUUID.)",
in_initrd() ? "/sysroot" : "/");
return 0;
} else if (r < 0)
return log_error_errno(r, "Failed to read loader partition UUID: %m");

View File

@ -691,45 +691,40 @@ static void dump_home_record(UserRecord *hr) {
}
}
static char **mangle_user_list(char **list, char ***ret_allocated) {
_cleanup_free_ char *myself = NULL;
static int mangle_user_list(char **list, char ***ret) {
char **l;
if (!strv_isempty(list)) {
*ret_allocated = NULL;
return list;
}
if (strv_isempty(list)) {
_cleanup_free_ char *myself = NULL;
myself = getusername_malloc();
if (!myself)
return NULL;
return log_oom();
l = new(char*, 2);
l = strv_new(myself);
} else
l = strv_copy(list);
if (!l)
return NULL;
return log_oom();
l[0] = TAKE_PTR(myself);
l[1] = NULL;
*ret_allocated = l;
return l;
*ret = l;
return 0;
}
static int inspect_home(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_strv_free_ char **mangled_list = NULL;
_cleanup_strv_free_ char **items = NULL;
int r, ret = 0;
char **items;
pager_open(arg_pager_flags);
r = mangle_user_list(strv_skip(argv, 1), &items);
if (r < 0)
return r;
r = acquire_bus(&bus);
if (r < 0)
return r;
items = mangle_user_list(strv_skip(argv, 1), &mangled_list);
if (!items)
return log_oom();
pager_open(arg_pager_flags);
STRV_FOREACH(i, items) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@ -800,13 +795,12 @@ static int inspect_home(int argc, char *argv[], void *userdata) {
static int authenticate_home(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_strv_free_ char **mangled_list = NULL;
_cleanup_strv_free_ char **items = NULL;
int r, ret = 0;
char **items;
items = mangle_user_list(strv_skip(argv, 1), &mangled_list);
if (!items)
return log_oom();
r = mangle_user_list(strv_skip(argv, 1), &items);
if (r < 0)
return r;
r = acquire_bus(&bus);
if (r < 0)

View File

@ -133,17 +133,7 @@ static int verb_show(int argc, char **argv, void *userdata) {
int r;
argv = strv_skip(argv, 1);
if (strv_isempty(argv)) {
if (!sd_id128_is_null(arg_app))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"'show --app-specific=' can only be used with explicit UUID input.");
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
if (r < 0)
return r;
}
} else
if (argv)
STRV_FOREACH(p, argv) {
sd_id128_t uuid;
const char *id = NULL;
@ -171,6 +161,17 @@ static int verb_show(int argc, char **argv, void *userdata) {
if (r < 0)
return r;
}
else {
if (!sd_id128_is_null(arg_app))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"'show --app-specific=' can only be used with explicit UUID input.");
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
if (r < 0)
return r;
}
}
if (table) {
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);

View File

@ -152,11 +152,13 @@ static int do_execute(
}
if (DEBUG_LOGGING) {
_cleanup_free_ char *args = NULL;
if (argv)
args = quote_command_line(strv_skip(argv, 1), SHELL_ESCAPE_EMPTY);
_cleanup_free_ char *s = NULL;
log_debug("About to execute %s%s%s", t, argv ? " " : "", argv ? strnull(args) : "");
char **args = strv_skip(argv, 1);
if (args)
s = quote_command_line(args, SHELL_ESCAPE_EMPTY);
log_debug("About to execute %s%s%s", t, args ? " " : "", args ? strnull(s) : "");
}
if (FLAGS_SET(flags, EXEC_DIR_WARN_WORLD_WRITABLE)) {

View File

@ -172,14 +172,14 @@ int verb_list_dependencies(int argc, char *argv[], void *userdata) {
return r;
patterns = strv_skip(argv, 1);
if (strv_isempty(patterns)) {
units = strv_new(SPECIAL_DEFAULT_TARGET);
if (!units)
return log_oom();
} else {
if (patterns) {
r = expand_unit_names(bus, patterns, NULL, &units, NULL);
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
} else {
units = strv_new(SPECIAL_DEFAULT_TARGET);
if (!units)
return log_oom();
}
pager_open(arg_pager_flags);

View File

@ -20,15 +20,13 @@
*/
static int run(int argc, char **argv) {
_cleanup_close_ int fd = -EBADF;
char **args = strv_skip(argv, 1);
int r;
test_setup_logging(LOG_DEBUG);
args = !strv_isempty(args) ? args : STRV_MAKE("/bin/true");
char **args = strv_skip(argv, 1) ?: STRV_MAKE("/bin/true");
fd = open(args[0], O_RDONLY | O_CLOEXEC);
_cleanup_close_ int fd = open(args[0], O_RDONLY | O_CLOEXEC);
if (fd < 0)
return log_error_errno(errno, "open(%s) failed: %m", args[0]);

View File

@ -1004,17 +1004,21 @@ TEST(strv_skip) {
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, NULL);
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, NULL);
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, NULL);
test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE("quux"), 1, NULL);
test_strv_skip_one(STRV_MAKE("quux"), 55, NULL);
test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
test_strv_skip_one(STRV_MAKE(NULL), 0, NULL);
test_strv_skip_one(STRV_MAKE(NULL), 1, NULL);
test_strv_skip_one(STRV_MAKE(NULL), 55, NULL);
test_strv_skip_one(NULL, 0, NULL);
test_strv_skip_one(NULL, 1, NULL);
test_strv_skip_one(NULL, 55, NULL);
}
TEST(strv_extend_n) {

View File

@ -35,7 +35,10 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) {
"%s: expected: load [module…]", argv[0]);
char **modules = strv_skip(argv, 2);
if (strv_isempty(modules)) {
if (modules)
STRV_FOREACH(module, modules)
(void) module_load_and_warn(ctx, *module, /* verbose = */ false);
else {
const char *modalias;
r = sd_device_get_property_value(dev, "MODALIAS", &modalias);
@ -43,9 +46,7 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) {
return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\": %m");
(void) module_load_and_warn(ctx, modalias, /* verbose = */ false);
} else
STRV_FOREACH(module, modules)
(void) module_load_and_warn(ctx, *module, /* verbose = */ false);
}
return 0;
}