]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: convenience functions to emit a signal to a destination (#25123)
authorErik Moqvist <erik.moqvist@gmail.com>
Mon, 31 Oct 2022 20:11:48 +0000 (21:11 +0100)
committerGitHub <noreply@github.com>
Mon, 31 Oct 2022 20:11:48 +0000 (20:11 +0000)
* sd-bus: convenience functions to emit a signal to a destination

man/sd-bus.xml
man/sd_bus_emit_signal.xml
man/sd_bus_message_new_signal.xml
src/libsystemd/libsystemd.sym
src/libsystemd/sd-bus/bus-convenience.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/test-bus-chat.c
src/systemd/sd-bus.h

index f43af897893ef0ecd65b19575c40f6227fd6ff9a..36925ba8c4c07f8a8494ab89d3ed66f2b4360e69 100644 (file)
@@ -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>,
 <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>,
index 08d5be400ed27f93651bde28e221f78e0e750955..52d08b7a92369571b14a9c822f257baefa301770 100644 (file)
@@ -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>
         <paramdef>va_list <parameter>ap</parameter></paramdef>
       </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>
     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
index 17862deb0b1a4aebfe17cb70d1de2aec56a9d7cf..0c4f6e3a35b9fd35dbfeba9ae48dba59f4cc2d29 100644 (file)
@@ -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>
         <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>
 
     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>
       <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>
 
index 3b72320f0cde32efafef879c19f604160d7248bb..07acb992717e59b4f6dd6aa67e149264f67c62d0 100644 (file)
@@ -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;
index 6a3f2ea0ecf31e352d124565f11e36576c9c7f45..6974e210a24a1d54c645b65364b26b47493e70db 100644 (file)
@@ -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,
index d9c52d64c07de002f0d0dbe4607fe6c7415a498d..39e21480ac2b2e36eb7e86c82eda3e744e112dd1 100644 (file)
@@ -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,
index 93e8ebfb1b2b1463c5d9818aefa628ea8265e71c..09401a978444e21e6381dcbe0d49021db9ed3965 100644 (file)
 #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,
index 74bc56b4274d356fb0605a381d1cf53f122ea935..bd3da36c36314e817dfb7ddc9e297c32f98617f6 100644 (file)
@@ -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_;