diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 820f3e13e1..05c3b99bd6 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -538,4 +538,6 @@ global: sd_bus_request_name_async; sd_bus_release_name_async; sd_bus_add_match_async; + sd_bus_match_signal; + sd_bus_match_signal_async; } LIBSYSTEMD_236; diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 9d3b596429..7d702e6376 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -615,3 +615,69 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) return 0; } + +#define make_expression(sender, path, interface, member) \ + strjoina( \ + "type='signal'", \ + sender ? ",sender='" : "", \ + sender ?: "", \ + sender ? "'" : "", \ + path ? ",path='" : "", \ + path ?: "", \ + path ? "'" : "", \ + interface ? ",interface='" : "", \ + interface ?: "", \ + interface ? "'" : "", \ + member ? ",member='" : "", \ + member ?: "", \ + member ? "'" : "" \ + ) + +_public_ int sd_bus_match_signal( + sd_bus *bus, + sd_bus_slot **ret, + const char *sender, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + void *userdata) { + + const char *expression; + + assert_return(bus, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(!sender || service_name_is_valid(sender), -EINVAL); + assert_return(!path || object_path_is_valid(path), -EINVAL); + assert_return(!interface || interface_name_is_valid(interface), -EINVAL); + assert_return(!member || member_name_is_valid(member), -EINVAL); + + expression = make_expression(sender, path, interface, member); + + return sd_bus_add_match(bus, ret, expression, callback, userdata); +} + +_public_ int sd_bus_match_signal_async( + sd_bus *bus, + sd_bus_slot **ret, + const char *sender, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + sd_bus_message_handler_t install_callback, + void *userdata) { + + const char *expression; + + assert_return(bus, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(!sender || service_name_is_valid(sender), -EINVAL); + assert_return(!path || object_path_is_valid(path), -EINVAL); + assert_return(!interface || interface_name_is_valid(interface), -EINVAL); + assert_return(!member || member_name_is_valid(member), -EINVAL); + + expression = make_expression(sender, path, interface, member); + + return sd_bus_add_match_async(bus, ret, expression, callback, install_callback, userdata); +} diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 8877778769..9a6581348c 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -341,6 +341,9 @@ int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *in int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds); int sd_bus_query_sender_privilege(sd_bus_message *call, int capability); +int sd_bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t match_callback, sd_bus_message_handler_t add_callback, void *userdata); + /* Credential handling */ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t creds_mask);