diff options
Diffstat (limited to 'src/libsystemd')
86 files changed, 1758 insertions, 1024 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index d5ad127bcb..043ff13e6f 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -473,3 +473,11 @@ global: sd_pid_get_cgroup; sd_peer_get_cgroup; } LIBSYSTEMD_222; + +LIBSYSTEMD_227 { +global: + sd_bus_default_flush_close; + sd_bus_path_decode_many; + sd_bus_path_encode_many; + sd_listen_fds_with_names; +} LIBSYSTEMD_226; diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c index 91fab90cb0..c0c5d445eb 100644 --- a/src/libsystemd/sd-bus/bus-bloom.c +++ b/src/libsystemd/sd-bus/bus-bloom.c @@ -19,9 +19,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "siphash24.h" #include "bus-bloom.h" +#include "siphash24.h" +#include "util.h" static inline void set_bit(uint64_t filter[], unsigned long b) { filter[b >> 6] |= 1ULL << (b & 63); @@ -45,7 +45,7 @@ static void bloom_add_data( const void *data, /* Data to hash */ size_t n) { /* Size of data to hash in bytes */ - uint8_t h[8]; + uint64_t h; uint64_t m; unsigned w, i, c = 0; unsigned hash_index; @@ -72,11 +72,11 @@ static void bloom_add_data( for (d = 0; d < w; d++) { if (c <= 0) { - siphash24(h, data, n, hash_keys[hash_index++].bytes); + h = siphash24(data, n, hash_keys[hash_index++].bytes); c += 8; } - p = (p << 8ULL) | (uint64_t) h[8 - c]; + p = (p << 8ULL) | (uint64_t) ((uint8_t *)&h)[8 - c]; c--; } diff --git a/src/libsystemd/sd-bus/bus-bloom.h b/src/libsystemd/sd-bus/bus-bloom.h index a9350d7f51..38892044f1 100644 --- a/src/libsystemd/sd-bus/bus-bloom.h +++ b/src/libsystemd/sd-bus/bus-bloom.h @@ -22,6 +22,7 @@ ***/ #include <stdbool.h> +#include <stddef.h> #include <stdint.h> /* diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index 52f8dfd3be..9ddc9b5aaf 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -22,8 +22,9 @@ #include <errno.h> #include "sd-bus.h" -#include "bus-error.h" + #include "bus-common-errors.h" +#include "bus-error.h" BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_UNIT, ENOENT), @@ -66,12 +67,19 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_PROCESS, ESRCH), - SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, EIO), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, ESRCH), SD_BUS_ERROR_MAP(BUS_ERROR_INVALID_REPLY, EINVAL), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_RR, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_NO_RESOURCES, ENOMEM), SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP, EDEADLK), SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED, ECANCELED), + SD_BUS_ERROR_MAP(BUS_ERROR_CONNECTION_FAILURE, ECONNREFUSED), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SERVICE, EUNATCH), + SD_BUS_ERROR_MAP(BUS_ERROR_DNSSEC_FAILED, EHOSTUNREACH), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_TRUST_ANCHOR, EHOSTUNREACH), + SD_BUS_ERROR_MAP(BUS_ERROR_RR_TYPE_UNSUPPORTED, EOPNOTSUPP), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_LINK, ENXIO), + SD_BUS_ERROR_MAP(BUS_ERROR_LINK_BUSY, EBUSY), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_TRANSFER, ENXIO), SD_BUS_ERROR_MAP(BUS_ERROR_TRANSFER_IN_PROGRESS, EBUSY), diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index f2092795f4..e93b6ac448 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -72,6 +72,13 @@ #define BUS_ERROR_NO_RESOURCES "org.freedesktop.resolve1.NoResources" #define BUS_ERROR_CNAME_LOOP "org.freedesktop.resolve1.CNameLoop" #define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted" +#define BUS_ERROR_CONNECTION_FAILURE "org.freedesktop.resolve1.ConnectionFailure" +#define BUS_ERROR_NO_SUCH_SERVICE "org.freedesktop.resolve1.NoSuchService" +#define BUS_ERROR_DNSSEC_FAILED "org.freedesktop.resolve1.DnssecFailed" +#define BUS_ERROR_NO_TRUST_ANCHOR "org.freedesktop.resolve1.NoTrustAnchor" +#define BUS_ERROR_RR_TYPE_UNSUPPORTED "org.freedesktop.resolve1.ResourceRecordTypeUnsupported" +#define BUS_ERROR_NO_SUCH_LINK "org.freedesktop.resolve1.NoSuchLink" +#define BUS_ERROR_LINK_BUSY "org.freedesktop.resolve1.LinkBusy" #define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError." #define BUS_ERROR_NO_SUCH_TRANSFER "org.freedesktop.import1.NoSuchTransfer" diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c index 5c607f49b1..7da6ba9903 100644 --- a/src/libsystemd/sd-bus/bus-container.c +++ b/src/libsystemd/sd-bus/bus-container.c @@ -19,14 +19,15 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <unistd.h> #include <fcntl.h> +#include <unistd.h> -#include "util.h" -#include "process-util.h" +#include "bus-container.h" #include "bus-internal.h" #include "bus-socket.h" -#include "bus-container.h" +#include "fd-util.h" +#include "process-util.h" +#include "util.h" int bus_container_connect_socket(sd_bus *b) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; @@ -217,15 +218,8 @@ int bus_container_connect_kernel(sd_bus *b) { _exit(EXIT_FAILURE); } - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - mh.msg_controllen = cmsg->cmsg_len; - - if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0) + r = send_one_fd(pair[1], fd, 0); + if (r < 0) _exit(EXIT_FAILURE); _exit(EXIT_SUCCESS); diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index aeb48bedd1..ff628cfe72 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -23,17 +23,22 @@ #include <valgrind/memcheck.h> #endif -#include <stddef.h> #include <errno.h> +#include <stddef.h> -#include "strv.h" #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-bloom.h" +#include "bus-control.h" #include "bus-internal.h" #include "bus-message.h" -#include "bus-control.h" -#include "bus-bloom.h" #include "bus-util.h" -#include "capability.h" +#include "capability-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "strv.h" +#include "user-util.h" _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { int r; @@ -86,7 +91,7 @@ static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags } static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; uint32_t ret, param = 0; int r; @@ -182,7 +187,7 @@ static int bus_release_name_kernel(sd_bus *bus, const char *name) { } static int bus_release_name_dbus1(sd_bus *bus, const char *name) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; uint32_t ret; int r; @@ -321,7 +326,7 @@ static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activata } static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_strv_free_ char **x = NULL, **y = NULL; int r; @@ -642,7 +647,7 @@ int bus_get_name_creds_kdbus( bool allow_activator, sd_bus_creds **creds) { - _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; struct kdbus_cmd_info *cmd; struct kdbus_info *conn_info; size_t size, l; @@ -748,8 +753,8 @@ static int bus_get_name_creds_dbus1( uint64_t mask, sd_bus_creds **creds) { - _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL; - _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_unique = NULL, *reply = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; const char *unique = NULL; pid_t pid = 0; int r; @@ -853,7 +858,7 @@ static int bus_get_name_creds_dbus1( } if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const void *p = NULL; size_t sz = 0; @@ -925,7 +930,7 @@ _public_ int sd_bus_get_name_creds( } static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { - _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; struct kdbus_cmd_info cmd = { .size = sizeof(struct kdbus_cmd_info), }; @@ -974,10 +979,14 @@ static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds ** } static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { - _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; pid_t pid = 0; + bool do_label; int r; - bool do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT); + + assert(bus); + + do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT); /* Avoid allocating anything if we have no chance of returning useful data */ if (!bus->ucred_valid && !do_label) @@ -1534,7 +1543,7 @@ int bus_remove_match_internal( } _public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL; const char *mid; int r; diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h index 5009ca8e61..e01b075832 100644 --- a/src/libsystemd/sd-bus/bus-control.h +++ b/src/libsystemd/sd-bus/bus-control.h @@ -22,6 +22,7 @@ ***/ #include "sd-bus.h" + #include "bus-match.h" int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components, uint64_t cookie); diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index af5f7da11c..d3d5149242 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -22,8 +22,9 @@ #include "bus-internal.h" #include "bus-message.h" #include "bus-signature.h" -#include "bus-util.h" #include "bus-type.h" +#include "bus-util.h" +#include "string-util.h" _public_ int sd_bus_emit_signal( sd_bus *bus, @@ -32,7 +33,7 @@ _public_ int sd_bus_emit_signal( const char *member, const char *types, ...) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert_return(bus, -EINVAL); @@ -69,7 +70,7 @@ _public_ int sd_bus_call_method_async( void *userdata, const char *types, ...) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert_return(bus, -EINVAL); @@ -105,7 +106,7 @@ _public_ int sd_bus_call_method( sd_bus_message **reply, const char *types, ...) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; bus_assert_return(bus, -EINVAL, error); @@ -140,7 +141,7 @@ _public_ int sd_bus_reply_method_return( sd_bus_message *call, const char *types, ...) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert_return(call, -EINVAL); @@ -176,7 +177,7 @@ _public_ int sd_bus_reply_method_error( sd_bus_message *call, const sd_bus_error *e) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert_return(call, -EINVAL); @@ -205,7 +206,7 @@ _public_ int sd_bus_reply_method_errorf( const char *format, ...) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; va_list ap; assert_return(call, -EINVAL); @@ -232,7 +233,7 @@ _public_ int sd_bus_reply_method_errno( int error, const sd_bus_error *p) { - _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL; assert_return(call, -EINVAL); assert_return(call->sealed, -EPERM); @@ -260,7 +261,7 @@ _public_ int sd_bus_reply_method_errnof( const char *format, ...) { - _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL; va_list ap; assert_return(call, -EINVAL); @@ -333,7 +334,7 @@ _public_ int sd_bus_get_property_trivial( sd_bus_error *error, char type, void *ptr) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; bus_assert_return(bus, -EINVAL, error); @@ -375,7 +376,7 @@ _public_ int sd_bus_get_property_string( sd_bus_error *error, char **ret) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; const char *s; char *n; int r; @@ -425,7 +426,7 @@ _public_ int sd_bus_get_property_strv( sd_bus_error *error, char ***ret) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; bus_assert_return(bus, -EINVAL, error); @@ -466,7 +467,7 @@ _public_ int sd_bus_set_property( sd_bus_error *error, const char *type, ...) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; va_list ap; int r; @@ -554,7 +555,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b } _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) { - _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; uid_t our_uid; bool know_caps = false; int r; diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 3e8cb0b7d0..4e0d02a62c 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -19,22 +19,28 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> #include <linux/capability.h> +#include <stdlib.h> -#include "util.h" -#include "formats-util.h" -#include "process-util.h" -#include "terminal-util.h" -#include "capability.h" -#include "cgroup-util.h" -#include "fileio.h" -#include "audit.h" +#include "alloc-util.h" +#include "audit-util.h" +#include "bus-creds.h" +#include "bus-label.h" #include "bus-message.h" #include "bus-util.h" +#include "capability-util.h" +#include "cgroup-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "formats-util.h" +#include "hexdecoct.h" +#include "parse-util.h" +#include "process-util.h" +#include "string-util.h" #include "strv.h" -#include "bus-creds.h" -#include "bus-label.h" +#include "terminal-util.h" +#include "user-util.h" +#include "util.h" enum { CAP_OFFSET_INHERITABLE = 0, @@ -69,7 +75,9 @@ void bus_creds_done(sd_bus_creds *c) { } _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { - assert_return(c, NULL); + + if (!c) + return NULL; if (c->allocated) { assert(c->n_ref > 0); @@ -1112,7 +1120,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { } int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) { - _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL; int r; assert(c); diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index a6b05eb88d..43a7e67a6d 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -19,18 +19,21 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "capability.h" -#include "strv.h" -#include "macro.h" +#include "alloc-util.h" +#include "bus-dump.h" +#include "bus-internal.h" +#include "bus-message.h" +#include "bus-type.h" #include "cap-list.h" +#include "capability-util.h" +#include "fileio.h" #include "formats-util.h" +#include "locale-util.h" +#include "macro.h" +#include "string-util.h" +#include "strv.h" #include "terminal-util.h" - -#include "bus-message.h" -#include "bus-internal.h" -#include "bus-type.h" -#include "bus-dump.h" +#include "util.h" static char *indent(unsigned level, unsigned flags) { char *p; @@ -73,8 +76,8 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64, m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() : m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() : - m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(), - ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(), + m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_normal(), + ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(), m->header->endian, m->header->flags, m->header->version, @@ -93,15 +96,15 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { fputs("\n", f); if (m->sender) - fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off()); + fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_normal()); if (m->destination) - fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off()); + fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_normal()); if (m->path) - fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off()); + fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_normal()); if (m->interface) - fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off()); + fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_normal()); if (m->member) - fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off()); + fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_normal()); if (m->sender || m->destination || m->path || m->interface || m->member) fputs("\n", f); @@ -110,8 +113,8 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { fprintf(f, " ErrorName=%s%s%s" " ErrorMessage=%s\"%s\"%s\n", - ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(), - ansi_highlight_red(), strna(m->error.message), ansi_highlight_off()); + ansi_highlight_red(), strna(m->error.name), ansi_normal(), + ansi_highlight_red(), strna(m->error.message), ansi_normal()); if (m->monotonic != 0) fprintf(f, " Monotonic="USEC_FMT, m->monotonic); @@ -211,55 +214,55 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { switch (type) { case SD_BUS_TYPE_BYTE: - fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off()); + fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_normal()); break; case SD_BUS_TYPE_BOOLEAN: - fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off()); + fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_normal()); break; case SD_BUS_TYPE_INT16: - fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off()); + fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_normal()); break; case SD_BUS_TYPE_UINT16: - fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off()); + fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_normal()); break; case SD_BUS_TYPE_INT32: - fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off()); + fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_normal()); break; case SD_BUS_TYPE_UINT32: - fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off()); + fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_normal()); break; case SD_BUS_TYPE_INT64: - fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off()); + fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_normal()); break; case SD_BUS_TYPE_UINT64: - fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off()); + fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_normal()); break; case SD_BUS_TYPE_DOUBLE: - fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off()); + fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_normal()); break; case SD_BUS_TYPE_STRING: - fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off()); + fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal()); break; case SD_BUS_TYPE_OBJECT_PATH: - fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off()); + fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal()); break; case SD_BUS_TYPE_SIGNATURE: - fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off()); + fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal()); break; case SD_BUS_TYPE_UNIX_FD: - fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off()); + fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_normal()); break; default: @@ -327,7 +330,7 @@ static void dump_capabilities( fputs("\n", f); if (!terse) - fputs(ansi_highlight_off(), f); + fputs(ansi_normal(), f); } int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) { @@ -352,7 +355,7 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) { prefix = ""; color = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); suffix = strjoina(off, "\n"); } diff --git a/src/libsystemd/sd-bus/bus-dump.h b/src/libsystemd/sd-bus/bus-dump.h index d2522edeba..71e56991fa 100644 --- a/src/libsystemd/sd-bus/bus-dump.h +++ b/src/libsystemd/sd-bus/bus-dump.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdio.h> #include <stdbool.h> +#include <stdio.h> #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 64a5a972ae..c77eb5fd03 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -20,17 +20,19 @@ ***/ #include <errno.h> -#include <stdlib.h> #include <stdarg.h> #include <stdbool.h> -#include <string.h> #include <stdio.h> - -#include "util.h" -#include "errno-list.h" +#include <stdlib.h> +#include <string.h> #include "sd-bus.h" + +#include "alloc-util.h" #include "bus-error.h" +#include "errno-list.h" +#include "string-util.h" +#include "util.h" BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_standard_errors[] = { SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Failed", EACCES), @@ -91,14 +93,14 @@ static int bus_error_name_to_errno(const char *name) { p = startswith(name, "System.Error."); if (p) { r = errno_from_name(p); - if (r <= 0) + if (r < 0) return EIO; return r; } - if (additional_error_maps) { - for (map = additional_error_maps; *map; map++) { + if (additional_error_maps) + for (map = additional_error_maps; *map; map++) for (m = *map;; m++) { /* For additional error maps the end marker is actually the end marker */ if (m->code == BUS_ERROR_MAP_END_MARKER) @@ -107,15 +109,13 @@ static int bus_error_name_to_errno(const char *name) { if (streq(m->name, name)) return m->code; } - } - } m = __start_BUS_ERROR_MAP; while (m < __stop_BUS_ERROR_MAP) { /* For magic ELF error maps, the end marker might * appear in the middle of things, since multiple maps * might appear in the same section. Hence, let's skip - * over it, but realign the pointer to the netx 8byte + * over it, but realign the pointer to the next 8 byte * boundary, which is the selected alignment for the * arrays. */ if (m->code == BUS_ERROR_MAP_END_MARKER) { @@ -256,25 +256,24 @@ int bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_li if (!name) return 0; - if (!e) - goto finish; - assert_return(!bus_error_is_dirty(e), -EINVAL); + if (e) { + assert_return(!bus_error_is_dirty(e), -EINVAL); - e->name = strdup(name); - if (!e->name) { - *e = BUS_ERROR_OOM; - return -ENOMEM; - } + e->name = strdup(name); + if (!e->name) { + *e = BUS_ERROR_OOM; + return -ENOMEM; + } - /* If we hit OOM on formatting the pretty message, we ignore - * this, since we at least managed to write the error name */ - if (format) - (void) vasprintf((char**) &e->message, format, ap); + /* If we hit OOM on formatting the pretty message, we ignore + * this, since we at least managed to write the error name */ + if (format) + (void) vasprintf((char**) &e->message, format, ap); - e->_need_free = 1; + e->_need_free = 1; + } -finish: return -bus_error_name_to_errno(name); } @@ -565,7 +564,7 @@ _public_ int sd_bus_error_set_errnof(sd_bus_error *e, int error, const char *for const char *bus_error_message(const sd_bus_error *e, int error) { if (e) { - /* Sometimes the D-Bus server is a little bit too verbose with + /* Sometimes, the D-Bus server is a little bit too verbose with * its error messages, so let's override them here */ if (sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) return "Access denied"; @@ -580,27 +579,29 @@ const char *bus_error_message(const sd_bus_error *e, int error) { return strerror(error); } +static bool map_ok(const sd_bus_error_map *map) { + for (; map->code != BUS_ERROR_MAP_END_MARKER; map++) + if (!map->name || map->code <=0) + return false; + return true; +} + _public_ int sd_bus_error_add_map(const sd_bus_error_map *map) { const sd_bus_error_map **maps = NULL; unsigned n = 0; assert_return(map, -EINVAL); + assert_return(map_ok(map), -EINVAL); - if (additional_error_maps) { - for (;; n++) { - if (additional_error_maps[n] == NULL) - break; - + if (additional_error_maps) + for (; additional_error_maps[n] != NULL; n++) if (additional_error_maps[n] == map) return 0; - } - } maps = realloc_multiply(additional_error_maps, sizeof(struct sd_bus_error_map*), n + 2); if (!maps) return -ENOMEM; - maps[n] = map; maps[n+1] = NULL; diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index fb0199c948..d7fd8612d0 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -24,6 +24,7 @@ #include <stdbool.h> #include "sd-bus.h" + #include "macro.h" bool bus_error_is_dirty(sd_bus_error *e); diff --git a/src/libsystemd/sd-bus/bus-gvariant.c b/src/libsystemd/sd-bus/bus-gvariant.c index 402d43d66d..ec027590b2 100644 --- a/src/libsystemd/sd-bus/bus-gvariant.c +++ b/src/libsystemd/sd-bus/bus-gvariant.c @@ -19,9 +19,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "bus-type.h" #include "bus-gvariant.h" #include "bus-signature.h" +#include "bus-type.h" int bus_gvariant_get_size(const char *signature) { const char *p; diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index fea796cd30..d9f9cd1c5e 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -19,8 +19,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "bus-message.h" +#include "alloc-util.h" #include "bus-internal.h" +#include "bus-message.h" +#include "hexdecoct.h" +#include "string-util.h" bool object_path_is_valid(const char *p) { const char *q; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 7af61a9433..35aed634f7 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -21,21 +21,21 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> #include <pthread.h> - -#include "hashmap.h" -#include "prioq.h" -#include "list.h" -#include "util.h" -#include "refcnt.h" -#include "socket-util.h" +#include <sys/socket.h> #include "sd-bus.h" + #include "bus-error.h" -#include "bus-match.h" #include "bus-kernel.h" +#include "bus-match.h" +#include "hashmap.h" #include "kdbus.h" +#include "list.h" +#include "prioq.h" +#include "refcnt.h" +#include "socket-util.h" +#include "util.h" struct reply_callback { sd_bus_message_handler_t callback; @@ -381,7 +381,7 @@ char *bus_address_escape(const char *v); * bus from the callback doesn't destroy the object we are working * on */ #define BUS_DONT_DESTROY(bus) \ - _cleanup_bus_unref_ _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) + _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) int bus_set_address_system(sd_bus *bus); int bus_set_address_user(sd_bus *bus); @@ -396,6 +396,6 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error); #define bus_assert_return(expr, r, error) \ do { \ - if (!assert_log(expr)) \ + if (!assert_log(expr, #expr)) \ return sd_bus_error_set_errno(error, r); \ } while (false) diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 3149a56397..a90536bac9 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -19,11 +19,14 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "bus-introspect.h" -#include "bus-signature.h" #include "bus-internal.h" +#include "bus-introspect.h" #include "bus-protocol.h" +#include "bus-signature.h" +#include "fd-util.h" +#include "fileio.h" +#include "string-util.h" +#include "util.h" int introspect_begin(struct introspect *i, bool trusted) { assert(i); diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h index 1914e6cb8b..57c2430ee8 100644 --- a/src/libsystemd/sd-bus/bus-introspect.h +++ b/src/libsystemd/sd-bus/bus-introspect.h @@ -24,6 +24,7 @@ #include <stdio.h> #include "sd-bus.h" + #include "set.h" struct introspect { diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 577a8b44c3..e7d6170eec 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -34,19 +34,24 @@ #include <libgen.h> #undef basename -#include "util.h" -#include "strv.h" -#include "memfd-util.h" -#include "capability.h" -#include "fileio.h" -#include "formats-util.h" - +#include "alloc-util.h" +#include "bus-bloom.h" #include "bus-internal.h" -#include "bus-message.h" #include "bus-kernel.h" -#include "bus-bloom.h" -#include "bus-util.h" #include "bus-label.h" +#include "bus-message.h" +#include "bus-util.h" +#include "capability-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "formats-util.h" +#include "memfd-util.h" +#include "parse-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "strv.h" +#include "user-util.h" +#include "util.h" #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -265,8 +270,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { struct bus_body_part *part; struct kdbus_item *d; const char *destination; - bool well_known; - uint64_t unique; + bool well_known = false; + uint64_t dst_id; size_t sz, dl; unsigned i; int r; @@ -283,13 +288,21 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { destination = m->destination ?: m->destination_ptr; if (destination) { - r = bus_kernel_parse_unique_name(destination, &unique); + r = bus_kernel_parse_unique_name(destination, &dst_id); if (r < 0) return r; - - well_known = r == 0; + if (r == 0) { + well_known = true; + + /* verify_destination_id will usually be 0, which makes the kernel + * driver only look at the provided well-known name. Otherwise, + * the kernel will make sure the provided destination id matches + * the owner of the provided well-known-name, and fail if they + * differ. Currently, this is only needed for bus-proxyd. */ + dst_id = m->verify_destination_id; + } } else - well_known = false; + dst_id = KDBUS_DST_ID_BROADCAST; sz = offsetof(struct kdbus_msg, items); @@ -327,15 +340,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) | ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0); - if (well_known) - /* verify_destination_id will usually be 0, which makes the kernel driver only look - * at the provided well-known name. Otherwise, the kernel will make sure the provided - * destination id matches the owner of the provided weel-known-name, and fail if they - * differ. Currently, this is only needed for bus-proxyd. */ - m->kdbus->dst_id = m->verify_destination_id; - else - m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST; - + m->kdbus->dst_id = dst_id; m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS; m->kdbus->cookie = m->header->dbus2.cookie; m->kdbus->priority = m->priority; @@ -845,7 +850,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { if (k->src_id == KDBUS_SRC_ID_KERNEL) bus_message_set_sender_driver(bus, m); else { - snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id); + xsprintf(m->sender_buffer, ":1.%llu", + (unsigned long long)k->src_id); m->sender = m->creds.unique_name = m->sender_buffer; } @@ -856,7 +862,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { else if (k->dst_id == KDBUS_DST_ID_NAME) m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */ else { - snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id); + xsprintf(m->destination_buffer, ":1.%llu", + (unsigned long long)k->dst_id); m->destination = m->destination_buffer; } @@ -1138,7 +1145,7 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call r = ioctl(bus->output_fd, KDBUS_CMD_SEND, &cmd); if (r < 0) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *reply; if (errno == EAGAIN || errno == EINTR) @@ -1217,7 +1224,7 @@ static int push_name_owner_changed( const char *new_owner, const struct kdbus_timestamp *ts) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert(bus); @@ -1304,7 +1311,7 @@ static int translate_reply( const struct kdbus_item *d, const struct kdbus_timestamp *ts) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert(bus); @@ -1433,12 +1440,12 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al if (!bus || !bus->is_kernel) return -EOPNOTSUPP; - assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); if (bus->n_memfd_cache <= 0) { int r; - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); r = memfd_new(bus->description); if (r < 0) @@ -1460,7 +1467,7 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al *allocated = c->allocated; fd = c->fd; - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); return fd; } @@ -1484,10 +1491,10 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, si return; } - assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) { - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); close_and_munmap(fd, address, mapped); return; @@ -1507,7 +1514,7 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, si c->allocated = allocated; } - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); } void bus_kernel_flush_memfd(sd_bus *b) { diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index 7234e7926a..cb3c8bbd26 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -19,10 +19,15 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "alloc-util.h" #include "bus-internal.h" -#include "bus-message.h" #include "bus-match.h" +#include "bus-message.h" #include "bus-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "hexdecoct.h" +#include "string-util.h" #include "strv.h" /* Example: @@ -312,7 +317,7 @@ int bus_match_run( /* Run the callback. And then invoke siblings. */ if (node->leaf.callback->callback) { - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; sd_bus_slot *slot; slot = container_of(node->leaf.callback, sd_bus_slot, match_callback); diff --git a/src/libsystemd/sd-bus/bus-match.h b/src/libsystemd/sd-bus/bus-match.h index 53ee0463ca..bc85af3ec0 100644 --- a/src/libsystemd/sd-bus/bus-match.h +++ b/src/libsystemd/sd-bus/bus-match.h @@ -21,10 +21,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "hashmap.h" - #include "sd-bus.h" +#include "hashmap.h" + enum bus_match_node_type { BUS_MATCH_ROOT, BUS_MATCH_VALUE, diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index 72e2b9f785..e939359338 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -23,19 +23,23 @@ #include <fcntl.h> #include <sys/mman.h> -#include "util.h" -#include "utf8.h" -#include "strv.h" -#include "time-util.h" -#include "memfd-util.h" - #include "sd-bus.h" -#include "bus-message.h" + +#include "alloc-util.h" +#include "bus-gvariant.h" #include "bus-internal.h" -#include "bus-type.h" +#include "bus-message.h" #include "bus-signature.h" -#include "bus-gvariant.h" +#include "bus-type.h" #include "bus-util.h" +#include "fd-util.h" +#include "io-util.h" +#include "memfd-util.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" +#include "utf8.h" +#include "util.h" static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored); @@ -798,7 +802,7 @@ _public_ int sd_bus_message_new_method_errorf( const char *format, ...) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; va_list ap; assert_return(name, -EINVAL); @@ -817,7 +821,7 @@ _public_ int sd_bus_message_new_method_errno( int error, const sd_bus_error *p) { - _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL; if (sd_bus_error_is_set(p)) return sd_bus_message_new_method_error(call, m, p); @@ -834,7 +838,7 @@ _public_ int sd_bus_message_new_method_errnof( const char *format, ...) { - _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL; va_list ap; va_start(ap, format); @@ -915,7 +919,9 @@ fail: } _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) { - assert_return(m, NULL); + + if (!m) + return NULL; assert(m->n_ref > 0); m->n_ref++; @@ -5834,7 +5840,7 @@ _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) { } int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { - _cleanup_bus_message_unref_ sd_bus_message *n = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL; usec_t timeout; int r; diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index ff25003461..4c91dbae09 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -21,15 +21,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdbool.h> #include <byteswap.h> +#include <stdbool.h> #include <sys/socket.h> -#include "macro.h" #include "sd-bus.h" -#include "time-util.h" + #include "bus-creds.h" #include "bus-protocol.h" +#include "macro.h" +#include "time-util.h" struct bus_container { char enclosing; diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 1d061cb9cf..4fc5f8dfa3 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -19,16 +19,18 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "strv.h" -#include "set.h" +#include "alloc-util.h" #include "bus-internal.h" +#include "bus-introspect.h" #include "bus-message.h" -#include "bus-type.h" +#include "bus-objects.h" #include "bus-signature.h" -#include "bus-introspect.h" -#include "bus-util.h" #include "bus-slot.h" -#include "bus-objects.h" +#include "bus-type.h" +#include "bus-util.h" +#include "set.h" +#include "string-util.h" +#include "strv.h" static int node_vtable_get_userdata( sd_bus *bus, @@ -270,7 +272,7 @@ static int node_callbacks_run( assert(found_object); LIST_FOREACH(callbacks, c, first) { - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; sd_bus_slot *slot; if (bus->nodes_modified) @@ -355,7 +357,7 @@ static int method_callbacks_run( bool require_fallback, bool *found_object) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *signature; void *u; int r; @@ -578,8 +580,8 @@ static int property_get_set_callbacks_run( bool is_get, bool *found_object) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; sd_bus_slot *slot; void *u = NULL; int r; @@ -779,7 +781,7 @@ static int property_get_all_callbacks_run( const char *iface, bool *found_object) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; struct node_vtable *c; bool found_interface; int r; @@ -802,7 +804,7 @@ static int property_get_all_callbacks_run( streq(iface, "org.freedesktop.DBus.Introspectable"); LIST_FOREACH(vtables, c, first) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; void *u; if (require_fallback && !c->is_fallback) @@ -879,7 +881,7 @@ static int bus_node_exists( } LIST_FOREACH(vtables, c, n->vtables) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; if (require_fallback && !c->is_fallback) continue; @@ -901,8 +903,8 @@ static int process_introspect( bool require_fallback, bool *found_object) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_set_free_free_ Set *s = NULL; const char *previous_interface = NULL; struct introspect intro; @@ -1162,8 +1164,8 @@ static int process_get_managed_objects( bool require_fallback, bool *found_object) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_set_free_free_ Set *s = NULL; Iterator i; char *path; @@ -1578,25 +1580,14 @@ _public_ int sd_bus_add_fallback( return bus_add_object(bus, slot, true, prefix, callback, userdata); } -static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) { +static void vtable_member_hash_func(const void *a, struct siphash *state) { const struct vtable_member *m = a; - uint8_t hash_key2[HASH_KEY_SIZE]; - unsigned long ret; assert(m); - ret = string_hash_func(m->path, hash_key); - - /* Use a slightly different hash key for the interface */ - memcpy(hash_key2, hash_key, HASH_KEY_SIZE); - hash_key2[0]++; - ret ^= string_hash_func(m->interface, hash_key2); - - /* And an even different one for the member */ - hash_key2[0]++; - ret ^= string_hash_func(m->member, hash_key2); - - return ret; + string_hash_func(m->path, state); + string_hash_func(m->interface, state); + string_hash_func(m->member, state); } static int vtable_member_compare_func(const void *a, const void *b) { @@ -1890,8 +1881,8 @@ static int emit_properties_changed_on_interface( bool *found_interface, char **names) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; bool has_invalidating = false, has_changing = false; struct vtable_member key = {}; struct node_vtable *c; @@ -2185,7 +2176,7 @@ static int object_added_append_all_prefix( return 0; LIST_FOREACH(vtables, c, n->vtables) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; void *u = NULL; if (require_fallback && !c->is_fallback) @@ -2314,7 +2305,7 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) { BUS_DONT_DESTROY(bus); - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; struct node *object_manager; int r; @@ -2398,7 +2389,7 @@ static int object_removed_append_all_prefix( return 0; LIST_FOREACH(vtables, c, n->vtables) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; void *u = NULL; if (require_fallback && !c->is_fallback) @@ -2484,7 +2475,7 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { BUS_DONT_DESTROY(bus); - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; struct node *object_manager; int r; @@ -2552,7 +2543,7 @@ static int interfaces_added_append_one_prefix( const char *interface, bool require_fallback) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool found_interface = false; struct node_vtable *c; struct node *n; @@ -2647,7 +2638,7 @@ static int interfaces_added_append_one( _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) { BUS_DONT_DESTROY(bus); - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; struct node *object_manager; char **i; int r; @@ -2731,7 +2722,7 @@ _public_ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const c } _public_ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; struct node *object_manager; int r; diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index b149ea16da..e396d6c3b4 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -20,9 +20,12 @@ ***/ #include "sd-bus.h" + +#include "alloc-util.h" #include "bus-control.h" #include "bus-objects.h" #include "bus-slot.h" +#include "string-util.h" sd_bus_slot *bus_slot_allocate( sd_bus *bus, @@ -54,7 +57,9 @@ sd_bus_slot *bus_slot_allocate( } _public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) { - assert_return(slot, NULL); + + if (!slot) + return NULL; assert(slot->n_ref > 0); diff --git a/src/libsystemd/sd-bus/bus-slot.h b/src/libsystemd/sd-bus/bus-slot.h index 23a15e4d02..c997e58f9a 100644 --- a/src/libsystemd/sd-bus/bus-slot.h +++ b/src/libsystemd/sd-bus/bus-slot.h @@ -22,6 +22,7 @@ ***/ #include "sd-bus.h" + #include "bus-internal.h" sd_bus_slot *bus_slot_allocate(sd_bus *bus, bool floating, BusSlotType type, size_t extra, void *userdata); diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 735a775cb4..1df571ac92 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -20,22 +20,29 @@ ***/ #include <endian.h> +#include <poll.h> #include <stdlib.h> #include <unistd.h> -#include <poll.h> +#include "sd-bus.h" #include "sd-daemon.h" -#include "util.h" -#include "macro.h" -#include "missing.h" -#include "utf8.h" -#include "formats-util.h" -#include "signal-util.h" -#include "sd-bus.h" -#include "bus-socket.h" +#include "alloc-util.h" #include "bus-internal.h" #include "bus-message.h" +#include "bus-socket.h" +#include "fd-util.h" +#include "formats-util.h" +#include "hexdecoct.h" +#include "macro.h" +#include "missing.h" +#include "selinux-util.h" +#include "signal-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "user-util.h" +#include "utf8.h" +#include "util.h" #define SNDBUF_SIZE (8*1024*1024) @@ -602,9 +609,11 @@ static void bus_get_peercred(sd_bus *b) { b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0; /* Get the SELinux context of the peer */ - r = getpeersec(b->input_fd, &b->label); - if (r < 0 && r != -EOPNOTSUPP) - log_debug_errno(r, "Failed to determine peer security context: %m"); + if (mac_selinux_have()) { + r = getpeersec(b->input_fd, &b->label); + if (r < 0 && r != -EOPNOTSUPP) + log_debug_errno(r, "Failed to determine peer security context: %m"); + } } static int bus_socket_start_auth_client(sd_bus *b) { @@ -985,7 +994,7 @@ int bus_socket_read_message(sd_bus *bus) { return -EIO; } - f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n)); + f = realloc(bus->fds, sizeof(int) * (bus->n_fds + n)); if (!f) { close_many((int*) CMSG_DATA(cmsg), n); return -ENOMEM; diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index e43891be25..2f6d7e9452 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -20,9 +20,11 @@ ***/ #include "sd-bus.h" -#include "bus-util.h" + +#include "alloc-util.h" #include "bus-internal.h" #include "bus-track.h" +#include "bus-util.h" struct sd_bus_track { unsigned n_ref; @@ -109,7 +111,9 @@ _public_ int sd_bus_track_new( } _public_ sd_bus_track* sd_bus_track_ref(sd_bus_track *track) { - assert_return(track, NULL); + + if (!track) + return NULL; assert(track->n_ref > 0); @@ -159,7 +163,7 @@ static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus } _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { - _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL; + _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL; _cleanup_free_ char *n = NULL; const char *match; int r; @@ -205,7 +209,7 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { } _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) { - _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL; + _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL; _cleanup_free_ char *n = NULL; assert_return(name, -EINVAL); diff --git a/src/libsystemd/sd-bus/bus-type.h b/src/libsystemd/sd-bus/bus-type.h index 581574ab73..ad89e6c911 100644 --- a/src/libsystemd/sd-bus/bus-type.h +++ b/src/libsystemd/sd-bus/bus-type.h @@ -23,9 +23,10 @@ #include <stdbool.h> -#include "macro.h" #include "sd-bus.h" +#include "macro.h" + bool bus_type_is_valid(char c) _const_; bool bus_type_is_valid_in_signature(char c) _const_; bool bus_type_is_basic(char c) _const_; diff --git a/src/libsystemd/sd-bus/busctl-introspect.c b/src/libsystemd/sd-bus/busctl-introspect.c index abe482fc46..71f962b00c 100644 --- a/src/libsystemd/sd-bus/busctl-introspect.c +++ b/src/libsystemd/sd-bus/busctl-introspect.c @@ -19,11 +19,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "xml.h" -#include "sd-bus-vtable.h" +#include "sd-bus.h" +#include "alloc-util.h" #include "busctl-introspect.h" +#include "string-util.h" +#include "util.h" +#include "xml.h" #define NODE_DEPTH_MAX 16 diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index 9a6d338231..3e66589489 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -21,22 +21,27 @@ #include <getopt.h> -#include "strv.h" -#include "util.h" -#include "log.h" -#include "build.h" -#include "pager.h" -#include "path-util.h" -#include "set.h" - #include "sd-bus.h" -#include "bus-internal.h" -#include "bus-util.h" + +#include "alloc-util.h" #include "bus-dump.h" +#include "bus-internal.h" #include "bus-signature.h" #include "bus-type.h" +#include "bus-util.h" #include "busctl-introspect.h" +#include "escape.h" +#include "fd-util.h" +#include "locale-util.h" +#include "log.h" +#include "pager.h" +#include "parse-util.h" +#include "path-util.h" +#include "set.h" +#include "strv.h" #include "terminal-util.h" +#include "user-util.h" +#include "util.h" static bool arg_no_pager = false; static bool arg_legend = true; @@ -132,7 +137,7 @@ static int list_bus_names(sd_bus *bus, char **argv) { } STRV_FOREACH(i, merged) { - _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; sd_id128_t mid; if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) { @@ -329,8 +334,8 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p .on_path = on_path, }; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *xml; int r; @@ -449,7 +454,7 @@ static int tree(sd_bus *bus, char **argv) { if (not_first) printf("\n"); - printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off()); + printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); q = tree_one(bus, *i, NULL, true); if (q < 0 && r >= 0) @@ -466,7 +471,7 @@ static int tree(sd_bus *bus, char **argv) { if (argv[2]) { pager_open_if_enabled(); - printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off()); + printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); } q = tree_one(bus, *i, NULL, !!argv[2]); @@ -629,22 +634,24 @@ typedef struct Member { uint64_t flags; } Member; -static unsigned long member_hash_func(const void *p, const uint8_t hash_key[]) { +static void member_hash_func(const void *p, struct siphash *state) { const Member *m = p; - unsigned long ul; + uint64_t arity = 1; assert(m); assert(m->type); - ul = string_hash_func(m->type, hash_key); + string_hash_func(m->type, state); + + arity += !!m->name + !!m->interface; + + uint64_hash_func(&arity, state); if (m->name) - ul ^= string_hash_func(m->name, hash_key); + string_hash_func(m->name, state); if (m->interface) - ul ^= string_hash_func(m->interface, hash_key); - - return ul; + string_hash_func(m->interface, state); } static int member_compare_func(const void *a, const void *b) { @@ -860,8 +867,8 @@ static int introspect(sd_bus *bus, char **argv) { .on_property = on_property, }; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(member_set_freep) Set *members = NULL; Iterator i; Member *m; @@ -1052,7 +1059,7 @@ static int introspect(sd_bus *bus, char **argv) { is_interface ? ansi_highlight() : "", is_interface ? "" : ".", - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name), - is_interface ? ansi_highlight_off() : "", + is_interface ? ansi_normal() : "", (int) type_width, strdash(m->type), (int) signature_width, strdash(m->signature), (int) result_width, rv, @@ -1096,6 +1103,15 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL if (r < 0) return log_error_errno(r, "Failed to add match: %m"); + free(m); + m = strjoin("destination='", *i, "'", NULL); + if (!m) + return log_oom(); + + r = sd_bus_add_match(bus, NULL, m, NULL, NULL); + if (r < 0) + return log_error_errno(r, "Failed to add match: %m"); + added_something = true; } @@ -1116,7 +1132,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL log_info("Monitoring bus message stream."); for (;;) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; r = sd_bus_process(bus, &m); if (r < 0) @@ -1166,7 +1182,7 @@ static int capture(sd_bus *bus, char *argv[]) { } static int status(sd_bus *bus, char *argv[]) { - _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; pid_t pid; int r; @@ -1196,15 +1212,15 @@ static int status(sd_bus *bus, char *argv[]) { r = sd_bus_get_address(bus, &address); if (r >= 0) - printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_highlight_off()); + printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_normal()); r = sd_bus_get_scope(bus, &scope); if (r >= 0) - printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_highlight_off()); + printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_normal()); r = sd_bus_get_bus_id(bus, &bus_id); if (r >= 0) - printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_highlight_off()); + printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_normal()); r = sd_bus_get_owner_creds( bus, @@ -1473,8 +1489,8 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char } static int call(sd_bus *bus, char *argv[]) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; int r; assert(bus); @@ -1560,7 +1576,7 @@ static int call(sd_bus *bus, char *argv[]) { } static int get_property(sd_bus *bus, char *argv[]) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; unsigned n; char **i; int r; @@ -1574,7 +1590,7 @@ static int get_property(sd_bus *bus, char *argv[]) { } STRV_FOREACH(i, argv + 4) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; const char *contents = NULL; char type; @@ -1618,8 +1634,8 @@ static int get_property(sd_bus *bus, char *argv[]) { } static int set_property(sd_bus *bus, char *argv[]) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; unsigned n; char **p; int r; @@ -1777,9 +1793,7 @@ static int parse_argv(int argc, char *argv[]) { return help(); case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0; + return version(); case ARG_NO_PAGER: arg_no_pager = true; @@ -1962,7 +1976,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; log_parse_environment(); diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 25fd3b5c52..3c2232a354 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -20,35 +20,40 @@ ***/ #include <endian.h> -#include <stdlib.h> -#include <unistd.h> #include <netdb.h> #include <poll.h> -#include <sys/mman.h> #include <pthread.h> - -#include "util.h" -#include "macro.h" -#include "strv.h" -#include "missing.h" -#include "def.h" -#include "cgroup-util.h" -#include "hostname-util.h" -#include "bus-label.h" +#include <stdlib.h> +#include <sys/mman.h> +#include <unistd.h> #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-container.h" +#include "bus-control.h" #include "bus-internal.h" -#include "bus-message.h" -#include "bus-type.h" -#include "bus-socket.h" #include "bus-kernel.h" -#include "bus-control.h" +#include "bus-label.h" +#include "bus-message.h" #include "bus-objects.h" -#include "bus-util.h" -#include "bus-container.h" #include "bus-protocol.h" -#include "bus-track.h" #include "bus-slot.h" +#include "bus-socket.h" +#include "bus-track.h" +#include "bus-type.h" +#include "bus-util.h" +#include "cgroup-util.h" +#include "def.h" +#include "fd-util.h" +#include "hexdecoct.h" +#include "hostname-util.h" +#include "macro.h" +#include "missing.h" +#include "parse-util.h" +#include "string-util.h" +#include "strv.h" +#include "util.h" #define log_debug_bus_message(m) \ do { \ @@ -69,6 +74,10 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec); static int attach_io_events(sd_bus *b); static void detach_io_events(sd_bus *b); +static thread_local sd_bus *default_system_bus = NULL; +static thread_local sd_bus *default_user_bus = NULL; +static thread_local sd_bus *default_starter_bus = NULL; + static void bus_close_fds(sd_bus *b) { assert(b); @@ -410,7 +419,7 @@ static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *e } static int bus_send_hello(sd_bus *bus) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert(bus); @@ -1471,7 +1480,9 @@ static void bus_enter_closing(sd_bus *bus) { } _public_ sd_bus *sd_bus_ref(sd_bus *bus) { - assert_return(bus, NULL); + + if (!bus) + return NULL; assert_se(REFCNT_INC(bus->n_ref) >= 2); @@ -1725,7 +1736,7 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd } static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) { - _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m); int r; assert_return(m, -EINVAL); @@ -1873,8 +1884,8 @@ _public_ int sd_bus_call_async( void *userdata, uint64_t usec) { - _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); - _cleanup_bus_slot_unref_ sd_bus_slot *s = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m); + _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL; int r; assert_return(m, -EINVAL); @@ -1972,7 +1983,7 @@ _public_ int sd_bus_call( sd_bus_error *error, sd_bus_message **reply) { - _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m); usec_t timeout; uint64_t cookie; unsigned i; @@ -2211,8 +2222,8 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { } static int process_timeout(sd_bus *bus) { - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message* m = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL; struct reply_callback *c; sd_bus_slot *slot; usec_t n; @@ -2293,8 +2304,8 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) { } static int process_reply(sd_bus *bus, sd_bus_message *m) { - _cleanup_bus_message_unref_ sd_bus_message *synthetic_reply = NULL; - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; struct reply_callback *c; sd_bus_slot *slot; int r; @@ -2373,7 +2384,7 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { } static int process_filter(sd_bus *bus, sd_bus_message *m) { - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; struct filter_callback *l; int r; @@ -2439,7 +2450,7 @@ static int process_match(sd_bus *bus, sd_bus_message *m) { } static int process_builtin(sd_bus *bus, sd_bus_message *m) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; assert(bus); @@ -2571,7 +2582,7 @@ static int dispatch_track(sd_bus *bus) { } static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert(bus); @@ -2635,7 +2646,7 @@ null_message: } static int process_closing(sd_bus *bus, sd_bus_message **ret) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; struct reply_callback *c; int r; @@ -2644,7 +2655,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { c = ordered_hashmap_first(bus->reply_callbacks); if (c) { - _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; sd_bus_slot *slot; /* First, fail all outstanding method calls */ @@ -3348,14 +3359,11 @@ static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus } _public_ int sd_bus_default_system(sd_bus **ret) { - static thread_local sd_bus *default_system_bus = NULL; - return bus_default(sd_bus_open_system, &default_system_bus, ret); } -_public_ int sd_bus_default_user(sd_bus **ret) { - static thread_local sd_bus *default_user_bus = NULL; +_public_ int sd_bus_default_user(sd_bus **ret) { return bus_default(sd_bus_open_user, &default_user_bus, ret); } @@ -3382,7 +3390,6 @@ _public_ int sd_bus_default(sd_bus **ret) { e = secure_getenv("DBUS_STARTER_ADDRESS"); if (e) { - static thread_local sd_bus *default_starter_bus = NULL; return bus_default(sd_bus_open, &default_starter_bus, ret); } @@ -3454,6 +3461,171 @@ _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **ext return 1; } +_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) { + _cleanup_strv_free_ char **labels = NULL; + char *path, *path_pos, **label_pos; + const char *sep, *template_pos; + size_t path_length; + va_list list; + int r; + + assert_return(out, -EINVAL); + assert_return(path_template, -EINVAL); + + path_length = strlen(path_template); + + va_start(list, path_template); + for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) { + const char *arg; + char *label; + + arg = va_arg(list, const char *); + if (!arg) { + va_end(list); + return -EINVAL; + } + + label = bus_label_escape(arg); + if (!label) { + va_end(list); + return -ENOMEM; + } + + r = strv_consume(&labels, label); + if (r < 0) { + va_end(list); + return r; + } + + /* add label length, but account for the format character */ + path_length += strlen(label) - 1; + } + va_end(list); + + path = malloc(path_length + 1); + if (!path) + return -ENOMEM; + + path_pos = path; + label_pos = labels; + + for (template_pos = path_template; *template_pos; ) { + sep = strchrnul(template_pos, '%'); + path_pos = mempcpy(path_pos, template_pos, sep - template_pos); + if (!*sep) + break; + + path_pos = stpcpy(path_pos, *label_pos++); + template_pos = sep + 1; + } + + *path_pos = 0; + *out = path; + return 0; +} + +_public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) { + _cleanup_strv_free_ char **labels = NULL; + const char *template_pos, *path_pos; + char **label_pos; + va_list list; + int r; + + /* + * This decodes an object-path based on a template argument. The + * template consists of a verbatim path, optionally including special + * directives: + * + * - Each occurrence of '%' in the template matches an arbitrary + * substring of a label in the given path. At most one such + * directive is allowed per label. For each such directive, the + * caller must provide an output parameter (char **) via va_arg. If + * NULL is passed, the given label is verified, but not returned. + * For each matched label, the *decoded* label is stored in the + * passed output argument, and the caller is responsible to free + * it. Note that the output arguments are only modified if the + * actualy path matched the template. Otherwise, they're left + * untouched. + * + * This function returns <0 on error, 0 if the path does not match the + * template, 1 if it matched. + */ + + assert_return(path, -EINVAL); + assert_return(path_template, -EINVAL); + + path_pos = path; + + for (template_pos = path_template; *template_pos; ) { + const char *sep; + size_t length; + char *label; + + /* verify everything until the next '%' matches verbatim */ + sep = strchrnul(template_pos, '%'); + length = sep - template_pos; + if (strncmp(path_pos, template_pos, length)) + return 0; + + path_pos += length; + template_pos += length; + + if (!*template_pos) + break; + + /* We found the next '%' character. Everything up until here + * matched. We now skip ahead to the end of this label and make + * sure it matches the tail of the label in the path. Then we + * decode the string in-between and save it for later use. */ + + ++template_pos; /* skip over '%' */ + + sep = strchrnul(template_pos, '/'); + length = sep - template_pos; /* length of suffix to match verbatim */ + + /* verify the suffixes match */ + sep = strchrnul(path_pos, '/'); + if (sep - path_pos < (ssize_t)length || + strncmp(sep - length, template_pos, length)) + return 0; + + template_pos += length; /* skip over matched label */ + length = sep - path_pos - length; /* length of sub-label to decode */ + + /* store unescaped label for later use */ + label = bus_label_unescape_n(path_pos, length); + if (!label) + return -ENOMEM; + + r = strv_consume(&labels, label); + if (r < 0) + return r; + + path_pos = sep; /* skip decoded label and suffix */ + } + + /* end of template must match end of path */ + if (*path_pos) + return 0; + + /* copy the labels over to the caller */ + va_start(list, path_template); + for (label_pos = labels; label_pos && *label_pos; ++label_pos) { + char **arg; + + arg = va_arg(list, char **); + if (arg) + *arg = *label_pos; + else + free(*label_pos); + } + va_end(list); + + free(labels); + labels = NULL; + return 1; +} + _public_ int sd_bus_try_close(sd_bus *bus) { int r; @@ -3605,3 +3777,20 @@ _public_ int sd_bus_is_monitor(sd_bus *bus) { return !!(bus->hello_flags & KDBUS_HELLO_MONITOR); } + +static void flush_close(sd_bus *bus) { + if (!bus) + return; + + /* Flushes and closes the specified bus. We take a ref before, + * to ensure the flushing does not cause the bus to be + * unreferenced. */ + + sd_bus_flush_close_unref(sd_bus_ref(bus)); +} + +_public_ void sd_bus_default_flush_close(void) { + flush_close(default_starter_bus); + flush_close(default_user_bus); + flush_close(default_system_bus); +} diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c index d14110aa04..3a88bf59c7 100644 --- a/src/libsystemd/sd-bus/test-bus-benchmark.c +++ b/src/libsystemd/sd-bus/test-bus-benchmark.c @@ -21,14 +21,16 @@ #include <sys/wait.h> -#include "def.h" -#include "util.h" -#include "time-util.h" - #include "sd-bus.h" -#include "bus-kernel.h" + +#include "alloc-util.h" #include "bus-internal.h" +#include "bus-kernel.h" #include "bus-util.h" +#include "def.h" +#include "fd-util.h" +#include "time-util.h" +#include "util.h" #define MAX_SIZE (2*1024*1024) @@ -44,7 +46,7 @@ static void server(sd_bus *b, size_t *result) { int r; for (;;) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; r = sd_bus_process(b, &m); assert_se(r >= 0); @@ -78,7 +80,7 @@ static void server(sd_bus *b, size_t *result) { } static void transaction(sd_bus *b, size_t sz, const char *server_name) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; uint8_t *p; assert_se(sd_bus_message_new_method_call(b, &m, server_name, "/", "benchmark.server", "Work") >= 0); @@ -90,7 +92,7 @@ static void transaction(sd_bus *b, size_t sz, const char *server_name) { } static void client_bisect(const char *address, const char *server_name) { - _cleanup_bus_message_unref_ sd_bus_message *x = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *x = NULL; size_t lsize, rsize, csize; sd_bus *b; int r; @@ -164,7 +166,7 @@ static void client_bisect(const char *address, const char *server_name) { } static void client_chart(Type type, const char *address, const char *server_name, int fd) { - _cleanup_bus_message_unref_ sd_bus_message *x = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *x = NULL; size_t csize; sd_bus *b; int r; diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 20f1b532b7..b07e348fdb 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -19,21 +19,23 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> +#include <fcntl.h> #include <pthread.h> +#include <stdlib.h> #include <unistd.h> -#include <fcntl.h> - -#include "log.h" -#include "util.h" -#include "macro.h" -#include "formats-util.h" #include "sd-bus.h" + +#include "alloc-util.h" #include "bus-error.h" -#include "bus-match.h" #include "bus-internal.h" +#include "bus-match.h" #include "bus-util.h" +#include "fd-util.h" +#include "formats-util.h" +#include "log.h" +#include "macro.h" +#include "util.h" static int match_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m))); @@ -128,7 +130,7 @@ static int server(sd_bus *bus) { bool client1_gone = false, client2_gone = false; while (!client1_gone || !client2_gone) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; pid_t pid = 0; const char *label = NULL; @@ -259,9 +261,9 @@ fail: } static void* client1(void*p) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *hello; int r; _cleanup_close_pair_ int pp[2] = { -1, -1 }; @@ -329,7 +331,7 @@ static void* client1(void*p) { finish: if (bus) { - _cleanup_bus_message_unref_ sd_bus_message *q; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *q; r = sd_bus_message_new_method_call( bus, @@ -358,9 +360,9 @@ static int quit_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_er } static void* client2(void*p) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool quit = false; const char *mid; int r; @@ -497,7 +499,7 @@ static void* client2(void*p) { finish: if (bus) { - _cleanup_bus_message_unref_ sd_bus_message *q; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *q; r = sd_bus_message_new_method_call( bus, diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c index f586880593..cbc450fdb2 100644 --- a/src/libsystemd/sd-bus/test-bus-cleanup.c +++ b/src/libsystemd/sd-bus/test-bus-cleanup.c @@ -22,20 +22,21 @@ #include <stdio.h> #include "sd-bus.h" -#include "bus-util.h" + #include "bus-internal.h" #include "bus-message.h" +#include "bus-util.h" #include "refcnt.h" static void test_bus_new(void) { - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; assert_se(sd_bus_new(&bus) == 0); printf("after new: refcount %u\n", REFCNT_GET(bus->n_ref)); } static int test_bus_open(void) { - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; r = sd_bus_open_system(&bus); @@ -50,7 +51,7 @@ static int test_bus_open(void) { static void test_bus_new_method_call(void) { sd_bus *bus = NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; assert_se(sd_bus_open_system(&bus) >= 0); @@ -58,13 +59,13 @@ static void test_bus_new_method_call(void) { printf("after message_new_method_call: refcount %u\n", REFCNT_GET(bus->n_ref)); - sd_bus_unref(bus); - printf("after bus_unref: refcount %u\n", m->n_ref); + sd_bus_flush_close_unref(bus); + printf("after bus_flush_close_unref: refcount %u\n", m->n_ref); } static void test_bus_new_signal(void) { sd_bus *bus = NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; assert_se(sd_bus_open_system(&bus) >= 0); @@ -72,8 +73,8 @@ static void test_bus_new_signal(void) { printf("after message_new_signal: refcount %u\n", REFCNT_GET(bus->n_ref)); - sd_bus_unref(bus); - printf("after bus_unref: refcount %u\n", m->n_ref); + sd_bus_flush_close_unref(bus); + printf("after bus_flush_close_unref: refcount %u\n", m->n_ref); } int main(int argc, char **argv) { diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c index 580117165a..8003501059 100644 --- a/src/libsystemd/sd-bus/test-bus-creds.c +++ b/src/libsystemd/sd-bus/test-bus-creds.c @@ -20,15 +20,16 @@ ***/ #include "sd-bus.h" + #include "bus-dump.h" #include "bus-util.h" #include "cgroup-util.h" int main(int argc, char *argv[]) { - _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; int r; - if (cg_unified() == -ENOEXEC) { + if (cg_unified() == -ENOMEDIUM) { puts("Skipping test: /sys/fs/cgroup/ not available"); return EXIT_TEST_SKIP; } diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index 5753c04b0e..407fd14555 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -20,13 +20,14 @@ ***/ #include "sd-bus.h" + +#include "bus-common-errors.h" #include "bus-error.h" #include "bus-util.h" #include "errno-list.h" -#include "bus-common-errors.h" static void test_error(void) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL; const sd_bus_error const_error = SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FILE_EXISTS, "const error"); const sd_bus_error temporarily_const_error = { .name = SD_BUS_ERROR_ACCESS_DENIED, @@ -43,7 +44,15 @@ static void test_error(void) { assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); + /* Check with no error */ + assert_se(!sd_bus_error_is_set(&error)); + assert_se(sd_bus_error_setf(&error, NULL, "yyy %i", -1) == 0); + assert_se(error.name == NULL); + assert_se(error.message == NULL); + assert_se(!sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND)); + assert_se(sd_bus_error_get_errno(&error) == 0); assert_se(!sd_bus_error_is_set(&error)); + assert_se(sd_bus_error_setf(&error, SD_BUS_ERROR_FILE_NOT_FOUND, "yyy %i", -1) == -ENOENT); assert_se(streq(error.name, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(streq(error.message, "yyy -1")); @@ -111,6 +120,16 @@ static void test_error(void) { assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR)); assert_se(sd_bus_error_get_errno(&error) == EIO); assert_se(sd_bus_error_is_set(&error)); + sd_bus_error_free(&error); + + /* Check with no error */ + assert_se(!sd_bus_error_is_set(&error)); + assert_se(sd_bus_error_set_errnof(&error, 0, "Waldi %c", 'X') == 0); + assert_se(error.name == NULL); + assert_se(error.message == NULL); + assert_se(!sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR)); + assert_se(sd_bus_error_get_errno(&error) == 0); + assert_se(!sd_bus_error_is_set(&error)); } extern const sd_bus_error_map __start_BUS_ERROR_MAP[]; @@ -166,6 +185,16 @@ static const sd_bus_error_map test_errors4[] = { SD_BUS_ERROR_MAP_END }; +static const sd_bus_error_map test_errors_bad1[] = { + SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-1", 0), + SD_BUS_ERROR_MAP_END +}; + +static const sd_bus_error_map test_errors_bad2[] = { + SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-1", -1), + SD_BUS_ERROR_MAP_END +}; + static void test_errno_mapping_custom(void) { assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error", NULL) == -5); assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-2", NULL) == -52); @@ -189,6 +218,9 @@ static void test_errno_mapping_custom(void) { assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-y", NULL) == -EIO); assert_se(sd_bus_error_set(NULL, BUS_ERROR_NO_SUCH_UNIT, NULL) == -ENOENT); + + assert_se(sd_bus_error_add_map(test_errors_bad1) == -EINVAL); + assert_se(sd_bus_error_add_map(test_errors_bad2) == -EINVAL); } int main(int argc, char *argv[]) { diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c index b078bdc5f6..2d8e9d2f28 100644 --- a/src/libsystemd/sd-bus/test-bus-gvariant.c +++ b/src/libsystemd/sd-bus/test-bus-gvariant.c @@ -23,14 +23,16 @@ #include <glib.h> #endif -#include "util.h" -#include "macro.h" #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-dump.h" #include "bus-gvariant.h" -#include "bus-util.h" #include "bus-internal.h" #include "bus-message.h" -#include "bus-dump.h" +#include "bus-util.h" +#include "macro.h" +#include "util.h" static void test_bus_gvariant_is_fixed_size(void) { assert_se(bus_gvariant_is_fixed_size("") > 0); @@ -131,8 +133,8 @@ static void test_bus_gvariant_get_alignment(void) { } static void test_marshal(void) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *n = NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *n = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_free_ void *blob; size_t sz; int r; diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c index f39dedeb24..26ba16d119 100644 --- a/src/libsystemd/sd-bus/test-bus-introspect.c +++ b/src/libsystemd/sd-bus/test-bus-introspect.c @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "log.h" #include "bus-introspect.h" +#include "log.h" static int prop_get(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) { return -EINVAL; diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c index f3d1099dd2..0e957253c0 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c +++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c @@ -19,12 +19,14 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "log.h" - #include "sd-bus.h" + +#include "alloc-util.h" #include "bus-kernel.h" #include "bus-util.h" +#include "fd-util.h" +#include "log.h" +#include "util.h" static int test_match(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { int *found = userdata; @@ -45,7 +47,7 @@ static void test_one( _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; sd_bus *a, *b; int r, found = 0; diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c index 6506eaab2e..6163c7784e 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel.c +++ b/src/libsystemd/sd-bus/test-bus-kernel.c @@ -21,19 +21,21 @@ #include <fcntl.h> -#include "util.h" -#include "log.h" - #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-dump.h" #include "bus-kernel.h" #include "bus-util.h" -#include "bus-dump.h" +#include "fd-util.h" +#include "log.h" +#include "util.h" int main(int argc, char *argv[]) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL, *bname = NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *ua = NULL, *ub = NULL, *the_string = NULL; sd_bus *a, *b; int r, pipe_fds[2]; diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c index b203707f27..b9d1ea5217 100644 --- a/src/libsystemd/sd-bus/test-bus-marshal.c +++ b/src/libsystemd/sd-bus/test-bus-marshal.c @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> #include <math.h> +#include <stdlib.h> #ifdef HAVE_GLIB #include <gio/gio.h> @@ -30,14 +30,17 @@ #include <dbus/dbus.h> #endif -#include "log.h" -#include "util.h" - #include "sd-bus.h" -#include "bus-message.h" -#include "bus-util.h" + +#include "alloc-util.h" #include "bus-dump.h" #include "bus-label.h" +#include "bus-message.h" +#include "bus-util.h" +#include "fd-util.h" +#include "hexdecoct.h" +#include "log.h" +#include "util.h" static void test_bus_path_encode_unique(void) { _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL; @@ -66,6 +69,36 @@ static void test_bus_path_encode(void) { assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar")); } +static void test_bus_path_encode_many(void) { + _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL; + + assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL) == 0); + assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL) == 1); + assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL) == 0); + assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a) == 1 && streq_ptr(a, "foobar")); + assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", &b, &c) == 1 && streq_ptr(b, "foo") && streq_ptr(c, "bar")); + assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", NULL, &d) == 1 && streq_ptr(d, "bar")); + + assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL, NULL) == 0); /* multiple '%' are treated verbatim */ + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e) == 1 && streq_ptr(e, "bar")); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL, NULL) == 1); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL, NULL, NULL) == 1); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL, NULL, NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL, NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL, NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL) == 0); + assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL) == 0); + + assert_se(sd_bus_path_encode_many(&f, "/prefix/one_%_two/mid/three_%_four/suffix", "foo", "bar") >= 0 && streq_ptr(f, "/prefix/one_foo_two/mid/three_bar_four/suffix")); +} + static void test_bus_label_escape_one(const char *a, const char *b) { _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL; @@ -90,7 +123,7 @@ static void test_bus_label_escape(void) { } int main(int argc, char *argv[]) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *copy = NULL; int r, boolean; const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature; uint8_t u, v; @@ -102,7 +135,7 @@ int main(int argc, char *argv[]) { _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL; _cleanup_fclose_ FILE *ms = NULL; size_t first_size = 0, second_size = 0, third_size = 0; - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; double dbl; uint64_t u64; @@ -213,6 +246,8 @@ int main(int argc, char *argv[]) { log_error("%s", error.message); else dbus_message_unref(w); + + dbus_error_free(&error); } #endif @@ -393,6 +428,7 @@ int main(int argc, char *argv[]) { test_bus_label_escape(); test_bus_path_encode(); test_bus_path_encode_unique(); + test_bus_path_encode_many(); return 0; } diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c index 75ea28371b..97ef396c6b 100644 --- a/src/libsystemd/sd-bus/test-bus-match.c +++ b/src/libsystemd/sd-bus/test-bus-match.c @@ -19,13 +19,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "log.h" -#include "macro.h" - #include "bus-match.h" #include "bus-message.h" -#include "bus-util.h" #include "bus-slot.h" +#include "bus-util.h" +#include "log.h" +#include "macro.h" static bool mask[32]; @@ -91,8 +90,8 @@ int main(int argc, char *argv[]) { .type = BUS_MATCH_ROOT, }; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; enum bus_match_node_type i; sd_bus_slot slots[19]; int r; diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c index 0a35b750b3..0dd248552c 100644 --- a/src/libsystemd/sd-bus/test-bus-objects.c +++ b/src/libsystemd/sd-bus/test-bus-objects.c @@ -19,19 +19,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> #include <pthread.h> - -#include "log.h" -#include "util.h" -#include "macro.h" -#include "strv.h" +#include <stdlib.h> #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-dump.h" #include "bus-internal.h" #include "bus-message.h" #include "bus-util.h" -#include "bus-dump.h" +#include "log.h" +#include "macro.h" +#include "strv.h" +#include "util.h" struct context { int fds[2]; @@ -296,9 +297,9 @@ fail: } static int client(struct context *c) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_unref_ sd_bus *bus = NULL; - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *s; int r; diff --git a/src/libsystemd/sd-bus/test-bus-proxy.c b/src/libsystemd/sd-bus/test-bus-proxy.c index aef768dc18..42fa3e6293 100644 --- a/src/libsystemd/sd-bus/test-bus-proxy.c +++ b/src/libsystemd/sd-bus/test-bus-proxy.c @@ -23,13 +23,14 @@ #include <fcntl.h> #include <stdlib.h> -#include "util.h" -#include "log.h" - #include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-dump.h" #include "bus-kernel.h" #include "bus-util.h" -#include "bus-dump.h" +#include "log.h" +#include "util.h" typedef struct { const char *sender; @@ -52,7 +53,7 @@ static int test_proxy_acquired(sd_bus_message *m, void *userdata, sd_bus_error * } static void test_proxy_matched(void) { - _cleanup_bus_flush_close_unref_ sd_bus *a = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *a = NULL; _cleanup_free_ char *matchstr = NULL; TestProxyMatch match = {}; const char *me; diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c index 080d8eddb7..bd89780346 100644 --- a/src/libsystemd/sd-bus/test-bus-server.c +++ b/src/libsystemd/sd-bus/test-bus-server.c @@ -19,16 +19,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> #include <pthread.h> - -#include "log.h" -#include "util.h" -#include "macro.h" +#include <stdlib.h> #include "sd-bus.h" + #include "bus-internal.h" #include "bus-util.h" +#include "log.h" +#include "macro.h" +#include "util.h" struct context { int fds[2]; @@ -57,7 +57,7 @@ static void *server(void *p) { assert_se(sd_bus_start(bus) >= 0); while (!quit) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; r = sd_bus_process(bus, &m); if (r < 0) { @@ -124,8 +124,8 @@ fail: } static int client(struct context *c) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; int r; diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c index 17c6188ca0..949d16e6e9 100644 --- a/src/libsystemd/sd-bus/test-bus-signature.c +++ b/src/libsystemd/sd-bus/test-bus-signature.c @@ -19,10 +19,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ - -#include "log.h" -#include "bus-signature.h" #include "bus-internal.h" +#include "bus-signature.h" +#include "log.h" +#include "string-util.h" int main(int argc, char *argv[]) { char prefix[256]; diff --git a/src/libsystemd/sd-bus/test-bus-zero-copy.c b/src/libsystemd/sd-bus/test-bus-zero-copy.c index 2d062fc9b5..1cf8416fa4 100644 --- a/src/libsystemd/sd-bus/test-bus-zero-copy.c +++ b/src/libsystemd/sd-bus/test-bus-zero-copy.c @@ -21,14 +21,17 @@ #include <sys/mman.h> -#include "util.h" -#include "log.h" -#include "memfd-util.h" - #include "sd-bus.h" -#include "bus-message.h" -#include "bus-kernel.h" + +#include "alloc-util.h" #include "bus-dump.h" +#include "bus-kernel.h" +#include "bus-message.h" +#include "fd-util.h" +#include "log.h" +#include "memfd-util.h" +#include "string-util.h" +#include "util.h" #define FIRST_ARRAY 17 #define SECOND_ARRAY 33 diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 9ec73406c6..f1e9b7ed1b 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -19,29 +19,46 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <stdlib.h> #include <errno.h> -#include <unistd.h> -#include <string.h> -#include <stdarg.h> -#include <stdio.h> -#include <stddef.h> #include <limits.h> #include <mqueue.h> +#include <netinet/in.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/un.h> +#include <unistd.h> -#include "util.h" +#include "sd-daemon.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "fs-util.h" +#include "parse-util.h" #include "path-util.h" #include "socket-util.h" -#include "sd-daemon.h" +#include "strv.h" +#include "util.h" + +#define SNDBUF_SIZE (8*1024*1024) + +static void unsetenv_all(bool unset_environment) { + + if (!unset_environment) + return; + + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); + unsetenv("LISTEN_FDNAMES"); +} _public_ int sd_listen_fds(int unset_environment) { const char *e; - unsigned n; - int r, fd; + int n, r, fd; pid_t pid; e = getenv("LISTEN_PID"); @@ -66,25 +83,68 @@ _public_ int sd_listen_fds(int unset_environment) { goto finish; } - r = safe_atou(e, &n); + r = safe_atoi(e, &n); if (r < 0) goto finish; - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) n; fd ++) { + assert_cc(SD_LISTEN_FDS_START < INT_MAX); + if (n <= 0 || n > INT_MAX - SD_LISTEN_FDS_START) { + r = -EINVAL; + goto finish; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) { r = fd_cloexec(fd, true); if (r < 0) goto finish; } - r = (int) n; + r = n; finish: - if (unset_environment) { - unsetenv("LISTEN_PID"); - unsetenv("LISTEN_FDS"); + unsetenv_all(unset_environment); + return r; +} + +_public_ int sd_listen_fds_with_names(int unset_environment, char ***names) { + _cleanup_strv_free_ char **l = NULL; + bool have_names; + int n_names = 0, n_fds; + const char *e; + int r; + + if (!names) + return sd_listen_fds(unset_environment); + + e = getenv("LISTEN_FDNAMES"); + if (e) { + n_names = strv_split_extract(&l, e, ":", EXTRACT_DONT_COALESCE_SEPARATORS); + if (n_names < 0) { + unsetenv_all(unset_environment); + return n_names; + } + + have_names = true; + } else + have_names = false; + + n_fds = sd_listen_fds(unset_environment); + if (n_fds <= 0) + return n_fds; + + if (have_names) { + if (n_names != n_fds) + return -EINVAL; + } else { + r = strv_extend_n(&l, "unknown", n_fds); + if (r < 0) + return r; } - return r; + *names = l; + l = NULL; + + return n_fds; } _public_ int sd_is_fifo(int fd, const char *path) { @@ -310,10 +370,15 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path _public_ int sd_is_mq(int fd, const char *path) { struct mq_attr attr; - assert_return(fd >= 0, -EBADF); + /* Check that the fd is valid */ + assert_return(fcntl(fd, F_GETFD) >= 0, -errno); - if (mq_getattr(fd, &attr) < 0) + if (mq_getattr(fd, &attr) < 0) { + if (errno == EBADF) + /* A non-mq fd (or an invalid one, but we ruled that out above) */ + return 0; return -errno; + } if (path) { char fpath[PATH_MAX]; @@ -376,12 +441,19 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char goto finish; } + if (strlen(e) > sizeof(sockaddr.un.sun_path)) { + r = -EINVAL; + goto finish; + } + fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); if (fd < 0) { r = -errno; goto finish; } + fd_inc_sndbuf(fd, SNDBUF_SIZE); + iovec.iov_len = strlen(state); strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); @@ -396,9 +468,11 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char if (n_fds > 0 || have_pid) { /* CMSG_SPACE(0) may return value different then zero, which results in miscalculated controllen. */ - msghdr.msg_controllen = (n_fds ? CMSG_SPACE(sizeof(int) * n_fds) : 0) + - CMSG_SPACE(sizeof(struct ucred)) * have_pid; - msghdr.msg_control = alloca(msghdr.msg_controllen); + msghdr.msg_controllen = + (n_fds > 0 ? CMSG_SPACE(sizeof(int) * n_fds) : 0) + + (have_pid ? CMSG_SPACE(sizeof(struct ucred)) : 0); + + msghdr.msg_control = alloca0(msghdr.msg_controllen); cmsg = CMSG_FIRSTHDR(&msghdr); if (n_fds > 0) { @@ -498,16 +572,11 @@ _public_ int sd_notifyf(int unset_environment, const char *format, ...) { } _public_ int sd_booted(void) { - struct stat st; - /* We test whether the runtime unit file directory has been * created. This takes place in mount-setup.c, so is * guaranteed to happen very early during boot. */ - if (lstat("/run/systemd/system/", &st) < 0) - return 0; - - return !!S_ISDIR(st.st_mode); + return laccess("/run/systemd/system/", F_OK) >= 0; } _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) { @@ -522,7 +591,7 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) { r = safe_atou64(s, &u); if (r < 0) goto finish; - if (u <= 0) { + if (u <= 0 || u >= USEC_INFINITY) { r = -EINVAL; goto finish; } diff --git a/src/libsystemd/sd-device/Makefile b/src/libsystemd/sd-device/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/sd-device/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 5eb37e16cb..4a7a8b1f9e 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -18,15 +18,18 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "prioq.h" -#include "strv.h" -#include "set.h" - #include "sd-device.h" -#include "device-util.h" +#include "alloc-util.h" #include "device-enumerator-private.h" +#include "device-util.h" +#include "dirent-util.h" +#include "fd-util.h" +#include "prioq.h" +#include "set.h" +#include "string-util.h" +#include "strv.h" +#include "util.h" #define DEVICE_ENUMERATE_MAX_DEPTH 256 @@ -56,7 +59,7 @@ struct sd_device_enumerator { }; _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) { - _cleanup_device_enumerator_unref_ sd_device_enumerator *enumerator = NULL; + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *enumerator = NULL; assert(ret); @@ -484,7 +487,7 @@ static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator, return -errno; FOREACH_DIRENT_ALL(dent, dir, return -errno) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; char syspath[strlen(path) + 1 + strlen(dent->d_name) + 1]; dev_t devnum; int ifindex, initialized, k; @@ -637,7 +640,7 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c /* TODO: filter away subsystems? */ FOREACH_DIRENT_ALL(dent, dir, return -errno) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; const char *subsystem, *sysname; int k; @@ -707,7 +710,7 @@ static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) { } static int parent_add_child(sd_device_enumerator *enumerator, const char *path) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; const char *subsystem, *sysname; int r; @@ -812,10 +815,8 @@ static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) { if (access("/sys/subsystem", F_OK) >= 0) { /* we have /subsystem/, forget all the old stuff */ r = enumerator_scan_dir(enumerator, "subsystem", "devices", NULL); - if (r < 0) { - log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "device-enumerator: failed to scan /sys/subsystem: %m"); } else { int k; diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index 0ec9667744..f2af3ab3ae 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -19,25 +19,31 @@ ***/ #include <ctype.h> -#include <sys/types.h> #include <net/if.h> - -#include "util.h" -#include "macro.h" -#include "refcnt.h" -#include "path-util.h" -#include "strxcpyx.h" -#include "fileio.h" -#include "hashmap.h" -#include "set.h" -#include "strv.h" -#include "mkdir.h" +#include <sys/types.h> #include "sd-device.h" -#include "device-util.h" +#include "alloc-util.h" #include "device-internal.h" #include "device-private.h" +#include "device-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "hashmap.h" +#include "macro.h" +#include "mkdir.h" +#include "parse-util.h" +#include "path-util.h" +#include "refcnt.h" +#include "set.h" +#include "string-table.h" +#include "string-util.h" +#include "strv.h" +#include "strxcpyx.h" +#include "user-util.h" +#include "util.h" int device_add_property(sd_device *device, const char *key, const char *value) { int r; @@ -200,10 +206,8 @@ static int device_read_db(sd_device *device) { if (r < 0) { if (r == -ENOENT) return 0; - else { - log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r)); - return r; - } + else + return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path); } /* devices with a database entry are initialized */ @@ -247,7 +251,7 @@ static int device_read_db(sd_device *device) { db[i] = '\0'; r = handle_db_line(device, key, value); if (r < 0) - log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r)); + log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value); state = PRE_KEY; } @@ -549,7 +553,7 @@ static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum } int device_new_from_strv(sd_device **ret, char **strv) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; char **key; const char *major = NULL, *minor = NULL; DeviceAction action = _DEVICE_ACTION_INVALID; @@ -586,7 +590,7 @@ int device_new_from_strv(sd_device **ret, char **strv) { } int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; const char *major = NULL, *minor = NULL; DeviceAction action = _DEVICE_ACTION_INVALID; uint64_t seqnum; @@ -789,7 +793,7 @@ int device_rename(sd_device *device, const char *name) { } int device_shallow_clone(sd_device *old_device, sd_device **new_device) { - _cleanup_device_unref_ sd_device *ret = NULL; + _cleanup_(sd_device_unrefp) sd_device *ret = NULL; int r; assert(old_device); @@ -816,7 +820,7 @@ int device_shallow_clone(sd_device *old_device, sd_device **new_device) { } int device_clone_with_db(sd_device *old_device, sd_device **new_device) { - _cleanup_device_unref_ sd_device *ret = NULL; + _cleanup_(sd_device_unrefp) sd_device *ret = NULL; int r; assert(old_device); @@ -839,7 +843,7 @@ int device_clone_with_db(sd_device *old_device, sd_device **new_device) { } int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) { - _cleanup_device_unref_ sd_device *ret = NULL; + _cleanup_(sd_device_unrefp) sd_device *ret = NULL; int r; assert(new_device); diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index 49a7b66a2b..d1f34efc2d 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -21,6 +21,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <inttypes.h> +#include <stdbool.h> +#include <sys/types.h> + +#include "sd-device.h" + int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len); int device_new_from_strv(sd_device **ret, char **strv); diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index 9b05a2498d..ba9edc61ce 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -23,12 +23,6 @@ #include "util.h" -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_device*, sd_device_unref); -#define _cleanup_device_unref_ _cleanup_(sd_device_unrefp) - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_device_enumerator*, sd_device_enumerator_unref); -#define _cleanup_device_enumerator_unref_ _cleanup_(sd_device_enumerator_unrefp) - #define FOREACH_DEVICE_PROPERTY(device, key, value) \ for (key = sd_device_get_property_first(device, &(value)); \ key; \ diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 7cea5a0746..9633e46ce0 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -19,26 +19,31 @@ ***/ #include <ctype.h> -#include <sys/types.h> #include <net/if.h> +#include <sys/types.h> -#include "util.h" -#include "macro.h" -#include "path-util.h" -#include "strxcpyx.h" +#include "sd-device.h" + +#include "alloc-util.h" +#include "device-internal.h" +#include "device-private.h" +#include "device-util.h" +#include "fd-util.h" #include "fileio.h" +#include "fs-util.h" #include "hashmap.h" +#include "macro.h" +#include "parse-util.h" +#include "path-util.h" #include "set.h" +#include "stat-util.h" +#include "string-util.h" #include "strv.h" - -#include "sd-device.h" - -#include "device-util.h" -#include "device-private.h" -#include "device-internal.h" +#include "strxcpyx.h" +#include "util.h" int device_new_aux(sd_device **ret) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; assert(ret); @@ -169,11 +174,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { /* the device does not exist (any more?) */ return -ENODEV; - log_debug("sd-device: could not canonicalize '%s': %m", _syspath); - return -errno; + return log_debug_errno(errno, "sd-device: could not canonicalize '%s': %m", _syspath); } } else if (r < 0) { - log_debug("sd-device: could not get target of '%s': %s", _syspath, strerror(-r)); + log_debug_errno(r, "sd-device: could not get target of '%s': %m", _syspath); return r; } @@ -218,7 +222,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { } _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; assert_return(ret, -EINVAL); @@ -296,15 +300,27 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s } else return -EINVAL; } else { - syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", sysname); + char *name; + size_t len = 0; + + /* translate sysname back to sysfs filename */ + name = strdupa(sysname); + while (name[len] != '\0') { + if (name[len] == '/') + name[len] = '!'; + + len ++; + } + + syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", name); if (access(syspath, F_OK) >= 0) return sd_device_new_from_syspath(ret, syspath); - syspath = strjoina("/sys/bus/", subsystem, "/devices/", sysname); + syspath = strjoina("/sys/bus/", subsystem, "/devices/", name); if (access(syspath, F_OK) >= 0) return sd_device_new_from_syspath(ret, syspath); - syspath = strjoina("/sys/class/", subsystem, "/", sysname); + syspath = strjoina("/sys/class/", subsystem, "/", name); if (access(syspath, F_OK) >= 0) return sd_device_new_from_syspath(ret, syspath); } @@ -340,13 +356,10 @@ int device_set_ifindex(sd_device *device, const char *_ifindex) { assert(device); assert(_ifindex); - r = safe_atoi(_ifindex, &ifindex); + r = parse_ifindex(_ifindex, &ifindex); if (r < 0) return r; - if (ifindex <= 0) - return -EINVAL; - r = device_add_property_internal(device, "IFINDEX", _ifindex); if (r < 0) return r; @@ -481,7 +494,7 @@ static int handle_uevent_line(sd_device *device, const char *key, const char *va int device_read_uevent_file(sd_device *device) { _cleanup_free_ char *uevent = NULL; - const char *syspath, *key, *value, *major = NULL, *minor = NULL; + const char *syspath, *key = NULL, *value = NULL, *major = NULL, *minor = NULL; char *path; size_t uevent_len; unsigned i; @@ -516,7 +529,7 @@ int device_read_uevent_file(sd_device *device) { /* some devices may not have uevent files, see set_syspath() */ return 0; else if (r < 0) { - log_debug("sd-device: failed to read uevent file '%s': %s", path, strerror(-r)); + log_debug_errno(r, "sd-device: failed to read uevent file '%s': %m", path); return r; } @@ -555,7 +568,7 @@ int device_read_uevent_file(sd_device *device) { r = handle_uevent_line(device, key, value, &major, &minor); if (r < 0) - log_debug("sd-device: failed to handle uevent entry '%s=%s': %s", key, value, strerror(-r)); + log_debug_errno(r, "sd-device: failed to handle uevent entry '%s=%s': %m", key, value); state = PRE_KEY; } @@ -569,7 +582,7 @@ int device_read_uevent_file(sd_device *device) { if (major) { r = device_set_devnum(device, major, minor); if (r < 0) - log_debug("sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %s", major, minor, path, strerror(-r)); + log_debug_errno(r, "sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %m", major, minor, path); } return 0; @@ -611,16 +624,14 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) { } case 'n': { - _cleanup_device_unref_ sd_device *device = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; _cleanup_close_ int sk = -1; struct ifreq ifr = {}; int ifindex; - r = safe_atoi(&id[1], &ifr.ifr_ifindex); + r = parse_ifindex(&id[1], &ifr.ifr_ifindex); if (r < 0) return r; - else if (ifr.ifr_ifindex <= 0) - return -EINVAL; sk = socket(PF_INET, SOCK_DGRAM, 0); if (sk < 0) @@ -1271,10 +1282,8 @@ int device_read_db_aux(sd_device *device, bool force) { if (r < 0) { if (r == -ENOENT) return 0; - else { - log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r)); - return r; - } + else + return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path); } /* devices with a database entry are initialized */ @@ -1318,7 +1327,7 @@ int device_read_db_aux(sd_device *device, bool force) { db[i] = '\0'; r = handle_db_line(device, key, value); if (r < 0) - log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r)); + log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value); state = PRE_KEY; } diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h deleted file mode 100644 index e7cad9be46..0000000000 --- a/src/libsystemd/sd-event/event-util.h +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "util.h" -#include "sd-event.h" - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event*, sd_event_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, sd_event_source_unref); - -#define _cleanup_event_unref_ _cleanup_(sd_event_unrefp) -#define _cleanup_event_source_unref_ _cleanup_(sd_event_source_unrefp) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index fd39a56225..11c7330b9b 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -23,19 +23,24 @@ #include <sys/timerfd.h> #include <sys/wait.h> -#include "sd-id128.h" #include "sd-daemon.h" -#include "macro.h" -#include "prioq.h" +#include "sd-event.h" +#include "sd-id128.h" + +#include "alloc-util.h" +#include "fd-util.h" #include "hashmap.h" -#include "util.h" -#include "time-util.h" +#include "list.h" +#include "macro.h" #include "missing.h" +#include "prioq.h" +#include "process-util.h" #include "set.h" -#include "list.h" #include "signal-util.h" - -#include "sd-event.h" +#include "string-table.h" +#include "string-util.h" +#include "time-util.h" +#include "util.h" #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC) @@ -56,6 +61,23 @@ typedef enum EventSourceType { _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 } EventSourceType; +static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = { + [SOURCE_IO] = "io", + [SOURCE_TIME_REALTIME] = "realtime", + [SOURCE_TIME_BOOTTIME] = "bootime", + [SOURCE_TIME_MONOTONIC] = "monotonic", + [SOURCE_TIME_REALTIME_ALARM] = "realtime-alarm", + [SOURCE_TIME_BOOTTIME_ALARM] = "boottime-alarm", + [SOURCE_SIGNAL] = "signal", + [SOURCE_CHILD] = "child", + [SOURCE_DEFER] = "defer", + [SOURCE_POST] = "post", + [SOURCE_EXIT] = "exit", + [SOURCE_WATCHDOG] = "watchdog", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int); + /* All objects we use in epoll events start with this value, so that * we know how to dispatch it */ typedef enum WakeupType { @@ -203,6 +225,7 @@ struct sd_event { bool exit_requested:1; bool need_process_child:1; bool watchdog:1; + bool profile_delays:1; int exit_code; @@ -214,6 +237,9 @@ struct sd_event { unsigned n_sources; LIST_HEAD(sd_event_source, sources); + + usec_t last_run, last_log; + unsigned delays[sizeof(usec_t) * 8]; }; static void source_disconnect(sd_event_source *s); @@ -242,12 +268,6 @@ static int pending_prioq_compare(const void *a, const void *b) { if (x->pending_iteration > y->pending_iteration) return 1; - /* Stability for the rest */ - if (x < y) - return -1; - if (x > y) - return 1; - return 0; } @@ -257,6 +277,12 @@ static int prepare_prioq_compare(const void *a, const void *b) { assert(x->prepare); assert(y->prepare); + /* Enabled ones first */ + if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) + return -1; + if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) + return 1; + /* Move most recently prepared ones last, so that we can stop * preparing as soon as we hit one that has already been * prepared in the current iteration */ @@ -265,24 +291,12 @@ static int prepare_prioq_compare(const void *a, const void *b) { if (x->prepare_iteration > y->prepare_iteration) return 1; - /* Enabled ones first */ - if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) - return -1; - if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) - return 1; - /* Lower priority values first */ if (x->priority < y->priority) return -1; if (x->priority > y->priority) return 1; - /* Stability for the rest */ - if (x < y) - return -1; - if (x > y) - return 1; - return 0; } @@ -310,12 +324,6 @@ static int earliest_time_prioq_compare(const void *a, const void *b) { if (x->time.next > y->time.next) return 1; - /* Stability for the rest */ - if (x < y) - return -1; - if (x > y) - return 1; - return 0; } @@ -343,12 +351,6 @@ static int latest_time_prioq_compare(const void *a, const void *b) { if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy) return 1; - /* Stability for the rest */ - if (x < y) - return -1; - if (x > y) - return 1; - return 0; } @@ -370,12 +372,6 @@ static int exit_prioq_compare(const void *a, const void *b) { if (x->priority > y->priority) return 1; - /* Stability for the rest */ - if (x < y) - return -1; - if (x > y) - return 1; - return 0; } @@ -442,11 +438,9 @@ _public_ int sd_event_new(sd_event** ret) { e->original_pid = getpid(); e->perturb = USEC_INFINITY; - e->pending = prioq_new(pending_prioq_compare); - if (!e->pending) { - r = -ENOMEM; + r = prioq_ensure_allocated(&e->pending, pending_prioq_compare); + if (r < 0) goto fail; - } e->epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (e->epoll_fd < 0) { @@ -454,6 +448,11 @@ _public_ int sd_event_new(sd_event** ret) { goto fail; } + if (secure_getenv("SD_EVENT_PROFILE_DELAYS")) { + log_debug("Event loop profiling enabled. Logarithmic histogram of event loop iterations in the range 2^0 ... 2^63 us will be logged every 5s."); + e->profile_delays = true; + } + *ret = e; return 0; @@ -463,7 +462,9 @@ fail: } _public_ sd_event* sd_event_ref(sd_event *e) { - assert_return(e, NULL); + + if (!e) + return NULL; assert(e->n_ref >= 1); e->n_ref++; @@ -508,7 +509,8 @@ static void source_io_unregister(sd_event_source *s) { r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL); if (r < 0) - log_debug_errno(errno, "Failed to remove source %s from epoll: %m", strna(s->description)); + log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m", + strna(s->description), event_source_type_to_string(s->type)); s->io.registered = false; } @@ -659,8 +661,10 @@ static int event_make_signal_data( d->priority = priority; r = hashmap_put(e->signal_data, &d->priority, d); - if (r < 0) + if (r < 0) { + free(d); return r; + } added = true; } @@ -835,7 +839,7 @@ static void source_disconnect(sd_event_source *s) { s->event->n_enabled_child_sources--; } - (void) hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid)); + (void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid)); event_gc_signal_data(s->event, &s->priority, SIGCHLD); } @@ -1076,17 +1080,13 @@ _public_ int sd_event_add_time( d = event_get_clock_data(e, type); assert(d); - if (!d->earliest) { - d->earliest = prioq_new(earliest_time_prioq_compare); - if (!d->earliest) - return -ENOMEM; - } + r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare); + if (r < 0) + return r; - if (!d->latest) { - d->latest = prioq_new(latest_time_prioq_compare); - if (!d->latest) - return -ENOMEM; - } + r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare); + if (r < 0) + return r; if (d->fd < 0) { r = event_setup_timer_fd(e, d, clock); @@ -1153,8 +1153,8 @@ _public_ int sd_event_add_signal( callback = signal_exit_callback; r = pthread_sigmask(SIG_SETMASK, NULL, &ss); - if (r < 0) - return -errno; + if (r != 0) + return -r; if (!sigismember(&ss, sig)) return -EBUSY; @@ -1215,7 +1215,7 @@ _public_ int sd_event_add_child( if (r < 0) return r; - if (hashmap_contains(e->child_sources, INT_TO_PTR(pid))) + if (hashmap_contains(e->child_sources, PID_TO_PTR(pid))) return -EBUSY; s = source_new(e, !ret, SOURCE_CHILD); @@ -1228,7 +1228,7 @@ _public_ int sd_event_add_child( s->userdata = userdata; s->enabled = SD_EVENT_ONESHOT; - r = hashmap_put(e->child_sources, INT_TO_PTR(pid), s); + r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s); if (r < 0) { source_free(s); return r; @@ -1337,11 +1337,9 @@ _public_ int sd_event_add_exit( assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); - if (!e->exit) { - e->exit = prioq_new(exit_prioq_compare); - if (!e->exit) - return -ENOMEM; - } + r = prioq_ensure_allocated(&e->exit, exit_prioq_compare); + if (r < 0) + return r; s = source_new(e, !ret, SOURCE_EXIT); if (!s) @@ -1365,7 +1363,9 @@ _public_ int sd_event_add_exit( } _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { - assert_return(s, NULL); + + if (!s) + return NULL; assert(s->n_ref >= 1); s->n_ref++; @@ -2311,12 +2311,9 @@ static int source_dispatch(sd_event_source *s) { s->dispatching = false; - if (r < 0) { - if (s->description) - log_debug_errno(r, "Event source '%s' returned error, disabling: %m", s->description); - else - log_debug_errno(r, "Event source %p returned error, disabling: %m", s); - } + if (r < 0) + log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m", + strna(s->description), event_source_type_to_string(s->type)); if (s->n_ref == 0) source_free(s); @@ -2349,12 +2346,9 @@ static int event_prepare(sd_event *e) { r = s->prepare(s, s->userdata); s->dispatching = false; - if (r < 0) { - if (s->description) - log_debug_errno(r, "Prepare callback of event source '%s' returned error, disabling: %m", s->description); - else - log_debug_errno(r, "Prepare callback of event source %p returned error, disabling: %m", s); - } + if (r < 0) + log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m", + strna(s->description), event_source_type_to_string(s->type)); if (s->n_ref == 0) source_free(s); @@ -2459,7 +2453,9 @@ _public_ int sd_event_prepare(sd_event *e) { e->iteration++; + e->state = SD_EVENT_PREPARING; r = event_prepare(e); + e->state = SD_EVENT_INITIAL; if (r < 0) return r; @@ -2637,6 +2633,18 @@ _public_ int sd_event_dispatch(sd_event *e) { return 1; } +static void event_log_delays(sd_event *e) { + char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1]; + unsigned i; + int o; + + for (i = o = 0; i < ELEMENTSOF(e->delays); i++) { + o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]); + e->delays[i] = 0; + } + log_debug("Event loop iterations: %.*s", o, b); +} + _public_ int sd_event_run(sd_event *e, uint64_t timeout) { int r; @@ -2645,11 +2653,30 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + if (e->profile_delays && e->last_run) { + usec_t this_run; + unsigned l; + + this_run = now(CLOCK_MONOTONIC); + + l = u64log2(this_run - e->last_run); + assert(l < sizeof(e->delays)); + e->delays[l]++; + + if (this_run - e->last_log >= 5*USEC_PER_SEC) { + event_log_delays(e); + e->last_log = this_run; + } + } + r = sd_event_prepare(e); if (r == 0) /* There was nothing? Then wait... */ r = sd_event_wait(e, timeout); + if (e->profile_delays) + e->last_run = now(CLOCK_MONOTONIC); + if (r > 0) { /* There's something now, then let's dispatch it */ r = sd_event_dispatch(e); @@ -2726,6 +2753,12 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { assert_return(e, -EINVAL); assert_return(usec, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); + assert_return(IN_SET(clock, + CLOCK_REALTIME, + CLOCK_REALTIME_ALARM, + CLOCK_MONOTONIC, + CLOCK_BOOTTIME, + CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP); if (!dual_timestamp_is_set(&e->timestamp)) { /* Implicitly fall back to now() if we never ran @@ -2745,8 +2778,7 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { *usec = e->timestamp.monotonic; break; - case CLOCK_BOOTTIME: - case CLOCK_BOOTTIME_ALARM: + default: *usec = e->timestamp_boottime; break; } diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c index c092e56b7a..c605b18ae9 100644 --- a/src/libsystemd/sd-event/test-event.c +++ b/src/libsystemd/sd-event/test-event.c @@ -20,10 +20,12 @@ ***/ #include "sd-event.h" + +#include "fd-util.h" #include "log.h" -#include "util.h" #include "macro.h" #include "signal-util.h" +#include "util.h" static int prepare_handler(sd_event_source *s, void *userdata) { log_info("preparing %c", PTR_TO_INT(userdata)); @@ -156,11 +158,22 @@ static int exit_handler(sd_event_source *s, void *userdata) { return 3; } +static bool got_post = false; + +static int post_handler(sd_event_source *s, void *userdata) { + log_info("got post handler"); + + got_post = true; + + return 2; +} + static void test_basic(void) { sd_event *e = NULL; sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL; static const char ch = 'x'; int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 }; + uint64_t event_now; assert_se(pipe(a) >= 0); assert_se(pipe(b) >= 0); @@ -168,6 +181,7 @@ static void test_basic(void) { assert_se(pipe(k) >= 0); assert_se(sd_event_default(&e) >= 0); + assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0); assert_se(sd_event_set_watchdog(e, true) >= 0); @@ -228,10 +242,14 @@ static void test_basic(void) { sd_event_source_unref(y); do_quit = true; - assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0); + assert_se(sd_event_add_post(e, NULL, post_handler, NULL) >= 0); + assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0); + assert_se(sd_event_source_set_time(z, event_now + 200 * USEC_PER_MSEC) >= 0); assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0); assert_se(sd_event_loop(e) >= 0); + assert_se(got_post); + assert_se(got_exit); sd_event_source_unref(z); sd_event_source_unref(q); @@ -246,6 +264,30 @@ static void test_basic(void) { safe_close_pair(k); } +static void test_sd_event_now(void) { + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + uint64_t event_now; + + assert_se(sd_event_new(&e) >= 0); + assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0); + assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) > 0); + assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) > 0); + assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) > 0); + assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) > 0); + assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP); + assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP); + + assert_se(sd_event_run(e, 0) == 0); + + assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0); + assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) == 0); + assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) == 0); + assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) == 0); + assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) == 0); + assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP); + assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP); +} + static int last_rtqueue_sigval = 0; static int n_rtqueue = 0; @@ -306,7 +348,11 @@ static void test_rtqueue(void) { int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + test_basic(); + test_sd_event_now(); test_rtqueue(); return 0; diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h index fedccdec72..13fddfc8ad 100644 --- a/src/libsystemd/sd-hwdb/hwdb-internal.h +++ b/src/libsystemd/sd-hwdb/hwdb-internal.h @@ -19,6 +19,7 @@ #pragma once #include "sparse-endian.h" +#include "util.h" #define HWDB_SIG { 'K', 'S', 'L', 'P', 'H', 'H', 'R', 'H' } diff --git a/src/libsystemd/sd-hwdb/hwdb-util.h b/src/libsystemd/sd-hwdb/hwdb-util.h index ee020a2942..6765ba9400 100644 --- a/src/libsystemd/sd-hwdb/hwdb-util.h +++ b/src/libsystemd/sd-hwdb/hwdb-util.h @@ -21,11 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" - #include "sd-hwdb.h" -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_hwdb*, sd_hwdb_unref); -#define _cleanup_hwdb_unref_ _cleanup_(sd_hwdb_unrefp) +#include "util.h" bool hwdb_validate(sd_hwdb *hwdb); diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c index f0316be659..062fa97b17 100644 --- a/src/libsystemd/sd-hwdb/sd-hwdb.c +++ b/src/libsystemd/sd-hwdb/sd-hwdb.c @@ -19,21 +19,23 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdio.h> #include <errno.h> -#include <string.h> +#include <fnmatch.h> #include <inttypes.h> +#include <stdio.h> #include <stdlib.h> -#include <fnmatch.h> +#include <string.h> #include <sys/mman.h> #include "sd-hwdb.h" +#include "alloc-util.h" +#include "fd-util.h" #include "hashmap.h" -#include "refcnt.h" - -#include "hwdb-util.h" #include "hwdb-internal.h" +#include "hwdb-util.h" +#include "refcnt.h" +#include "string-util.h" struct sd_hwdb { RefCount n_ref; @@ -277,7 +279,7 @@ static const char hwdb_bin_paths[] = UDEVLIBEXECDIR "/hwdb.bin\0"; _public_ int sd_hwdb_new(sd_hwdb **ret) { - _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL; + _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; const char *hwdb_bin_path; const char sig[] = HWDB_SIG; diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index 46f2181ea8..c12bb1e20b 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -23,12 +23,16 @@ #include <fcntl.h> #include <unistd.h> -#include "util.h" -#include "macro.h" #include "sd-id128.h" + +#include "fd-util.h" +#include "hexdecoct.h" +#include "io-util.h" +#include "macro.h" #include "random-util.h" +#include "util.h" -_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) { +_public_ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]) { unsigned n; assert_return(s, NULL); diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 265c7c7db2..ef240c3531 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -19,21 +19,33 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <unistd.h> -#include <string.h> #include <errno.h> -#include <sys/inotify.h> #include <poll.h> +#include <string.h> +#include <sys/inotify.h> +#include <unistd.h> -#include "util.h" +#include "sd-login.h" + +#include "alloc-util.h" #include "cgroup-util.h" -#include "macro.h" -#include "strv.h" +#include "dirent-util.h" +#include "escape.h" +#include "fd-util.h" #include "fileio.h" -#include "login-util.h" #include "formats-util.h" +#include "fs-util.h" #include "hostname-util.h" -#include "sd-login.h" +#include "io-util.h" +#include "login-util.h" +#include "macro.h" +#include "parse-util.h" +#include "path-util.h" +#include "socket-util.h" +#include "string-util.h" +#include "strv.h" +#include "user-util.h" +#include "util.h" /* Error codes: * @@ -798,7 +810,7 @@ _public_ int sd_get_uids(uid_t **users) { errno = 0; de = readdir(d); - if (!de && errno != 0) + if (!de && errno > 0) return -errno; if (!de) @@ -920,9 +932,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { *(char*) (mempcpy(buf, word, l)) = 0; - if (safe_atoi(buf, &ifi) < 0) - continue; - if (ifi <= 0) + if (parse_ifindex(buf, &ifi) < 0) continue; if (!GREEDY_REALLOC(ni, allocated, nr+1)) { @@ -1007,7 +1017,8 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { _public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) { int fd; - assert_return(m, NULL); + if (!m) + return NULL; fd = MONITOR_TO_FD(m); close_nointr(fd); diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index f734ce9eee..b0f94c9522 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -22,11 +22,14 @@ #include <poll.h> #include <string.h> -#include "systemd/sd-login.h" +#include "sd-login.h" -#include "util.h" -#include "strv.h" +#include "alloc-util.h" +#include "fd-util.h" #include "formats-util.h" +#include "string-util.h" +#include "strv.h" +#include "util.h" static void test_login(void) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; diff --git a/src/libsystemd/sd-netlink/local-addresses.c b/src/libsystemd/sd-netlink/local-addresses.c index e2f637f7f9..997b048e58 100644 --- a/src/libsystemd/sd-netlink/local-addresses.c +++ b/src/libsystemd/sd-netlink/local-addresses.c @@ -21,9 +21,11 @@ ***/ #include "sd-netlink.h" -#include "netlink-util.h" -#include "macro.h" + +#include "alloc-util.h" #include "local-addresses.h" +#include "macro.h" +#include "netlink-util.h" static int address_compare(const void *_a, const void *_b) { const struct local_address *a = _a, *b = _b; @@ -54,8 +56,8 @@ static int address_compare(const void *_a, const void *_b) { } int local_addresses(sd_netlink *context, int ifindex, int af, struct local_address **ret) { - _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL; - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_free_ struct local_address *list = NULL; size_t n_list = 0, n_allocated = 0; sd_netlink_message *m; @@ -165,8 +167,8 @@ int local_addresses(sd_netlink *context, int ifindex, int af, struct local_addre } int local_gateways(sd_netlink *context, int ifindex, int af, struct local_address **ret) { - _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL; - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_free_ struct local_address *list = NULL; sd_netlink_message *m = NULL; size_t n_list = 0, n_allocated = 0; diff --git a/src/libsystemd/sd-netlink/local-addresses.h b/src/libsystemd/sd-netlink/local-addresses.h index 5d0f11a2c1..74d4f25534 100644 --- a/src/libsystemd/sd-netlink/local-addresses.h +++ b/src/libsystemd/sd-netlink/local-addresses.h @@ -23,6 +23,7 @@ #include "sd-netlink.h" + #include "in-addr-util.h" struct local_address { diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 4026e2c341..6c752ac65e 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -23,13 +23,12 @@ #include <linux/netlink.h> -#include "refcnt.h" -#include "prioq.h" -#include "list.h" - #include "sd-netlink.h" +#include "list.h" #include "netlink-types.h" +#include "prioq.h" +#include "refcnt.h" #define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) @@ -64,6 +63,9 @@ struct sd_netlink { struct sockaddr_nl nl; } sockaddr; + Hashmap *broadcast_group_refs; + bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */ + sd_netlink_message **rqueue; unsigned rqueue_size; size_t rqueue_allocated; @@ -124,7 +126,8 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret); int socket_open(int family); int socket_bind(sd_netlink *nl); -int socket_join_broadcast_group(sd_netlink *nl, unsigned group); +int socket_broadcast_group_ref(sd_netlink *nl, unsigned group); +int socket_broadcast_group_unref(sd_netlink *nl, unsigned group); int socket_write_message(sd_netlink *nl, sd_netlink_message *m); int socket_read_message(sd_netlink *nl); @@ -132,5 +135,5 @@ int rtnl_rqueue_make_room(sd_netlink *rtnl); int rtnl_rqueue_partial_make_room(sd_netlink *rtnl); /* Make sure callbacks don't destroy the rtnl connection */ -#define RTNL_DONT_DESTROY(rtnl) \ - _cleanup_netlink_unref_ _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) +#define NETLINK_DONT_DESTROY(rtnl) \ + _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 0d8e37b856..50792bc4a3 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -23,16 +23,17 @@ #include <stdbool.h> #include <unistd.h> -#include "util.h" -#include "socket-util.h" +#include "sd-netlink.h" + +#include "alloc-util.h" #include "formats-util.h" -#include "refcnt.h" #include "missing.h" - -#include "sd-netlink.h" -#include "netlink-util.h" #include "netlink-internal.h" #include "netlink-types.h" +#include "netlink-util.h" +#include "refcnt.h" +#include "socket-util.h" +#include "util.h" #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL) #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr; @@ -64,7 +65,7 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { } int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; size_t size; int r; @@ -149,6 +150,15 @@ int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type) { return 0; } +int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags) { + assert_return(m, -EINVAL); + assert_return(flags, -EINVAL); + + m->hdr->nlmsg_flags = flags; + + return 0; +} + int sd_netlink_message_is_broadcast(sd_netlink_message *m) { assert_return(m, -EINVAL); diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 84ff7c38c9..e95c99af0d 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -23,16 +23,17 @@ #include <stdbool.h> #include <unistd.h> -#include "util.h" -#include "socket-util.h" +#include "sd-netlink.h" + +#include "alloc-util.h" #include "formats-util.h" -#include "refcnt.h" #include "missing.h" - -#include "sd-netlink.h" -#include "netlink-util.h" #include "netlink-internal.h" #include "netlink-types.h" +#include "netlink-util.h" +#include "refcnt.h" +#include "socket-util.h" +#include "util.h" int socket_open(int family) { int fd; @@ -44,6 +45,65 @@ int socket_open(int family) { return fd; } +static int broadcast_groups_get(sd_netlink *nl) { + _cleanup_free_ uint32_t *groups = NULL; + socklen_t len = 0, old_len; + unsigned i, j; + int r; + + assert(nl); + assert(nl->fd >= 0); + + r = getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len); + if (r < 0) { + if (errno == ENOPROTOOPT) { + nl->broadcast_group_dont_leave = true; + return 0; + } else + return -errno; + } + + if (len == 0) + return 0; + + groups = new0(uint32_t, len); + if (!groups) + return -ENOMEM; + + old_len = len; + + r = getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len); + if (r < 0) + return -errno; + + if (old_len != len) + return -EIO; + + r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL); + if (r < 0) + return r; + + for (i = 0; i < len; i++) { + for (j = 0; j < sizeof(uint32_t) * 8; j ++) { + uint32_t offset; + unsigned group; + + offset = 1U << j; + + if (!(groups[i] & offset)) + continue; + + group = i * sizeof(uint32_t) * 8 + j + 1; + + r = hashmap_put(nl->broadcast_group_refs, UINT_TO_PTR(group), UINT_TO_PTR(1)); + if (r < 0) + return r; + } + } + + return 0; +} + int socket_bind(sd_netlink *nl) { socklen_t addrlen; int r, one = 1; @@ -63,11 +123,32 @@ int socket_bind(sd_netlink *nl) { if (r < 0) return -errno; + r = broadcast_groups_get(nl); + if (r < 0) + return r; + return 0; } +static unsigned broadcast_group_get_ref(sd_netlink *nl, unsigned group) { + assert(nl); + + return PTR_TO_UINT(hashmap_get(nl->broadcast_group_refs, UINT_TO_PTR(group))); +} + +static int broadcast_group_set_ref(sd_netlink *nl, unsigned group, unsigned n_ref) { + int r; + + assert(nl); + + r = hashmap_replace(nl->broadcast_group_refs, UINT_TO_PTR(group), UINT_TO_PTR(n_ref)); + if (r < 0) + return r; + + return 0; +} -int socket_join_broadcast_group(sd_netlink *nl, unsigned group) { +static int broadcast_group_join(sd_netlink *nl, unsigned group) { int r; assert(nl); @@ -81,6 +162,79 @@ int socket_join_broadcast_group(sd_netlink *nl, unsigned group) { return 0; } +int socket_broadcast_group_ref(sd_netlink *nl, unsigned group) { + unsigned n_ref; + int r; + + assert(nl); + + n_ref = broadcast_group_get_ref(nl, group); + + n_ref ++; + + r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL); + if (r < 0) + return r; + + r = broadcast_group_set_ref(nl, group, n_ref); + if (r < 0) + return r; + + if (n_ref > 1) + /* not yet in the group */ + return 0; + + r = broadcast_group_join(nl, group); + if (r < 0) + return r; + + return 0; +} + +static int broadcast_group_leave(sd_netlink *nl, unsigned group) { + int r; + + assert(nl); + assert(nl->fd >= 0); + assert(group > 0); + + if (nl->broadcast_group_dont_leave) + return 0; + + r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &group, sizeof(group)); + if (r < 0) + return -errno; + + return 0; +} + +int socket_broadcast_group_unref(sd_netlink *nl, unsigned group) { + unsigned n_ref; + int r; + + assert(nl); + + n_ref = broadcast_group_get_ref(nl, group); + + assert(n_ref > 0); + + n_ref --; + + r = broadcast_group_set_ref(nl, group, n_ref); + if (r < 0) + return r; + + if (n_ref > 0) + /* still refs left */ + return 0; + + r = broadcast_group_leave(nl, group); + if (r < 0) + return r; + + return 0; +} + /* returns the number of bytes sent, or a negative error code */ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) { union { @@ -169,7 +323,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool * On failure, a negative error code is returned. */ int socket_read_message(sd_netlink *rtnl) { - _cleanup_netlink_message_unref_ sd_netlink_message *first = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *first = NULL; struct iovec iov = {}; uint32_t group = 0; bool multi_part = false, done = false; @@ -222,7 +376,7 @@ int socket_read_message(sd_netlink *rtnl) { } for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 2128329191..be4ab1373d 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -28,16 +28,15 @@ #include <linux/if_bridge.h> #include <linux/if_addr.h> #include <linux/if.h> - #include <linux/ip.h> #include <linux/if_link.h> #include <linux/if_tunnel.h> #include "macro.h" -#include "util.h" - -#include "netlink-types.h" #include "missing.h" +#include "netlink-types.h" +#include "string-table.h" +#include "util.h" /* Maximum ARP IP target defined in kernel */ #define BOND_MAX_ARP_TARGETS 16 @@ -84,29 +83,29 @@ static const NLTypeSystem empty_type_system = { .types = empty_types, }; -static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = { +static const NLType rtnl_link_info_data_veth_types[] = { [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, }; -static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = { +static const NLType rtnl_link_info_data_ipvlan_types[] = { [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = { +static const NLType rtnl_link_info_data_macvlan_types[] = { [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = { - [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 }, -/* - [IFLA_BRIDGE_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY, - .len = sizeof(struct bridge_vlan_info), }, -*/ +static const NLType rtnl_link_info_data_bridge_types[] = { + [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = { +static const NLType rtnl_link_info_data_vlan_types[] = { [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, /* [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) }, @@ -116,7 +115,7 @@ static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = { [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = { +static const NLType rtnl_link_info_data_vxlan_types[] = { [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR }, [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, @@ -143,7 +142,7 @@ static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = { [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, }; -static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = { +static const NLType rtnl_bond_arp_target_types[] = { [BOND_ARP_TARGETS_0] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_1] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_2] = { .type = NETLINK_TYPE_U32 }, @@ -167,7 +166,7 @@ static const NLTypeSystem rtnl_bond_arp_type_system = { .types = rtnl_bond_arp_target_types, }; -static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = { +static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, [IFLA_BOND_ACTIVE_SLAVE] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_MIIMON] = { .type = NETLINK_TYPE_U32 }, @@ -193,7 +192,7 @@ static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = { [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED }, }; -static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = { +static const NLType rtnl_link_info_data_iptun_types[] = { [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, @@ -212,7 +211,7 @@ static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = { +static const NLType rtnl_link_info_data_ipgre_types[] = { [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, @@ -231,7 +230,7 @@ static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = { [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = { +static const NLType rtnl_link_info_data_ipvti_types[] = { [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, @@ -239,7 +238,7 @@ static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = { [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, }; -static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = { +static const NLType rtnl_link_info_data_ip6tnl_types[] = { [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, @@ -251,7 +250,7 @@ static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = { }; /* these strings must match the .kind entries in the kernel */ -static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = { +static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_BOND] = "bond", [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge", [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan", @@ -274,7 +273,7 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_ DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); -static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = { +static const NLTypeSystem rtnl_link_info_data_type_systems[] = { [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), .types = rtnl_link_info_data_bond_types }, [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), @@ -320,7 +319,7 @@ static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { .match = IFLA_INFO_KIND, }; -static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = { +static const NLType rtnl_link_info_types[] = { [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union}, /* @@ -335,7 +334,7 @@ static const NLTypeSystem rtnl_link_info_type_system = { .types = rtnl_link_info_types, }; -static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = { +static const struct NLType rtnl_prot_info_bridge_port_types[] = { [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, @@ -349,7 +348,7 @@ static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 }, }; -static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = { +static const NLTypeSystem rtnl_prot_info_type_systems[] = { [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), .types = rtnl_prot_info_bridge_port_types }, }; @@ -360,7 +359,7 @@ static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { .match_type = NL_MATCH_PROTOCOL, }; -static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = { +static const struct NLType rtnl_af_spec_inet6_types[] = { [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, /* IFLA_INET6_CONF, @@ -378,7 +377,7 @@ static const NLTypeSystem rtnl_af_spec_inet6_type_system = { .types = rtnl_af_spec_inet6_types, }; -static const NLType rtnl_af_spec_types[AF_MAX + 1] = { +static const NLType rtnl_af_spec_types[] = { [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, }; @@ -387,7 +386,7 @@ static const NLTypeSystem rtnl_af_spec_type_system = { .types = rtnl_af_spec_types, }; -static const NLType rtnl_link_types[IFLA_MAX + 1 ] = { +static const NLType rtnl_link_types[] = { [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, @@ -446,7 +445,7 @@ static const NLTypeSystem rtnl_link_type_system = { /* IFA_FLAGS was defined in kernel 3.14, but we still support older * kernels where IFA_MAX is lower. */ -static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = { +static const NLType rtnl_address_types[] = { [IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR }, [IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, [IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, @@ -464,7 +463,7 @@ static const NLTypeSystem rtnl_address_type_system = { .types = rtnl_address_types, }; -static const NLType rtnl_route_types[RTA_MAX + 1] = { +static const NLType rtnl_route_types[] = { [RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ [RTA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ [RTA_IIF] = { .type = NETLINK_TYPE_U32 }, @@ -482,7 +481,11 @@ static const NLType rtnl_route_types[RTA_MAX + 1] = { RTA_TABLE, RTA_MARK, RTA_MFC_STATS, + RTA_VIA, + RTA_NEWDST, */ + [RTA_PREF] = { .type = NETLINK_TYPE_U8 }, + }; static const NLTypeSystem rtnl_route_type_system = { @@ -490,7 +493,7 @@ static const NLTypeSystem rtnl_route_type_system = { .types = rtnl_route_types, }; -static const NLType rtnl_neigh_types[NDA_MAX + 1] = { +static const NLType rtnl_neigh_types[] = { [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, [NDA_LLADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, [NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, @@ -506,7 +509,7 @@ static const NLTypeSystem rtnl_neigh_type_system = { .types = rtnl_neigh_types, }; -static const NLType rtnl_types[RTM_MAX + 1] = { +static const NLType rtnl_types[] = { [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) }, [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index bf7c641541..9e636a0b53 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -21,6 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "macro.h" + enum { NETLINK_TYPE_UNSPEC, NETLINK_TYPE_U8, /* NLA_U8 */ diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 482ff6b1c2..b69969e426 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -19,14 +19,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ - #include "sd-netlink.h" -#include "netlink-util.h" #include "netlink-internal.h" +#include "netlink-util.h" int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { - _cleanup_netlink_message_unref_ sd_netlink_message *message = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; assert(rtnl); @@ -56,7 +55,7 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu) { - _cleanup_netlink_message_unref_ sd_netlink_message *message = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; assert(rtnl); diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 9df0aa28bf..a0e59e1ec6 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -21,9 +21,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "sd-netlink.h" #include "util.h" -#include "sd-netlink.h" int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_netlink_message **ret); uint32_t rtnl_message_get_serial(sd_netlink_message *m); @@ -39,9 +39,3 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, int rtnl_log_parse_error(int r); int rtnl_log_create_error(int r); - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_netlink*, sd_netlink_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_netlink_message*, sd_netlink_message_unref); - -#define _cleanup_netlink_unref_ _cleanup_(sd_netlink_unrefp) -#define _cleanup_netlink_message_unref_ _cleanup_(sd_netlink_message_unrefp) diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c index 2f31f4ee69..3e605db661 100644 --- a/src/libsystemd/sd-netlink/rtnl-message.c +++ b/src/libsystemd/sd-netlink/rtnl-message.c @@ -23,16 +23,16 @@ #include <stdbool.h> #include <unistd.h> -#include "util.h" -#include "socket-util.h" +#include "sd-netlink.h" + #include "formats-util.h" -#include "refcnt.h" #include "missing.h" - -#include "sd-netlink.h" -#include "netlink-util.h" #include "netlink-internal.h" #include "netlink-types.h" +#include "netlink-util.h" +#include "refcnt.h" +#include "socket-util.h" +#include "util.h" int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen) { struct rtmsg *rtm; @@ -84,6 +84,35 @@ int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope) return 0; } +int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + rtm->rtm_flags = flags; + + return 0; +} + +int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + assert_return(flags, -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + *flags = rtm->rtm_flags; + + return 0; +} + int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) { struct rtmsg *rtm; @@ -99,6 +128,66 @@ int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) { return 0; } +int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + assert_return(protocol, -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + *protocol = rtm->rtm_protocol; + + return 0; +} + +int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + assert_return(scope, -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + *scope = rtm->rtm_scope; + + return 0; +} + +int sd_rtnl_message_route_get_tos(sd_netlink_message *m, unsigned char *tos) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + assert_return(tos, -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + *tos = rtm->rtm_tos; + + return 0; +} + +int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table) { + struct rtmsg *rtm; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); + assert_return(table, -EINVAL); + + rtm = NLMSG_DATA(m->hdr); + + *table = rtm->rtm_table; + + return 0; +} + int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char *dst_len) { struct rtmsg *rtm; diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index d248869c8d..15d387df2c 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -19,20 +19,23 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> #include <poll.h> - -#include "missing.h" -#include "macro.h" -#include "util.h" -#include "hashmap.h" +#include <sys/socket.h> #include "sd-netlink.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "hashmap.h" +#include "macro.h" +#include "missing.h" #include "netlink-internal.h" #include "netlink-util.h" +#include "socket-util.h" +#include "util.h" static int sd_netlink_new(sd_netlink **ret) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; assert_return(ret, -EINVAL); @@ -68,7 +71,7 @@ static int sd_netlink_new(sd_netlink **ret) { } int sd_netlink_new_from_netlink(sd_netlink **ret, int fd) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; socklen_t addrlen; int r; @@ -102,7 +105,7 @@ static bool rtnl_pid_changed(sd_netlink *rtnl) { } int sd_netlink_open_fd(sd_netlink **ret, int fd) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; int r; assert_return(ret, -EINVAL); @@ -183,10 +186,11 @@ sd_netlink *sd_netlink_unref(sd_netlink *rtnl) { sd_event_unref(rtnl->event); while ((f = rtnl->match_callbacks)) { - LIST_REMOVE(match_callbacks, rtnl->match_callbacks, f); - free(f); + sd_netlink_remove_match(rtnl, f->type, f->callback, f->userdata); } + hashmap_free(rtnl->broadcast_group_refs); + safe_close(rtnl->fd); free(rtnl); } @@ -282,7 +286,7 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) { } static int process_timeout(sd_netlink *rtnl) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; struct reply_callback *c; usec_t n; int r; @@ -372,7 +376,7 @@ static int process_match(sd_netlink *rtnl, sd_netlink_message *m) { } static int process_running(sd_netlink *rtnl, sd_netlink_message **ret) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; assert(rtnl); @@ -414,7 +418,7 @@ null_message: } int sd_netlink_process(sd_netlink *rtnl, sd_netlink_message **ret) { - RTNL_DONT_DESTROY(rtnl); + NETLINK_DONT_DESTROY(rtnl); int r; assert_return(rtnl, -EINVAL); @@ -619,7 +623,7 @@ int sd_netlink_call(sd_netlink *rtnl, received_serial = rtnl_message_get_serial(rtnl->rqueue[i]); if (received_serial == serial) { - _cleanup_netlink_message_unref_ sd_netlink_message *incoming = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *incoming = NULL; uint16_t type; incoming = rtnl->rqueue[i]; @@ -856,26 +860,33 @@ int sd_netlink_add_match(sd_netlink *rtnl, switch (type) { case RTM_NEWLINK: - case RTM_SETLINK: - case RTM_GETLINK: case RTM_DELLINK: - r = socket_join_broadcast_group(rtnl, RTNLGRP_LINK); + r = socket_broadcast_group_ref(rtnl, RTNLGRP_LINK); if (r < 0) return r; break; case RTM_NEWADDR: - case RTM_GETADDR: case RTM_DELADDR: - r = socket_join_broadcast_group(rtnl, RTNLGRP_IPV4_IFADDR); + r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_IFADDR); if (r < 0) return r; - r = socket_join_broadcast_group(rtnl, RTNLGRP_IPV6_IFADDR); + r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_IFADDR); if (r < 0) return r; break; + case RTM_NEWROUTE: + case RTM_DELROUTE: + r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_ROUTE); + if (r < 0) + return r; + + r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_ROUTE); + if (r < 0) + return r; + break; default: return -EOPNOTSUPP; } @@ -892,23 +903,50 @@ int sd_netlink_remove_match(sd_netlink *rtnl, sd_netlink_message_handler_t callback, void *userdata) { struct match_callback *c; + int r; assert_return(rtnl, -EINVAL); assert_return(callback, -EINVAL); assert_return(!rtnl_pid_changed(rtnl), -ECHILD); - /* we should unsubscribe from the broadcast groups at this point, but it is not so - trivial for a few reasons: the refcounting is a bit of a mess and not obvious - how it will look like after we add genetlink support, and it is also not possible - to query what broadcast groups were subscribed to when we inherit the socket to get - the initial refcount. The latter could indeed be done for the first 32 broadcast - groups (which incidentally is all we currently support in .socket units anyway), - but we better not rely on only ever using 32 groups. */ LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) if (c->callback == callback && c->type == type && c->userdata == userdata) { LIST_REMOVE(match_callbacks, rtnl->match_callbacks, c); free(c); + switch (type) { + case RTM_NEWLINK: + case RTM_DELLINK: + r = socket_broadcast_group_unref(rtnl, RTNLGRP_LINK); + if (r < 0) + return r; + + break; + case RTM_NEWADDR: + case RTM_DELADDR: + r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_IFADDR); + if (r < 0) + return r; + + r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_IFADDR); + if (r < 0) + return r; + + break; + case RTM_NEWROUTE: + case RTM_DELROUTE: + r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_ROUTE); + if (r < 0) + return r; + + r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_ROUTE); + if (r < 0) + return r; + break; + default: + return -EOPNOTSUPP; + } + return 1; } diff --git a/src/libsystemd/sd-netlink/test-local-addresses.c b/src/libsystemd/sd-netlink/test-local-addresses.c index 9867eec065..0b53297ab8 100644 --- a/src/libsystemd/sd-netlink/test-local-addresses.c +++ b/src/libsystemd/sd-netlink/test-local-addresses.c @@ -19,9 +19,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "af-list.h" +#include "alloc-util.h" #include "in-addr-util.h" #include "local-addresses.h" -#include "af-list.h" static void print_local_addresses(struct local_address *a, unsigned n) { unsigned i; diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index c9cb415ca0..6a8b4d31d1 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -19,19 +19,21 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <netinet/ether.h> #include <net/if.h> +#include <netinet/ether.h> -#include "util.h" -#include "macro.h" #include "sd-netlink.h" -#include "socket-util.h" -#include "netlink-util.h" -#include "event-util.h" + +#include "ether-addr-util.h" +#include "macro.h" #include "missing.h" +#include "netlink-util.h" +#include "socket-util.h" +#include "string-util.h" +#include "util.h" static void test_message_link_bridge(sd_netlink *rtnl) { - _cleanup_netlink_message_unref_ sd_netlink_message *message = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; uint32_t cost; assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1) >= 0); @@ -49,7 +51,7 @@ static void test_message_link_bridge(sd_netlink *rtnl) { } static void test_link_configure(sd_netlink *rtnl, int ifindex) { - _cleanup_netlink_message_unref_ sd_netlink_message *message = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; const char *mac = "98:fe:94:3f:c6:18", *name = "test"; char buffer[ETHER_ADDR_TO_STRING_MAX]; unsigned int mtu = 1450, mtu_out; @@ -143,7 +145,7 @@ static void test_address_get(sd_netlink *rtnl, int ifindex) { } static void test_route(void) { - _cleanup_netlink_message_unref_ sd_netlink_message *req; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req; struct in_addr addr, addr_data; uint32_t index = 2, u32_data; int r; @@ -206,9 +208,9 @@ static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) } static void test_event_loop(int ifindex) { - _cleanup_event_unref_ sd_event *event = NULL; - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; char *ifname; ifname = strdup("lo2"); @@ -246,8 +248,8 @@ static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) } static void test_async(int ifindex) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL, *r = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL; uint32_t serial; char *ifname; @@ -267,8 +269,8 @@ static void test_async(int ifindex) { } static void test_pipe(int ifindex) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; - _cleanup_netlink_message_unref_ sd_netlink_message *m1 = NULL, *m2 = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL; int counter = 0; assert_se(sd_netlink_open(&rtnl) >= 0); @@ -291,7 +293,7 @@ static void test_pipe(int ifindex) { } static void test_container(void) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; uint16_t u16_data; uint32_t u32_data; const char *string_data; @@ -326,7 +328,7 @@ static void test_container(void) { } static void test_match(void) { - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; assert_se(sd_netlink_open(&rtnl) >= 0); @@ -341,7 +343,7 @@ static void test_match(void) { } static void test_get_addresses(sd_netlink *rtnl) { - _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; sd_netlink_message *m; assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0); @@ -369,7 +371,7 @@ static void test_get_addresses(sd_netlink *rtnl) { } static void test_message(void) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; assert_se(rtnl_message_new_synthetic_error(-ETIMEDOUT, 1, &m) >= 0); assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c index 48958e8a9f..a2d6c59314 100644 --- a/src/libsystemd/sd-network/network-util.c +++ b/src/libsystemd/sd-network/network-util.c @@ -19,8 +19,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "strv.h" +#include "alloc-util.h" +#include "fd-util.h" #include "network-util.h" +#include "strv.h" bool network_is_online(void) { _cleanup_free_ char *state = NULL; diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h index 11a0012348..57bbb70f41 100644 --- a/src/libsystemd/sd-network/network-util.h +++ b/src/libsystemd/sd-network/network-util.h @@ -23,7 +23,4 @@ #include "sd-network.h" -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_network_monitor*, sd_network_monitor_unref); -#define _cleanup_network_monitor_unref_ _cleanup_(sd_network_monitor_unrefp) - bool network_is_online(void); diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 87d87359b8..c1f5867ee4 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -20,16 +20,22 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <string.h> #include <errno.h> -#include <sys/inotify.h> #include <poll.h> +#include <string.h> +#include <sys/inotify.h> -#include "util.h" +#include "sd-network.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" #include "macro.h" +#include "parse-util.h" +#include "string-util.h" #include "strv.h" -#include "fileio.h" -#include "sd-network.h" +#include "util.h" _public_ int sd_network_get_operational_state(char **state) { _cleanup_free_ char *s = NULL; @@ -93,17 +99,17 @@ _public_ int sd_network_get_domains(char ***ret) { return network_get_strv("DOMAINS", ret); } -_public_ int sd_network_link_get_setup_state(int ifindex, char **state) { +static int network_link_get_string(int ifindex, const char *field, char **ret) { _cleanup_free_ char *s = NULL, *p = NULL; int r; assert_return(ifindex > 0, -EINVAL); - assert_return(state, -EINVAL); + assert_return(ret, -EINVAL); - if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) + if (asprintf(&p, "/run/systemd/netif/links/%i", ifindex) < 0) return -ENOMEM; - r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL); + r = parse_env_file(p, NEWLINE, field, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -111,82 +117,72 @@ _public_ int sd_network_link_get_setup_state(int ifindex, char **state) { if (isempty(s)) return -ENODATA; - *state = s; + *ret = s; s = NULL; return 0; } -_public_ int sd_network_link_get_network_file(int ifindex, char **filename) { - _cleanup_free_ char *s = NULL, *p = NULL; +static int network_link_get_strv(int ifindex, const char *key, char ***ret) { + _cleanup_free_ char *p = NULL, *s = NULL; + _cleanup_strv_free_ char **a = NULL; int r; assert_return(ifindex > 0, -EINVAL); - assert_return(filename, -EINVAL); + assert_return(ret, -EINVAL); if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) return -ENOMEM; - r = parse_env_file(p, NEWLINE, "NETWORK_FILE", &s, NULL); + r = parse_env_file(p, NEWLINE, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) return r; - if (isempty(s)) - return -ENODATA; - - *filename = s; - s = NULL; + if (isempty(s)) { + *ret = NULL; + return 0; + } - return 0; -} + a = strv_split(s, " "); + if (!a) + return -ENOMEM; -_public_ int sd_network_link_get_operational_state(int ifindex, char **state) { - _cleanup_free_ char *s = NULL, *p = NULL; - int r; + strv_uniq(a); + r = strv_length(a); - assert_return(ifindex > 0, -EINVAL); - assert_return(state, -EINVAL); + *ret = a; + a = NULL; - if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) - return -ENOMEM; + return r; +} - r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL); - if (r == -ENOENT) - return -ENODATA; - if (r < 0) - return r; - if (isempty(s)) - return -ENODATA; +_public_ int sd_network_link_get_setup_state(int ifindex, char **state) { + return network_link_get_string(ifindex, "ADMIN_STATE", state); +} - *state = s; - s = NULL; +_public_ int sd_network_link_get_network_file(int ifindex, char **filename) { + return network_link_get_string(ifindex, "NETWORK_FILE", filename); +} - return 0; +_public_ int sd_network_link_get_operational_state(int ifindex, char **state) { + return network_link_get_string(ifindex, "OPER_STATE", state); } _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) { - _cleanup_free_ char *s = NULL, *p = NULL; - int r; - - assert_return(ifindex > 0, -EINVAL); - assert_return(llmnr, -EINVAL); - - if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) - return -ENOMEM; + return network_link_get_string(ifindex, "LLMNR", llmnr); +} - r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL); - if (r == -ENOENT) - return -ENODATA; - if (r < 0) - return r; - if (isempty(s)) - return -ENODATA; +_public_ int sd_network_link_get_mdns(int ifindex, char **mdns) { + return network_link_get_string(ifindex, "MDNS", mdns); +} - *llmnr = s; - s = NULL; +_public_ int sd_network_link_get_dnssec(int ifindex, char **dnssec) { + return network_link_get_string(ifindex, "DNSSEC", dnssec); +} - return 0; +_public_ int sd_network_link_get_dnssec_negative_trust_anchors(int ifindex, char ***nta) { + return network_link_get_strv(ifindex, "DNSSEC_NTA", nta); } _public_ int sd_network_link_get_lldp(int ifindex, char **lldp) { @@ -215,85 +211,32 @@ _public_ int sd_network_link_get_lldp(int ifindex, char **lldp) { } int sd_network_link_get_timezone(int ifindex, char **ret) { - _cleanup_free_ char *s = NULL, *p = NULL; - int r; - - assert_return(ifindex > 0, -EINVAL); - assert_return(ret, -EINVAL); - - if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) - return -ENOMEM; - - r = parse_env_file(p, NEWLINE, "TIMEZONE", &s, NULL); - if (r == -ENOENT) - return -ENODATA; - if (r < 0) - return r; - if (isempty(s)) - return -ENODATA; - - *ret = s; - s = NULL; - return 0; -} - -static int network_get_link_strv(const char *key, int ifindex, char ***ret) { - _cleanup_free_ char *p = NULL, *s = NULL; - _cleanup_strv_free_ char **a = NULL; - int r; - - assert_return(ifindex > 0, -EINVAL); - assert_return(ret, -EINVAL); - - if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) - return -ENOMEM; - - r = parse_env_file(p, NEWLINE, key, &s, NULL); - if (r == -ENOENT) - return -ENODATA; - if (r < 0) - return r; - if (isempty(s)) { - *ret = NULL; - return 0; - } - - a = strv_split(s, " "); - if (!a) - return -ENOMEM; - - strv_uniq(a); - r = strv_length(a); - - *ret = a; - a = NULL; - - return r; + return network_link_get_string(ifindex, "TIMEZONE", ret); } _public_ int sd_network_link_get_dns(int ifindex, char ***ret) { - return network_get_link_strv("DNS", ifindex, ret); + return network_link_get_strv(ifindex, "DNS", ret); } _public_ int sd_network_link_get_ntp(int ifindex, char ***ret) { - return network_get_link_strv("NTP", ifindex, ret); + return network_link_get_strv(ifindex, "NTP", ret); } _public_ int sd_network_link_get_domains(int ifindex, char ***ret) { - return network_get_link_strv("DOMAINS", ifindex, ret); + return network_link_get_strv(ifindex, "DOMAINS", ret); } _public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) { - return network_get_link_strv("CARRIER_BOUND_TO", ifindex, ret); + return network_link_get_strv(ifindex, "CARRIER_BOUND_TO", ret); } _public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) { - return network_get_link_strv("CARRIER_BOUND_BY", ifindex, ret); + return network_link_get_strv(ifindex, "CARRIER_BOUND_BY", ret); } _public_ int sd_network_link_get_wildcard_domain(int ifindex) { - int r; _cleanup_free_ char *p = NULL, *s = NULL; + int r; assert_return(ifindex > 0, -EINVAL); diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c index 7363be2794..480f1ad065 100644 --- a/src/libsystemd/sd-path/sd-path.c +++ b/src/libsystemd/sd-path/sd-path.c @@ -17,12 +17,18 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" +#include "sd-path.h" + +#include "alloc-util.h" #include "architecture.h" +#include "fd-util.h" +#include "fileio.h" +#include "missing.h" #include "path-util.h" +#include "string-util.h" #include "strv.h" -#include "sd-path.h" -#include "missing.h" +#include "user-util.h" +#include "util.h" static int from_environment(const char *envname, const char *fallback, const char **ret) { assert(ret); diff --git a/src/libsystemd/sd-resolve/resolve-util.h b/src/libsystemd/sd-resolve/resolve-util.h deleted file mode 100644 index 019cdaffe1..0000000000 --- a/src/libsystemd/sd-resolve/resolve-util.h +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2014 Daniel Buch - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "util.h" -#include "sd-resolve.h" - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_resolve*, sd_resolve_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_resolve_query*, sd_resolve_query_unref); - -#define _cleanup_resolve_unref_ _cleanup_(sd_resolve_unrefp) -#define _cleanup_resolve_query_unref_ _cleanup_(sd_resolve_query_unrefp) diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c index 888b372c99..d6e6f396d4 100644 --- a/src/libsystemd/sd-resolve/sd-resolve.c +++ b/src/libsystemd/sd-resolve/sd-resolve.c @@ -19,24 +19,27 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <signal.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> #include <errno.h> +#include <poll.h> +#include <pthread.h> #include <resolv.h> +#include <signal.h> #include <stdint.h> -#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <sys/prctl.h> -#include <poll.h> +#include <unistd.h> -#include "util.h" +#include "sd-resolve.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "io-util.h" #include "list.h" -#include "socket-util.h" #include "missing.h" -#include "resolve-util.h" -#include "sd-resolve.h" +#include "socket-util.h" +#include "util.h" #define WORKERS_MIN 1U #define WORKERS_MAX 16U @@ -175,7 +178,7 @@ static int getnameinfo_done(sd_resolve_query *q); static void resolve_query_disconnect(sd_resolve_query *q); #define RESOLVE_DONT_DESTROY(resolve) \ - _cleanup_resolve_unref_ _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve) + _cleanup_(sd_resolve_unrefp) _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve) static int send_died(int out_fd) { @@ -580,12 +583,8 @@ static void resolve_free(sd_resolve *resolve) { } /* Now terminate them and wait until they are gone. */ - for (i = 0; i < resolve->n_valid_workers; i++) { - for (;;) { - if (pthread_join(resolve->workers[i], NULL) != EINTR) - break; - } - } + for (i = 0; i < resolve->n_valid_workers; i++) + pthread_join(resolve->workers[i], NULL); /* Close all communication channels */ for (i = 0; i < _FD_MAX; i++) diff --git a/src/libsystemd/sd-resolve/test-resolve.c b/src/libsystemd/sd-resolve/test-resolve.c index e8056529f5..ce97e81ed6 100644 --- a/src/libsystemd/sd-resolve/test-resolve.c +++ b/src/libsystemd/sd-resolve/test-resolve.c @@ -20,18 +20,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <string.h> -#include <sys/socket.h> #include <arpa/inet.h> -#include <stdio.h> +#include <errno.h> #include <netinet/in.h> #include <resolv.h> -#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> -#include "socket-util.h" #include "sd-resolve.h" -#include "resolve-util.h" + +#include "alloc-util.h" #include "macro.h" +#include "socket-util.h" +#include "string-util.h" static int getaddrinfo_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) { const struct addrinfo *i; @@ -68,8 +70,8 @@ static int getnameinfo_handler(sd_resolve_query *q, int ret, const char *host, c } int main(int argc, char *argv[]) { - _cleanup_resolve_query_unref_ sd_resolve_query *q1 = NULL, *q2 = NULL; - _cleanup_resolve_unref_ sd_resolve *resolve = NULL; + _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q1 = NULL, *q2 = NULL; + _cleanup_(sd_resolve_unrefp) sd_resolve *resolve = NULL; int r = 0; struct addrinfo hints = { @@ -99,11 +101,11 @@ int main(int argc, char *argv[]) { if (r < 0) log_error_errno(r, "sd_resolve_getnameinfo(): %m"); - /* Wait until the two queries are completed */ - while (sd_resolve_query_is_done(q1) == 0 || - sd_resolve_query_is_done(q2) == 0) { - + /* Wait until all queries are completed */ + for (;;) { r = sd_resolve_wait(resolve, (uint64_t) -1); + if (r == 0) + break; if (r < 0) { log_error_errno(r, "sd_resolve_wait(): %m"); assert_not_reached("sd_resolve_wait() failed"); diff --git a/src/libsystemd/sd-utf8/sd-utf8.c b/src/libsystemd/sd-utf8/sd-utf8.c index 6f2aa6064c..9e52db3b3d 100644 --- a/src/libsystemd/sd-utf8/sd-utf8.c +++ b/src/libsystemd/sd-utf8/sd-utf8.c @@ -19,10 +19,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "utf8.h" #include "sd-utf8.h" +#include "utf8.h" +#include "util.h" + _public_ const char *sd_utf8_is_valid(const char *s) { assert_return(s, NULL); |