commit 701540827e27a4f07ac725db3ce361d3be0c106f
parent 83853a80eb18238796154164f9ea776b0c167ab7
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date: Mon, 19 Jan 2015 16:11:24 +0000
- added the s6_fdholder library to libs6. (Nothing useful yet.)
- fixed execline invocation in s6-log with slashpackage
- integrated s6_svc_main.c's functionality into s6-svscanctl and deleted it
- integrated Olivier Brunel's suggestions for wstat report in supervise/status
- minor fixes to s6-supervise's status reports
- separated sigaction calls in ftrigw_notifyb, this spares a few syscalls in s6-supervise
- updated doc to reflect the changes
- version bumped to 2.1.0.0 because API breakage (./finish, s6-svstat)
Diffstat:
35 files changed, 708 insertions(+), 144 deletions(-)
diff --git a/AUTHORS b/AUTHORS
@@ -7,6 +7,7 @@ Contributors:
Clemens Fischer <ino-waiting@gmx.net>
Stefan Karrman <sk@mathematik.uni-ulm.de>
Jean Marot <jean.marot@skarnet.org>
+ Olivier Brunel <jjk@jacky.com>
Thanks to:
Dan J. Bernstein <djb@cr.yp.to>
@@ -15,3 +16,5 @@ Thanks to:
Nicolas George <cigaes@salle-s.org>
Frans Haarman <franshaarman@gmail.com>
Vallo Kallaste <kalts@estpak.ee>
+ Patrick Mahoney <pat@polycrystal.org>
+ Colin Booth <cathexis@gmail.com>
diff --git a/INSTALL b/INSTALL
@@ -6,7 +6,7 @@ Build Instructions
- A POSIX-compliant C development environment
- GNU make version 4.0 or later
- - skalibs version 2.2.0.0 or later: http://skarnet.org/software/skalibs/
+ - skalibs version 2.2.1.0 or later: http://skarnet.org/software/skalibs/
- execline version 2.0.1.1 or later: http://skarnet.org/software/execline/
This software will run on any operating system that implements
diff --git a/doc/index.html b/doc/index.html
@@ -53,7 +53,7 @@ supervision that might help you understand the basics.
<li> A POSIX-compliant system with a standard C development environment </li>
<li> GNU make, version 4.0 or later </li>
<li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version
-2.2.0.0 or later </li>
+2.2.1.0 or later </li>
<li> <a href="http://skarnet.org/software/execline/">execline</a> version
2.0.1.1 or later </li>
</ul>
@@ -68,7 +68,7 @@ supervision that might help you understand the basics.
<h3> Download </h3>
<ul>
- <li> The current released version of s6 is <a href="s6-2.0.2.0.tar.gz">2.0.2.0</a>. </li>
+ <li> The current released version of s6 is <a href="s6-2.1.0.0.tar.gz">2.1.0.0</a>. </li>
<li> Alternatively, you can checkout a copy of the s6 git repository:
<pre> git clone git://git.skarnet.org/s6 </pre> </li>
</ul>
diff --git a/doc/s6-supervise.html b/doc/s6-supervise.html
@@ -44,9 +44,12 @@ If it already exists, it uses it as is, without modifying the subscription right
<li> s6-supervise sends a <tt>'u'</tt> event to <tt>./event</tt> whenever it
successfully spawns <tt>./run</tt>. </li>
<li> When <tt>./run</tt> dies, s6-supervise sends a <tt>'d'</tt> event to <tt>./event</tt>. </li>
- <li> When <tt>./run</tt> dies, s6-supervise spawns <tt>./finish</tt> if it exists. </li>
+ <li> When <tt>./run</tt> dies, s6-supervise spawns <tt>./finish</tt> if it exists.
+<tt>./finish</tt> will have <tt>./run</tt>'s exit code as first argument, or 256 if
+<tt>./run</tt> was signaled; it will have the number of the signal that killed <tt>./run</tt>
+as second argument, or an undefined number if <tt>./run</tt> was not signaled. </li>
<li> <tt>./finish</tt> must exit in less than 5 seconds. If it takes more than that,
-s6-supervise kills it. </li>
+s6-supervise kills it with a SIGKILL. </li>
<li> When <tt>./finish</tt> dies, s6-supervise restarts <tt>./run</tt> unless it has been
told not to. </li>
<li> There is a minimum 1-second delay between two <tt>./run</tt> spawns, to avoid busylooping
diff --git a/doc/s6-svstat.html b/doc/s6-svstat.html
@@ -18,27 +18,38 @@
<h1> The s6-svstat program </h1>
<p>
-s6-svstat prints a short, human-readable summary of the state of a supervised
-service.
+s6-svstat prints a short, human-readable summary of the state of a process
+monitored by <a href="s6-supervise.html">s6-supervise</a>.
</p>
<h2> Interface </h2>
<pre>
- s6-svstat <em>servicedir</em>
+ s6-svstat [ -n ] <em>servicedir</em>
</pre>
<p>
- s6-svstat gives the following information about the process being monitored
+ s6-svstat gives information about the process being monitored
at the <em>servicedir</em> <a href="servicedir.html">service directory</a>, then
-exits 0:
+exits 0. The information includes the following:
</p>
<ul>
- <li> whether it is up or down </li>
- <li> its pid, if it is up </li>
+ <li> whether the process is up or down </li>
+ <li> the process' pid, if it is up, or its last exit code or terminating
+signal, if it is down </li>
<li> what its default state is, if it is different from its current state </li>
<li> the number of seconds since it last changed states </li>
+ <li> if the current state is transient and will change as soon as the
+kernel's scheduler picks up s6-supervise </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-n</tt> : if the monitored process has been killed by a signal,
+print the signal number. By default, a symbolic name for the signal will be
+printed instead. </li>
</ul>
</body>
diff --git a/doc/upgrade.html b/doc/upgrade.html
@@ -17,12 +17,21 @@
<h1> What has changed in s6 </h1>
-<h2> in 2.0.2.0 </h2>
+<h2> in 2.1.0.0 </h2>
<ul>
+ <li> skalibs dependency bumped to 2.2.1.0. </li>
<li> Unix domain socket utilities moved from the
<a href="http://skarnet.org/software/s6-networking/">s6-networking</a>
package to s6. </li>
+ <li> <tt>./finish</tt> argument for "service crashed" is now 256
+instead of 255 </li>
+ <li> <tt>supervise/status</tt> now includes wstat information
+when the service died, svstat reports it </li>
+ <li> svstat now reports symbolic signal information by default,
+use <tt>-n</tt> to get the old behaviour </li>
+ <li> s6-log now properly calls execlineb with its installation
+prefix, in the slashpackage case </li>
</ul>
<h2> in 2.0.1.0 </h2>
diff --git a/package/deps.mak b/package/deps.mak
@@ -8,6 +8,7 @@ src/include/s6/s6lock.h: src/include/s6/config.h
src/conn-tools/s6-accessrules-cdb-from-fs.o src/conn-tools/s6-accessrules-cdb-from-fs.lo: src/conn-tools/s6-accessrules-cdb-from-fs.c
src/conn-tools/s6-accessrules-fs-from-cdb.o src/conn-tools/s6-accessrules-fs-from-cdb.lo: src/conn-tools/s6-accessrules-fs-from-cdb.c
src/conn-tools/s6-connlimit.o src/conn-tools/s6-connlimit.lo: src/conn-tools/s6-connlimit.c
+src/conn-tools/s6-fdholderd.o src/conn-tools/s6-fdholderd.lo: src/conn-tools/s6-fdholderd.c src/include/s6/accessrules.h src/include/s6/s6-fdholder.h src/include/s6/s6-supervise.h
src/conn-tools/s6-ioconnect.o src/conn-tools/s6-ioconnect.lo: src/conn-tools/s6-ioconnect.c
src/conn-tools/s6-ipcclient.o src/conn-tools/s6-ipcclient.lo: src/conn-tools/s6-ipcclient.c
src/conn-tools/s6-ipcserver-access.o src/conn-tools/s6-ipcserver-access.lo: src/conn-tools/s6-ipcserver-access.c src/include/s6/accessrules.h
@@ -46,7 +47,8 @@ src/libs6/ftrigr_zero.o src/libs6/ftrigr_zero.lo: src/libs6/ftrigr_zero.c src/in
src/libs6/ftrigw_clean.o src/libs6/ftrigw_clean.lo: src/libs6/ftrigw_clean.c src/libs6/ftrig1.h src/include/s6/ftrigw.h
src/libs6/ftrigw_fifodir_make.o src/libs6/ftrigw_fifodir_make.lo: src/libs6/ftrigw_fifodir_make.c src/include/s6/ftrigw.h
src/libs6/ftrigw_notify.o src/libs6/ftrigw_notify.lo: src/libs6/ftrigw_notify.c src/include/s6/ftrigw.h
-src/libs6/ftrigw_notifyb.o src/libs6/ftrigw_notifyb.lo: src/libs6/ftrigw_notifyb.c src/libs6/ftrig1.h src/include/s6/ftrigw.h
+src/libs6/ftrigw_notifyb.o src/libs6/ftrigw_notifyb.lo: src/libs6/ftrigw_notifyb.c src/include/s6/ftrigw.h
+src/libs6/ftrigw_notifyb_nosig.o src/libs6/ftrigw_notifyb_nosig.lo: src/libs6/ftrigw_notifyb_nosig.c src/libs6/ftrig1.h src/include/s6/ftrigw.h
src/libs6/s6-ftrigrd.o src/libs6/s6-ftrigrd.lo: src/libs6/s6-ftrigrd.c src/libs6/ftrig1.h src/include/s6/ftrigr.h
src/libs6/s6_accessrules_backend_cdb.o src/libs6/s6_accessrules_backend_cdb.lo: src/libs6/s6_accessrules_backend_cdb.c src/include/s6/accessrules.h
src/libs6/s6_accessrules_backend_fs.o src/libs6/s6_accessrules_backend_fs.lo: src/libs6/s6_accessrules_backend_fs.c src/include/s6/accessrules.h
@@ -56,9 +58,20 @@ src/libs6/s6_accessrules_keycheck_reversedns.o src/libs6/s6_accessrules_keycheck
src/libs6/s6_accessrules_keycheck_uidgid.o src/libs6/s6_accessrules_keycheck_uidgid.lo: src/libs6/s6_accessrules_keycheck_uidgid.c src/include/s6/accessrules.h
src/libs6/s6_accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_cdb.lo: src/libs6/s6_accessrules_uidgid_cdb.c src/include/s6/accessrules.h
src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6_accessrules_uidgid_fs.lo: src/libs6/s6_accessrules_uidgid_fs.c src/include/s6/accessrules.h
+src/libs6/s6_fdholder_delete.o src/libs6/s6_fdholder_delete.lo: src/libs6/s6_fdholder_delete.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_delete_async.o src/libs6/s6_fdholder_delete_async.lo: src/libs6/s6_fdholder_delete_async.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_getdump.o src/libs6/s6_fdholder_getdump.lo: src/libs6/s6_fdholder_getdump.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_list.o src/libs6/s6_fdholder_list.lo: src/libs6/s6_fdholder_list.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_list_async.o src/libs6/s6_fdholder_list_async.lo: src/libs6/s6_fdholder_list_async.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_list_cb.o src/libs6/s6_fdholder_list_cb.lo: src/libs6/s6_fdholder_list_cb.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_retrieve.o src/libs6/s6_fdholder_retrieve.lo: src/libs6/s6_fdholder_retrieve.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_retrieve_async.o src/libs6/s6_fdholder_retrieve_async.lo: src/libs6/s6_fdholder_retrieve_async.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_retrieve_cb.o src/libs6/s6_fdholder_retrieve_cb.lo: src/libs6/s6_fdholder_retrieve_cb.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_setdump.o src/libs6/s6_fdholder_setdump.lo: src/libs6/s6_fdholder_setdump.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_store.o src/libs6/s6_fdholder_store.lo: src/libs6/s6_fdholder_store.c src/include/s6/s6-fdholder.h
+src/libs6/s6_fdholder_store_async.o src/libs6/s6_fdholder_store_async.lo: src/libs6/s6_fdholder_store_async.c src/include/s6/s6-fdholder.h
src/libs6/s6_supervise_lock.o src/libs6/s6_supervise_lock.lo: src/libs6/s6_supervise_lock.c src/include/s6/s6-supervise.h
src/libs6/s6_supervise_lock_mode.o src/libs6/s6_supervise_lock_mode.lo: src/libs6/s6_supervise_lock_mode.c src/include/s6/s6-supervise.h
-src/libs6/s6_svc_main.o src/libs6/s6_svc_main.lo: src/libs6/s6_svc_main.c src/include/s6/s6-supervise.h
src/libs6/s6_svc_write.o src/libs6/s6_svc_write.lo: src/libs6/s6_svc_write.c src/include/s6/s6-supervise.h
src/libs6/s6_svstatus_pack.o src/libs6/s6_svstatus_pack.lo: src/libs6/s6_svstatus_pack.c src/include/s6/s6-supervise.h
src/libs6/s6_svstatus_read.o src/libs6/s6_svstatus_read.lo: src/libs6/s6_svstatus_read.c src/include/s6/s6-supervise.h
@@ -142,8 +155,8 @@ s6-tai64nlocal: private EXTRA_LIBS :=
s6-tai64nlocal: src/daemontools-extras/s6-tai64nlocal.o -lskarnet
ucspilogd: private EXTRA_LIBS :=
ucspilogd: src/daemontools-extras/ucspilogd.o -lskarnet
-libs6.a: src/libs6/ftrigr1_zero.o src/libs6/ftrigr_check.o src/libs6/ftrigr_end.o src/libs6/ftrigr_start.o src/libs6/ftrigr_startf.o src/libs6/ftrigr_subscribe.o src/libs6/ftrigr_unsubscribe.o src/libs6/ftrigr_update.o src/libs6/ftrigr_wait_and.o src/libs6/ftrigr_wait_or.o src/libs6/ftrigr_zero.o src/libs6/ftrigw_clean.o src/libs6/ftrigw_fifodir_make.o src/libs6/ftrigw_notify.o src/libs6/ftrigw_notifyb.o src/libs6/s6_accessrules_backend_cdb.o src/libs6/s6_accessrules_backend_fs.o src/libs6/s6_accessrules_keycheck_ip4.o src/libs6/s6_accessrules_keycheck_ip6.o src/libs6/s6_accessrules_keycheck_reversedns.o src/libs6/s6_accessrules_keycheck_uidgid.o src/libs6/s6_accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6_supervise_lock.o src/libs6/s6_supervise_lock_mode.o src/libs6/s6_svc_main.o src/libs6/s6_svc_write.o src/libs6/s6_svstatus_pack.o src/libs6/s6_svstatus_read.o src/libs6/s6_svstatus_unpack.o src/libs6/s6_svstatus_write.o src/libs6/s6lock_acquire.o src/libs6/s6lock_check.o src/libs6/s6lock_end.o src/libs6/s6lock_release.o src/libs6/s6lock_start.o src/libs6/s6lock_startf.o src/libs6/s6lock_update.o src/libs6/s6lock_wait_and.o src/libs6/s6lock_wait_or.o src/libs6/s6lock_zero.o
-libs6.so: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_end.lo src/libs6/ftrigr_start.lo src/libs6/ftrigr_startf.lo src/libs6/ftrigr_subscribe.lo src/libs6/ftrigr_unsubscribe.lo src/libs6/ftrigr_update.lo src/libs6/ftrigr_wait_and.lo src/libs6/ftrigr_wait_or.lo src/libs6/ftrigr_zero.lo src/libs6/ftrigw_clean.lo src/libs6/ftrigw_fifodir_make.lo src/libs6/ftrigw_notify.lo src/libs6/ftrigw_notifyb.lo src/libs6/s6_accessrules_backend_cdb.lo src/libs6/s6_accessrules_backend_fs.lo src/libs6/s6_accessrules_keycheck_ip4.lo src/libs6/s6_accessrules_keycheck_ip6.lo src/libs6/s6_accessrules_keycheck_reversedns.lo src/libs6/s6_accessrules_keycheck_uidgid.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_supervise_lock.lo src/libs6/s6_supervise_lock_mode.lo src/libs6/s6_svc_main.lo src/libs6/s6_svc_write.lo src/libs6/s6_svstatus_pack.lo src/libs6/s6_svstatus_read.lo src/libs6/s6_svstatus_unpack.lo src/libs6/s6_svstatus_write.lo src/libs6/s6lock_acquire.lo src/libs6/s6lock_check.lo src/libs6/s6lock_end.lo src/libs6/s6lock_release.lo src/libs6/s6lock_start.lo src/libs6/s6lock_startf.lo src/libs6/s6lock_update.lo src/libs6/s6lock_wait_and.lo src/libs6/s6lock_wait_or.lo src/libs6/s6lock_zero.lo
+libs6.a: src/libs6/ftrigr1_zero.o src/libs6/ftrigr_check.o src/libs6/ftrigr_end.o src/libs6/ftrigr_start.o src/libs6/ftrigr_startf.o src/libs6/ftrigr_subscribe.o src/libs6/ftrigr_unsubscribe.o src/libs6/ftrigr_update.o src/libs6/ftrigr_wait_and.o src/libs6/ftrigr_wait_or.o src/libs6/ftrigr_zero.o src/libs6/ftrigw_clean.o src/libs6/ftrigw_fifodir_make.o src/libs6/ftrigw_notify.o src/libs6/ftrigw_notifyb.o src/libs6/ftrigw_notifyb_nosig.o src/libs6/s6_accessrules_backend_cdb.o src/libs6/s6_accessrules_backend_fs.o src/libs6/s6_accessrules_keycheck_ip4.o src/libs6/s6_accessrules_keycheck_ip6.o src/libs6/s6_accessrules_keycheck_reversedns.o src/libs6/s6_accessrules_keycheck_uidgid.o src/libs6/s6_accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6_supervise_lock.o src/libs6/s6_supervise_lock_mode.o src/libs6/s6_svc_write.o src/libs6/s6_svstatus_pack.o src/libs6/s6_svstatus_read.o src/libs6/s6_svstatus_unpack.o src/libs6/s6_svstatus_write.o src/libs6/s6lock_acquire.o src/libs6/s6lock_check.o src/libs6/s6lock_end.o src/libs6/s6lock_release.o src/libs6/s6lock_start.o src/libs6/s6lock_startf.o src/libs6/s6lock_update.o src/libs6/s6lock_wait_and.o src/libs6/s6lock_wait_or.o src/libs6/s6lock_zero.o src/libs6/s6_fdholder_delete.o src/libs6/s6_fdholder_delete_async.o src/libs6/s6_fdholder_getdump.o src/libs6/s6_fdholder_list.o src/libs6/s6_fdholder_list_async.o src/libs6/s6_fdholder_list_cb.o src/libs6/s6_fdholder_retrieve.o src/libs6/s6_fdholder_retrieve_async.o src/libs6/s6_fdholder_retrieve_cb.o src/libs6/s6_fdholder_setdump.o src/libs6/s6_fdholder_store.o src/libs6/s6_fdholder_store_async.o
+libs6.so: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_end.lo src/libs6/ftrigr_start.lo src/libs6/ftrigr_startf.lo src/libs6/ftrigr_subscribe.lo src/libs6/ftrigr_unsubscribe.lo src/libs6/ftrigr_update.lo src/libs6/ftrigr_wait_and.lo src/libs6/ftrigr_wait_or.lo src/libs6/ftrigr_zero.lo src/libs6/ftrigw_clean.lo src/libs6/ftrigw_fifodir_make.lo src/libs6/ftrigw_notify.lo src/libs6/ftrigw_notifyb.lo src/libs6/ftrigw_notifyb_nosig.lo src/libs6/s6_accessrules_backend_cdb.lo src/libs6/s6_accessrules_backend_fs.lo src/libs6/s6_accessrules_keycheck_ip4.lo src/libs6/s6_accessrules_keycheck_ip6.lo src/libs6/s6_accessrules_keycheck_reversedns.lo src/libs6/s6_accessrules_keycheck_uidgid.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_supervise_lock.lo src/libs6/s6_supervise_lock_mode.lo src/libs6/s6_svc_write.lo src/libs6/s6_svstatus_pack.lo src/libs6/s6_svstatus_read.lo src/libs6/s6_svstatus_unpack.lo src/libs6/s6_svstatus_write.lo src/libs6/s6lock_acquire.lo src/libs6/s6lock_check.lo src/libs6/s6lock_end.lo src/libs6/s6lock_release.lo src/libs6/s6lock_start.lo src/libs6/s6lock_startf.lo src/libs6/s6lock_update.lo src/libs6/s6lock_wait_and.lo src/libs6/s6lock_wait_or.lo src/libs6/s6lock_zero.lo src/libs6/s6_fdholder_delete.lo src/libs6/s6_fdholder_delete_async.lo src/libs6/s6_fdholder_getdump.lo src/libs6/s6_fdholder_list.lo src/libs6/s6_fdholder_list_async.lo src/libs6/s6_fdholder_list_cb.lo src/libs6/s6_fdholder_retrieve.lo src/libs6/s6_fdholder_retrieve_async.lo src/libs6/s6_fdholder_retrieve_cb.lo src/libs6/s6_fdholder_setdump.lo src/libs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo
s6-ftrigrd: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
s6-ftrigrd: src/libs6/s6-ftrigrd.o src/libs6/ftrig1_free.o src/libs6/ftrig1_make.o -lskarnet
s6lockd: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
diff --git a/package/info b/package/info
@@ -1,4 +1,4 @@
package=s6
-version=2.0.2.0
+version=2.1.0.0
category=admin
package_macro_name=S6
diff --git a/src/daemontools-extras/s6-log.c b/src/daemontools-extras/s6-log.c
@@ -30,6 +30,7 @@
#include <skalibs/selfpipe.h>
#include <skalibs/skamisc.h>
#include <skalibs/environ.h>
+#include <execline/config.h>
#define USAGE "s6-log [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] logging_script"
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
@@ -354,7 +355,7 @@ static int finish (logdir_t *ldp, char const *name, char suffix)
static inline void exec_processor (logdir_t_ref ldp)
{
- char const *cargv[4] = { "execlineb", "-Pc", ldp->processor, 0 } ;
+ char const *cargv[4] = { EXECLINE_EXTBINPREFIX "execlineb", "-Pc", ldp->processor, 0 } ;
unsigned int dirlen = str_len(ldp->dir) ;
int fd ;
char x[dirlen + 10] ;
diff --git a/src/include/s6/ftrigw.h b/src/include/s6/ftrigw.h
@@ -8,6 +8,7 @@
extern int ftrigw_fifodir_make (char const *, int, int) ;
extern int ftrigw_notify (char const *, char) ;
extern int ftrigw_notifyb (char const *, char const *, unsigned int) ;
+extern int ftrigw_notifyb_nosig (char const *, char const *, unsigned int) ;
#define ftrigw_notifys(f, s) ftrigw_notifyb(f, (s), str_len(s))
extern int ftrigw_clean (char const *) ;
diff --git a/src/include/s6/s6-fdholder.h b/src/include/s6/s6-fdholder.h
@@ -0,0 +1,80 @@
+ /* ISC license. */
+
+#ifndef S6_FDHOLDER_H
+#define S6_FDHOLDER_H
+
+#include <skalibs/tai.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/unixmessage.h>
+#include <skalibs/unixconnection.h>
+
+#define S6_FDHOLDER_ID_SIZE 255
+
+typedef struct s6_fdholder_s s6_fdholder_t, *s6_fdholder_t_ref ;
+struct s6_fdholder_s
+{
+ unixconnection_t connection ;
+} ;
+#define S6_FDHOLDER_ZERO { .connection = UNIXMESSAGE_CONNECTION_ZERO } ;
+
+#define s6_fdholder_init(a, fdin, fdout) unixconnection_init(&(a)->connection, fdin, fdout)
+#define s6_fdholder_free(a) unixconnection_free(&(a)->connection)
+
+
+ /* Individual fds */
+
+extern int s6_fdholder_store_async (s6_fdholder_t *, int, char const *, tain_t const *) ;
+extern int s6_fdholder_store (s6_fdholder_t *, int, char const *, tain_t const *, tain_t const *, tain_t *) ;
+#define s6_fdholder_store_g(a, fd, id, limit, deadline) s6_fdholder_store(a, fd, id, limit, (deadline), &STAMP)
+
+extern int s6_fdholder_delete_async (s6_fdholder_t *, char const *) ;
+extern int s6_fdholder_delete (s6_fdholder_t *, char const *, tain_t const *, tain_t *) ;
+#define s6_fdholder_delete_g(a, id, deadline) s6_fdholder_delete(a, id, (deadline), &STAMP)
+
+typedef struct s6_fdholder_retrieve_result_s s6_fdholder_retrieve_result_t, *s6_fdholder_retrieve_result_t_ref ;
+struct s6_fdholder_retrieve_result_s
+{
+ int fd ;
+ unsigned char err ;
+} ;
+
+extern int s6_fdholder_retrieve_maybe_delete_async (s6_fdholder_t *, char const *, int) ;
+extern unixmessage_handler_func_t s6_fdholder_retrieve_cb ;
+extern int s6_fdholder_retrieve_maybe_delete (s6_fdholder_t *, char const *, int, tain_t const *, tain_t *) ;
+#define s6_fdholder_retrieve_maybe_delete_g (a, id, h, deadline) s6_fdholder_retrieve(a, id, h, (deadline), &STAMP)
+#define s6_fdholder_retrieve(a, id, deadline, stamp) s6_fdholder_retrieve_maybe_delete(a, id, 0, deadline, stamp)
+#define s6_fdholder_retrieve_g (a, id, deadline) s6_fdholder_retrieve(a, id, (deadline), &STAMP)
+#define s6_fdholder_retrieve_delete(a, id, deadline, stamp) s6_fdholder_retrieve_maybe_delete(a, id, 1, deadline, stamp)
+#define s6_fdholder_retrieve_delete_g (a, id, deadline) s6_fdholder_retrieve(a, id, (deadline), &STAMP)
+
+typedef struct s6_fdholder_list_result_s s6_fdholder_list_result_t, *s6_fdholder_list_result_t_ref ;
+struct s6_fdholder_list_result_s
+{
+ stralloc *sa ;
+ unsigned int n ;
+ unsigned char err ;
+} ;
+
+extern int s6_fdholder_list_async (s6_fdholder_t *) ;
+extern unixmessage_handler_func_t s6_fdholder_list_cb ;
+extern int s6_fdholder_list (s6_fdholder_t *, stralloc *, tain_t const *, tain_t *) ;
+#define s6_fdholder_list_g(a, sa, deadline) s6_fdholder_list(a, sa, (deadline), &STAMP)
+
+
+ /* Dumps */
+
+typedef struct s6_fdholder_fd_s s6_fdholder_fd_t, *s6_fdholder_fd_t_ref ;
+struct s6_fdholder_fd_s
+{
+ char id[S6_FDHOLDER_ID_SIZE + 1] ;
+ int fd ;
+ tain_t limit ;
+} ;
+
+extern int s6_fdholder_getdump (s6_fdholder_t *, genalloc *, tain_t const *, tain_t *) ;
+#define s6_fdholder_getdump_g(a, g, deadline) s6_fdholder_getdump_g(a, g, (deadline), &STAMP)
+extern int s6_fdholder_setdump (s6_fdholder_t *, s6_fdholder_fd_t const *, unsigned int, tain_t const *, tain_t *) ;
+#define s6_fdholder_setdump_g(a, list, n, deadline) s6_fdholder_setdump(a, list, n, (deadline), &STAMP)
+
+#endif
diff --git a/src/include/s6/s6-supervise.h b/src/include/s6/s6-supervise.h
@@ -10,7 +10,7 @@
#define S6_SVSCAN_CTLDIR ".s6-svscan"
#define S6_SVSTATUS_FILENAME S6_SUPERVISE_CTLDIR "/status"
#define S6_SUPERVISE_READY_FILENAME S6_SUPERVISE_CTLDIR "/ready"
-#define S6_SVSTATUS_SIZE 18
+#define S6_SVSTATUS_SIZE 26
extern int s6_svc_write (char const *, char const *, unsigned int) ;
extern int s6_svc_main (int, char const *const *, char const *, char const *, char const *) ;
@@ -24,14 +24,23 @@ struct s6_svstatus_s
unsigned int flagwantup : 1 ;
unsigned int flagpaused : 1 ;
unsigned int flagfinishing : 1 ;
+ unsigned int wstat ;
} ;
-#define S6_SVSTATUS_ZERO { .stamp = TAIN_ZERO, .pid = 0, .flagwant = 0, .flagwantup = 0, .flagpaused = 0, .flagfinishing = 0 }
-
+#define S6_SVSTATUS_ZERO \
+{ \
+ .stamp = TAIN_ZERO, \
+ .pid = 0, \
+ .flagwant = 0, \
+ .flagwantup = 0, \
+ .flagpaused = 0, \
+ .flagfinishing = 0, \
+ .wstat = 0 \
+}
extern void s6_svstatus_pack (char *, s6_svstatus_t const *) ;
-extern void s6_svstatus_unpack (char const *, s6_svstatus_t_ref) ;
-extern int s6_svstatus_read (char const *, s6_svstatus_t_ref) ;
+extern void s6_svstatus_unpack (char const *, s6_svstatus_t *) ;
+extern int s6_svstatus_read (char const *, s6_svstatus_t *) ;
extern int s6_svstatus_write (char const *, s6_svstatus_t const *) ;
/* These functions leak a fd, that's intended */
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
@@ -13,6 +13,7 @@ ftrigw_clean.o
ftrigw_fifodir_make.o
ftrigw_notify.o
ftrigw_notifyb.o
+ftrigw_notifyb_nosig.o
s6_accessrules_backend_cdb.o
s6_accessrules_backend_fs.o
s6_accessrules_keycheck_ip4.o
@@ -23,7 +24,6 @@ s6_accessrules_uidgid_cdb.o
s6_accessrules_uidgid_fs.o
s6_supervise_lock.o
s6_supervise_lock_mode.o
-s6_svc_main.o
s6_svc_write.o
s6_svstatus_pack.o
s6_svstatus_read.o
@@ -39,3 +39,15 @@ s6lock_update.o
s6lock_wait_and.o
s6lock_wait_or.o
s6lock_zero.o
+s6_fdholder_delete.o
+s6_fdholder_delete_async.o
+s6_fdholder_getdump.o
+s6_fdholder_list.o
+s6_fdholder_list_async.o
+s6_fdholder_list_cb.o
+s6_fdholder_retrieve.o
+s6_fdholder_retrieve_async.o
+s6_fdholder_retrieve_cb.o
+s6_fdholder_setdump.o
+s6_fdholder_store.o
+s6_fdholder_store_async.o
diff --git a/src/libs6/ftrigw_notifyb.c b/src/libs6/ftrigw_notifyb.c
@@ -1,67 +1,20 @@
/* ISC license. */
-#include <unistd.h>
#include <errno.h>
#include <signal.h>
-#include <skalibs/direntry.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/bytestr.h>
#include <skalibs/sig.h>
-#include <skalibs/djbunix.h>
-#include "ftrig1.h"
#include <s6/ftrigw.h>
int ftrigw_notifyb (char const *path, char const *s, unsigned int len)
{
- unsigned int i = 0 ;
struct skasigaction old ;
- DIR *dir = opendir(path) ;
- if (!dir) return -1 ;
+ int r ;
if (skasigaction(SIGPIPE, &SKASIG_IGN, &old) < 0) return -1 ;
- {
- unsigned int pathlen = str_len(path) ;
- char tmp[pathlen + FTRIG1_PREFIXLEN + 45] ;
- byte_copy(tmp, pathlen, path) ;
- tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 44] = 0 ;
- for (;;)
- {
- direntry *d ;
- int fd ;
- errno = 0 ;
- d = readdir(dir) ;
- if (!d) break ;
- if (str_diffn(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ;
- if (str_len(d->d_name) != FTRIG1_PREFIXLEN + 43) continue ;
- byte_copy(tmp + pathlen + 1, FTRIG1_PREFIXLEN + 43, d->d_name) ;
- fd = open_write(tmp) ;
- if (fd == -1)
- {
- if (errno == ENXIO) unlink(tmp) ;
- }
- else
- {
- register int r = fd_write(fd, s, len) ;
- if ((r < 0) || (unsigned int)r < len)
- {
- if (errno == EPIPE) unlink(tmp) ;
- /* what to do if EGAIN ? full fifo -> fix the reader !
- There's a race condition in extreme cases though ;
- but it's still better to be nonblocking - the writer
- shouldn't get in trouble because of a bad reader. */
- fd_close(fd) ;
- }
- else
- {
- fd_close(fd) ;
- i++ ;
- }
- }
- }
- }
+ r = ftrigw_notifyb_nosig(path, s, len) ;
{
int e = errno ;
skasigaction(SIGPIPE, &old, 0) ;
- dir_close(dir) ;
- return e ? (errno = e, -1) : (int)i ;
+ errno = e ;
}
+ return r ;
}
diff --git a/src/libs6/ftrigw_notifyb_nosig.c b/src/libs6/ftrigw_notifyb_nosig.c
@@ -0,0 +1,62 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <errno.h>
+#include <skalibs/direntry.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/djbunix.h>
+#include "ftrig1.h"
+#include <s6/ftrigw.h>
+
+int ftrigw_notifyb_nosig (char const *path, char const *s, unsigned int len)
+{
+ unsigned int i = 0 ;
+ DIR *dir = opendir(path) ;
+ if (!dir) return -1 ;
+ {
+ unsigned int pathlen = str_len(path) ;
+ char tmp[pathlen + FTRIG1_PREFIXLEN + 45] ;
+ byte_copy(tmp, pathlen, path) ;
+ tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 44] = 0 ;
+ for (;;)
+ {
+ direntry *d ;
+ int fd ;
+ errno = 0 ;
+ d = readdir(dir) ;
+ if (!d) break ;
+ if (str_diffn(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ;
+ if (str_len(d->d_name) != FTRIG1_PREFIXLEN + 43) continue ;
+ byte_copy(tmp + pathlen + 1, FTRIG1_PREFIXLEN + 43, d->d_name) ;
+ fd = open_write(tmp) ;
+ if (fd == -1)
+ {
+ if (errno == ENXIO) unlink(tmp) ;
+ }
+ else
+ {
+ register int r = fd_write(fd, s, len) ;
+ if ((r < 0) || (unsigned int)r < len)
+ {
+ if (errno == EPIPE) unlink(tmp) ;
+ /* what to do if EGAIN ? full fifo -> fix the reader !
+ There's a race condition in extreme cases though ;
+ but it's still better to be nonblocking - the writer
+ shouldn't get in trouble because of a bad reader. */
+ fd_close(fd) ;
+ }
+ else
+ {
+ fd_close(fd) ;
+ i++ ;
+ }
+ }
+ }
+ }
+ {
+ int e = errno ;
+ dir_close(dir) ;
+ return e ? (errno = e, -1) : (int)i ;
+ }
+}
diff --git a/src/libs6/s6_fdholder_delete.c b/src/libs6/s6_fdholder_delete.c
@@ -0,0 +1,21 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_delete (s6_fdholder_t *a, char const *id, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ if (!s6_fdholder_delete_async(a, id)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ return m.s[0] ? (errno = m.s[0], 0) : 1 ;
+}
diff --git a/src/libs6/s6_fdholder_delete_async.c b/src/libs6/s6_fdholder_delete_async.c
@@ -0,0 +1,18 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_delete_async (s6_fdholder_t *a, char const *id)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[2] = "D" ;
+ siovec_t v[2] = { { .s = pack, .len = 2 }, { .s = (char *)id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = 0, .nfds = 0 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = (unsigned char)idlen ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_getdump.c b/src/libs6/s6_fdholder_getdump.c
@@ -0,0 +1,73 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/error.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_getdump (s6_fdholder_t *a, genalloc *g, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m = { .s = "?", .len = 1, .fds = 0, .nfds = 0 } ;
+ uint32 ntot, n ;
+ unsigned int oldlen = genalloc_len(s6_fdholder_fd_t, g) ;
+ unsigned int i = 0 ;
+ int ok ;
+ if (!unixmessage_put(&a->connection.out, &m)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (!m.len || m.nfds) return (errno = EPROTO, 0) ;
+ if (m.s[0]) return (errno = m.s[0], 0) ;
+ if (m.len != 9) return (errno = EPROTO, 0) ;
+ uint32_unpack_big(m.s + 1, &n) ;
+ uint32_unpack_big(m.s + 5, &ntot) ;
+ if (!ntot) return 1 ;
+ if (n != 1 + (ntot-1) / UNIXMESSAGE_MAXFDS) return (errno = EPROTO, 0) ;
+ ok = genalloc_readyplus(s6_fdholder_fd_t, g, ntot) ;
+
+ for (; i < n ; i++)
+ {
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) goto err ;
+ if (genalloc_len(s6_fdholder_fd_t, g) + m.nfds > ntot) goto droperr ;
+ if (ok)
+ {
+ s6_fdholder_fd_t *tab = genalloc_s(s6_fdholder_fd_t, g) + genalloc_len(s6_fdholder_fd_t, g) ;
+ unsigned int i = 0 ;
+ for (; i < m.nfds ; i++)
+ {
+ unsigned char thislen ;
+ if (m.len < TAIN_PACK + 3) goto droperr ;
+ tain_unpack(m.s, &tab[i].limit) ;
+ m.s += TAIN_PACK ; m.len -= TAIN_PACK + 1 ;
+ thislen = *m.s++ ;
+ if (thislen > m.len - 1 || thislen > S6_FDHOLDER_ID_SIZE || m.s[thislen]) goto droperr ;
+ byte_copy(tab[i].id, thislen, m.s) ;
+ byte_zero(tab[i].id + thislen, S6_FDHOLDER_ID_SIZE + 1 - thislen) ;
+ m.s += (unsigned int)thislen + 1 ; m.len -= (unsigned int)thislen + 1 ;
+ tab[i].fd = m.fds[i] ;
+ }
+ genalloc_setlen(s6_fdholder_fd_t, g, genalloc_len(s6_fdholder_fd_t, g) + m.nfds) ;
+ }
+ else unixmessage_drop(&m) ;
+ }
+
+ if (!ok) return (errno = ENOMEM, 0) ;
+ return 1 ;
+
+ droperr:
+ unixmessage_drop(&m) ;
+ errno = EPROTO ;
+ err:
+ {
+ int e = errno ;
+ i = genalloc_len(s6_fdholder_fd_t, g) ;
+ while (i-- > oldlen) fd_close(genalloc_s(s6_fdholder_fd_t, g)[i].fd) ;
+ genalloc_setlen(s6_fdholder_fd_t, g, oldlen) ;
+ errno = e ;
+ }
+ return 0 ;
+}
diff --git a/src/libs6/s6_fdholder_list.c b/src/libs6/s6_fdholder_list.c
@@ -0,0 +1,19 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list (s6_fdholder_t *a, stralloc *sa, tain_t const *deadline, tain_t *stamp)
+{
+ s6_fdholder_list_result_t res = { .sa = sa } ;
+ unixmessage_t m ;
+ if (!s6_fdholder_list_async(a)) return -1 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return -1 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return -1 ;
+ if (!s6_fdholder_list_cb(&m, &res)) return -1 ;
+ if (res.err) return (errno = res.err, -1) ;
+ return (int)res.n ;
+}
diff --git a/src/libs6/s6_fdholder_list_async.c b/src/libs6/s6_fdholder_list_async.c
@@ -0,0 +1,11 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list_async (s6_fdholder_t *a)
+{
+ unixmessage_t m = { .s = "L", .len = 1, .fds = 0, .nfds = 0 } ;
+ return unixmessage_put(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_list_cb.c b/src/libs6/s6_fdholder_list_cb.c
@@ -0,0 +1,31 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/error.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list_cb (unixmessage_t const *m, void *p)
+{
+ uint32 n ;
+ register s6_fdholder_list_result_t *res = p ;
+ if (m->nfds) goto droperr ;
+ if (m->len < 5) goto err ;
+ if (m->s[0])
+ {
+ res->err = m->s[0] ;
+ return 1 ;
+ }
+ uint32_unpack_big(m->s + 1, &n) ;
+ if (!stralloc_catb(res->sa, m->s + 5, m->len - 5)) return 0 ;
+ res->n = n ;
+ res->err = 0 ;
+ return 1 ;
+
+ droperr:
+ unixmessage_drop(m) ;
+ err:
+ return (errno = EPROTO, 0) ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve.c b/src/libs6/s6_fdholder_retrieve.c
@@ -0,0 +1,18 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_maybe_delete (s6_fdholder_t *a, char const *id, int dodelete, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ s6_fdholder_retrieve_result_t res ;
+ if (!s6_fdholder_retrieve_maybe_delete_async(a, id, dodelete)) return -1 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return -1 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return -1 ;
+ if (!s6_fdholder_retrieve_cb(&m, &res)) return -1 ;
+ if (res.err) return (errno = res.err, -1) ;
+ return res.fd ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve_async.c b/src/libs6/s6_fdholder_retrieve_async.c
@@ -0,0 +1,20 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_maybe_delete_async (s6_fdholder_t *a, char const *id, int dodelete)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[3] = "R" ;
+ siovec_t v[2] = { { .s = pack, .len = 3 }, { .s = (char *)id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = 0, .nfds = 0 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = !!dodelete ;
+ pack[2] = (unsigned char)idlen ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve_cb.c b/src/libs6/s6_fdholder_retrieve_cb.c
@@ -0,0 +1,26 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_cb (unixmessage_t const *m, void *p)
+{
+ register s6_fdholder_retrieve_result_t *res = p ;
+ if (m->len != 1) goto err ;
+ if (m->s[0])
+ {
+ if (m->nfds) goto err ;
+ res->err = m->s[0] ;
+ return 1 ;
+ }
+ if (m->nfds != 1) goto err ;
+ res->fd = m->fds[0] ;
+ res->err = 0 ;
+ return 1 ;
+
+ err:
+ unixmessage_drop(m) ;
+ return (errno = EPROTO, 0) ;
+}
diff --git a/src/libs6/s6_fdholder_setdump.c b/src/libs6/s6_fdholder_setdump.c
@@ -0,0 +1,74 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_setdump (s6_fdholder_t *a, s6_fdholder_fd_t const *list, unsigned int ntot, tain_t const *deadline, tain_t *stamp)
+{
+ uint32 trips ;
+ if (!ntot) return 1 ;
+ unsigned int i = 0 ;
+ for (; i < ntot ; i++)
+ {
+ unsigned int zpos = byte_chr(list[i].id, S6_FDHOLDER_ID_SIZE + 1, 0) ;
+ if (!zpos || zpos >= S6_FDHOLDER_ID_SIZE + 1) return (errno = EINVAL, 0) ;
+ }
+ {
+ char pack[5] = "!" ;
+ unixmessage_t m = { .s = pack, .len = 5, .fds = 0, .nfds = 0 } ;
+ uint32_pack_big(pack+1, ntot) ;
+ if (!unixmessage_put(&a->connection.out, &m)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (!m.len || m.nfds) { unixmessage_drop(&m) ; return (errno = EPROTO, 0) ; }
+ if (m.s[0]) return (errno = m.s[0], 0) ;
+ if (m.len != 5) return (errno = EPROTO, 0) ;
+ uint32_unpack_big(pack + 1, &trips) ;
+ if (trips != 1 + (ntot-1) / UNIXMESSAGE_MAXFDS) return (errno = EPROTO, 0) ;
+ }
+ for (i = 0 ; i < trips ; i++, ntot -= UNIXMESSAGE_MAXFDS)
+ {
+ {
+ unsigned int n = ntot > UNIXMESSAGE_MAXFDS ? UNIXMESSAGE_MAXFDS : ntot ;
+ unsigned int j = 0 ;
+ siovec_t v[1 + (n<<1)] ;
+ int fds[n] ;
+ unixmessage_v_t m = { .v = v, .vlen = 1 + (n<<1), .fds = fds, .nfds = n } ;
+ char pack[n * (TAIN_PACK+1)] ;
+ v[0].s = "." ; v[0].len = 1 ;
+ for (; j < n ; j++, list++, ntot--)
+ {
+ unsigned int len = str_len(list->id) ;
+ v[1 + (j<<1)].s = pack + j * (TAIN_PACK+1) ;
+ v[1 + (j<<1)].len = TAIN_PACK + 1 ;
+ tain_pack(pack + j * (TAIN_PACK+1), &list->limit) ;
+ pack[j * (TAIN_PACK+1) + TAIN_PACK] = (unsigned char)len + 1 ;
+ v[2 + (j<<1)].s = (char *)list->id ;
+ v[2 + (j<<1)].len = len ;
+ fds[j] = list->fd ;
+ }
+ if (!unixmessage_putv(&a->connection.out, &m)) return 0 ;
+ }
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ {
+ unixmessage_t m ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ if (!error_isagain(m.s[0]) && i < trips-1)
+ return errno = m.s[0] ? m.s[0] : EPROTO, 0 ;
+ if (i == trips - 1 && m.s[0])
+ return errno = error_isagain(m.s[0]) ? EPROTO : m.s[0], 0 ;
+ }
+ }
+ return 1 ;
+}
diff --git a/src/libs6/s6_fdholder_store.c b/src/libs6/s6_fdholder_store.c
@@ -0,0 +1,21 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_store (s6_fdholder_t *a, int fd, char const *id, tain_t const *limit, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ if (!s6_fdholder_store_async(a, fd, id, limit)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ return m.s[0] ? (errno = m.s[0], 0) : 1 ;
+}
diff --git a/src/libs6/s6_fdholder_store_async.c b/src/libs6/s6_fdholder_store_async.c
@@ -0,0 +1,20 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_store_async (s6_fdholder_t *a, int fd, char const *id, tain_t const *limit)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[2 + TAIN_PACK] = "S" ;
+ siovec_t v[2] = { { .s = pack, .len = 2 + TAIN_PACK }, { .s = id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = &fd, .nfds = 1 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = (unsigned char)idlen ;
+ tain_pack(pack + 2, limit) ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_svc_main.c b/src/libs6/s6_svc_main.c
@@ -1,39 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/bytestr.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr2.h>
-#include <s6/s6-supervise.h>
-
-#define DATASIZE 256
-
-int s6_svc_main (int argc, char const *const *argv, char const *optstring, char const *usage, char const *controldir)
-{
- char data[DATASIZE] ;
- unsigned int datalen = 0 ;
- register int r ;
- for (;;)
- {
- register int opt = subgetopt(argc, argv, optstring) ;
- if (opt == -1) break ;
- if (opt == '?') strerr_dieusage(100, usage) ;
- if (datalen >= DATASIZE) strerr_dief1x(100, "too many commands") ;
- data[datalen++] = opt ;
- }
- argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
- if (!argc) strerr_dieusage(100, usage) ;
-
- {
- unsigned int arglen = str_len(*argv) ;
- unsigned int cdirlen = str_len(controldir) ;
- char tmp[arglen + cdirlen + 10] ;
- byte_copy(tmp, arglen, *argv) ;
- tmp[arglen] = '/' ;
- byte_copy(tmp + arglen + 1, cdirlen, controldir) ;
- byte_copy(tmp + arglen + 1 + cdirlen, 9, "/control") ;
- r = s6_svc_write(tmp, data, datalen) ;
- }
- if (r < 0) strerr_diefu2sys(111, "control ", *argv) ;
- else if (!r) strerr_diefu3x(100, "control ", *argv, ": supervisor not listening") ;
- return 0 ;
-}
diff --git a/src/libs6/s6_svstatus_pack.c b/src/libs6/s6_svstatus_pack.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/tai.h>
#include <s6/s6-supervise.h>
@@ -10,4 +11,5 @@ void s6_svstatus_pack (char *pack, s6_svstatus_t const *sv)
uint32_pack(pack + 12, (uint32)sv->pid) ;
pack[16] = sv->flagpaused | (sv->flagfinishing << 1) ;
pack[17] = sv->flagwant ? sv->flagwantup ? 'u' : 'd' : 0 ;
+ uint64_pack(pack + 18, (uint64)sv->wstat) ;
}
diff --git a/src/libs6/s6_svstatus_read.c b/src/libs6/s6_svstatus_read.c
@@ -4,7 +4,7 @@
#include <skalibs/djbunix.h>
#include <s6/s6-supervise.h>
-int s6_svstatus_read (char const *dir, s6_svstatus_t_ref status)
+int s6_svstatus_read (char const *dir, s6_svstatus_t *status)
{
unsigned int n = str_len(dir) ;
char pack[S6_SVSTATUS_SIZE] ;
diff --git a/src/libs6/s6_svstatus_unpack.c b/src/libs6/s6_svstatus_unpack.c
@@ -1,15 +1,19 @@
/* ISC license. */
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/tai.h>
#include <s6/s6-supervise.h>
-void s6_svstatus_unpack (char const *pack, s6_svstatus_t_ref sv)
+void s6_svstatus_unpack (char const *pack, s6_svstatus_t *sv)
{
uint32 pid ;
+ uint64 wstat ;
tain_unpack(pack, &sv->stamp) ;
uint32_unpack(pack + 12, &pid) ;
- sv->pid = (int)pid ;
+ sv->pid = (unsigned int)pid ;
+ uint64_unpack(pack + 18, &wstat) ;
+ sv->wstat = (unsigned int)wstat ;
sv->flagpaused = pack[16] & 1 ;
sv->flagfinishing = (pack[16] >> 1) & 1 ;
switch (pack[17])
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
@@ -45,7 +45,7 @@ typedef void action_t (void) ;
typedef action_t *action_t_ref ;
static tain_t deadline ;
-static s6_svstatus_t status = { .stamp = TAIN_ZERO, .pid = 0, .flagwant = 1, .flagwantup = 1, .flagpaused = 0, .flagfinishing = 0 } ;
+static s6_svstatus_t status = { .stamp = TAIN_ZERO, .pid = 0, .flagwant = 1, .flagwantup = 1, .flagpaused = 0, .flagfinishing = 0, .wstat = 0 } ;
static state_t state = DOWN ;
static int flagsetsid = 1 ;
static int cont = 1 ;
@@ -166,7 +166,7 @@ static void trystart (void)
if (flagsetsid) setsid() ;
execve("./run", (char *const *)cargv, (char *const *)environ) ;
fd_write(p[1], "", 1) ;
- strerr_dieexec(111, "run") ;
+ strerr_dieexec(127, "run") ;
}
fd_close(p[1]) ;
{
@@ -194,7 +194,7 @@ static void trystart (void)
status.pid = pid ;
tain_copynow(&status.stamp) ;
announce() ;
- ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'u') ;
+ ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ;
}
static void downtimeout (void)
@@ -230,7 +230,7 @@ static void down_d (void)
announce() ;
}
-static void tryfinish (int wstat, int islast)
+static inline void tryfinish (int islast)
{
register pid_t pid = fork() ;
if (pid < 0)
@@ -238,7 +238,6 @@ static void tryfinish (int wstat, int islast)
strerr_warnwu2sys("fork for ", "./finish") ;
if (islast) bail() ;
state = DOWN ;
- status.pid = 0 ;
settimeout(1) ;
return ;
}
@@ -248,16 +247,15 @@ static void tryfinish (int wstat, int islast)
char fmt1[UINT_FMT] ;
char *cargv[4] = { "finish", fmt0, fmt1, 0 } ;
selfpipe_finish() ;
- fmt0[uint_fmt(fmt0, WIFSIGNALED(wstat) ? 255 : WEXITSTATUS(wstat))] = 0 ;
- fmt1[uint_fmt(fmt1, WTERMSIG(wstat))] = 0 ;
+ fmt0[uint_fmt(fmt0, WIFSIGNALED(status.wstat) ? 256 : WEXITSTATUS(status.wstat))] = 0 ;
+ fmt1[uint_fmt(fmt1, WTERMSIG(status.wstat))] = 0 ;
if (flagsetsid) setsid() ;
execve("./finish", cargv, (char *const *)environ) ;
- _exit(111) ;
+ _exit(127) ;
}
status.pid = pid ;
status.flagfinishing = 1 ;
state = islast ? LASTFINISH : FINISH ;
- settimeout(5) ;
}
static void uptimeout (void)
@@ -268,18 +266,20 @@ static void uptimeout (void)
static void uplastup_z (int islast)
{
- int wstat = status.pid ;
+ status.wstat = status.pid ;
status.pid = 0 ;
tain_copynow(&status.stamp) ;
+ tryfinish(islast) ;
announce() ;
- ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'd') ;
+ ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "d", 1) ;
if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT)
strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ;
- tryfinish(wstat, islast) ;
+ settimeout(5) ;
}
static void up_z (void)
{
+ status.flagpaused = 0 ;
uplastup_z(0) ;
}
@@ -401,7 +401,7 @@ static void handle_signals (void)
if (errno != ECHILD) strerr_diefu1sys(111, "wait_pid_nohang") ;
else break ;
else if (!r) break ;
- status.pid = wstat ;
+ status.pid = wstat ; /* don't overwrite status.wstat if it's ./finish */
(*actions[state][V_CHLD])() ;
}
break ;
@@ -490,7 +490,7 @@ int main (int argc, char const *const *argv)
settimeout(0) ;
tain_copynow(&status.stamp) ;
announce() ;
- ftrigw_notify(S6_SUPERVISE_EVENTDIR, 's') ;
+ ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ;
while (cont)
{
@@ -506,7 +506,7 @@ int main (int argc, char const *const *argv)
}
}
- ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'x') ;
+ ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "x", 1) ;
}
return 0 ;
}
diff --git a/src/supervision/s6-svscan.c b/src/supervision/s6-svscan.c
@@ -29,7 +29,7 @@
#define DIR_RETRY_TIMEOUT 3
#define CHECK_RETRY_TIMEOUT 4
-struct svinfo
+struct svinfo_s
{
dev_t dev ;
ino_t ino ;
@@ -39,9 +39,8 @@ struct svinfo
unsigned int flagactive : 1 ;
unsigned int flaglog : 1 ;
} ;
-#define SVINFO_ZERO { -1, -1, { TAIN_ZERO, TAIN_ZERO }, { 0, 0 }, { -1, -1 }, 0, 0, 0 } ;
-static struct svinfo *services ;
+static struct svinfo_s *services ;
static unsigned int max = 500 ;
static unsigned int n = 0 ;
static tain_t deadline, defaulttimeout ;
@@ -452,7 +451,7 @@ int main (int argc, char const *const *argv)
{
- struct svinfo blob[max] ; /* careful with that stack, Eugene */
+ struct svinfo_s blob[max] ; /* careful with that stack, Eugene */
services = blob ;
tain_now_g() ;
diff --git a/src/supervision/s6-svscanctl.c b/src/supervision/s6-svscanctl.c
@@ -1,12 +1,65 @@
/* ISC license. */
+#include <skalibs/bytestr.h>
+#include <skalibs/sgetopt.h>
#include <skalibs/strerr2.h>
#include <s6/s6-supervise.h>
#define USAGE "s6-svscanctl [ -phratszbnNiq0678 ] svscandir"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+#define DATASIZE 64
int main (int argc, char const *const *argv)
{
+ char data[DATASIZE] ;
+ unsigned int datalen = 0 ;
+ int r ;
PROG = "s6-svscanctl" ;
- return s6_svc_main(argc, argv, "phratszbnNiq0678", USAGE, ".s6-svscan") ;
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ register int opt = subgetopt_r(argc, argv, "phratszbnNiq0678", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'p' :
+ case 'h' :
+ case 'r' :
+ case 'a' :
+ case 't' :
+ case 's' :
+ case 'z' :
+ case 'b' :
+ case 'n' :
+ case 'N' :
+ case 'i' :
+ case 'q' :
+ case '0' :
+ case '6' :
+ case '7' :
+ case '8' :
+ {
+ if (datalen >= DATASIZE) strerr_dief1x(100, "too many commands") ;
+ data[datalen++] = opt ;
+ break ;
+ }
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+ if (!argc) dieusage() ;
+
+ {
+ unsigned int arglen = str_len(*argv) ;
+ char tmp[arglen + 20] ;
+ byte_copy(tmp, arglen, *argv) ;
+ byte_copy(tmp + arglen, 20, "/.s6-svscan/control") ;
+ r = s6_svc_write(tmp, data, datalen) ;
+ }
+ if (r < 0) strerr_diefu2sys(111, "control ", *argv) ;
+ else if (!r) strerr_diefu3x(100, "control ", *argv, ": supervisor not listening") ;
+ return 0 ;
}
diff --git a/src/supervision/s6-svstat.c b/src/supervision/s6-svstat.c
@@ -1,27 +1,46 @@
/* ISC license. */
-#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
#include <skalibs/uint64.h>
#include <skalibs/uint.h>
#include <skalibs/bytestr.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr2.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/sig.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <s6/s6-supervise.h>
-#define USAGE "s6-svstat servicedir"
+#define USAGE "s6-svstat [ -n ] servicedir"
+#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
{
s6_svstatus_t status ;
- char fmt[UINT_FMT] ;
+ int flagnum = 0 ;
int isup, normallyup ;
+ char fmt[UINT_FMT] ;
PROG = "s6-svstat" ;
- if (argc < 2) strerr_dieusage(100, USAGE) ;
- argv++ ; argc-- ;
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ register int opt = subgetopt_r(argc, argv, "n", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'n' : flagnum = 1 ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+ if (!argc) dieusage() ;
+
if (!s6_svstatus_read(*argv, &status))
strerr_diefu2sys(111, "read status for ", *argv) ;
@@ -48,7 +67,24 @@ int main (int argc, char const *const *argv)
buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, status.pid)) ;
buffer_putnoflush(buffer_1small, ") ", 2) ;
}
- else buffer_putnoflush(buffer_1small, "down ", 5) ;
+ else
+ {
+ buffer_putnoflush(buffer_1small, "down (", 6) ;
+ if (WIFSIGNALED(status.wstat))
+ {
+ buffer_putnoflush(buffer_1small, "signal ", 7) ;
+ if (flagnum)
+ buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, WTERMSIG(status.wstat))) ;
+ else
+ buffer_putsnoflush(buffer_1small, sig_name(WTERMSIG(status.wstat))) ;
+ }
+ else
+ {
+ buffer_putnoflush(buffer_1small, "exitcode ", 9) ;
+ buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, WEXITSTATUS(status.wstat))) ;
+ }
+ buffer_putnoflush(buffer_1small, ") ", 2) ;
+ }
buffer_putnoflush(buffer_1small, fmt, uint64_fmt(fmt, status.stamp.sec.x)) ;
buffer_putnoflush(buffer_1small," seconds", 8) ;