diff --git a/src/basic/sort-util.h b/src/basic/sort-util.h index e029f8646e..a8dc3bb6ed 100644 --- a/src/basic/sort-util.h +++ b/src/basic/sort-util.h @@ -39,7 +39,7 @@ static inline void* bsearch_safe(const void *key, const void *base, * Normal qsort requires base to be nonnull. Here were require * that only if nmemb > 0. */ -static inline void qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { +static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { if (nmemb <= 1) return; @@ -52,7 +52,7 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn #define typesafe_qsort(p, n, func) \ ({ \ int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \ - qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \ + _qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \ }) static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) { diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 9983aa826e..755a37f667 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -19,18 +19,19 @@ #include "util.h" int strcmp_ptr(const char *a, const char *b) { - /* Like strcmp(), but tries to make sense of NULL pointers */ + if (a && b) return strcmp(a, b); + return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */ +} - if (!a && b) - return -1; +int strcasecmp_ptr(const char *a, const char *b) { + /* Like strcasecmp(), but tries to make sense of NULL pointers */ - if (a && !b) - return 1; - - return 0; + if (a && b) + return strcasecmp(a, b); + return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */ } char* endswith(const char *s, const char *postfix) { diff --git a/src/basic/string-util.h b/src/basic/string-util.h index 2a344b996f..09131455bf 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -27,6 +27,7 @@ #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) int strcmp_ptr(const char *a, const char *b) _pure_; +int strcasecmp_ptr(const char *a, const char *b) _pure_; static inline bool streq_ptr(const char *a, const char *b) { return strcmp_ptr(a, b) == 0; diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c index 59d0b5b74e..9b888a2baa 100644 --- a/src/pstore/pstore.c +++ b/src/pstore/pstore.c @@ -101,8 +101,8 @@ typedef struct PStoreEntry { typedef struct PStoreList { PStoreEntry *entries; + size_t n_allocated; size_t n_entries; - size_t n_entries_allocated; } PStoreList; static void pstore_entries_reset(PStoreList *list) { @@ -112,8 +112,7 @@ static void pstore_entries_reset(PStoreList *list) { list->n_entries = 0; } -static int compare_pstore_entries(const void *_a, const void *_b) { - PStoreEntry *a = (PStoreEntry *)_a, *b = (PStoreEntry *)_b; +static int compare_pstore_entries(const PStoreEntry *a, const PStoreEntry *b) { return strcmp(a->dirent.d_name, b->dirent.d_name); } @@ -349,7 +348,7 @@ static int list_files(PStoreList *list, const char *sourcepath) { continue; } - if (!GREEDY_REALLOC(list->entries, list->n_entries_allocated, list->n_entries + 1)) + if (!GREEDY_REALLOC(list->entries, list->n_allocated, list->n_entries + 1)) return log_oom(); list->entries[list->n_entries++] = (PStoreEntry) { @@ -394,7 +393,7 @@ static int run(int argc, char *argv[]) { /* Handle each pstore file */ /* Sort files lexigraphically ascending, generally needed by all */ - qsort_safe(list.entries, list.n_entries, sizeof(PStoreEntry), compare_pstore_entries); + typesafe_qsort(list.entries, list.n_entries, compare_pstore_entries); /* Process known file types */ process_dmesg_files(&list); diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index d68b7ba784..3cadac7639 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -28,6 +28,7 @@ #include "resolved-def.h" #include "resolved-dns-packet.h" #include "socket-netlink.h" +#include "sort-util.h" #include "stdio-util.h" #include "string-table.h" #include "strv.h" @@ -79,6 +80,21 @@ typedef enum StatusMode { STATUS_NTA, } StatusMode; +typedef struct InterfaceInfo { + int index; + const char *name; +} InterfaceInfo; + +static int interface_info_compare(const InterfaceInfo *a, const InterfaceInfo *b) { + int r; + + r = CMP(a->index, b->index); + if (r != 0) + return r; + + return strcmp_ptr(a->name, b->name); +} + int ifname_mangle(const char *s) { _cleanup_free_ char *iface = NULL; const char *dot; @@ -1500,10 +1516,6 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode if (r < 0) return r; - r = dump_list(table, "DNSSEC NTA:", link_info.ntas); - if (r < 0) - return r; - r = table_print(table, NULL); if (r < 0) return log_error_errno(r, "Failed to print table: %m"); @@ -1745,11 +1757,6 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { if (r < 0) return r; - strv_sort(global_info.ntas); - r = dump_list(table, "DNSSEC NTA:", global_info.ntas); - if (r < 0) - return r; - r = table_print(table, NULL); if (r < 0) return log_error_errno(r, "Failed to print table: %m"); @@ -1762,7 +1769,6 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) { static int status_all(sd_bus *bus, StatusMode mode) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; - sd_netlink_message *i; bool empty_line = false; int r; @@ -1788,31 +1794,43 @@ static int status_all(sd_bus *bus, StatusMode mode) { if (r < 0) return log_error_errno(r, "Failed to enumerate links: %m"); - r = 0; - for (i = reply; i; i = sd_netlink_message_next(i)) { + _cleanup_free_ InterfaceInfo *infos = NULL; + size_t n_allocated = 0, n_infos = 0; + + for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i)) { const char *name; - int ifindex, q; + int ifindex; uint16_t type; - q = sd_netlink_message_get_type(i, &type); - if (q < 0) - return rtnl_log_parse_error(q); + r = sd_netlink_message_get_type(i, &type); + if (r < 0) + return rtnl_log_parse_error(r); if (type != RTM_NEWLINK) continue; - q = sd_rtnl_message_link_get_ifindex(i, &ifindex); - if (q < 0) - return rtnl_log_parse_error(q); + r = sd_rtnl_message_link_get_ifindex(i, &ifindex); + if (r < 0) + return rtnl_log_parse_error(r); if (ifindex == LOOPBACK_IFINDEX) continue; - q = sd_netlink_message_read_string(i, IFLA_IFNAME, &name); - if (q < 0) - return rtnl_log_parse_error(q); + r = sd_netlink_message_read_string(i, IFLA_IFNAME, &name); + if (r < 0) + return rtnl_log_parse_error(r); - q = status_ifindex(bus, ifindex, name, mode, &empty_line); + if (!GREEDY_REALLOC(infos, n_allocated, n_infos + 1)) + return log_oom(); + + infos[n_infos++] = (InterfaceInfo) { ifindex, name }; + } + + typesafe_qsort(infos, n_infos, interface_info_compare); + + r = 0; + for (size_t i = 0; i < n_infos; i++) { + int q = status_ifindex(bus, infos[i].index, infos[i].name, mode, &empty_line); if (q < 0 && r >= 0) r = q; } @@ -3042,7 +3060,7 @@ static int native_main(int argc, char *argv[], sd_bus *bus) { static int translate(const char *verb, const char *single_arg, size_t num_args, char **args, sd_bus *bus) { char **fake, **p; - size_t num, i; + size_t num; assert(verb); assert(num_args == 0 || args); @@ -3053,7 +3071,7 @@ static int translate(const char *verb, const char *single_arg, size_t num_args, *p++ = (char *) verb; if (single_arg) *p++ = (char *) single_arg; - for (i = 0; i < num_args; i++) + for (size_t i = 0; i < num_args; i++) *p++ = args[i]; optind = 0; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index ae5c691057..4d59b5d1f5 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -322,28 +322,17 @@ static bool install_client_side(void) { } static int compare_unit_info(const UnitInfo *a, const UnitInfo *b) { - const char *d1, *d2; int r; /* First, order by machine */ - if (!a->machine && b->machine) - return -1; - if (a->machine && !b->machine) - return 1; - if (a->machine && b->machine) { - r = strcasecmp(a->machine, b->machine); - if (r != 0) - return r; - } + r = strcasecmp_ptr(a->machine, b->machine); + if (r != 0) + return r; /* Second, order by unit type */ - d1 = strrchr(a->id, '.'); - d2 = strrchr(b->id, '.'); - if (d1 && d2) { - r = strcasecmp(d1, d2); - if (r != 0) - return r; - } + r = strcasecmp_ptr(strrchr(a->id, '.'), strrchr(b->id, '.')); + if (r != 0) + return r; /* Third, order by name */ return strcasecmp(a->id, b->id); @@ -408,8 +397,6 @@ static int output_table(Table *table) { static int output_units_list(const UnitInfo *unit_infos, unsigned c) { _cleanup_(table_unrefp) Table *table = NULL; - const UnitInfo *u; - int job_count = 0; int r; table = table_new("", "unit", "load", "active", "sub", "job", "description"); @@ -428,7 +415,8 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { (void) table_set_empty_string(table, "-"); - for (u = unit_infos; unit_infos && u < unit_infos + c; u++) { + int job_count = 0; + for (const UnitInfo *u = unit_infos; unit_infos && u < unit_infos + c; u++) { _cleanup_free_ char *j = NULL; const char *on_underline = "", *on_loaded = "", *on_active = ""; const char *on_circle = "", *id; @@ -975,21 +963,15 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_ assert(a); assert(b); - if (!a->machine && b->machine) - return -1; - if (a->machine && !b->machine) - return 1; - if (a->machine && b->machine) { - r = strcasecmp(a->machine, b->machine); - if (r != 0) - return r; - } + r = strcasecmp_ptr(a->machine, b->machine); + if (r != 0) + return r; r = strcmp(a->path, b->path); - if (r == 0) - r = strcmp(a->type, b->type); + if (r != 0) + return r; - return r; + return strcmp(a->type, b->type); } static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { @@ -1234,15 +1216,9 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf assert(a); assert(b); - if (!a->machine && b->machine) - return -1; - if (a->machine && !b->machine) - return 1; - if (a->machine && b->machine) { - r = strcasecmp(a->machine, b->machine); - if (r != 0) - return r; - } + r = strcasecmp_ptr(a->machine, b->machine); + if (r != 0) + return r; r = CMP(a->next_elapse, b->next_elapse); if (r != 0)