about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--COPYING2
-rw-r--r--INSTALL4
-rw-r--r--Makefile8
-rwxr-xr-xconfigure5
-rw-r--r--doc/index.html6
-rw-r--r--doc/notifywhenup.html36
-rw-r--r--doc/s6-notifywhenup.html3
-rw-r--r--doc/s6-svwait.html12
-rw-r--r--doc/upgrade.html8
-rw-r--r--package/deps.mak30
-rw-r--r--package/info2
-rw-r--r--package/targets.mak6
-rw-r--r--src/daemontools-extras/deps-exe/s6-notifywhenup2
-rw-r--r--src/daemontools-extras/s6-notifywhenup.c5
-rw-r--r--src/daemontools-extras/s6-setuidgid.c30
-rw-r--r--src/include/s6/s6-supervise.h1
-rw-r--r--src/pipe-tools/deps-exe/s6-cleanfifodir2
-rw-r--r--src/pipe-tools/deps-exe/s6-ftrig-listen2
-rw-r--r--src/pipe-tools/deps-exe/s6-ftrig-listen12
-rw-r--r--src/pipe-tools/deps-exe/s6-ftrig-notify2
-rw-r--r--src/pipe-tools/deps-exe/s6-ftrig-wait2
-rw-r--r--src/pipe-tools/deps-exe/s6-mkfifodir2
-rw-r--r--src/supervision/deps-exe/s6-supervise2
-rw-r--r--src/supervision/deps-exe/s6-svc2
-rw-r--r--src/supervision/deps-exe/s6-svscan2
-rw-r--r--src/supervision/deps-exe/s6-svscanctl2
-rw-r--r--src/supervision/deps-exe/s6-svstat2
-rw-r--r--src/supervision/deps-exe/s6-svwait2
-rw-r--r--src/supervision/s6-supervise.c20
-rw-r--r--src/supervision/s6-svwait.c19
-rwxr-xr-xtools/gen-deps.sh2
31 files changed, 134 insertions, 91 deletions
diff --git a/COPYING b/COPYING
index 63309ba..a49b1ca 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2014 Laurent Bercot <ska-skaware@skarnet.org>
+Copyright (c) 2011-2015 Laurent Bercot <ska-skaware@skarnet.org>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
diff --git a/INSTALL b/INSTALL
index eb61192..71947f5 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,8 +6,8 @@ Build Instructions
 
   - A POSIX-compliant C development environment
   - GNU make version 4.0 or later
-  - skalibs version 2.1.0.0 or later: http://skarnet.org/software/skalibs/
-  - execline version 2.0.0.0 or later: http://skarnet.org/software/execline/
+  - skalibs version 2.2.0.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
 POSIX.1-2008, available at:
diff --git a/Makefile b/Makefile
index b9eb4ea..c602cad 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,8 @@ CC = $(error Please use ./configure first)
 
 STATIC_LIBS :=
 SHARED_LIBS :=
+INTERNAL_LIBS :=
+EXTRA_TARGETS :=
 
 -include config.mak
 include package/targets.mak
@@ -32,13 +34,13 @@ STRIP := $(CROSS_COMPILE)strip
 INSTALL := ./tools/install.sh
 
 ALL_BINS := $(LIBEXEC_TARGETS) $(BIN_TARGETS) $(SBIN_TARGETS)
