aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--INSTALL4
-rw-r--r--NEWS4
-rw-r--r--doc/index.html7
-rw-r--r--doc/overview.html12
-rw-r--r--doc/s6-svscan-not-1.html18
-rw-r--r--doc/s6-svscan.html2
-rw-r--r--doc/upgrade.html5
-rw-r--r--doc/why.html6
-rw-r--r--package/deps-build2
-rw-r--r--package/deps.mak3
-rw-r--r--package/info2
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak2
-rw-r--r--src/alias/s6-alias.c10
-rw-r--r--src/supervision/deps-exe/s6-svscanboot1
-rw-r--r--src/supervision/s6-svscanboot.c270
17 files changed, 323 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore
index 3063492..545156b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@
/s6-cleanfifodir
/s6-mkfifodir
/s6-svscan
+/s6-svscanboot
/s6-supervise
/s6-svc
/s6-svscanctl
diff --git a/INSTALL b/INSTALL
index 340d2d2..2dd3f1f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,8 +6,8 @@ Build Instructions
- A POSIX-compliant C development environment
- GNU make version 3.81 or later
- - skalibs version 2.15.0.0 or later: https://skarnet.org/software/skalibs/
- - Recommended: execline version 2.9.9.0 or later: https://skarnet.org/software/execline/
+ - skalibs version 2.15.0.1 or later: https://skarnet.org/software/skalibs/
+ - Recommended: execline version 2.9.9.2 or later: https://skarnet.org/software/execline/
(You can disable this requirement at configure time, but will
lose some functionality.)
- Optional: nsss version 0.2.1.2 or later: https://skarnet.org/software/nsss/
diff --git a/NEWS b/NEWS
index 2c61928..89b9bd0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,11 @@
Changelog for s6.
-In 2.15.0.1
+In 2.15.1.0
-----------
- Bugfixes.
+ - New command: s6-svscanboot, for a self-logging s6-svscan
+that is not pid 1.
In 2.15.0.0
diff --git a/doc/index.html b/doc/index.html
index 53d0b49..d9b8918 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -89,7 +89,7 @@ requirement if you link against the shared version of the skalibs
library. </li>
<li> (Optional, but really recommended for full functionality):
<a href="//skarnet.org/software/execline/">execline</a> version
-2.9.9.1 or later. When s6 is built with execline support (which is the default),
+2.9.9.2 or later. When s6 is built with execline support (which is the default),
execline is a build-time requirement, and also a run-time requirement for
certain binaries that spawn scripts interpreted with
<a href="//skarnet.org/software/execline/execlineb.html">execlineb</a>. </li>
@@ -116,8 +116,8 @@ want nsswitch-like functionality:
<h3> Download </h3>
<ul>
- <li> The current released version of s6 is <a href="s6-2.15.0.1.tar.gz">2.15.0.1</a>.
-You can access its checksum <a href="s6-2.15.0.1.tar.gz.sha256">here</a>. </li>
+ <li> The current released version of s6 is <a href="s6-2.15.1.0.tar.gz">2.15.1.0</a>.
+You can access its checksum <a href="s6-2.15.1.0.tar.gz.sha256">here</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6/">s6
git repository</a>:
@@ -175,6 +175,7 @@ a user interface to control those processes and monitor service states.
<li><a href="s6-svscanctl.html">The <tt>s6-svscanctl</tt> program</a></li>
<li><a href="s6-supervise.html">The <tt>s6-supervise</tt> program</a></li>
<li><a href="s6-svc.html">The <tt>s6-svc</tt> program</a></li>
+<li><a href="s6-svscanboot.html">The <tt>s6-svscanboot</tt> program</a></li>
<li><a href="s6-svok.html">The <tt>s6-svok</tt> program</a></li>
<li><a href="s6-svstat.html">The <tt>s6-svstat</tt> program</a></li>
<li><a href="s6-svperms.html">The <tt>s6-svperms</tt> program</a></li>
diff --git a/doc/overview.html b/doc/overview.html
index 164cffd..599ca4f 100644
--- a/doc/overview.html
+++ b/doc/overview.html
@@ -219,7 +219,17 @@ context entirely. </li>
on an empty scan directory, then populate it step by step and send an
update command to s6-svscan via
<a href="s6-svscanctl.html">s6-svscanctl</a> whenever the supervision
-tree should pick up the differences and start the services you added. </li>
+tree should pick up the differences and start the services you added.
+ <ul>
+ <li> If you're running Linux and want the smallest possible amount
+of overhead, you should check the
+<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init</a> companion
+package, which will start <a href="s6-svscan.html">s6-svscan</a> as process
+1 for you, no need for another initialization system. </li>
+ <li> If you have an init system you're happy with and just want to run
+a self-sufficient supervision tree, the
+<a href="s6-svscanboot.html">s6-svscanboot</a> program is a good option. </li>
+ </ul> </li>
<li> That's it, your services are running. To control them manually,
you can use the <a href="s6-svc.html">s6-svc</a> command. </li>
<li> At the end of the system's lifetime, you can use
diff --git a/doc/s6-svscan-not-1.html b/doc/s6-svscan-not-1.html
index 163b792..632dab2 100644
--- a/doc/s6-svscan-not-1.html
+++ b/doc/s6-svscan-not-1.html
@@ -50,17 +50,15 @@ of by the logging tools. </li>
<li> You can use a trick similar to the <a href="s6-svscan-1.html#log">process
1 output logging trick</a> so the supervision tree's messages are logged via
a service that's maintained by the supervision tree itself. Then your init
-system should not launch s6-svscan directly, but a wrapper script that performs
-the proper redirections. The
-<tt>examples/s6-svscanboot</tt> file in the s6 distribution gives an example of
-such a script. Make sure that your initial <a href="scandir.html">scan
-directory</a> contains a <a href="servicedir.html">service directory</a> for your
-initial logging service, that must read on the logging FIFO. </li>
+system should not launch s6-svscan directly, but a wrapper script, or a binary,
+ that performs the proper redirections. The
+<a href="s6-svscanboot.html">s6-svscanboot</a> binary is an example of such
+a program, and it is recommended that you use it. </li>
</ul>
<p>
In some of the following examples, we'll assume that <tt>/command/s6-svscanboot</tt>
-is the name of the script you are using to start s6-svscan. We will also assume
+is the name of the program you are using to start s6-svscan. We will also assume
that all of the s6 executables are available through the <tt>/command</tt> path.
Adjust this accordingly.
</p>
@@ -76,7 +74,7 @@ config file with <tt>telinit q</tt>.
<h3> Example </h3>
-<pre> SV:123456:respawn:/command/s6-svscanboot </pre>
+<pre>SV:123456:respawn:/command/s6-svscanboot -c /dev/console /run/service</pre>
<a name="upstart">
@@ -97,7 +95,7 @@ stop on runlevel [!2345]
oom never
respawn
-exec /command/s6-svscanboot
+exec /command/s6-svscanboot -c /dev/console /run/service
</pre>
<a name="systemd">
@@ -149,7 +147,7 @@ file with <tt>kill -s HUP 1</tt>.
<h3> Example </h3>
-<pre> sv /command/s6-svscanboot "" on </pre>
+<pre> sv "/command/s6-svscanboot -c /dev/console /run/service" "" on </pre>
<a name="launchd">
<h2> MacOS launchd </h2>
diff --git a/doc/s6-svscan.html b/doc/s6-svscan.html
index 5a09527..fc50f60 100644
--- a/doc/s6-svscan.html
+++ b/doc/s6-svscan.html
@@ -28,7 +28,7 @@ the root or a branch of a <em>supervision tree</em>.
<h2> Interface </h2>
<pre>
- s6-svscan [ -d <em>notif</em> ] [ -X <em>consoleholder</em> ] [ -C services_max ] [ -L name_max ] [ -t <em>rescan</em> ] <em>scandir</em>
+ s6-svscan [ -d <em>notif</em> ] [ -X <em>consoleholder</em> ] [ -C <em>services_max</em> ] [ -L <em>name_max</em> ] [ -t <em>rescan</em> ] <em>scandir</em>
</pre>
<ul>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index e8cf485..43bd3f4 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -19,13 +19,14 @@
<h1> What has changed in s6 </h1>
-<h2> in 2.15.0.1 </h2>
+<h2> in 2.15.1.0 </h2>
<ul>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
dependency bumped to 2.15.0.1. </li>
<li> <a href="//skarnet.org/software/execline/">execline</a>
-recommended dependency bumped to 2.9.9.1. </li>
+recommended dependency bumped to 2.9.9.2. </li>
+ <li> New <a href="s6-svscanboot.html">s6-svscanboot</a> binary. </li>
</ul>
<h2> in 2.15.0.0 </h2>
diff --git a/doc/why.html b/doc/why.html
index bfb4b13..c75dda0 100644
--- a/doc/why.html
+++ b/doc/why.html
@@ -32,9 +32,9 @@ developers is using <tt>/etc/ttys</tt> to this purpose, so I won't consider BSD
<li> <a href="http://smarden.org/runit/">runit</a>, Gerrit Pape's suite, well-integrated with Debian </li>
<li> <a href="http://b0llix.net/perp/">perp</a>, Wayne Marshall's take on supervision </li>
<li> Integrated init systems providing a lot of features, process supervision being one of them.
-For instance, <a href="https://upstart.ubuntu.com/">Upstart</a>, MacOS X's
-<a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/launchd.8.html">launchd</a>,
-and Fedora's <a href="https://freedesktop.org/wiki/Software/systemd">systemd</a>. </li>
+For instance, <a href="https://wiki.ubuntu.com/Upstart">Upstart</a>, MacOS X's
+<a href="https://www.launchd.info/">launchd</a>,
+and Fedora's <a href="https://systemd.io/">systemd</a>. </li>
</ul>
<p>
diff --git a/package/deps-build b/package/deps-build
index 071d42c..8678590 100644
--- a/package/deps-build
+++ b/package/deps-build
@@ -1,3 +1,3 @@
true true /package/prog/skalibs 2.15.0.1 libskarnet
$usensss false /package/admin/nsss 0.2.1.2 libnsss
-$useexecline $useexecline /package/admin/execline 2.9.9.1 libexecline
+$useexecline $useexecline /package/admin/execline 2.9.9.2 libexecline
diff --git a/package/deps.mak b/package/deps.mak
index 4f58086..0771491 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -135,6 +135,7 @@ src/supervision/s6-svlisten1.o src/supervision/s6-svlisten1.lo: src/supervision/
src/supervision/s6-svok.o src/supervision/s6-svok.lo: src/supervision/s6-svok.c src/include/s6/supervise.h
src/supervision/s6-svperms.o src/supervision/s6-svperms.lo: src/supervision/s6-svperms.c src/include/s6/supervise.h
src/supervision/s6-svscan.o src/supervision/s6-svscan.lo: src/supervision/s6-svscan.c src/include/s6/config.h src/include/s6/supervise.h
+src/supervision/s6-svscanboot.o src/supervision/s6-svscanboot.lo: src/supervision/s6-svscanboot.c src/include/s6/config.h
src/supervision/s6-svscanctl.o src/supervision/s6-svscanctl.lo: src/supervision/s6-svscanctl.c src/include/s6/supervise.h
src/supervision/s6-svstat.o src/supervision/s6-svstat.lo: src/supervision/s6-svstat.c src/include/s6/supervise.h
src/supervision/s6-svunlink.o src/supervision/s6-svunlink.lo: src/supervision/s6-svunlink.c src/include/s6/supervise.h
@@ -293,6 +294,8 @@ s6-svperms: EXTRA_LIBS :=
s6-svperms: src/supervision/s6-svperms.o ${LIBNSSS} -lskarnet
s6-svscan: EXTRA_LIBS := ${SYSCLOCK_LIB} ${SPAWN_LIB}
s6-svscan: src/supervision/s6-svscan.o -lskarnet
+s6-svscanboot: EXTRA_LIBS :=
+s6-svscanboot: src/supervision/s6-svscanboot.o -lskarnet
s6-svscanctl: EXTRA_LIBS :=
s6-svscanctl: src/supervision/s6-svscanctl.o ${LIBS6} -lskarnet
s6-svstat: EXTRA_LIBS := ${SYSCLOCK_LIB}
diff --git a/package/info b/package/info
index 6eff7fb..d7c4218 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6
-version=2.15.0.1
+version=2.15.1.0
category=admin
package_macro_name=S6
diff --git a/package/modes b/package/modes
index d7b6953..e8a1fae 100644
--- a/package/modes
+++ b/package/modes
@@ -10,6 +10,7 @@ s6-ftrig-wait 0755
s6-cleanfifodir 0755
s6-mkfifodir 0755
s6-svscan 0755
+s6-svscanboot 0755
s6-supervise 0755
s6-svc 0755
s6-svlink 0755
diff --git a/package/targets.mak b/package/targets.mak
index a607f2b..409f511 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -80,7 +80,7 @@ endif
ifneq ($(EXECLINE_LIB),)
LIB_DEFS += S6AUTO=s6auto
S6AUTO_DESCRIPTION := The s6auto library (C helpers to create service directories)
-BIN_TARGETS += s6-usertree-maker s6-instance-maker
+BIN_TARGETS += s6-usertree-maker s6-instance-maker s6-svscanboot
endif
WRAP_ANY :=
diff --git a/src/alias/s6-alias.c b/src/alias/s6-alias.c
index 568d29d..f530fe9 100644
--- a/src/alias/s6-alias.c
+++ b/src/alias/s6-alias.c
@@ -56,9 +56,17 @@ static void readproctitle (int argc, char const *const *argv)
static void svscanboot (int argc, char const *const *argv)
{
+ char const *newargv[6] ;
+ unsigned int m = 0 ;
+ newargv[m++] = S6_BINPREFIX "s6-svscanboot" ;
+ newargv[m++] = "-c" ;
+ newargv[m++] = "/dev/console" ;
+ newargv[m++] = "--" ;
+ newargv[m++] = "/service" ;
+ newargv[m++] = 0 ;
(void)argc ;
(void)argv ;
- noboot("svscanboot") ;
+ xexec(newargv) ;
}
#endif
diff --git a/src/supervision/deps-exe/s6-svscanboot b/src/supervision/deps-exe/s6-svscanboot
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/supervision/deps-exe/s6-svscanboot
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/supervision/s6-svscanboot.c b/src/supervision/s6-svscanboot.c
new file mode 100644
index 0000000..8de924b
--- /dev/null
+++ b/src/supervision/s6-svscanboot.c
@@ -0,0 +1,270 @@
+/* ISC license. */
+
+#include <skalibs/bsdsnowflake.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+#include <skalibs/types.h>
+#include <skalibs/posixplz.h>
+#include <skalibs/stat.h>
+#include <skalibs/envexec.h>
+#include <skalibs/alloc.h>
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/skamisc.h>
+
+#include <execline/config.h>
+
+#include <s6/config.h>
+
+#define USAGE "s6-svscanboot [ -c devconsole ] [ -D catchalldir ] [ -m catchallmode ] [ -l catchalluser ] [ -o catchalloptions ] [ -d notif ] [ -C services_max ] [ -L name_max ] [ -t rescan ] scandir"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+enum golb_e
+{
+ GOLB_USER = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_CONSOLE,
+ GOLA_DIR,
+ GOLA_MODE,
+ GOLA_USER,
+ GOLA_OPTIONS,
+ GOLA_NOTIF,
+ GOLA_MAXSERVICES,
+ GOLA_MAXLEN,
+ GOLA_TIMEOUT,
+ GOLA_N
+} ;
+
+int main (int argc, char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'u', .lo = "user", .clear = 0, .set = GOLB_USER },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'c', .lo = "console", .i = GOLA_CONSOLE },
+ { .so = 'D', .lo = "catchall-directory", .i = GOLA_DIR },
+ { .so = 'm', .lo = "catchall-mode", .i = GOLA_MODE },
+ { .so = 'l', .lo = "catchall-user", .i = GOLA_USER },
+ { .so = 'o', .lo = "catchall-options", .i = GOLA_OPTIONS },
+ { .so = 'd', .lo = "notification-fd", .i = GOLA_NOTIF },
+ { .so = 'C', .lo = "services-max", .i = GOLA_MAXSERVICES },
+ { .so = 'L', .lo = "name-max", .i = GOLA_MAXLEN },
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ unsigned int catchall_mode = 02700 ;
+ unsigned int fdconsole = 3 ;
+ unsigned int fdnotif = 0 ;
+ unsigned int servicesmax = 0 ;
+ unsigned int namemax = 0 ;
+ unsigned int timeout = 0 ;
+ uid_t uid = -1 ;
+ gid_t gid = -1 ;
+ stralloc sa = STRALLOC_ZERO ;
+ buffer b ;
+ int fd ;
+ unsigned int m = 0 ;
+ char const *newargv[14] ;
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ unsigned int golc ;
+ char buf[4096] ;
+ char fmtc[UINT_FMT] ;
+ char fmtd[UINT_FMT] ;
+ char fmtC[UINT_FMT] ;
+ char fmtL[UINT_FMT] ;
+ char fmtt[UINT_FMT] ;
+
+ PROG = "s6-svscanboot" ;
+ wgola[GOLA_OPTIONS] = "t" ;
+
+ golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (!argc) dieusage() ;
+
+ if (wgola[GOLA_MODE] && !uint0_oscan(wgola[GOLA_MODE], &catchall_mode))
+ strerr_dief(100, "catchall-mode must be an (octal) unsigned integer") ;
+ if (wgola[GOLA_NOTIF])
+ {
+ if (!uint0_scan(wgola[GOLA_NOTIF], &fdnotif))
+ strerr_dief(100, "notification-fd", " must be an unsigned integer") ;
+ if (fdnotif < 3)
+ strerr_dief(100, "notification-fd", " must be 3 or greater") ;
+ if (fcntl(fdnotif, F_GETFD) == -1)
+ strerr_diefsys(111, "notification-fd", " sanity check failed") ;
+ if (fdnotif == 3) fdconsole = 4 ;
+ }
+ if (wgola[GOLA_MAXSERVICES])
+ {
+ if (!uint0_scan(wgola[GOLA_MAXSERVICES], &servicesmax))
+ strerr_dief(100, "services-max", " must be an unsigned integer") ;
+ if (servicesmax < 4) servicesmax = 4 ;
+ if (servicesmax > 160000) servicesmax = 160000 ;
+ }
+ if (wgola[GOLA_MAXLEN])
+ {
+ if (!uint0_scan(wgola[GOLA_MAXLEN], &namemax))
+ strerr_dief(100, "name-max", " must be an unsigned integer") ;
+ if (namemax < 11) namemax = 11 ;
+ if (namemax > 1019) namemax = 1019 ;
+ }
+ if (wgola[GOLA_TIMEOUT] && !uint0_scan(wgola[GOLA_TIMEOUT], &timeout))
+ strerr_dief(100, "timeout", " must be an unsigned integer") ;
+ if (wgola[GOLA_USER] && geteuid())
+ {
+ wgola[GOLA_USER] = 0 ;
+ strerr_warnw("ignoring catchall-user option when not root") ;
+ }
+ if (wgolb & GOLB_USER && (!wgola[GOLA_DIR] || wgola[GOLA_DIR][0] != '/'))
+ {
+ size_t namelen ;
+ size_t dirlen ;
+ char *logdir ;
+ char *x = getenv("XDG_RUNTIME_DIR") ;
+ if (!x) strerr_dienotset(100, "XDG_RUNTIME_DIR") ;
+ if (!wgola[GOLA_DIR]) wgola[GOLA_DIR] = "uncaught-logs" ;
+ dirlen = strlen(x) ;
+ namelen = strlen(wgola[GOLA_DIR]) ;
+ logdir = alloc(dirlen + namelen + 2) ;
+ if (!logdir) strerr_diefusys(111, "alloc") ;
+ memcpy(logdir, x, dirlen) ;
+ logdir[dirlen] = '/' ;
+ memcpy(logdir + dirlen + 1, wgola[GOLA_DIR], namelen + 1) ;
+ wgola[GOLA_DIR] = logdir ;
+ }
+ if (!wgola[GOLA_DIR]) wgola[GOLA_DIR] = "/run/uncaught-logs" ;
+ if (wgola[GOLA_USER])
+ {
+ struct passwd *pw = getpwnam(wgola[GOLA_USER]) ;
+ if (!pw) strerr_diefsys(111, "getpwnam ", wgola[GOLA_USER]) ;
+ uid = pw->pw_uid ;
+ gid = pw->pw_gid ;
+ }
+
+ if (mkdirp(wgola[GOLA_DIR], catchall_mode) == -1)
+ strerr_diefusys(111, "mkdir ", wgola[GOLA_DIR]) ;
+ if (chown(wgola[GOLA_DIR], uid, gid) == -1)
+ strerr_diefusys(111, "chown ", wgola[GOLA_DIR]) ;
+ if (chmod(wgola[GOLA_DIR], catchall_mode) == -1)
+ strerr_diefusys(111, "chmod ", wgola[GOLA_DIR]) ;
+ if (wgola[GOLA_DIR][0] != '/')
+ {
+ char *x = realpath(wgola[GOLA_DIR], 0) ;
+ if (!x) strerr_diefusys(111, "realpath ", wgola[GOLA_DIR]) ;
+ wgola[GOLA_DIR] = x ;
+ }
+
+ size_t slen = strlen(argv[0]) ;
+ char fn[slen + 31] ;
+ memcpy(fn, argv[0], slen) ;
+ memcpy(fn + slen, "/s6-svscan-log", 15) ;
+ rm_rf(fn) ;
+ if (mkdirp2(fn, 02755) == -1)
+ strerr_diefusys(111, "mkdir ", fn) ;
+
+ memcpy(fn + slen + 14, "/notification-fd", 17) ;
+ if (!openwritenclose_unsafe(fn, "3\n", 2))
+ strerr_diefusys(111, "write to ", fn) ;
+
+ memcpy(fn + slen + 14, "/run", 5) ;
+ fd = openc_create(fn) ;
+ buffer_init(&b, &buffer_write, fd, buf, 4096) ;
+
+#define diew() strerr_diefusys(111, "write to ", fn) ;
+
+ if (buffer_puts(&b,
+ "#!" EXECLINE_SHEBANGPREFIX "execlineb -s1\n"
+ EXECLINE_EXTBINPREFIX "fdmove -c 1 2\n"
+ EXECLINE_EXTBINPREFIX "redirfd -rnb 0 fifo\n") == -1) diew() ;
+ if (wgola[GOLA_USER])
+ {
+ if (!string_quotes(&sa, wgola[GOLA_USER]))
+ strerr_diefusys(111, "quote ", "catchall-user") ;
+ if (buffer_puts(&b, S6_EXTBINPREFIX "s6-setuidgid ") == -1
+ || buffer_put(&b, sa.s, sa.len) == -1
+ || buffer_put(&b, "\n", 1) == -1) diew() ;
+ sa.len = 0 ;
+ }
+ if (!string_quotes(&sa, wgola[GOLA_DIR]))
+ strerr_diefusys(111, "quote ", "catchall-directory") ;
+ if (buffer_puts(&b,
+ EXECLINE_EXTBINPREFIX "exec -c\n"
+ S6_EXTBINPREFIX "s6-log -bpd3 -- ") == -1
+ || buffer_puts(&b, wgola[GOLA_OPTIONS]) == -1
+ || buffer_put(&b, " ", 1) == -1
+ || buffer_put(&b, sa.s, sa.len) == -1
+ || buffer_putflush(&b, "\n", 1) == -1) diew() ;
+ sa.len = 0 ;
+ if (fchmod(fd, 0755) == -1)
+ strerr_diefusys(111, "chmod ", fn) ;
+ fd_close(fd) ;
+
+ memcpy(fn + slen + 14, "/fifo", 6) ;
+ if (mkfifo(fn, 0600) == -1)
+ strerr_diefusys(111, "mkfifo ", fn) ;
+
+ fd = open2("/dev/null", O_RDONLY) ;
+ if (fd == -1) strerr_diefusys(111, "open ", "/dev/null") ;
+ if (fd_move(0, fd) == -1) strerr_diefusys(111, "fd_move ", "/dev/null", " to ", "stdin") ;
+ if (wgola[GOLA_CONSOLE])
+ {
+ fd = open2("/dev/console", O_WRONLY) ;
+ if (fd == -1) strerr_diefusys(111, "open ", "/dev/console") ;
+ if (fd_move(fdconsole, fd) == -1) strerr_diefusys(111, "fd_move ", "/dev/console") ;
+ }
+ else if (fd_copy(fdconsole, 2) == -1) strerr_diefusys(111, "fd_copy ", "stderr") ;
+ b.fd = open2(fn, O_RDONLY | O_NONBLOCK) ;
+ if (b.fd == -1) strerr_diefusys(111, "open ", fn, " for reading") ;
+ fd = open2(fn, O_WRONLY | O_NONBLOCK) ;
+ if (fd == -1) strerr_diefusys(111, "open ", fn, " for writing") ;
+ fd_close(b.fd) ;
+ if (ndelay_off(fd) == -1) strerr_diefusys(111, "ndelay_off ", fn) ;
+ if (fd_move(1, fd) == -1) strerr_diefusys(111, "fd_move ", fn, " to ", "stdout") ;
+ if (fd_copy(2, 1) == -1) strerr_diefusys(111, "copy ", "stdout", " to ", "stderr") ;
+
+ fmtc[uint_fmt(fmtc, fdconsole)] = 0 ;
+
+ newargv[m++] = S6_BINPREFIX "s6-svscan" ;
+ newargv[m++] = "-X" ;
+ newargv[m++] = fmtc ;
+ if (fdnotif)
+ {
+ fmtd[uint_fmt(fmtd, fdnotif)] = 0 ;
+ newargv[m++] = "-d" ;
+ newargv[m++] = fmtd ;
+ }
+ if (servicesmax)
+ {
+ fmtC[uint_fmt(fmtC, servicesmax)] = 0 ;
+ newargv[m++] = "-C" ;
+ newargv[m++] = fmtC ;
+ }
+ if (namemax)
+ {
+ fmtL[uint_fmt(fmtL, namemax)] = 0 ;
+ newargv[m++] = "-L" ;
+ newargv[m++] = fmtL ;
+ }
+ if (timeout)
+ {
+ fmtt[uint_fmt(fmtt, timeout)] = 0 ;
+ newargv[m++] = "-t" ;
+ newargv[m++] = fmtt ;
+ }
+ newargv[m++] = "--" ;
+ newargv[m++] = argv[0] ;
+ newargv[m++] = 0 ;
+
+ exec(newargv) ;
+ _exit(111) ;
+}