]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
busctl: add --num-matches= for monitor verb 33961/head
authorLuca Boccassi <bluca@debian.org>
Wed, 7 Aug 2024 20:59:26 +0000 (21:59 +0100)
committerLuca Boccassi <bluca@debian.org>
Fri, 9 Aug 2024 11:12:28 +0000 (12:12 +0100)
Useful in scripts when one wants to wait for a specific
signal before continuing

man/busctl.xml
shell-completion/bash/busctl
shell-completion/zsh/_busctl
src/busctl/busctl.c
test/units/TEST-74-AUX-UTILS.busctl.sh

index 0938582c8bd799cdbbc5aca8ec3772128a953a74..c313d29955a43dc03dfbb633fff27d2b1fc6c5c4 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--num-matches=<replaceable>NUMBER</replaceable></option></term>
+
+        <listitem>
+          <para>When used with the <command>monitor</command> command, if enabled will make
+          <command>busctl</command> exit when the specified number of messages have been received and
+          printed. This is useful in combination with <option>--match=</option>, to wait for the specified
+          number of occurrences of specific D-Bus messages.</para>
+
+        <xi:include href="version-info.xml" xpointer="v257"/>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--augment-creds=<replaceable>BOOL</replaceable></option></term>
 
index bb80c1768302d0f56afb5182cffbc258d3b3d4e6..ea88cca8c6e4f8c81724b5ce48c2b9920d12cc9c 100644 (file)
@@ -89,7 +89,7 @@ _busctl() {
                       --allow-interactive-authorization=no --augment-creds=no
                       --watch-bind=yes -j -l --full --xml-interface'
         [ARG]='--address -H --host -M --machine --match --timeout --size --json
-                      --destination'
+                      --destination --num-matches'
     )
 
     if __contains_word "--user" ${COMP_WORDS[*]}; then
index c8c4f96ed1654b7d890cdbd86749d81b0f2da3a8..0018cf662233a4c93010ac486496d0db53a5fa7b 100644 (file)
@@ -284,4 +284,5 @@ _arguments \
     '--allow-interactive-authorization=[Allow interactive authorization for operation]:boolean:(1 0)' \
     '--timeout=[Maximum time to wait for method call completion and monitoring]:timeout (seconds)' \
     '--augment-creds=[Extend credential data with data read from /proc/$PID]:boolean:(1 0)' \
+    '--num-matches=[Exit after receiving a number of matches while monitoring]:integer' \
     '*::busctl command:_busctl_commands'
index 31104f36c5943f41c1973aad6e4b2c4bcc87501e..3735337a800d430f77d3ed121b1ceb196bdfa504 100644 (file)
@@ -63,6 +63,7 @@ static bool arg_augment_creds = true;
 static bool arg_watch_bind = false;
 static usec_t arg_timeout = 0;
 static const char *arg_destination = NULL;
+static uint64_t arg_num_matches = UINT64_MAX;
 
 STATIC_DESTRUCTOR_REGISTER(arg_matches, strv_freep);
 
@@ -1361,6 +1362,12 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f
                         dump(m, stdout);
                         fflush(stdout);
 
+                        if (arg_num_matches != UINT64_MAX && --arg_num_matches == 0) {
+                                if (!arg_quiet && arg_json_format_flags == SD_JSON_FORMAT_OFF)
+                                        log_info("Received requested number of matching messages, exiting.");
+                                return 0;
+                        }
+
                         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
                                 if (!arg_quiet && arg_json_format_flags == SD_JSON_FORMAT_OFF)
                                         log_info("Connection terminated, exiting.");
@@ -2361,6 +2368,8 @@ static int help(void) {
                "     --watch-bind=BOOL     Wait for bus AF_UNIX socket to be bound in the file\n"
                "                           system\n"
                "     --destination=SERVICE Destination service of a signal\n"
+               "     --num-matches=NUMBER  Exit after receiving a number of matches while\n"
+               "                           monitoring\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                ansi_highlight(),
@@ -2400,6 +2409,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_WATCH_BIND,
                 ARG_JSON,
                 ARG_DESTINATION,
+                ARG_NUM_MATCHES,
         };
 
         static const struct option options[] = {
@@ -2432,6 +2442,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "watch-bind",                      required_argument, NULL, ARG_WATCH_BIND                      },
                 { "json",                            required_argument, NULL, ARG_JSON                            },
                 { "destination",                     required_argument, NULL, ARG_DESTINATION                     },
+                { "num-matches",                     required_argument, NULL, ARG_NUM_MATCHES                     },
                 {},
         };
 
@@ -2600,6 +2611,15 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_destination = optarg;
                         break;
 
+                case ARG_NUM_MATCHES:
+                        r = safe_atou64(optarg, &arg_num_matches);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --num-matches= parameter '%s': %m", optarg);
+                        if (arg_num_matches == 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--num-matches= parameter cannot be 0");
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
index 6e997b46c641b24e523ed1b2b2a1e6ef9b722214..3ef94e5cb9f3b81a5a86a525bddd34d5e302aaa8 100755 (executable)
@@ -109,4 +109,4 @@ busctl get-property -j \
 (! busctl set-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager \
                        KExecWatchdogUSec t "foo")
 
-busctl --quiet --timeout 1 --match "interface=org.freedesktop.systemd1.Manager" monitor >/dev/null
+busctl --quiet --timeout 1 --num-matches 1 --match "interface=org.freedesktop.systemd1.Manager" monitor >/dev/null