aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-11-10 07:35:10 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2025-11-10 07:35:10 +0000
commitcfacd5d6205ab664a0de185e6361c1702d16f622 (patch)
tree988bfb1c27356d1041574c6147005a458245a13d
parent8c7a6fdf4b9cae2d44a9ab03e0c4df5c2f59eb9b (diff)
downloads6-frontend-cfacd5d6205ab664a0de185e6361c1702d16f622.tar.gz
Add live_status
-rw-r--r--src/s6-frontend/live_status.c203
1 files changed, 199 insertions, 4 deletions
diff --git a/src/s6-frontend/live_status.c b/src/s6-frontend/live_status.c
index 67c6782..1d43166 100644
--- a/src/s6-frontend/live_status.c
+++ b/src/s6-frontend/live_status.c
@@ -1,18 +1,213 @@
/* ISC license. */
#include <unistd.h>
+#include <sys/wait.h>
-#include <skalibs/strerr.h>
-#include <skalibs/gol.h>
+#include <skalibs/gccattributes.h>
+#include <skalibs/envexec.h>
+#include <skalibs/cspawn.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/skamisc.h>
+#include <execline/config.h>
+
+#include <s6-rc/config.h>
+
+#include <s6-frontend/config.h>
#include "s6-frontend-internal.h"
#define USAGE "s6 live status services..."
#define dieusage() strerr_dieusage(100, USAGE)
+#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
+
+static void live_status_all (void) gccattr_noreturn ;
+static void live_status_all (void)
+{
+ static char const *const argv[] =
+ {
+#ifdef S6_FRONTEND_USE_UTIL_LINUX
+ EXECLINE_EXTBINPREFIX "pipeline", "-w", "--",
+ " column", " -ts/",
+ "",
+#endif
+ EXECLINE_EXTBINPREFIX "if",
+ " " EXECLINE_EXTBINPREFIX "pipeline",
+ " " S6RC_EXTBINPREFIX "s6-rc",
+ " -ua",
+ " list",
+ " ",
+ " sed",
+ " s|$|/up",
+ "",
+ " " S6RC_EXTBINPREFIX "s6-rc",
+ " -da",
+ " list",
+ "",
+ "sed",
+ "s|$|/down",
+ 0
+ } ;
+ xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
+
+static int get_list_of_up (stralloc *storage)
+{
+ int swasnull = !storage->s ;
+ size_t sabase = storage->len ;
+ int fd ;
+ int wstat ;
+ char const *argv[7] = { S6RC_EXTBINPREFIX "s6-rc", "-l", g->dirs.live, "-ba", "--", "list", 0 } ;
+ pid_t pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ;
+ if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; }
+ if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; }
+ fd_close(fd) ;
+ if (wait_pid(pid, &wstat) == -1)
+ {
+ strerr_warnfu2sys("wait for ", argv[0]) ;
+ goto err ;
+ }
+ if (WIFSIGNALED(wstat))
+ {
+ char fmt[UINT_FMT] ;
+ fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
+ strerr_warnf3x(argv[0], " crashed with signal ", fmt) ;
+ goto err ;
+ }
+ return wait_estatus(wstat) ;
+
+ err:
+ if (swasnull) stralloc_free(storage) ;
+ else storage->len = sabase ;
+ return 111 ;
+}
+
+static int get_atomics (char const *const *services, unsigned int n, stralloc *storage)
+{
+ int swasnull = !storage->s ;
+ size_t sabase = storage->len ;
+ pid_t pid ;
+ int fd ;
+ int wstat ;
+ unsigned int m = 0 ;
+ char const *argv[7 + n] ;
+ argv[m++] = S6RC_EXTBINPREFIX "s6-rc-db" ;
+ argv[m++] = "-l";
+ argv[m++] = g->dirs.live ;
+ argv[m++] = "-b" ;
+ argv[m++] = "--" ;
+ argv[m++] = "atomics" ;
+ for (unsigned int i = 0 ; i < n ; i++) argv[m++] = services[i] ;
+ argv[m++] = 0 ;
+ pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ;
+ if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; }
+ if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; }
+ fd_close(fd) ;
+ if (wait_pid(pid, &wstat) == -1)
+ {
+ strerr_warnfu2sys("wait for ", argv[0]) ;
+ goto err ;
+ }
+ if (WIFSIGNALED(wstat))
+ {
+ char fmt[UINT_FMT] ;
+ fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
+ strerr_warnf3x(argv[0], " crashed with signal ", fmt) ;
+ goto err ;
+ }
+ return wait_estatus(wstat) ;
+
+ err:
+ if (swasnull) stralloc_free(storage) ;
+ else storage->len = sabase ;
+ return 111 ;
+}
+
+static void live_status_some (char const *const *services) gccattr_noreturn ;
+static void live_status_some (char const *const *services)
+{
+ stralloc sa = STRALLOC_ZERO ;
+ unsigned int m = 0 ;
+ size_t uplistpos ;
+ int e ;
+ char const * argv[59] ;
+ if (!stralloc_catb(&sa, " ", 1)) dienomem() ;
+ e = get_atomics(services, env_len(services), &sa) ;
+ if (e) _exit(e) ;
+ if (!stralloc_catb(&sa, "\0 ", 3)) dienomem() ;
+ uplistpos = sa.len ;
+ e = get_list_of_up(&sa) ;
+ if (e) _exit(e) ;
+ if (!stralloc_0(&sa)) dienomem() ;
+
+#ifdef S6_FRONTEND_USE_UTIL_LINUX
+ argv[m++] = EXECLINE_EXTBINPREFIX "pipeline" ;
+ argv[m++] = "-w" ;
+ argv[m++] = "--" ;
+ argv[m++] = " column" ;
+ argv[m++] = " -ts/" ;
+ argv[m++] = "",
+#endif
+ argv[m++] = EXECLINE_EXTBINPREFIX "if" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "piperw" ;
+ argv[m++] = " 3" ;
+ argv[m++] = " 4" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "background" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "fdclose" ;
+ argv[m++] = " 3" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "fdmove" ;
+ argv[m++] = " 1" ;
+ argv[m++] = " 4" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "heredoc" ;
+ argv[m++] = " 0" ;
+ argv[m++] = sa.s + uplistpos - 2 ;
+ argv[m++] = " " ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "fdclose" ;
+ argv[m++] = " 4" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "heredoc" ;
+ argv[m++] = " 0" ;
+ argv[m++] = sa.s ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "pipeline" ;
+ argv[m++] = " grep" ;
+ argv[m++] = " -Fxf" ;
+ argv[m++] = " /dev/fd/3" ;
+ argv[m++] = " " ;
+ argv[m++] = " sed" ;
+ argv[m++] = " s|$|/up" ;
+ argv[m++] = "" ;
+ argv[m++] = EXECLINE_EXTBINPREFIX "piperw" ;
+ argv[m++] = "3" ;
+ argv[m++] = "4" ;
+ argv[m++] = EXECLINE_EXTBINPREFIX "background" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "fdclose" ;
+ argv[m++] = " 3" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "fdmove" ;
+ argv[m++] = " 1" ;
+ argv[m++] = " 4" ;
+ argv[m++] = " " EXECLINE_EXTBINPREFIX "heredoc" ;
+ argv[m++] = " 0" ;
+ argv[m++] = sa.s + uplistpos - 1 ;
+ argv[m++] = "" ;
+ argv[m++] = EXECLINE_EXTBINPREFIX "fdclose" ;
+ argv[m++] = "4" ;
+ argv[m++] = EXECLINE_EXTBINPREFIX "heredoc" ;
+ argv[m++] = "0" ;
+ argv[m++] = sa.s + 1 ;
+ argv[m++] = EXECLINE_EXTBINPREFIX "pipeline" ;
+ argv[m++] = " grep" ;
+ argv[m++] = " -Fxf" ;
+ argv[m++] = " /dev/fd/3" ;
+ argv[m++] = "" ;
+ argv[m++] = "sed" ;
+ argv[m++] = "s|$|/down" ;
+ argv[m++] = 0 ;
+ xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
void live_status (char const *const *argv)
{
argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ;
- if (!argv) dieusage() ;
- _exit(0) ;
+ if (!argv) live_status_all() ;
+ else live_status_some(argv) ;
+ // _exit(0) ;
}