Add exec_command_status_build_json() and exec_command_status_list_build_json() to varlink-common, alongside exec_command_build_json() and exec_command_list_build_json(). The status list function is the runtime counterpart of the command list function — the two arrays are positionally aligned so index N in the status array corresponds to index N in the command array. Commands that have not yet run produce null entries to preserve alignment.
Add the ExecCommandStatus varlink struct type to varlink-idl-common next to ExecCommand. It contains PID, timestamps, and mutually exclusive ExitStatus (int, for normal exit) / ExitSignal (string, for signal kill).
#include "cpu-set-util.h"
#include "execute.h"
#include "json-util.h"
+#include "pidref.h"
+#include "process-util.h"
#include "rlimit-util.h"
#include "varlink-common.h"
#include "varlink-unit.h"
*ret = TAKE_PTR(v);
return 0;
}
+
+int exec_command_status_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+ ExecStatus *status = ASSERT_PTR(userdata);
+
+ assert(ret);
+
+ if (!pid_is_valid(status->pid)) {
+ *ret = NULL;
+ return 0;
+ }
+
+ return sd_json_buildo(
+ ret,
+ /* TODO: replace with a real PidRef once ExecStatus carries one */
+ SD_JSON_BUILD_PAIR("PID", JSON_BUILD_PIDREF(&PIDREF_MAKE_FROM_PID(status->pid))),
+ JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("StartTimestamp", &status->start_timestamp),
+ JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ExitTimestamp", &status->exit_timestamp),
+ JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("HandoffTimestamp", &status->handoff_timestamp),
+ SD_JSON_BUILD_PAIR_CONDITION(status->code > 0, "Code", SD_JSON_BUILD_INTEGER(status->code)),
+ SD_JSON_BUILD_PAIR_CONDITION(status->code > 0, "Status", SD_JSON_BUILD_INTEGER(status->status)));
+}
+
+/* exec_command_status_list_build_json() is the runtime counterpart of exec_command_list_build_json().
+ * The two arrays are positionally aligned: index N in the status array corresponds to index N in the
+ * command array. Commands that have not yet run produce null entries to preserve alignment. */
+int exec_command_status_list_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+ ExecCommand *list = userdata;
+ bool any_ran = false;
+ int r;
+
+ assert(ret);
+
+ LIST_FOREACH(command, c, list) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *entry = NULL;
+
+ r = exec_command_status_build_json(&entry, /* name= */ NULL, &c->exec_status);
+ if (r < 0)
+ return r;
+
+ if (entry) {
+ any_ran = true;
+ r = sd_json_variant_append_array(&v, entry);
+ } else
+ r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_NULL);
+ if (r < 0)
+ return r;
+ }
+
+ if (!any_ran) {
+ *ret = NULL;
+ return 0;
+ }
+
+ *ret = TAKE_PTR(v);
+ return 0;
+}
const char* varlink_error_id_from_bus_error(const sd_bus_error *e);
int exec_command_build_json(sd_json_variant **ret, const char *name, void *userdata);
int exec_command_list_build_json(sd_json_variant **ret, const char *name, void *userdata);
+int exec_command_status_build_json(sd_json_variant **ret, const char *name, void *userdata);
+int exec_command_status_list_build_json(sd_json_variant **ret, const char *name, void *userdata);
int varlink_reply_bus_error(sd_varlink *link, int r, const sd_bus_error *e);
SD_VARLINK_FIELD_COMMENT("Run via shell"),
SD_VARLINK_DEFINE_FIELD(viaShell, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
+SD_VARLINK_DEFINE_STRUCT_TYPE(
+ ExecCommandStatus,
+ SD_VARLINK_FIELD_COMMENT("Process ID"),
+ SD_VARLINK_DEFINE_FIELD_BY_TYPE(PID, ProcessId, 0),
+ SD_VARLINK_FIELD_COMMENT("Timestamp when the process started"),
+ SD_VARLINK_DEFINE_FIELD_BY_TYPE(StartTimestamp, Timestamp, SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("Timestamp when the process exited"),
+ SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExitTimestamp, Timestamp, SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("Timestamp when the process was handed off to the executor"),
+ SD_VARLINK_DEFINE_FIELD_BY_TYPE(HandoffTimestamp, Timestamp, SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("Termination reason (si_code): CLD_EXITED, CLD_KILLED, CLD_DUMPED"),
+ SD_VARLINK_DEFINE_FIELD(Code, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("Exit code or signal number (si_status), meaning depends on Code"),
+ SD_VARLINK_DEFINE_FIELD(Status, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
+
SD_VARLINK_DEFINE_ENUM_TYPE(
ExecOutputType,
SD_VARLINK_DEFINE_ENUM_VALUE(inherit),
extern const sd_varlink_symbol vl_type_ResourceLimit;
extern const sd_varlink_symbol vl_type_ResourceLimitTable;
extern const sd_varlink_symbol vl_type_ExecCommand;
+extern const sd_varlink_symbol vl_type_ExecCommandStatus;
extern const sd_varlink_symbol vl_type_ExecOutputType;
extern const sd_varlink_symbol vl_type_CGroupPressureWatch;
extern const sd_varlink_symbol vl_type_ManagedOOMMode;