diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index e4c2d5d..61ed34d 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -29,13 +29,14 @@ BUS_PROPERTY_DUAL_TIMESTAMP(prefix "ExitTimestamp", (offset) + offsetof(ExecStatus, exit_timestamp), flags), \ SD_BUS_PROPERTY(prefix "PID", "u", bus_property_get_pid, (offset) + offsetof(ExecStatus, pid), flags), \ SD_BUS_PROPERTY(prefix "Code", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, code), flags), \ - SD_BUS_PROPERTY(prefix "Status", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, status), flags) + SD_BUS_PROPERTY(prefix "Status", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, status), flags), \ + SD_BUS_PROPERTY(prefix "ERRNO", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, errno_code), flags) #define BUS_EXEC_COMMAND_VTABLE(name, offset, flags) \ - SD_BUS_PROPERTY(name, "a(sasbttttuii)", bus_property_get_exec_command, offset, flags) + SD_BUS_PROPERTY(name, "a(sasbttttuiii)", bus_property_get_exec_command, offset, flags) #define BUS_EXEC_COMMAND_LIST_VTABLE(name, offset, flags) \ - SD_BUS_PROPERTY(name, "a(sasbttttuii)", bus_property_get_exec_command_list, offset, flags) + SD_BUS_PROPERTY(name, "a(sasbttttuiii)", bus_property_get_exec_command_list, offset, flags) extern const sd_bus_vtable bus_exec_vtable[]; diff --git a/src/core/execute.c b/src/core/execute.c index 1ea6463..e30ec95 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2421,6 +2421,11 @@ void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) { prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime), prefix, sigchld_code_to_string(s->code), prefix, s->status); + + if (s->errno_code != 0) + fprintf(f, + "%sErrno Code: %i\n", + prefix, s->errno_code); } char *exec_command_line(char **argv) { diff --git a/src/core/execute.h b/src/core/execute.h index 9d05d3a..1c8efd8 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -72,6 +72,7 @@ struct ExecStatus { pid_t pid; int code; /* as in siginfo_t::si_code */ int status; /* as in sigingo_t::si_status */ + int errno_code; /* ERRNO message from NOTIFY_SOCKET interface */ }; struct ExecCommand { diff --git a/src/core/service.c b/src/core/service.c index 10dc79c..4e4dc21 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2565,6 +2565,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { Service *s = SERVICE(u); const char *e; bool notify_dbus = false; + int errno_code; assert(u); @@ -2604,6 +2605,24 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { } } + /* Interpret ERRNO= */ + if ((e = strv_find_prefix(tags, "ERRNO=")) && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) { + + if (safe_atoi(e + 6, &errno_code) < 0) + log_warning_unit(u->id, + "Failed to parse notification message %s", e); + else { + log_debug_unit(u->id, + "%s: got %s", u->id, e); + s->main_exec_status.errno_code = errno_code; + notify_dbus = true; + } + } + /* Interpret READY= */ if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START && strv_find(tags, "READY=1")) { log_debug_unit(u->id, "%s: got READY=1", u->id);