]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared: add exec_command_status_build_json() and ExecCommandStatus varlink type to...
authorIvan Kruglov <mail@ikruglov.com>
Thu, 14 May 2026 16:41:24 +0000 (09:41 -0700)
committerikruglov <ikruglov@fb.com>
Fri, 15 May 2026 07:02:01 +0000 (00:02 -0700)
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).

src/core/varlink-common.c
src/core/varlink-common.h
src/shared/varlink-idl-common.c
src/shared/varlink-idl-common.h

index f5745e12e8e494dafdfd3d873c3da408b2b4d273..bdbecd4551bd6995cd1a9895fbfdf192441fc2f1 100644 (file)
@@ -7,6 +7,8 @@
 #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"
@@ -159,3 +161,60 @@ int exec_command_list_build_json(sd_json_variant **ret, const char *name, void *
         *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;
+}
index 8a238c34a5d7397ab9a69cd6bfde9dac1d179554..98fe47b48ccaadc64a6aa40bf6019aeeaa3130f0 100644 (file)
@@ -9,4 +9,6 @@ int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata);
 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);
index a543c92a3b8a3f2c7171926b7142fdd7e554cb5f..d9b148daac66af802b3f551fa7cd7a2e7beda598 100644 (file)
@@ -71,6 +71,21 @@ SD_VARLINK_DEFINE_STRUCT_TYPE(
                 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),
index a42df7118bdc1d9e8913ec9d0880a32613ffaaf4..5bd351734a9b9ca17fc912ec211ae5dbe8e7a3b6 100644 (file)
@@ -9,6 +9,7 @@ extern const sd_varlink_symbol vl_type_RateLimit;
 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;