-ALL_LIBS := $(SHARED_LIBS) $(STATIC_LIBS)
+ALL_LIBS := $(SHARED_LIBS) $(STATIC_LIBS) $(INTERNAL_LIBS)
 ALL_INCLUDES := $(wildcard src/include/$(package)/*.h)
 
 all: $(ALL_LIBS) $(ALL_BINS) $(ALL_INCLUDES)
 
 clean:
-	@exec rm -f $(ALL_LIBS) $(ALL_BINS) $(wildcard src/*/*.o src/*/*.lo)
+	@exec rm -f $(ALL_LIBS) $(ALL_BINS) $(wildcard src/*/*.o src/*/*.lo) $(EXTRA_TARGETS)
 
 distclean: clean
 	@exec rm -f config.mak src/include/${package}/config.h
@@ -122,5 +124,3 @@ lib%.so:
 .PHONY: it all clean distclean tgz strip install install-dynlib install-bin install-sbin install-lib install-include
 
 .DELETE_ON_ERROR:
-
-.NOTPARALLEL:
diff --git a/configure b/configure
index 056061c..d8d62e8 100755
--- a/configure
+++ b/configure
@@ -169,8 +169,8 @@ for arg ; do
     --enable-static|--enable-static=yes) static=true ;;
     --disable-static|--enable-static=no) static=false ;;
     --enable-allstatic|--enable-allstatic=yes) allstatic=true ;;
-    --disable-allstatic|--enable-allstatic=no) allstatic=false ;;
-    --enable-static-libc|--enable-static-libc=yes) evenmorestatic=true ;;
+    --disable-allstatic|--enable-allstatic=no) allstatic=false ; evenmorestatic=false ;;
+    --enable-static-libc|--enable-static-libc=yes) allstatic=true ; evenmorestatic=true ;;
     --disable-static-libc|--enable-static-libc=no) evenmorestatic=false ;;
     --enable-slashpackage=*) sproot=${arg#*=} ; slashpackage=true ; ;;
     --enable-slashpackage) sproot= ; slashpackage=true ;;
@@ -358,6 +358,7 @@ vpath lib%a$vpaths
 EOF
 if $allstatic ; then
   echo ".LIBPATTERNS := lib%.a"
+  echo "DO_ALLSTATIC := 1"
   vpathd=
 fi
   echo "vpath lib%.so$vpathd"
diff --git a/doc/index.html b/doc/index.html
index bf8d0ae..1507705 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -52,9 +52,9 @@ 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.1.0.0 or later </li>
+2.2.0.0 or later </li>
  <li> <a href="http://skarnet.org/software/execline/">execline</a> version
-2.0.0.0 or later </li>
+2.0.1.1 or later </li>
 </ul>
 
 <h3> Licensing </h3>
@@ -67,7 +67,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.0.1.tar.gz">2.0.0.1</a>. </li>
+ <li> The current released version of s6 is <a href="s6-2.0.1.0.tar.gz">2.0.1.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/notifywhenup.html b/doc/notifywhenup.html
index f73e2aa..6847cb2 100644
--- a/doc/notifywhenup.html
+++ b/doc/notifywhenup.html
@@ -42,25 +42,28 @@ daemon may not be ready yet.
 
 <p>
  Reliable startup notifications need support from the daemons themselves.
-Daemons should notify the outside world when the service they are providing
-is reliably up - because only they know when it is the case.
-</p>
-
-<p>
- s6 provides two ways for daemons to perform startup notification.
+Daemons should do two things to signal the outside world that they are
+ready:
 </p>
 
 <ol>
- <li> Daemons can use the <tt>ftrigw_notify()</tt> function, provided in
-<a href="libftrigw.html">the ftrigw library</a>. This is extremely
-simple and efficient, but requires specific s6 support in the daemon. </li>
- <li> Daemons can write a line to a file descriptor of their choice,
+ <li> Update a state file, so other processes can get a snapshot
+of the daemon's state </li>
+ <li> Send an event to processes waiting for a state change. </li>
+</ol>
+
+<p>
+ This is complex to implement in every single daemon, so s6 provides
+tools to make it easier for daemon authors, without any need to link
+against the s6 library or use any s6-specific construct:
+ daemons can simply write a line to a file descriptor of their choice,
 then close that file descriptor, when they're ready to serve. This is
-a generic mechanism that some daemons already implement, and does not
-require anything specific in the daemon's code. The administrator can
+a generic mechanism that some daemons already implement.
+The administrator can
 then run the daemon under <a href="s6-notifywhenup.html">s6-notifywhenup</a>,
-which will properly catch the daemon's message and notify all the subscribers
-with a 'U' event, meaning that the service is now up. <br /> <br />
+which will properly catch the daemon's message and update a state file
+itself, then notify all the subscribers
+with a 'U' event, meaning that the service is now up. <br />
  Note that there is <em>still</em> a small race condition remaining:
 if the daemon writes a line then instantly dies, and the supervisor
 picks up the death before the <a href="s6-notifywhenup.html">s6-notifywhenup</a>
@@ -69,11 +72,10 @@ to the fifodir to be wrong - 'd' before 'U'. This should be extremely
 rare, but unfortunately the race condition is unavoidable. The only
 way to be absolutely race-free is to have the daemon perform its
 readiness notification itself, which requires specific support.
- </li>
-</ol>
+</p>
 
 <p>
- The second method should really be implemented in every long-running
+ This method should really be implemented in every long-running
 program providing a service. When it is not the case, it's impossible
 to provide reliable startup notifications, and subscribers should then
 be content with the unreliable 'u' events provided by s6-supervise.
diff --git a/doc/s6-notifywhenup.html b/doc/s6-notifywhenup.html
index f192ca4..b772925 100644
--- a/doc/s6-notifywhenup.html
+++ b/doc/s6-notifywhenup.html
@@ -38,7 +38,8 @@ needed.
  <li> s6-notifywhenup forks and executes <em>prog...</em> as the
 parent, with a pipe from <em>prog...</em>'s stdout to the child. </li>
  <li> The child waits for a newline (<tt>\n</tt>) to be written
-on the pipe. When it gets it, it sends a 'U' event to the
+on the pipe. When it gets it, it creates an empty
+<tt>./supervise/ready</tt> file then sends a 'U' event to the
 <tt>./event</tt> fifodir. </li>
  <li> The child exits 0. </li>
 </ul>
diff --git a/doc/s6-svwait.html b/doc/s6-svwait.html
index 6e15704..5f3cb08 100644
--- a/doc/s6-svwait.html
+++ b/doc/s6-svwait.html
@@ -33,7 +33,7 @@ s6-svwait only waits for notifications; it never polls.
 
 <p>
 s6-svwait monitors one or more <a href="servicedir.html">service
-directories</a> given as its arguments, waiting for a state (up or down) to
+directories</a> given as its arguments, waiting for a state (ready, up or down) to
 happen. It exits 0 when the wanted condition becomes true.
 </p>
 
@@ -46,8 +46,10 @@ This is the default; it is not reliable, but it does not depend on specific
 support in the service programs. See <a href="notifywhenup.html">this page</a>
 for details. </li>
  <li> <tt>-U</tt>&nbsp;: really up. s6-svwait will wait until the services are
-up, as reported by the services themselves. This requires specific support in the
-service programs: see the explanation on <a href="notifywhenup.html">this page</a>. </li>
+up <em>and</em> ready as reported by the services themselves. This requires
+specific support in the service programs, and the use of
+<a href="s6-notifywhenup.html">s6-notifywhenup</a> in the service's run script.
+See the explanation on <a href="notifywhenup.html">this page</a>. </li>
  <li> <tt>-d</tt>&nbsp;: down. s6-svwait will wait until the services are down. </li>
  <li> <tt>-o</tt>&nbsp;: or. s6-svwait will wait until <em>one</em> of the
 given services comes up or down. </li>
@@ -59,13 +61,13 @@ to stderr and exit 1. By default, <em>timeout</em> is 0, which means no time
 limit. </li>
 </ul>
 
-
 <h2> Internals </h2>
 
 <p>
 s6-svwait spawns a <a href="s6-ftrigrd.html">s6-ftrigrd</a> child to
 listen to notifications sent by <a href="s6-supervise.html">s6-supervise</a>.
-It also checks <tt>supervise/status</tt> files to get the current service
+It also checks <tt>supervise/status</tt> files, as well as the
+<tt>supervise/ready</tt> files if necessary, to get the current service
 states, so it is immune to race conditions.
 </p>
 
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 789d425..0851534 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -17,6 +17,14 @@
 
 <h1> What has changed in s6 </h1>
 
+<h2> in 2.0.1.0 </h2>
+
+<ul>
+ <li> skalibs dependency bumped to 2.2.0.0. </li>
+ <li> execline dependency bumped to 2.0.1.1. </li>
+ <li> Better readiness notification management via s6-svwait -U. </li>
+</ul>
+
 <h2> in 2.0.0.1 </h2>
 
 <ul>
diff --git a/package/deps.mak b/package/deps.mak
index 4b33279..3c9cd26 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -10,10 +10,10 @@ src/daemontools-extras/s6-envdir.o src/daemontools-extras/s6-envdir.lo: src/daem
 src/daemontools-extras/s6-envuidgid.o src/daemontools-extras/s6-envuidgid.lo: src/daemontools-extras/s6-envuidgid.c
 src/daemontools-extras/s6-fghack.o src/daemontools-extras/s6-fghack.lo: src/daemontools-extras/s6-fghack.c
 src/daemontools-extras/s6-log.o src/daemontools-extras/s6-log.lo: src/daemontools-extras/s6-log.c
-src/daemontools-extras/s6-notifywhenup.o src/daemontools-extras/s6-notifywhenup.lo: src/daemontools-extras/s6-notifywhenup.c src/include/s6/ftrigw.h
+src/daemontools-extras/s6-notifywhenup.o src/daemontools-extras/s6-notifywhenup.lo: src/daemontools-extras/s6-notifywhenup.c src/include/s6/ftrigw.h src/include/s6/s6-supervise.h
 src/daemontools-extras/s6-setlock.o src/daemontools-extras/s6-setlock.lo: src/daemontools-extras/s6-setlock.c src/include/s6/config.h
 src/daemontools-extras/s6-setsid.o src/daemontools-extras/s6-setsid.lo: src/daemontools-extras/s6-setsid.c
-src/daemontools-extras/s6-setuidgid.o src/daemontools-extras/s6-setuidgid.lo: src/daemontools-extras/s6-setuidgid.c
+src/daemontools-extras/s6-setuidgid.o src/daemontools-extras/s6-setuidgid.lo: src/daemontools-extras/s6-setuidgid.c src/include/s6/config.h
 src/daemontools-extras/s6-softlimit.o src/daemontools-extras/s6-softlimit.lo: src/daemontools-extras/s6-softlimit.c
 src/daemontools-extras/s6-tai64n.o src/daemontools-extras/s6-tai64n.lo: src/daemontools-extras/s6-tai64n.c
 src/daemontools-extras/s6-tai64nlocal.o src/daemontools-extras/s6-tai64nlocal.lo: src/daemontools-extras/s6-tai64nlocal.c
@@ -81,7 +81,7 @@ s6-fghack: src/daemontools-extras/s6-fghack.o -lskarnet
 s6-log: private EXTRA_LIBS := ${TAINNOW_LIB}
 s6-log: src/daemontools-extras/s6-log.o -lskarnet
 s6-notifywhenup: private EXTRA_LIBS := ${TAINNOW_LIB}
-s6-notifywhenup: src/daemontools-extras/s6-notifywhenup.o -ls6 -lskarnet
+s6-notifywhenup: src/daemontools-extras/s6-notifywhenup.o ${LIBS6} -lskarnet
 s6-setlock: private EXTRA_LIBS := ${TAINNOW_LIB}
 s6-setlock: src/daemontools-extras/s6-setlock.o -lskarnet
 s6-setsid: private EXTRA_LIBS :=
@@ -105,28 +105,28 @@ s6lockd: src/libs6/s6lockd.o -lskarnet
 s6lockd-helper: private EXTRA_LIBS :=
 s6lockd-helper: src/libs6/s6lockd-helper.o -lskarnet
 s6-cleanfifodir: private EXTRA_LIBS :=
-s6-cleanfifodir: src/pipe-tools/s6-cleanfifodir.o -ls6 -lskarnet
+s6-cleanfifodir: src/pipe-tools/s6-cleanfifodir.o ${LIBS6} -lskarnet
 s6-ftrig-listen: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
-s6-ftrig-listen: src/pipe-tools/s6-ftrig-listen.o -ls6 -lexecline -lskarnet
+s6-ftrig-listen: src/pipe-tools/s6-ftrig-listen.o ${LIBS6} -lexecline -lskarnet
 s6-ftrig-listen1: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
-s6-ftrig-listen1: src/pipe-tools/s6-ftrig-listen1.o -ls6 -lskarnet
+s6-ftrig-listen1: src/pipe-tools/s6-ftrig-listen1.o ${LIBS6} -lskarnet
 s6-ftrig-notify: private EXTRA_LIBS :=
-s6-ftrig-notify: src/pipe-tools/s6-ftrig-notify.o -ls6 -lskarnet
+s6-ftrig-notify: src/pipe-tools/s6-ftrig-notify.o ${LIBS6} -lskarnet
 s6-ftrig-wait: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
-s6-ftrig-wait: src/pipe-tools/s6-ftrig-wait.o -ls6 -lskarnet
+s6-ftrig-wait: src/pipe-tools/s6-ftrig-wait.o ${LIBS6} -lskarnet
 s6-mkfifodir: private EXTRA_LIBS :=
-s6-mkfifodir: src/pipe-tools/s6-mkfifodir.o -ls6 -lskarnet
+s6-mkfifodir: src/pipe-tools/s6-mkfifodir.o ${LIBS6} -lskarnet
 s6-supervise: private EXTRA_LIBS := ${TAINNOW_LIB}
-s6-supervise: src/supervision/s6-supervise.o -ls6 -lskarnet
+s6-supervise: src/supervision/s6-supervise.o ${LIBS6} -lskarnet
 s6-svc: private EXTRA_LIBS :=
-s6-svc: src/supervision/s6-svc.o -ls6 -lskarnet
+s6-svc: src/supervision/s6-svc.o ${LIBS6} -lskarnet
 s6-svok: private EXTRA_LIBS :=
 s6-svok: src/supervision/s6-svok.o -lskarnet
 s6-svscan: private EXTRA_LIBS := ${TAINNOW_LIB}
-s6-svscan: src/supervision/s6-svscan.o -ls6 -lskarnet
+s6-svscan: src/supervision/s6-svscan.o ${LIBS6} -lskarnet
 s6-svscanctl: private EXTRA_LIBS :=
-s6-svscanctl: src/supervision/s6-svscanctl.o -ls6 -lskarnet
+s6-svscanctl: src/supervision/s6-svscanctl.o ${LIBS6} -lskarnet
 s6-svstat: private EXTRA_LIBS := ${SYSCLOCK_LIB}
-s6-svstat: src/supervision/s6-svstat.o -ls6 -lskarnet
+s6-svstat: src/supervision/s6-svstat.o ${LIBS6} -lskarnet
 s6-svwait: private EXTRA_LIBS := ${SOCKET_LIB} ${TAINNOW_LIB}
-s6-svwait: src/supervision/s6-svwait.o -ls6 -lskarnet
+s6-svwait: src/supervision/s6-svwait.o ${LIBS6} -lskarnet
diff --git a/package/info b/package/info
index 6211698..64279ff 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
 package=s6
-version=2.0.0.1
+version=2.0.1.0
 category=admin
 package_macro_name=S6
diff --git a/package/targets.mak b/package/targets.mak
index 283cc67..cf5bc6d 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -32,6 +32,12 @@ s6-setuidgid
 
 LIBEXEC_TARGETS := s6lockd-helper
 
+ifdef DO_ALLSTATIC
+LIBS6 := libs6.a
+else
+LIBS6 := libs6.so
+endif
+
 ifdef DO_SHARED
 SHARED_LIBS := libs6.so
 endif
diff --git a/src/daemontools-extras/deps-exe/s6-notifywhenup b/src/daemontools-extras/deps-exe/s6-notifywhenup
index 58a34e0..077e863 100644
--- a/src/daemontools-extras/deps-exe/s6-notifywhenup
+++ b/src/daemontools-extras/deps-exe/s6-notifywhenup
@@ -1,3 +1,3 @@
--ls6
+${LIBS6}
 -lskarnet
 ${TAINNOW_LIB}
diff --git a/src/daemontools-extras/s6-notifywhenup.c b/src/daemontools-extras/s6-notifywhenup.c
index 37f6de1..e1c02b7 100644
--- a/src/daemontools-extras/s6-notifywhenup.c
+++ b/src/daemontools-extras/s6-notifywhenup.c
@@ -11,6 +11,7 @@
 #include <skalibs/iopause.h>
 #include <skalibs/djbunix.h>
 #include <s6/ftrigw.h>
+#include <s6/s6-supervise.h>
 
 #define USAGE "s6-notifywhenup [ -d fd ] [ -e fifodir ] [ -f ] [ -t timeout ] prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
@@ -36,6 +37,10 @@ static int run_child (int fd, char const *fifodir, unsigned int timeout)
     else if (r)
       if (byte_chr(dummy, r, '\n') < r) break ;
   }
+  close(fd) ;
+  fd = open_create(S6_SUPERVISE_READY_FILENAME) ;
+  if (fd < 0) strerr_warnwu1sys("touch " S6_SUPERVISE_READY_FILENAME) ;
+  else close(fd) ;
   ftrigw_notify(fifodir, 'U') ;
   return 0 ;
 }
diff --git a/src/daemontools-extras/s6-setuidgid.c b/src/daemontools-extras/s6-setuidgid.c
index d2e7361..cc7f21a 100644
--- a/src/daemontools-extras/s6-setuidgid.c
+++ b/src/daemontools-extras/s6-setuidgid.c
@@ -1,30 +1,26 @@
 /* ISC license. */
 
-#include <unistd.h>
-#include <skalibs/bytestr.h>
-#include <skalibs/uint.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <s6/config.h>
 
 #define USAGE "s6-setuidgid username prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
 int main (int argc, char const *const *argv, char const *const *envp)
 {
-  unsigned int pos ;
+  char const *newargv[argc + 4] ;
+  unsigned int m = 5 ;
   PROG = "s6-setuidgid" ;
   if (argc < 3) dieusage() ;
-  pos = str_chr(argv[1], ':') ;
-  if (argv[1][pos])
-  {
-    unsigned int uid = 0, gid = 0, len = uint_scan(argv[1], &uid) ;
-    if (len != pos) dieusage() ;
-    if (argv[1][pos+1] && !uint0_scan(argv[1]+pos+1, &gid)) dieusage() ;
-    if (gid && setgid(gid)) strerr_diefu1sys(111, "setgid") ;
-    if (uid && setuid(uid)) strerr_diefu1sys(111, "setuid") ;
-  }
-  else if (!prot_setuidgid(argv[1]))
-    strerr_diefu2sys(111, "change identity to ", argv[1]) ;
-  pathexec_run(argv[2], argv+2, envp) ;
-  strerr_dieexec(111, argv[2]) ;
+  argv++ ;
+  newargv[0] = S6_BINPREFIX "s6-envuidgid" ;
+  newargv[1] = *argv++ ;
+  newargv[2] = S6_BINPREFIX "s6-applyuidgid" ;
+  newargv[3] = "-Uz" ;
+  newargv[4] = "--" ;
+  while (*argv) newargv[m++] = *argv++ ;
+  newargv[m++] = 0 ;
+  pathexec_run(newargv[0], newargv, envp) ;
+  strerr_dieexec(111, newargv[0]) ;
 }
diff --git a/src/include/s6/s6-supervise.h b/src/include/s6/s6-supervise.h
index 2a39393..c8d72d7 100644
--- a/src/include/s6/s6-supervise.h
+++ b/src/include/s6/s6-supervise.h
@@ -9,6 +9,7 @@
 #define S6_SUPERVISE_EVENTDIR "event"
 #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
 
 extern int s6_svc_write (char const *, char const *, unsigned int) ;
diff --git a/src/pipe-tools/deps-exe/s6-cleanfifodir b/src/pipe-tools/deps-exe/s6-cleanfifodir
index 83cec1e..08815d9 100644
--- a/src/pipe-tools/deps-exe/s6-cleanfifodir
+++ b/src/pipe-tools/deps-exe/s6-cleanfifodir
@@ -1,2 +1,2 @@
--ls6
+${LIBS6}
 -lskarnet
diff --git a/src/pipe-tools/deps-exe/s6-ftrig-listen b/src/pipe-tools/deps-exe/s6-ftrig-listen
index 3ad9adf..3bbf778 100644
--- a/src/pipe-tools/deps-exe/s6-ftrig-listen
+++ b/src/pipe-tools/deps-exe/s6-ftrig-listen
@@ -1,4 +1,4 @@
--ls6
+${LIBS6}
 -lexecline
 -lskarnet
 ${SOCKET_LIB}
diff --git a/src/pipe-tools/deps-exe/s6-ftrig-listen1 b/src/pipe-tools/deps-exe/s6-ftrig-listen1
index ac0cace..f3a3143 100644
--- a/src/pipe-tools/deps-exe/s6-ftrig-listen1
+++ b/src/pipe-tools/deps-exe/s6-ftrig-listen1
@@ -1,4 +1,4 @@
--ls6
+${LIBS6}
 -lskarnet
 ${SOCKET_LIB}
 ${TAINNOW_LIB}
diff --git a/src/pipe-tools/deps-exe/s6-ftrig-notify b/src/pipe-tools/deps-exe/s6-ftrig-notify
index 83cec1e..08815d9 100644
--- a/src/pipe-tools/deps-exe/s6-ftrig-notify
+++ b/src/pipe-tools/deps-exe/s6-ftrig-notify
@@ -1,2 +1,2 @@
--ls6
+${LIBS6}
 -lskarnet
diff --git a/src/pipe-tools/deps-exe/s6-ftrig-wait b/src/pipe-tools/deps-exe/s6-ftrig-wait
index ac0cace..f3a3143 100644
--- a/src/pipe-tools/deps-exe/s6-ftrig-wait
+++ b/src/pipe-tools/deps-exe/s6-ftrig-wait
@@ -1,4 +1,4 @@
--ls6
+${LIBS6}
 -lskarnet
 ${SOCKET_LIB}
 ${TAINNOW_LIB}
diff --git a/src/pipe-tools/deps-exe/s6-mkfifodir b/src/pipe-tools/deps-exe/s6-mkfifodir
index 83cec1e..08815d9 100644
--- a/src/pipe-tools/deps-exe/s6-mkfifodir
+++ b/src/pipe-tools/deps-exe/s6-mkfifodir
@@ -1,2 +1,2 @@
--ls6
+${LIBS6}
 -lskarnet
diff --git a/src/supervision/deps-exe/s6-supervise b/src/supervision/deps-exe/s6-supervise
index 58a34e0..077e863 100644
--- a/src/supervision/deps-exe/s6-supervise
+++ b/src/supervision/deps-exe/s6-supervise
@@ -1,3 +1,3 @@
--ls6
+${LIBS6}
 -lskarnet
 ${TAINNOW_LIB}
diff --git a/src/supervision/deps-exe/s6-svc b/src/supervision/deps-exe/s6-svc
index 83cec1e..08815d9 100644
--- a/src/supervision/deps-exe/s6-svc
+++ b/src/supervision/deps-exe/s6-svc
@@ -1,2 +1,2 @@
--ls6
+${LIBS6}
 -lskarnet
diff --git a/src/supervision/deps-exe/s6-svscan b/src/supervision/deps-exe/s6-svscan
index 58a34e0..077e863 100644
--- a/src/supervision/deps-exe/s6-svscan
+++ b/src/supervision/deps-exe/s6-svscan
@@ -1,3 +1,3 @@
--ls6
+${LIBS6}
 -lskarnet
 ${TAINNOW_LIB}
diff --git a/src/supervision/deps-exe/s6-svscanctl b/src/supervision/deps-exe/s6-svscanctl
index 83cec1e..08815d9 100644
--- a/src/supervision/deps-exe/s6-svscanctl
+++ b/src/supervision/deps-exe/s6-svscanctl
@@ -1,2 +1,2 @@
--ls6
+${LIBS6}
 -lskarnet
diff --git a/src/supervision/deps-exe/s6-svstat b/src/supervision/deps-exe/s6-svstat
index 7065b26..b1e57e4 100644
--- a/src/supervision/deps-exe/s6-svstat
+++ b/src/supervision/deps-exe/s6-svstat
@@ -1,3 +1,3 @@
--ls6
+${LIBS6}
 -lskarnet
 ${SYSCLOCK_LIB}
diff --git a/src/supervision/deps-exe/s6-svwait b/src/supervision/deps-exe/s6-svwait
index ac0cace..f3a3143 100644
--- a/src/supervision/deps-exe/s6-svwait
+++ b/src/supervision/deps-exe/s6-svwait
@@ -1,4 +1,4 @@
--ls6
+${LIBS6}
 -lskarnet
 ${SOCKET_LIB}
 ${TAINNOW_LIB}
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
index de9b6ea..65cbd9d 100644
--- a/src/supervision/s6-supervise.c
+++ b/src/supervision/s6-supervise.c
@@ -161,6 +161,8 @@ static void trystart (void)
     PROG = "s6-supervise (child)" ;
     selfpipe_finish() ;
     fd_close(p[0]) ;
+    if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT)
+      strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ;
     if (flagsetsid) setsid() ;
     execve("./run", (char *const *)cargv, (char *const *)environ) ;
     fd_write(p[1], "", 1) ;
