diff --git a/cmd/Makemodule.am b/cmd/Makemodule.am index c503215..5c9ed56 100644 --- a/cmd/Makemodule.am +++ b/cmd/Makemodule.am @@ -19,6 +19,7 @@ SRVHEADERS = cmd/service/servicecmd.h service_SOURCES = cmd/service/servicecmd.c cmd/service/help.c service_SOURCES += cmd/service/enable.c cmd/service/disable.c service_SOURCES += cmd/service/dumpscript.c cmd/service/list.c +service_SOURCES += cmd/service/status.c service_SOURCES += $(SRVHEADERS) service_CPPFLAGS = $(AM_CPPFLAGS) service_CFLAGS = $(AM_CFLAGS) diff --git a/cmd/service/service.8 b/cmd/service/service.8 index 86036a3..c69aac5 100644 --- a/cmd/service/service.8 +++ b/cmd/service/service.8 @@ -38,6 +38,10 @@ the desired service instance. .BR dumpscript " " \fI\fP " " \fI[arguments]\fP Parse a service file from and produce a pseudo shell script containing the exact commands executed when starting the service. +.TP +.BR status +Print a status report of all supervised services, i.e. if they are currently +running, have exited or waiting to be scheduled. .SH AVAILABILITY This program is part of the Pygos init system. .SH COPYRIGHT diff --git a/cmd/service/status.c b/cmd/service/status.c new file mode 100644 index 0000000..c8e87c4 --- /dev/null +++ b/cmd/service/status.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: ISC */ +#include "servicecmd.h" +#include "initsock.h" +#include "service.h" +#include "config.h" + +#include + +static void free_resp(init_status_response_t *resp) +{ + free(resp->filename); + free(resp->service_name); +} + +static int cmd_status(int argc, char **argv) +{ + init_status_response_t resp; + int fd, ret = EXIT_FAILURE; + char tmppath[256]; + const char *state; + bool is_tty; + + if (check_arguments(argv[0], argc, 1, 1)) + return EXIT_FAILURE; + + sprintf(tmppath, "/tmp/svcstatus.%d.sock", (int)getpid()); + fd = init_socket_open(tmppath); + + if (fd < 0) { + unlink(tmppath); + return EXIT_FAILURE; + } + + if (init_socket_send_request(fd, EIR_STATUS)) + goto out; + + is_tty = (isatty(STDOUT_FILENO) == 1); + + for (;;) { + memset(&resp, 0, sizeof(resp)); + + if (init_socket_recv_status(fd, &resp)) { + perror("reading from initd socket"); + free_resp(&resp); + goto out; + } + + if (resp.state == ESS_NONE) { + free_resp(&resp); + break; + } + + switch (resp.state) { + case ESS_RUNNING: + if (!is_tty) { + state = "Running"; + break; + } + state = "\033[22;32mRunning\033[0m"; + break; + case ESS_ENQUEUED: + state = " Queue "; + break; + case ESS_EXITED: + if (!is_tty) { + state = "Exited "; + break; + } + if (resp.exit_status == EXIT_SUCCESS) { + state = "\033[22;33mExited \033[0m"; + } else { + state = "\033[22;31mExited \033[0m"; + } + break; + default: + if (!is_tty) { + state = "Unknown"; + break; + } + state = "\033[22;31mUnknown\033[0m"; + break; + } + + printf("[%s] %s\n", state, resp.filename); + + free_resp(&resp); + } + + ret = EXIT_SUCCESS; +out: + close(fd); + unlink(tmppath); + return ret; +} + +static command_t status = { + .cmd = "status", + .usage = "", + .s_desc = "report the status of the currently enabled services", + .l_desc = "Gathers a list of all currently running services and the " + "state that they are in (currently running, exited, wating " + "to get scheduled).", + .run_cmd = cmd_status, +}; + +REGISTER_COMMAND(status)