diff options
author | Erik Moqvist <erik.moqvist@gmail.com> | 2022-10-31 21:11:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-31 20:11:48 +0000 |
commit | 85bc6b05491fb4c9f40f8a0e8615ac5321efbea0 (patch) | |
tree | 103829f6929abbcd723da69a796902968bfefe29 | |
parent | a0961675d370ebe1308b8c11db46871aeed9948c (diff) | |
download | systemd-85bc6b05491fb4c9f40f8a0e8615ac5321efbea0.tar.gz |
sd-bus: convenience functions to emit a signal to a destination (#25123)
* sd-bus: convenience functions to emit a signal to a destination
-rw-r--r-- | man/sd-bus.xml | 3 | ||||
-rw-r--r-- | man/sd_bus_emit_signal.xml | 29 | ||||
-rw-r--r-- | man/sd_bus_message_new_signal.xml | 16 | ||||
-rw-r--r-- | src/libsystemd/libsystemd.sym | 7 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-convenience.c | 33 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-message.c | 20 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-chat.c | 31 | ||||
-rw-r--r-- | src/systemd/sd-bus.h | 3 |
8 files changed, 138 insertions, 4 deletions
diff --git a/man/sd-bus.xml b/man/sd-bus.xml index f43af89789..36925ba8c4 100644 --- a/man/sd-bus.xml +++ b/man/sd-bus.xml @@ -68,6 +68,8 @@ <citerefentry><refentrytitle>sd_bus_emit_properties_changed_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_emit_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_emit_signalv</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_emit_signal_to</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_emit_signal_tov</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-bus-errors</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_error_add_map</refentrytitle><manvolnum>3</manvolnum></citerefentry>, @@ -122,6 +124,7 @@ <citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_new_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_new_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_message_new_signal_to</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_open_container</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_peek_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_read</refentrytitle><manvolnum>3</manvolnum></citerefentry>, diff --git a/man/sd_bus_emit_signal.xml b/man/sd_bus_emit_signal.xml index 08d5be400e..52d08b7a92 100644 --- a/man/sd_bus_emit_signal.xml +++ b/man/sd_bus_emit_signal.xml @@ -19,6 +19,8 @@ <refnamediv> <refname>sd_bus_emit_signal</refname> <refname>sd_bus_emit_signalv</refname> + <refname>sd_bus_emit_signal_to</refname> + <refname>sd_bus_emit_signal_tov</refname> <refname>sd_bus_emit_interfaces_added</refname> <refname>sd_bus_emit_interfaces_added_strv</refname> <refname>sd_bus_emit_interfaces_removed</refname> @@ -56,6 +58,28 @@ </funcprototype> <funcprototype> + <funcdef>int <function>sd_bus_emit_signal_to</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>const char *<parameter>types</parameter></paramdef> + <paramdef>...</paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_emit_signal_tov</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>const char *<parameter>types</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> + </funcprototype> + + <funcprototype> <funcdef>int <function>sd_bus_emit_interfaces_added</function></funcdef> <paramdef>sd_bus *<parameter>bus</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef> @@ -128,6 +152,11 @@ equivalent to <function>sd_bus_message_append()</function>, except that it is called with a <literal>va_list</literal> instead of a variable number of arguments.</para> + <para><function>sd_bus_emit_signal_to()</function> and <function>sd_bus_emit_signal_tov()</function> are + identical to <function>sd_bus_emit_signal()</function> and <function>sd_bus_emit_signalv()</function>, except + that they can emit the signal to a single destination. Give <parameter>destination</parameter> as + <constant>NULL</constant> to broadcast the signal.</para> + <para><function>sd_bus_emit_interfaces_added()</function> and <function>sd_bus_emit_interfaces_removed()</function> are used to implement the <function>InterfacesAdded</function> and <function>InterfacesRemoved</function> signals of the diff --git a/man/sd_bus_message_new_signal.xml b/man/sd_bus_message_new_signal.xml index 17862deb0b..0c4f6e3a35 100644 --- a/man/sd_bus_message_new_signal.xml +++ b/man/sd_bus_message_new_signal.xml @@ -18,6 +18,7 @@ <refnamediv> <refname>sd_bus_message_new_signal</refname> + <refname>sd_bus_message_new_signal_to</refname> <refpurpose>Create a signal message</refpurpose> </refnamediv> @@ -34,6 +35,16 @@ <paramdef>const char *<parameter>interface</parameter></paramdef> <paramdef>const char *<parameter>member</parameter></paramdef> </funcprototype> + + <funcprototype> + <funcdef>int sd_bus_message_new_signal_to</funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_message **<parameter>m</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> @@ -49,6 +60,10 @@ for a short description of the meaning of the <parameter>path</parameter>, <parameter>interface</parameter>, and <parameter>member</parameter> parameters. </para> + + <para><function>sd_bus_message_new_signal_to()</function> is a shorthand for creating a new bus message + to a specific destination. It's behavior is similar to calling <function>sd_bus_message_new_signal()</function> + followed by calling <citerefentry><refentrytitle>sd_bus_message_set_destination()</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> </refsect1> <refsect1> @@ -115,6 +130,7 @@ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_emit_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry> + <citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry> </para> </refsect1> diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 3b72320f0c..07acb99271 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -796,3 +796,10 @@ global: sd_hwdb_new_from_path; } LIBSYSTEMD_251; + +LIBSYSTEMD_253 { +global: + sd_bus_emit_signal_to; + sd_bus_emit_signal_tov; + sd_bus_message_new_signal_to; +} LIBSYSTEMD_252; diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 6a3f2ea0ec..6974e210a2 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -17,8 +17,9 @@ _public_ int sd_bus_message_send(sd_bus_message *reply) { return sd_bus_send(reply->bus, reply, NULL); } -_public_ int sd_bus_emit_signalv( +_public_ int sd_bus_emit_signal_tov( sd_bus *bus, + const char *destination, const char *path, const char *interface, const char *member, @@ -34,7 +35,7 @@ _public_ int sd_bus_emit_signalv( if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; - r = sd_bus_message_new_signal(bus, &m, path, interface, member); + r = sd_bus_message_new_signal_to(bus, &m, destination, path, interface, member); if (r < 0) return r; @@ -47,6 +48,34 @@ _public_ int sd_bus_emit_signalv( return sd_bus_send(bus, m, NULL); } +_public_ int sd_bus_emit_signal_to( + sd_bus *bus, + const char *destination, + const char *path, + const char *interface, + const char *member, + const char *types, ...) { + + va_list ap; + int r; + + va_start(ap, types); + r = sd_bus_emit_signal_tov(bus, destination, path, interface, member, types, ap); + va_end(ap); + + return r; +} + +_public_ int sd_bus_emit_signalv( + sd_bus *bus, + const char *path, + const char *interface, + const char *member, + const char *types, va_list ap) { + + return sd_bus_emit_signal_tov(bus, NULL, path, interface, member, types, ap); +} + _public_ int sd_bus_emit_signal( sd_bus *bus, const char *path, diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index d9c52d64c0..39e21480ac 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -483,9 +483,10 @@ _public_ int sd_bus_message_new( return 0; } -_public_ int sd_bus_message_new_signal( +_public_ int sd_bus_message_new_signal_to( sd_bus *bus, sd_bus_message **m, + const char *destination, const char *path, const char *interface, const char *member) { @@ -496,6 +497,7 @@ _public_ int sd_bus_message_new_signal( assert_return(bus, -ENOTCONN); assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state != BUS_UNSET, -ENOTCONN); + assert_return(!destination || service_name_is_valid(destination), -EINVAL); assert_return(object_path_is_valid(path), -EINVAL); assert_return(interface_name_is_valid(interface), -EINVAL); assert_return(member_name_is_valid(member), -EINVAL); @@ -519,10 +521,26 @@ _public_ int sd_bus_message_new_signal( if (r < 0) return r; + if (destination) { + r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination); + if (r < 0) + return r; + } + *m = TAKE_PTR(t); return 0; } +_public_ int sd_bus_message_new_signal( + sd_bus *bus, + sd_bus_message **m, + const char *path, + const char *interface, + const char *member) { + + return sd_bus_message_new_signal_to(bus, m, NULL, path, interface, member); +} + _public_ int sd_bus_message_new_method_call( sd_bus *bus, sd_bus_message **m, diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 93e8ebfb1b..09401a9784 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -21,7 +21,10 @@ #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))); + log_info("Match triggered! destination=%s interface=%s member=%s", + strna(sd_bus_message_get_destination(m)), + strna(sd_bus_message_get_interface(m)), + strna(sd_bus_message_get_member(m))); return 0; } @@ -95,6 +98,12 @@ static int server_init(sd_bus **_bus) { goto fail; } + r = sd_bus_match_signal(bus, NULL, NULL, NULL, "foo.bar", "NotifyTo", match_callback, NULL); + if (r < 0) { + log_error_errno(r, "Failed to request match: %m"); + goto fail; + } + r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); @@ -397,6 +406,26 @@ static void* client2(void *p) { m = sd_bus_message_unref(m); + r = sd_bus_message_new_signal_to( + bus, + &m, + "org.freedesktop.systemd.test", + "/foobar", + "foo.bar", + "NotifyTo"); + if (r < 0) { + log_error_errno(r, "Failed to allocate signal to: %m"); + goto finish; + } + + r = sd_bus_send(bus, m, NULL); + if (r < 0) { + log_error("Failed to issue signal to: %s", bus_error_message(&error, r)); + goto finish; + } + + m = sd_bus_message_unref(m); + r = sd_bus_message_new_method_call( bus, &m, diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 74bc56b427..bd3da36c36 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -260,6 +260,7 @@ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot); int sd_bus_message_new(sd_bus *bus, sd_bus_message **m, uint8_t type); int sd_bus_message_new_signal(sd_bus *bus, sd_bus_message **m, const char *path, const char *interface, const char *member); +int sd_bus_message_new_signal_to(sd_bus *bus, sd_bus_message **m, const char *destination, const char *path, const char *interface, const char *member); int sd_bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const char *destination, const char *path, const char *interface, const char *member); int sd_bus_message_new_method_return(sd_bus_message *call, sd_bus_message **m); int sd_bus_message_new_method_error(sd_bus_message *call, sd_bus_message **m, const sd_bus_error *e); @@ -379,6 +380,8 @@ int sd_bus_reply_method_errnof(sd_bus_message *call, int error, const char *form int sd_bus_emit_signalv(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, va_list ap); int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...); +int sd_bus_emit_signal_tov(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, const char *types, va_list ap); +int sd_bus_emit_signal_to(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, const char *types, ...); int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names); int sd_bus_emit_properties_changed(sd_bus *bus, const char *path, const char *interface, const char *name, ...) _sd_sentinel_; |