@@ -264,14 +266,21 @@ static void uptimeout (void)
   strerr_warnw1x("can't happen: timeout while the service is up!") ;
 }
 
-static void up_z (void)
+static void uplastup_z (int islast)
 {
   int wstat = status.pid ;
   status.pid = 0 ;
   tain_copynow(&status.stamp) ;
   announce() ;
   ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'd') ;
-  tryfinish(wstat, 0) ;
+  if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT)
+    strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ;
+  tryfinish(wstat, islast) ;
+}
+
+static void up_z (void)
+{
+  uplastup_z(0) ;
 }
 
 static void up_o (void)
@@ -346,12 +355,7 @@ static void finish_x (void)
 
 static void lastup_z (void)
 {
-  int wstat = status.pid ;
-  status.pid = 0 ;
-  tain_copynow(&status.stamp) ;
-  announce() ;
-  ftrigw_notify(S6_SUPERVISE_EVENTDIR, 'd') ;
-  tryfinish(wstat, 1) ;
+  uplastup_z(1) ;
 }
 
 static action_t_ref const actions[5][23] =
diff --git a/src/supervision/s6-svwait.c b/src/supervision/s6-svwait.c
index 0d7c96c..a6dc410 100644
--- a/src/supervision/s6-svwait.c
+++ b/src/supervision/s6-svwait.c
@@ -1,5 +1,7 @@
 /* ISC license. */
 
