diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c index 1fcdbf9cd3..5408cfdeaa 100644 --- a/src/analyze/analyze-security.c +++ b/src/analyze/analyze-security.c @@ -2726,8 +2726,7 @@ static int offline_security_checks( k = verify_prepare_filename(*filename, &prepared); if (k < 0) { log_warning_errno(k, "Failed to prepare filename %s: %m", *filename); - if (r == 0) - r = k; + RET_GATHER(r, k); continue; } @@ -2760,19 +2759,15 @@ static int offline_security_checks( k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]); if (k < 0) { - if (r == 0) - r = k; + RET_GATHER(r, k); continue; } count++; } - for (size_t i = 0; i < count; i++) { - k = offline_security_check(units[i], threshold, policy, pager_flags, json_format_flags); - if (k < 0 && r == 0) - r = k; - } + for (size_t i = 0; i < count; i++) + RET_GATHER(r, offline_security_check(units[i], threshold, policy, pager_flags, json_format_flags)); return r; } diff --git a/src/analyze/analyze-verify-util.c b/src/analyze/analyze-verify-util.c index 132a84649b..ae4164d053 100644 --- a/src/analyze/analyze-verify-util.c +++ b/src/analyze/analyze-verify-util.c @@ -157,32 +157,23 @@ int verify_executable(Unit *u, const ExecCommand *exec, const char *root) { } static int verify_executables(Unit *u, const char *root) { - ExecCommand *exec; - int r = 0, k; - unsigned i; + int r = 0; assert(u); - exec = u->type == UNIT_SOCKET ? SOCKET(u)->control_command : + ExecCommand *exec = + u->type == UNIT_SOCKET ? SOCKET(u)->control_command : u->type == UNIT_MOUNT ? MOUNT(u)->control_command : u->type == UNIT_SWAP ? SWAP(u)->control_command : NULL; - k = verify_executable(u, exec, root); - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, verify_executable(u, exec, root)); if (u->type == UNIT_SERVICE) - for (i = 0; i < ELEMENTSOF(SERVICE(u)->exec_command); i++) { - k = verify_executable(u, SERVICE(u)->exec_command[i], root); - if (k < 0 && r == 0) - r = k; - } + for (unsigned i = 0; i < ELEMENTSOF(SERVICE(u)->exec_command); i++) + RET_GATHER(r, verify_executable(u, SERVICE(u)->exec_command[i], root)); if (u->type == UNIT_SOCKET) - for (i = 0; i < ELEMENTSOF(SOCKET(u)->exec_command); i++) { - k = verify_executable(u, SOCKET(u)->exec_command[i], root); - if (k < 0 && r == 0) - r = k; - } + for (unsigned i = 0; i < ELEMENTSOF(SOCKET(u)->exec_command); i++) + RET_GATHER(r, verify_executable(u, SOCKET(u)->exec_command[i], root)); return r; } @@ -215,7 +206,7 @@ static int verify_documentation(Unit *u, bool check_man) { static int verify_unit(Unit *u, bool check_man, const char *root) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - int r, k; + int r; assert(u); @@ -227,17 +218,9 @@ static int verify_unit(Unit *u, bool check_man, const char *root) { if (r < 0) log_unit_error_errno(u, r, "Failed to create %s/start: %s", u->id, bus_error_message(&error, r)); - k = verify_socket(u); - if (k < 0 && r == 0) - r = k; - - k = verify_executables(u, root); - if (k < 0 && r == 0) - r = k; - - k = verify_documentation(u, check_man); - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, verify_socket(u)); + RET_GATHER(r, verify_executables(u, root)); + RET_GATHER(r, verify_documentation(u, check_man)); return r; } @@ -267,7 +250,7 @@ int verify_units( _unused_ _cleanup_(clear_log_syntax_callback) dummy_t dummy; Unit *units[strv_length(filenames)]; _cleanup_free_ char *var = NULL; - int r, k, i, count = 0; + int r, k, count = 0; if (strv_isempty(filenames)) return 0; @@ -306,26 +289,21 @@ int verify_units( k = verify_prepare_filename(*filename, &prepared); if (k < 0) { log_error_errno(k, "Failed to prepare filename %s: %m", *filename); - if (r == 0) - r = k; + RET_GATHER(r, k); continue; } k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]); if (k < 0) { - if (r == 0) - r = k; + RET_GATHER(r, k); continue; } count++; } - for (i = 0; i < count; i++) { - k = verify_unit(units[i], check_man, root); - if (k < 0 && r == 0) - r = k; - } + for (int i = 0; i < count; i++) + RET_GATHER(r, verify_unit(units[i], check_man, root)); if (s == POINTER_MAX) return log_oom(); diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h index 091f99c590..f477db7852 100644 --- a/src/basic/errno-util.h +++ b/src/basic/errno-util.h @@ -73,6 +73,16 @@ static inline int RET_NERRNO(int ret) { return ret; } +/* Collect possible errors in , so that the first error can be returned. + * Returns (possibly updated) . */ +#define RET_GATHER(acc, err) \ + ({ \ + int *__a = &(acc), __e = (err); \ + if (*__a >= 0 && __e < 0) \ + *__a = __e; \ + *__a; \ + }) + static inline int errno_or_else(int fallback) { /* To be used when invoking library calls where errno handling is not defined clearly: we return * errno if it is set, and the specified error otherwise. The idea is that the caller initializes diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index e1ddf97914..675ae185e2 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -100,9 +100,7 @@ static int apply_file(const char *filename, bool ignore_enoent) { if (strchr(COMMENTS, p[0])) continue; - k = apply_rule(filename, line, p); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, apply_rule(filename, line, p)); } return r; @@ -201,7 +199,7 @@ static int binfmt_mounted_warn(void) { } static int run(int argc, char *argv[]) { - int r, k; + int r; r = parse_argv(argc, argv); if (r <= 0) @@ -221,11 +219,9 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - for (int i = optind; i < argc; i++) { - k = apply_file(argv[i], false); - if (k < 0 && r >= 0) - r = k; - } + for (int i = optind; i < argc; i++) + RET_GATHER(r, apply_file(argv[i], false)); + } else { _cleanup_strv_free_ char **files = NULL; @@ -250,11 +246,8 @@ static int run(int argc, char *argv[]) { else log_debug("Flushed all binfmt_misc rules."); - STRV_FOREACH(f, files) { - k = apply_file(*f, true); - if (k < 0 && r >= 0) - r = k; - } + STRV_FOREACH(f, files) + RET_GATHER(r, apply_file(*f, true)); } return r; diff --git a/src/boot/bootctl-install.c b/src/boot/bootctl-install.c index 397db7d3a2..7e85c2f08e 100644 --- a/src/boot/bootctl-install.c +++ b/src/boot/bootctl-install.c @@ -421,8 +421,7 @@ static int install_binaries(const char *esp_path, const char *arch, bool force) * newer version, or other boot loader in place. */ if (arg_graceful && IN_SET(k, -ESTALE, -ESRCH)) continue; - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, k); } return r; diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index 0bfbf86e10..0f2e9204b7 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -483,17 +483,11 @@ int verb_status(int argc, char *argv[], void *userdata) { "Not booted with EFI\n\n", ansi_underline(), ansi_normal()); - if (arg_esp_path) { - k = status_binaries(arg_esp_path, esp_uuid); - if (k < 0) - r = k; - } + if (arg_esp_path) + RET_GATHER(r, status_binaries(arg_esp_path, esp_uuid)); - if (!arg_root && is_efi_boot()) { - k = status_variables(); - if (k < 0) - r = k; - } + if (!arg_root && is_efi_boot()) + RET_GATHER(r, status_variables()); if (arg_esp_path || arg_xbootldr_path) { _cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL; @@ -501,15 +495,13 @@ int verb_status(int argc, char *argv[], void *userdata) { k = boot_config_load_and_select(&config, arg_esp_path, esp_devid, arg_xbootldr_path, xbootldr_devid); - if (k < 0) - r = k; - else { - k = status_entries(&config, - arg_esp_path, esp_uuid, - arg_xbootldr_path, xbootldr_uuid); - if (k < 0) - r = k; - } + RET_GATHER(r, k); + + if (k >= 0) + RET_GATHER(r, + status_entries(&config, + arg_esp_path, esp_uuid, + arg_xbootldr_path, xbootldr_uuid)); } return r; diff --git a/src/boot/bootctl-util.c b/src/boot/bootctl-util.c index 6d886aba35..3cab875fa0 100644 --- a/src/boot/bootctl-util.c +++ b/src/boot/bootctl-util.c @@ -4,26 +4,27 @@ #include "bootctl.h" #include "bootctl-util.h" +#include "errno-util.h" #include "fileio.h" #include "stat-util.h" #include "sync-util.h" int sync_everything(void) { - int ret = 0, k; + int r = 0, k; if (arg_esp_path) { k = syncfs_path(AT_FDCWD, arg_esp_path); if (k < 0) - ret = log_error_errno(k, "Failed to synchronize the ESP '%s': %m", arg_esp_path); + RET_GATHER(r, log_error_errno(k, "Failed to synchronize the ESP '%s': %m", arg_esp_path)); } if (arg_xbootldr_path) { k = syncfs_path(AT_FDCWD, arg_xbootldr_path); if (k < 0) - ret = log_error_errno(k, "Failed to synchronize $BOOT '%s': %m", arg_xbootldr_path); + RET_GATHER(r, log_error_errno(k, "Failed to synchronize $BOOT '%s': %m", arg_xbootldr_path)); } - return ret; + return r; } const char *get_efi_arch(void) { diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 24b019294b..8ae4a9f63f 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -245,8 +245,7 @@ static int fix_xattr(int fd, const Context *context) { assert(fd >= 0); - /* Attach some metadata to coredumps via extended - * attributes. Just because we can. */ + /* Attach some metadata to coredumps via extended attributes. Just because we can. */ for (unsigned i = 0; i < _META_MAX; i++) { int k; @@ -254,9 +253,8 @@ static int fix_xattr(int fd, const Context *context) { if (isempty(context->meta[i]) || !xattrs[i]) continue; - k = fsetxattr(fd, xattrs[i], context->meta[i], strlen(context->meta[i]), XATTR_CREATE); - if (k < 0 && r == 0) - r = -errno; + k = RET_NERRNO(fsetxattr(fd, xattrs[i], context->meta[i], strlen(context->meta[i]), XATTR_CREATE)); + RET_GATHER(r, k); } return r; diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 7ff5db14d2..041789673f 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -744,8 +744,7 @@ static int do_daemon_reload(void) { k = bus_call_method(bus, bus_systemd_mgr, "StartUnit", &error, NULL, "ss", unit, "replace"); if (k < 0) { log_error_errno(k, "Failed to (re)start %s: %s", unit, bus_error_message(&error, r)); - if (r == 0) - r = k; + RET_GATHER(r, k); } } diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 840d3b6ed1..4465038198 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -763,7 +763,7 @@ static int add_root_mount(void) { static int process_loader_partitions(DissectedPartition *esp, DissectedPartition *xbootldr) { sd_id128_t loader_uuid; - int r, ret = 0; + int r; assert(esp); assert(xbootldr); @@ -797,26 +797,21 @@ static int process_loader_partitions(DissectedPartition *esp, DissectedPartition return 0; mount: - if (xbootldr->found) { - r = add_partition_xbootldr(xbootldr); - if (r < 0) - ret = r; - } + r = 0; - if (esp->found) { - r = add_partition_esp(esp, xbootldr->found); - if (r < 0) - ret = r; - } + if (xbootldr->found) + RET_GATHER(r, add_partition_xbootldr(xbootldr)); + if (esp->found) + RET_GATHER(r, add_partition_esp(esp, xbootldr->found)); - return ret; + return r; } static int enumerate_partitions(dev_t devnum) { _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL; _cleanup_free_ char *devname = NULL; - int r, k; + int r; r = block_get_whole_disk(devnum, &devnum); if (r < 0) @@ -856,45 +851,29 @@ static int enumerate_partitions(dev_t devnum) { return ok ? 0 : r; } - if (m->partitions[PARTITION_SWAP].found) { - k = add_partition_swap(m->partitions + PARTITION_SWAP); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_SWAP].found) + RET_GATHER(r, add_partition_swap(m->partitions + PARTITION_SWAP)); - k = process_loader_partitions(m->partitions + PARTITION_ESP, m->partitions + PARTITION_XBOOTLDR); - if (k < 0) - r = k; + RET_GATHER(r, process_loader_partitions(m->partitions + PARTITION_ESP, m->partitions + PARTITION_XBOOTLDR)); - if (m->partitions[PARTITION_HOME].found) { - k = add_partition_mount(PARTITION_HOME, m->partitions + PARTITION_HOME, "home", "/home", "Home Partition"); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_HOME].found) + RET_GATHER(r, add_partition_mount(PARTITION_HOME, m->partitions + PARTITION_HOME, + "home", "/home", "Home Partition")); - if (m->partitions[PARTITION_SRV].found) { - k = add_partition_mount(PARTITION_SRV, m->partitions + PARTITION_SRV, "srv", "/srv", "Server Data Partition"); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_SRV].found) + RET_GATHER(r, add_partition_mount(PARTITION_SRV, m->partitions + PARTITION_SRV, + "srv", "/srv", "Server Data Partition")); - if (m->partitions[PARTITION_VAR].found) { - k = add_partition_mount(PARTITION_VAR, m->partitions + PARTITION_VAR, "var", "/var", "Variable Data Partition"); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_VAR].found) + RET_GATHER(r, add_partition_mount(PARTITION_VAR, m->partitions + PARTITION_VAR, + "var", "/var", "Variable Data Partition")); - if (m->partitions[PARTITION_TMP].found) { - k = add_partition_mount(PARTITION_TMP, m->partitions + PARTITION_TMP, "var-tmp", "/var/tmp", "Temporary Data Partition"); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_TMP].found) + RET_GATHER(r, add_partition_mount(PARTITION_TMP, m->partitions + PARTITION_TMP, + "var-tmp", "/var/tmp", "Temporary Data Partition")); - if (m->partitions[PARTITION_ROOT].found) { - k = add_partition_root_rw(m->partitions + PARTITION_ROOT); - if (k < 0) - r = k; - } + if (m->partitions[PARTITION_ROOT].found) + RET_GATHER(r, add_partition_root_rw(m->partitions + PARTITION_ROOT)); return r; } diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index df6812bb8a..717dc195c5 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -1448,19 +1448,16 @@ on_error: int sd_dhcp_server_forcerenew(sd_dhcp_server *server) { DHCPLease *lease; - int k, r = 0; + int r = 0; assert_return(server, -EINVAL); log_dhcp_server(server, "FORCERENEW"); - HASHMAP_FOREACH(lease, server->bound_leases_by_client_id) { - k = server_send_forcerenew(server, lease->address, lease->gateway, - lease->htype, lease->hlen, lease->chaddr); - if (k < 0) - r = k; - } - + HASHMAP_FOREACH(lease, server->bound_leases_by_client_id) + RET_GATHER(r, + server_send_forcerenew(server, lease->address, lease->gateway, + lease->htype, lease->hlen, lease->chaddr)); return r; } diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index e072d976d3..766fadd22c 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -613,38 +613,30 @@ static int enumerator_add_parent_devices( sd_device *device, MatchFlag flags) { - int k, r = 0; + int r; assert(enumerator); assert(device); for (;;) { - k = sd_device_get_parent(device, &device); - if (k == -ENOENT) /* Reached the top? */ - break; - if (k < 0) { - r = k; - break; - } + r = sd_device_get_parent(device, &device); + if (r == -ENOENT) /* Reached the top? */ + return 0; + if (r < 0) + return r; - k = test_matches(enumerator, device, flags); - if (k < 0) { - r = k; - break; - } - if (k == 0) + r = test_matches(enumerator, device, flags); + if (r < 0) + return r; + if (r == 0) continue; - k = device_enumerator_add_device(enumerator, device); - if (k < 0) { - r = k; - break; - } - if (k == 0) /* Exists already? Then no need to go further up. */ - break; + r = device_enumerator_add_device(enumerator, device); + if (r < 0) + return r; + if (r == 0) /* Exists already? Then no need to go further up. */ + return 0; } - - return r; } int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device) { diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index 582f623efe..a8cec2bd8b 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -184,7 +184,7 @@ int sd_nfnl_call_batch( _cleanup_free_ sd_netlink_message **replies = NULL; _cleanup_free_ uint32_t *serials = NULL; - int k, r; + int r; assert_return(nfnl, -EINVAL); assert_return(!netlink_pid_changed(nfnl), -ECHILD); @@ -201,11 +201,9 @@ int sd_nfnl_call_batch( if (r < 0) return r; - for (size_t i = 0; i < n_messages; i++) { - k = sd_netlink_read(nfnl, serials[i], usec, ret_messages ? replies + i : NULL); - if (k < 0 && r >= 0) - r = k; - } + for (size_t i = 0; i < n_messages; i++) + RET_GATHER(r, + sd_netlink_read(nfnl, serials[i], usec, ret_messages ? replies + i : NULL)); if (r < 0) return r; diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c index 8e7f7a5eba..4adeef3afb 100644 --- a/src/modules-load/modules-load.c +++ b/src/modules-load/modules-load.c @@ -97,8 +97,7 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent k = module_load_and_warn(ctx, l, true); if (k == -ENOENT) continue; - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, k); } return r; @@ -186,11 +185,8 @@ static int run(int argc, char *argv[]) { r = 0; if (argc > optind) { - for (int i = optind; i < argc; i++) { - k = apply_file(ctx, argv[i], false); - if (k < 0 && r == 0) - r = k; - } + for (int i = optind; i < argc; i++) + RET_GATHER(r, apply_file(ctx, argv[i], false)); } else { _cleanup_strv_free_ char **files = NULL; @@ -199,23 +195,15 @@ static int run(int argc, char *argv[]) { k = module_load_and_warn(ctx, *i, true); if (k == -ENOENT) continue; - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, k); } k = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs); - if (k < 0) { - log_error_errno(k, "Failed to enumerate modules-load.d files: %m"); - if (r == 0) - r = k; - return r; - } + if (k < 0) + return log_error_errno(k, "Failed to enumerate modules-load.d files: %m"); - STRV_FOREACH(fn, files) { - k = apply_file(ctx, *fn, true); - if (k < 0 && r == 0) - r = k; - } + STRV_FOREACH(fn, files) + RET_GATHER(r, apply_file(ctx, *fn, true)); } return r; diff --git a/src/network/generator/main.c b/src/network/generator/main.c index 839ca80bec..3456fc4cf8 100644 --- a/src/network/generator/main.c +++ b/src/network/generator/main.c @@ -102,32 +102,22 @@ static int context_save(Context *context) { Network *network; NetDev *netdev; Link *link; - int k, r; - const char *p; + int r; - p = prefix_roota(arg_root, NETWORKD_UNIT_DIRECTORY); + const char *p = prefix_roota(arg_root, NETWORKD_UNIT_DIRECTORY); r = mkdir_p(p, 0755); if (r < 0) return log_error_errno(r, "Failed to create directory " NETWORKD_UNIT_DIRECTORY ": %m"); - HASHMAP_FOREACH(network, context->networks_by_name) { - k = network_save(network, p); - if (k < 0 && r >= 0) - r = k; - } + HASHMAP_FOREACH(network, context->networks_by_name) + RET_GATHER(r, network_save(network, p)); - HASHMAP_FOREACH(netdev, context->netdevs_by_name) { - k = netdev_save(netdev, p); - if (k < 0 && r >= 0) - r = k; - } + HASHMAP_FOREACH(netdev, context->netdevs_by_name) + RET_GATHER(r, netdev_save(netdev, p)); - HASHMAP_FOREACH(link, context->links_by_filename) { - k = link_save(link, p); - if (k < 0 && r >= 0) - r = k; - } + HASHMAP_FOREACH(link, context->links_by_filename) + RET_GATHER(r, link_save(link, p)); return r; } diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 2f77db95ab..c33ffa9576 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -994,7 +994,7 @@ int link_drop_ipv6ll_addresses(Link *link) { int link_drop_foreign_addresses(Link *link) { Address *address; - int k, r = 0; + int r = 0; assert(link); assert(link->network); @@ -1054,9 +1054,7 @@ int link_drop_foreign_addresses(Link *link) { if (!address_is_marked(address)) continue; - k = address_remove(address); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, address_remove(address)); } return r; @@ -1064,7 +1062,7 @@ int link_drop_foreign_addresses(Link *link) { int link_drop_managed_addresses(Link *link) { Address *address; - int k, r = 0; + int r = 0; assert(link); @@ -1077,11 +1075,7 @@ int link_drop_managed_addresses(Link *link) { if (!address_exists(address)) continue; - k = address_remove(address); - if (k < 0 && r >= 0) { - r = k; - continue; - } + RET_GATHER(r, address_remove(address)); } return r; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 62dd892afa..c237295606 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -950,7 +950,7 @@ static Link *link_drop(Link *link) { } static int link_drop_foreign_config(Link *link) { - int k, r; + int r; assert(link); assert(link->manager); @@ -967,48 +967,26 @@ static int link_drop_foreign_config(Link *link) { r = link_drop_foreign_routes(link); - k = link_drop_foreign_nexthops(link); - if (k < 0 && r >= 0) - r = k; - - k = link_drop_foreign_addresses(link); - if (k < 0 && r >= 0) - r = k; - - k = link_drop_foreign_neighbors(link); - if (k < 0 && r >= 0) - r = k; - - k = manager_drop_foreign_routing_policy_rules(link->manager); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, link_drop_foreign_nexthops(link)); + RET_GATHER(r, link_drop_foreign_addresses(link)); + RET_GATHER(r, link_drop_foreign_neighbors(link)); + RET_GATHER(r, manager_drop_foreign_routing_policy_rules(link->manager)); return r; } static int link_drop_managed_config(Link *link) { - int k, r; + int r; assert(link); assert(link->manager); r = link_drop_managed_routes(link); - k = link_drop_managed_nexthops(link); - if (k < 0 && r >= 0) - r = k; - - k = link_drop_managed_addresses(link); - if (k < 0 && r >= 0) - r = k; - - k = link_drop_managed_neighbors(link); - if (k < 0 && r >= 0) - r = k; - - k = link_drop_managed_routing_policy_rules(link); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, link_drop_managed_nexthops(link)); + RET_GATHER(r, link_drop_managed_addresses(link)); + RET_GATHER(r, link_drop_managed_neighbors(link)); + RET_GATHER(r, link_drop_managed_routing_policy_rules(link)); return r; } diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index b6ba216eee..ab5460db27 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -723,7 +723,7 @@ static int manager_enumerate_internal( int (*process)(sd_netlink *, sd_netlink_message *, Manager *)) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *reply = NULL; - int k, r; + int r; assert(m); assert(nl); @@ -739,11 +739,8 @@ static int manager_enumerate_internal( return r; m->enumerating = true; - for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) { - k = process(nl, reply_one, m); - if (k < 0 && r >= 0) - r = k; - } + for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) + RET_GATHER(r, process(nl, reply_one, m)); m->enumerating = false; return r; diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index f0f78b9c4a..e3c332eadb 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -377,7 +377,7 @@ static int neighbor_remove(Neighbor *neighbor) { int link_drop_foreign_neighbors(Link *link) { Neighbor *neighbor; - int k, r = 0; + int r = 0; assert(link); assert(link->network); @@ -407,9 +407,7 @@ int link_drop_foreign_neighbors(Link *link) { if (!neighbor_is_marked(neighbor)) continue; - k = neighbor_remove(neighbor); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, neighbor_remove(neighbor)); } return r; @@ -417,7 +415,7 @@ int link_drop_foreign_neighbors(Link *link) { int link_drop_managed_neighbors(Link *link) { Neighbor *neighbor; - int k, r = 0; + int r = 0; assert(link); @@ -430,9 +428,7 @@ int link_drop_managed_neighbors(Link *link) { if (!neighbor_exists(neighbor)) continue; - k = neighbor_remove(neighbor); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, neighbor_remove(neighbor)); } return r; diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index 0820e0db2d..eed28440c2 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -687,7 +687,7 @@ static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *ex static int manager_drop_marked_nexthops(Manager *manager) { NextHop *nexthop; - int k, r = 0; + int r = 0; assert(manager); @@ -695,9 +695,7 @@ static int manager_drop_marked_nexthops(Manager *manager) { if (!nexthop_is_marked(nexthop)) continue; - k = nexthop_remove(nexthop); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, nexthop_remove(nexthop)); } return r; @@ -705,7 +703,7 @@ static int manager_drop_marked_nexthops(Manager *manager) { int link_drop_foreign_nexthops(Link *link) { NextHop *nexthop; - int k, r = 0; + int r = 0; assert(link); assert(link->manager); @@ -741,23 +739,17 @@ int link_drop_foreign_nexthops(Link *link) { if (!nexthop_is_marked(nexthop)) continue; - k = nexthop_remove(nexthop); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, nexthop_remove(nexthop)); } manager_mark_nexthops(link->manager, /* foreign = */ true, NULL); - k = manager_drop_marked_nexthops(link->manager); - if (k < 0 && r >= 0) - r = k; - - return r; + return RET_GATHER(r, manager_drop_marked_nexthops(link->manager)); } int link_drop_managed_nexthops(Link *link) { NextHop *nexthop; - int k, r = 0; + int r = 0; assert(link); assert(link->manager); @@ -775,18 +767,12 @@ int link_drop_managed_nexthops(Link *link) { if (!nexthop_exists(nexthop)) continue; - k = nexthop_remove(nexthop); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, nexthop_remove(nexthop)); } manager_mark_nexthops(link->manager, /* foreign = */ false, link); - k = manager_drop_marked_nexthops(link->manager); - if (k < 0 && r >= 0) - r = k; - - return r; + return RET_GATHER(r, manager_drop_marked_nexthops(link->manager)); } void link_foreignize_nexthops(Link *link) { diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index f1f4447ec7..44dc63b642 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -857,7 +857,7 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce static int manager_drop_marked_routes(Manager *manager) { Route *route; - int k, r = 0; + int r = 0; assert(manager); @@ -865,9 +865,7 @@ static int manager_drop_marked_routes(Manager *manager) { if (!route_is_marked(route)) continue; - k = route_remove(route); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, route_remove(route)); } return r; @@ -907,7 +905,7 @@ static void link_unmark_wireguard_routes(Link *link) { int link_drop_foreign_routes(Link *link) { Route *route; - int k, r; + int r; assert(link); assert(link->manager); @@ -962,23 +960,17 @@ int link_drop_foreign_routes(Link *link) { if (!route_is_marked(route)) continue; - k = route_remove(route); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, route_remove(route)); } manager_mark_routes(link->manager, /* foreign = */ true, NULL); - k = manager_drop_marked_routes(link->manager); - if (k < 0 && r >= 0) - r = k; - - return r; + return RET_GATHER(r, manager_drop_marked_routes(link->manager)); } int link_drop_managed_routes(Link *link) { Route *route; - int k, r = 0; + int r = 0; assert(link); @@ -994,18 +986,12 @@ int link_drop_managed_routes(Link *link) { if (!route_exists(route)) continue; - k = route_remove(route); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, route_remove(route)); } manager_mark_routes(link->manager, /* foreign = */ false, link); - k = manager_drop_marked_routes(link->manager); - if (k < 0 && r >= 0) - r = k; - - return r; + return RET_GATHER(r, manager_drop_marked_routes(link->manager)); } void link_foreignize_routes(Link *link) { diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index ee3b1b275e..0cb5831ea3 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -684,7 +684,7 @@ static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Li int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) { RoutingPolicyRule *rule; - int k, r = 0; + int r = 0; assert(m); @@ -694,9 +694,7 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L if (!routing_policy_rule_is_marked(rule)) continue; - k = routing_policy_rule_remove(rule); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, routing_policy_rule_remove(rule)); } return r; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index d4c91fa3aa..4123152d93 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -516,14 +516,8 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) { /* Continues adding after failure, and returns the first failure. */ - STRV_FOREACH(i, l) { - int k; - - k = sd_bus_track_add_name(t, *i); - if (k < 0 && r >= 0) - r = k; - } - + STRV_FOREACH(i, l) + RET_GATHER(r, sd_bus_track_add_name(t, *i)); return r; } diff --git a/src/shared/devnode-acl.c b/src/shared/devnode-acl.c index 92a2aff3dc..b239699e8a 100644 --- a/src/shared/devnode-acl.c +++ b/src/shared/devnode-acl.c @@ -218,8 +218,8 @@ int devnode_acl_all(const char *seat, k = devnode_acl(n, flush, del, old_uid, add, new_uid); if (k == -ENOENT) log_debug("Device %s disappeared while setting ACLs", n); - else if (k < 0 && r == 0) - r = k; + else + RET_GATHER(r, k); } return r; diff --git a/src/shared/nscd-flush.c b/src/shared/nscd-flush.c index dfc7db6964..6df18d7aac 100644 --- a/src/shared/nscd-flush.c +++ b/src/shared/nscd-flush.c @@ -128,21 +128,15 @@ static int nscd_flush_cache_one(const char *database, usec_t end) { } int nscd_flush_cache(char **databases) { - usec_t end; int r = 0; - /* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s timeout, so that we - * don't block indefinitely on another service. */ + /* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s timeout, + * so that we don't block indefinitely on another service. */ - end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC); + usec_t end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC); - STRV_FOREACH(i, databases) { - int k; - - k = nscd_flush_cache_one(*i, end); - if (k < 0 && r >= 0) - r = k; - } + STRV_FOREACH(i, databases) + RET_GATHER(r, nscd_flush_cache_one(*i, end)); return r; } diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index c9b277b124..ca41f02fdd 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -113,7 +113,7 @@ static int sysctl_write_or_warn(const char *key, const char *value, bool ignore_ static int apply_glob_option_with_prefix(OrderedHashmap *sysctl_options, Option *option, const char *prefix) { _cleanup_strv_free_ char **paths = NULL; _cleanup_free_ char *pattern = NULL; - int r, k; + int r; assert(sysctl_options); assert(option); @@ -173,28 +173,23 @@ static int apply_glob_option_with_prefix(OrderedHashmap *sysctl_options, Option continue; } - k = sysctl_write_or_warn(key, option->value, - /* ignore_failure = */ option->ignore_failure, - /* ignore_enoent = */ !arg_strict); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, + sysctl_write_or_warn(key, option->value, + /* ignore_failure = */ option->ignore_failure, + /* ignore_enoent = */ !arg_strict)); } return r; } static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) { - int r = 0, k; + int r = 0; if (strv_isempty(arg_prefixes)) return apply_glob_option_with_prefix(sysctl_options, option, NULL); - STRV_FOREACH(i, arg_prefixes) { - k = apply_glob_option_with_prefix(sysctl_options, option, *i); - if (k < 0 && r >= 0) - r = k; - } - + STRV_FOREACH(i, arg_prefixes) + RET_GATHER(r, apply_glob_option_with_prefix(sysctl_options, option, *i)); return r; } @@ -215,8 +210,7 @@ static int apply_all(OrderedHashmap *sysctl_options) { k = sysctl_write_or_warn(option->key, option->value, /* ignore_failure = */ option->ignore_failure, /* ignore_enoent = */ !arg_strict); - if (k < 0 && r >= 0) - r = k; + RET_GATHER(r, k); } return r; @@ -444,7 +438,7 @@ static int parse_argv(int argc, char *argv[]) { static int run(int argc, char *argv[]) { _cleanup_ordered_hashmap_free_ OrderedHashmap *sysctl_options = NULL; - int r, k; + int r; r = parse_argv(argc, argv); if (r <= 0) @@ -455,15 +449,11 @@ static int run(int argc, char *argv[]) { umask(0022); if (argc > optind) { - int i; - r = 0; - for (i = optind; i < argc; i++) { - k = parse_file(&sysctl_options, argv[i], false); - if (k < 0 && r == 0) - r = k; - } + for (int i = optind; i < argc; i++) + RET_GATHER(r, parse_file(&sysctl_options, argv[i], false)); + } else { _cleanup_strv_free_ char **files = NULL; @@ -477,20 +467,13 @@ static int run(int argc, char *argv[]) { return cat_files(NULL, files, 0); } - STRV_FOREACH(f, files) { - k = parse_file(&sysctl_options, *f, true); - if (k < 0 && r == 0) - r = k; - } + STRV_FOREACH(f, files) + RET_GATHER(r, parse_file(&sysctl_options, *f, true)); - k = read_credential_lines(&sysctl_options); - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, read_credential_lines(&sysctl_options)); } - k = apply_all(sysctl_options); - if (k < 0 && r == 0) - r = k; + RET_GATHER(r, apply_all(sysctl_options)); return r; } diff --git a/src/systemctl/systemctl-set-property.c b/src/systemctl/systemctl-set-property.c index b8d702ac0e..5f4b810525 100644 --- a/src/systemctl/systemctl-set-property.c +++ b/src/systemctl/systemctl-set-property.c @@ -46,7 +46,7 @@ static int set_property_one(sd_bus *bus, const char *name, char **properties) { int verb_set_property(int argc, char *argv[], void *userdata) { sd_bus *bus; _cleanup_strv_free_ char **names = NULL; - int r, k; + int r; r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -59,10 +59,7 @@ int verb_set_property(int argc, char *argv[], void *userdata) { return log_error_errno(r, "Failed to expand '%s' into names: %m", argv[1]); r = 0; - STRV_FOREACH(name, names) { - k = set_property_one(bus, *name, strv_skip(argv, 2)); - if (k < 0 && r >= 0) - r = k; - } + STRV_FOREACH(name, names) + RET_GATHER(r, set_property_one(bus, *name, strv_skip(argv, 2))); return r; } diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 8acda4ef25..09af6dcd93 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -107,7 +107,9 @@ static OrderedHashmap *members = NULL; static Hashmap *database_by_uid = NULL, *database_by_username = NULL; static Hashmap *database_by_gid = NULL, *database_by_groupname = NULL; -static Set *database_users = NULL, *database_groups = NULL; + +/* A helper set to hold names that are used by database_by_{uid,gid,username,groupname} above. */ +static Set *names = NULL; static uid_t search_uid = UID_INVALID; static UidRange *uid_range = NULL; @@ -122,10 +124,9 @@ STATIC_DESTRUCTOR_REGISTER(todo_uids, ordered_hashmap_freep); STATIC_DESTRUCTOR_REGISTER(todo_gids, ordered_hashmap_freep); STATIC_DESTRUCTOR_REGISTER(database_by_uid, hashmap_freep); STATIC_DESTRUCTOR_REGISTER(database_by_username, hashmap_freep); -STATIC_DESTRUCTOR_REGISTER(database_users, set_free_freep); STATIC_DESTRUCTOR_REGISTER(database_by_gid, hashmap_freep); STATIC_DESTRUCTOR_REGISTER(database_by_groupname, hashmap_freep); -STATIC_DESTRUCTOR_REGISTER(database_groups, set_free_freep); +STATIC_DESTRUCTOR_REGISTER(names, set_free_freep); STATIC_DESTRUCTOR_REGISTER(uid_range, uid_range_freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); @@ -184,31 +185,35 @@ static int load_user_database(void) { if (r < 0) return r; - r = set_ensure_allocated(&database_users, NULL); + /* Note that we use NULL, i.e. trivial_hash_ops here, so identical strings can exist in the set. */ + r = set_ensure_allocated(&names, NULL); if (r < 0) return r; while ((r = fgetpwent_sane(f, &pw)) > 0) { - char *n; - int k, q; - n = strdup(pw->pw_name); + char *n = strdup(pw->pw_name); if (!n) return -ENOMEM; - k = set_put(database_users, n); - if (k < 0) { - free(n); - return k; - } + r = set_consume(names, n); + if (r < 0) + return r; + assert(r > 0); /* The set uses pointer comparisons, so n must not be in the set. */ - k = hashmap_put(database_by_username, n, UID_TO_PTR(pw->pw_uid)); - if (k < 0 && k != -EEXIST) - return k; + r = hashmap_put(database_by_username, n, UID_TO_PTR(pw->pw_uid)); + if (r == -EEXIST) + log_debug_errno(r, "%s: user '%s' is listed twice, ignoring duplicate uid.", + passwd_path, n); + else if (r < 0) + return r; - q = hashmap_put(database_by_uid, UID_TO_PTR(pw->pw_uid), n); - if (q < 0 && q != -EEXIST) - return q; + r = hashmap_put(database_by_uid, UID_TO_PTR(pw->pw_uid), n); + if (r == -EEXIST) + log_debug_errno(r, "%s: uid "UID_FMT" is listed twice, ignoring duplicate name.", + passwd_path, pw->pw_uid); + else if (r < 0) + return r; } return r; } @@ -232,31 +237,35 @@ static int load_group_database(void) { if (r < 0) return r; - r = set_ensure_allocated(&database_groups, NULL); + /* Note that we use NULL, i.e. trivial_hash_ops here, so identical strings can exist in the set. */ + r = set_ensure_allocated(&names, NULL); if (r < 0) return r; while ((r = fgetgrent_sane(f, &gr)) > 0) { - char *n; - int k, q; - n = strdup(gr->gr_name); + char *n = strdup(gr->gr_name); if (!n) return -ENOMEM; - k = set_put(database_groups, n); - if (k < 0) { - free(n); - return k; - } + r = set_consume(names, n); + if (r < 0) + return r; + assert(r > 0); /* The set uses pointer comparisons, so n must not be in the set. */ - k = hashmap_put(database_by_groupname, n, GID_TO_PTR(gr->gr_gid)); - if (k < 0 && k != -EEXIST) - return k; + r = hashmap_put(database_by_groupname, n, GID_TO_PTR(gr->gr_gid)); + if (r == -EEXIST) + log_debug_errno(r, "%s: group '%s' is listed twice, ignoring duplicate gid.", + group_path, n); + else if (r < 0) + return r; - q = hashmap_put(database_by_gid, GID_TO_PTR(gr->gr_gid), n); - if (q < 0 && q != -EEXIST) - return q; + r = hashmap_put(database_by_gid, GID_TO_PTR(gr->gr_gid), n); + if (r == -EEXIST) + log_debug_errno(r, "%s: gid "GID_FMT" is listed twice, ignoring duplicate name.", + group_path, gr->gr_gid); + else if (r < 0) + return r; } return r; } diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c index d3d022c33f..62a508c4c9 100644 --- a/src/test/test-errno-util.c +++ b/src/test/test-errno-util.c @@ -78,4 +78,15 @@ TEST(UNPROTECT_ERRNO) { assert_se(errno == 4711); } +TEST(RET_GATHER) { + int x = 0, y = 2; + + assert_se(RET_GATHER(x, 5) == 0); + assert_se(RET_GATHER(x, -5) == -5); + assert_se(RET_GATHER(x, -1) == -5); + + assert_se(RET_GATHER(x, y++) == -5); + assert_se(y == 3); +} + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c index 36c993cbb0..da42ef59b0 100644 --- a/src/udev/udev-builtin-uaccess.c +++ b/src/udev/udev-builtin-uaccess.c @@ -12,6 +12,7 @@ #include "device-util.h" #include "devnode-acl.h" +#include "errno-util.h" #include "login-util.h" #include "log.h" #include "udev-builtin.h" @@ -66,8 +67,7 @@ finish: k = devnode_acl(path, true, false, 0, false, 0); if (k < 0) { log_device_full_errno(dev, k == -ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to apply ACL: %m"); - if (r >= 0) - r = k; + RET_GATHER(r, k); } }