diff --git a/man/varlinkctl.xml b/man/varlinkctl.xml index eff49af349b..646fea0d247 100644 --- a/man/varlinkctl.xml +++ b/man/varlinkctl.xml @@ -184,6 +184,15 @@ + + + + This is similar to but collects all responses in a JSON + array, and prints it, rather than in JSON_SEQ mode. + + + + diff --git a/src/varlinkctl/varlinkctl.c b/src/varlinkctl/varlinkctl.c index 8f3a88aba57..714396d3874 100644 --- a/src/varlinkctl/varlinkctl.c +++ b/src/varlinkctl/varlinkctl.c @@ -19,6 +19,7 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF; static PagerFlags arg_pager_flags = 0; static VarlinkMethodFlags arg_method_flags = 0; +static bool arg_collect = false; static int help(void) { _cleanup_free_ char *link = NULL; @@ -47,6 +48,7 @@ static int help(void) { " --version Show package version\n" " --no-pager Do not pipe output into a pager\n" " --more Request multiple responses\n" + " --collect Collect multiple responses in a JSON array\n" " --oneway Do not request response\n" " --json=MODE Output as JSON\n" " -j Same as --json=pretty on tty, --json=short otherwise\n" @@ -73,6 +75,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_MORE, ARG_ONEWAY, ARG_JSON, + ARG_COLLECT, }; static const struct option options[] = { @@ -82,6 +85,7 @@ static int parse_argv(int argc, char *argv[]) { { "more", no_argument, NULL, ARG_MORE }, { "oneway", no_argument, NULL, ARG_ONEWAY }, { "json", required_argument, NULL, ARG_JSON }, + { "collect", no_argument, NULL, ARG_COLLECT }, {}, }; @@ -112,6 +116,10 @@ static int parse_argv(int argc, char *argv[]) { arg_method_flags = (arg_method_flags & ~VARLINK_METHOD_MORE) | VARLINK_METHOD_ONEWAY; break; + case ARG_COLLECT: + arg_collect = true; + break; + case ARG_JSON: r = parse_json_argument(optarg, &arg_json_format_flags); if (r <= 0) @@ -388,7 +396,26 @@ static int verb_call(int argc, char *argv[], void *userdata) { if (r < 0) return r; - if (arg_method_flags & VARLINK_METHOD_ONEWAY) { + if (arg_collect) { + JsonVariant *reply = NULL; + const char *error = NULL; + + r = varlink_collect(vl, method, jp, &reply, &error); + if (r < 0) + return log_error_errno(r, "Failed to issue %s() call: %m", method); + if (error) { + /* Propagate the error we received via sd_notify() */ + (void) sd_notifyf(/* unset_environment= */ false, "VARLINKERROR=%s", error); + + r = log_error_errno(SYNTHETIC_ERRNO(EBADE), "Method call %s() failed: %s", method, error); + } else + r = 0; + + pager_open(arg_pager_flags); + json_variant_dump(reply, arg_json_format_flags, stdout, NULL); + return r; + + } else if (arg_method_flags & VARLINK_METHOD_ONEWAY) { r = varlink_send(vl, method, jp); if (r < 0) return log_error_errno(r, "Failed to issue %s() call: %m", method);