aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-01-20 05:09:46 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-01-20 05:09:46 +0000
commit7b721d760c3238ff4a40dc7e5934dfa97dd7852c (patch)
treed0469321766a63e7a02c86e458522b505aad4040
parenteae030239206c6217bd311be43a81809eb13239c (diff)
downloads6-frontend-7b721d760c3238ff4a40dc7e5934dfa97dd7852c.tar.gz
Add s6-frontend-helper-echo, fix live_status and process_startstop
-rw-r--r--doc/index.html1
-rw-r--r--doc/s6-frontend-helper-echo.html40
-rw-r--r--package/deps.mak5
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak1
-rw-r--r--src/helpers/deps-exe/s6-frontend-helper-echo1
-rw-r--r--src/helpers/s6-frontend-helper-echo.c54
-rw-r--r--src/s6-frontend/live_status.c16
-rw-r--r--src/s6-frontend/process_startstop.c2
9 files changed, 112 insertions, 9 deletions
diff --git a/doc/index.html b/doc/index.html
index 4b7c0e9..766c42e 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -161,6 +161,7 @@ the previous versions of s6-frontend and the current one. </li>
<ul>
<li> <a href="s6-frontend.html">The <tt>s6-frontend</tt> program</a> </li>
<li> <a href="s6-frontend-helper-kill.html">The <tt>s6-frontend-helper-kill</tt> program</a> </li>
+<li> <a href="s6-frontend-helper-echo.html">The <tt>s6-frontend-helper-echo</tt> program</a> </li>
</ul>
<h3> Configuration </h3>
diff --git a/doc/s6-frontend-helper-echo.html b/doc/s6-frontend-helper-echo.html
new file mode 100644
index 0000000..9a99689
--- /dev/null
+++ b/doc/s6-frontend-helper-echo.html
@@ -0,0 +1,40 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-frontend: the s6-frontend-helper-echo program</title>
+ <meta name="Description" content="s6-frontend: the s6-frontend-helper-echo program" />
+ <meta name="Keywords" content="s6 s6-frontend helper echo" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-frontend-helper-echo</tt> internal program </h1>
+
+<p>
+ <tt>s6-frontend-helper-echo</tt> is a small utility to echo arguments to stdout.
+It is not meant to be called directly,
+although nothing bad will happen if you do. It is used in command lines crafted by
+<a href="s6_live.html#status">s6 live status</a> instead of the POSIX
+<a href="https://pubs.opengroup.org/onlinepubs/9799919799/utilities/echo.html">echo</a>
+program, because implementations of <tt>echo</tt> are infamously inconsistent with
+regards to options and arguments starting with a dash, so it's better not to rely on
+them at all.
+</p>
+
+<p>
+ <tt>s6-frontend-helper-echo</tt> is basically a copy of
+<a href="//skarnet.org/software/s6-portable-utils/s6-echo.html">s6-echo</a> and
+behaves exactly the same. The program has been included in s6-frontend in order to avoid
+a dependency to <a href="//skarnet.org/software/s6-portable-utils/">s6-portable-utils</a>.
+</p>
+
+</body>
+</html>
diff --git a/package/deps.mak b/package/deps.mak
index a715f1c..3ea6480 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -3,6 +3,7 @@
#
src/s6-frontend/s6-frontend-internal.h: src/include/s6-frontend/config.h src/include-local/s6f.h
+src/helpers/s6-frontend-helper-echo.o src/helpers/s6-frontend-helper-echo.lo: src/helpers/s6-frontend-helper-echo.c
src/helpers/s6-frontend-helper-kill.o src/helpers/s6-frontend-helper-kill.lo: src/helpers/s6-frontend-helper-kill.c
src/libs6f/s6f_confdir_open.o src/libs6f/s6f_confdir_open.lo: src/libs6f/s6f_confdir_open.c src/include-local/s6f.h
src/libs6f/s6f_equote.o src/libs6f/s6f_equote.lo: src/libs6f/s6f_equote.c src/include-local/s6f.h
@@ -26,7 +27,7 @@ src/s6-frontend/repository_check.o src/s6-frontend/repository_check.lo: src/s6-f
src/s6-frontend/repository_init.o src/s6-frontend/repository_init.lo: src/s6-frontend/repository_init.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/repository_list.o src/s6-frontend/repository_list.lo: src/s6-frontend/repository_list.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/repository_sync.o src/s6-frontend/repository_sync.lo: src/s6-frontend/repository_sync.c src/s6-frontend/s6-frontend-internal.h
-src/s6-frontend/s6-frontend.o src/s6-frontend/s6-frontend.lo: src/s6-frontend/s6-frontend.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/s6-frontend.o src/s6-frontend/s6-frontend.lo: src/s6-frontend/s6-frontend.c src/s6-frontend/s6-frontend-internal.h src/include-local/s6f.h
src/s6-frontend/s6.o src/s6-frontend/s6.lo: src/s6-frontend/s6.c src/include/s6-frontend/config.h
src/s6-frontend/set.o src/s6-frontend/set.lo: src/s6-frontend/set.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/set_change.o src/s6-frontend/set_change.lo: src/s6-frontend/set_change.c src/s6-frontend/s6-frontend-internal.h
@@ -39,6 +40,8 @@ src/s6-frontend/system.o src/s6-frontend/system.lo: src/s6-frontend/system.c src
src/s6-frontend/system_boot.o src/s6-frontend/system_boot.lo: src/s6-frontend/system_boot.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/system_hpr.o src/s6-frontend/system_hpr.lo: src/s6-frontend/system_hpr.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
+s6-frontend-helper-echo: EXTRA_LIBS :=
+s6-frontend-helper-echo: src/helpers/s6-frontend-helper-echo.o -lskarnet
s6-frontend-helper-kill: EXTRA_LIBS :=
s6-frontend-helper-kill: src/helpers/s6-frontend-helper-kill.o -lskarnet
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
diff --git a/package/modes b/package/modes
index 5245abe..0021ad6 100644
--- a/package/modes
+++ b/package/modes
@@ -1,3 +1,4 @@
s6 0755
s6-frontend 0755
s6-frontend-helper-kill 0755
+s6-frontend-helper-echo 0755
diff --git a/package/targets.mak b/package/targets.mak
index bc266f5..eea22fc 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -4,6 +4,7 @@ s6 \
LIBEXEC_TARGETS := \
s6-frontend \
s6-frontend-helper-kill \
+s6-frontend-helper-echo \
EXTRA_TARGETS := \
src/s6-frontend/live_help.c \
diff --git a/src/helpers/deps-exe/s6-frontend-helper-echo b/src/helpers/deps-exe/s6-frontend-helper-echo
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/helpers/deps-exe/s6-frontend-helper-echo
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/helpers/s6-frontend-helper-echo.c b/src/helpers/s6-frontend-helper-echo.c
new file mode 100644
index 0000000..5d416bd
--- /dev/null
+++ b/src/helpers/s6-frontend-helper-echo.c
@@ -0,0 +1,54 @@
+/* ISC license. */
+
+#include <unistd.h>
+
+#include <skalibs/uint64.h>
+#include <skalibs/buffer.h>
+#include <skalibs/envexec.h>
+
+#define USAGE "s6-frontend-helper-echo [ -n ] [ -s sep ] args..."
+
+enum golb_e
+{
+ GOLB_CHOMP = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_SEP,
+ GOLA_N
+} ;
+
+int main (int argc, char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'n', .lo = "chomp", .clear = 0, .set = GOLB_CHOMP },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 's', .lo = "separator", .i = GOLA_SEP },
+ } ;
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { [GOLA_SEP] = " " } ;
+ PROG = "s6-frontend-helper-echo" ;
+ {
+ unsigned int golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ }
+
+ for (; *argv ; argv++)
+ {
+ if (buffer_puts(buffer_1small, *argv) == -1) goto err ;
+ if (argv[1] && buffer_put(buffer_1small, wgola[GOLA_SEP], 1) == -1) goto err ;
+ }
+ if (!(wgolb & GOLB_CHOMP))
+ {
+ if (buffer_put(buffer_1small, "\n", 1) == -1) goto err ;
+ }
+ if (!buffer_flush(buffer_1small)) goto err ;
+ _exit(0) ;
+
+err:
+ strerr_diefu1sys(111, "write to stdout") ;
+}
diff --git a/src/s6-frontend/live_status.c b/src/s6-frontend/live_status.c
index 2a3a9af..4a7711a 100644
--- a/src/s6-frontend/live_status.c
+++ b/src/s6-frontend/live_status.c
@@ -138,7 +138,7 @@ static void live_status_some (char const *const *services, int withe)
unsigned int m = 0 ;
size_t uplistpos ;
int e ;
- char const *argv[53] ;
+ char const *argv[55] ;
if (!stralloc_catb(&sa, " ", 1)) dienomem() ;
e = get_atomics(services, env_len(services), &sa, withe) ;
if (e) _exit(e) ;
@@ -158,8 +158,8 @@ static void live_status_some (char const *const *services, int withe)
argv[m++] = " " EXECLINE_EXTBINPREFIX "fdmove" ;
argv[m++] = " 1" ;
argv[m++] = " 4" ;
- argv[m++] = " " EXECLINE_EXTBINPREFIX "heredoc" ;
- argv[m++] = " 0" ;
+ argv[m++] = " " S6_FRONTEND_LIBEXECPREFIX "s6-frontend-helper-echo" ;
+ argv[m++] = " --" ;
argv[m++] = sa.s + uplistpos - 2 ;
argv[m++] = " " ;
argv[m++] = " " EXECLINE_EXTBINPREFIX "fdclose" ;
@@ -169,7 +169,8 @@ static void live_status_some (char const *const *services, int withe)
argv[m++] = sa.s ;
argv[m++] = " " EXECLINE_EXTBINPREFIX "pipeline" ;
argv[m++] = " grep" ;
- argv[m++] = " -Fxf" ;
+ argv[m++] = " -Fx" ;
+ argv[m++] = " -f" ;
argv[m++] = " /dev/fd/3" ;
argv[m++] = " " ;
argv[m++] = " sed" ;
@@ -184,8 +185,8 @@ static void live_status_some (char const *const *services, int withe)
argv[m++] = " " EXECLINE_EXTBINPREFIX "fdmove" ;
argv[m++] = " 1" ;
argv[m++] = " 4" ;
- argv[m++] = " " EXECLINE_EXTBINPREFIX "heredoc" ;
- argv[m++] = " 0" ;
+ argv[m++] = " " S6_FRONTEND_LIBEXECPREFIX "s6-frontend-helper-echo" ;
+ argv[m++] = " --" ;
argv[m++] = sa.s + uplistpos - 1 ;
argv[m++] = "" ;
argv[m++] = EXECLINE_EXTBINPREFIX "fdclose" ;
@@ -195,7 +196,8 @@ static void live_status_some (char const *const *services, int withe)
argv[m++] = sa.s + 1 ;
argv[m++] = EXECLINE_EXTBINPREFIX "pipeline" ;
argv[m++] = " grep" ;
- argv[m++] = " -Fxf" ;
+ argv[m++] = " -Fx" ;
+ argv[m++] = " -f" ;
argv[m++] = " /dev/fd/3" ;
argv[m++] = "" ;
argv[m++] = "sed" ;
diff --git a/src/s6-frontend/process_startstop.c b/src/s6-frontend/process_startstop.c
index 9df5f96..511bde7 100644
--- a/src/s6-frontend/process_startstop.c
+++ b/src/s6-frontend/process_startstop.c
@@ -48,7 +48,7 @@ static void process_startstop (char const *const *argv, int h, char const *usage
}
argc = env_len(argv) ;
process_check_services(argv, argc) ;
- process_send_svc(svcopts[wgolb & (GOLB_PERMANENT|GOLB_WAIT) | h], argv, argc, timeout) ;
+ process_send_svc(svcopts[(wgolb & (GOLB_PERMANENT|GOLB_WAIT)) | h], argv, argc, timeout) ;
}
void process_start (char const *const *argv)