+#include <unistd.h>
+#include <errno.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/bytestr.h>
 #include <skalibs/uint16.h>
@@ -77,8 +79,23 @@ int main (int argc, char const *const *argv)
     for (i = 0 ; i < (unsigned int)argc ; i++)
     {
       s6_svstatus_t st = S6_SVSTATUS_ZERO ;
+      int isup ;
       if (!s6_svstatus_read(argv[i], &st)) strerr_diefu1sys(111, "s6_svstatus_read") ;
-      bitarray_poke(states, i, !!st.pid) ;
+      isup = !!st.pid ;
+      if (re[0] == 'U' && isup)
+      {
+        unsigned int len = str_len(argv[i]) ;
+        char s[len + 1 + sizeof(S6_SUPERVISE_READY_FILENAME)] ;
+        byte_copy(s, len, argv[i]) ;
+        s[len] = '/' ;
+        byte_copy(s + len + 1, sizeof(S6_SUPERVISE_READY_FILENAME), S6_SUPERVISE_READY_FILENAME) ;
+        if (access(s, F_OK) < 0)
+        {
+          if (errno == ENOENT) isup = 0 ;
+          else strerr_warnwu2sys("check ", s) ;
+        }
+      }
+      bitarray_poke(states, i, isup) ;
     }
 
     for (;;)
diff --git a/tools/gen-deps.sh b/tools/gen-deps.sh
index 5824dd6..2f7c57d 100755
--- a/tools/gen-deps.sh
+++ b/tools/gen-deps.sh
@@ -71,7 +71,7 @@ for dir in $(ls -1 src | grep -v ^include) ; do
       if echo $dep | grep -q -- \\.o$ ; then
         dep="src/$dir/$dep"
       fi
-      if echo $dep | grep -q ^\\\$ ; then
+      if echo $dep | grep -q '^\${.*_LIB}' ; then
         libs="$libs $dep"
       else
         deps="$deps $dep"