summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2018-08-14 20:22:43 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2018-08-14 20:22:43 +0000
commitf703916c3702d8f32dc535161571874cb007ca6d (patch)
tree0298bb0de1d464c3868a6547a225534a4ccc40cc
parent3e34202f32ab10017d55aedb2665cf55fb5af5c0 (diff)
downloads6-linux-utils-f703916c3702d8f32dc535161571874cb007ca6d.tar.gz
s6-linux-utils-f703916c3702d8f32dc535161571874cb007ca6d.tar.xz
s6-linux-utils-f703916c3702d8f32dc535161571874cb007ca6d.zip
Remove s6-devd, s6-uevent-listener, s6-uevent-spawner, prepare for 2.5.0.0
-rw-r--r--NEWS5
-rw-r--r--doc/index.html5
-rw-r--r--doc/s6-devd.html80
-rw-r--r--doc/s6-uevent-listener.html117
-rw-r--r--doc/s6-uevent-spawner.html87
-rw-r--r--doc/upgrade.html5
-rw-r--r--package/deps.mak9
-rw-r--r--package/info2
-rw-r--r--package/modes3
-rw-r--r--package/targets.mak3
-rw-r--r--src/minutils/deps-exe/s6-devd1
-rw-r--r--src/minutils/deps-exe/s6-uevent-listener2
-rw-r--r--src/minutils/deps-exe/s6-uevent-spawner2
-rw-r--r--src/minutils/s6-devd.c103
-rw-r--r--src/minutils/s6-uevent-listener.c168
-rw-r--r--src/minutils/s6-uevent-spawner.c243
16 files changed, 9 insertions, 826 deletions
diff --git a/NEWS b/NEWS
index 8ba2725..6581540 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,10 @@
 Changelog for s6-linux-utils.
 
-In 2.4.0.3
+In 2.5.0.0
 ----------
 
- - nsss support.
+ - Optional nsss support.
+ - s6-devd, s6-uevent-listener, s6-uevent-spawner removed.
 
 
 In 2.4.0.2
diff --git a/doc/index.html b/doc/index.html
index 638b55e..98e43a5 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -50,7 +50,7 @@ library. </li>
 
 <ul>
  <li> The current released version of s6-linux-utils is
-<a href="s6-linux-utils-2.4.0.3.tar.gz">2.4.0.3</a>. </li>
+<a href="s6-linux-utils-2.5.0.0.tar.gz">2.5.0.0</a>. </li>
  <li> Alternatively, you can checkout a copy of the
 <a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-linux-utils/">s6-linux-utils
 git repository</a>:
@@ -88,9 +88,6 @@ the previous versions of s6-linux-utils and the current one. </li>
 
 <ul>
 <li><a href="s6-chroot.html">The <tt>s6-chroot</tt> program</a></li>
-<li><a href="s6-devd.html">The <tt>s6-devd</tt> program</a></li>
-<li><a href="s6-uevent-listener.html">The <tt>s6-uevent-listener</tt> program</a> <strong>(deprecated)</strong></li>
-<li><a href="s6-uevent-spawner.html">The <tt>s6-uevent-spawner</tt> program</a> <strong>(deprecated)</strong></li>
 <li><a href="s6-fillurandompool.html">The <tt>s6-fillurandompool</tt> program</a></li>
 <li><a href="s6-freeramdisk.html">The <tt>s6-freeramdisk</tt> program</a></li>
 <li><a href="s6-hostname.html">The <tt>s6-hostname</tt> program</a></li>
diff --git a/doc/s6-devd.html b/doc/s6-devd.html
deleted file mode 100644
index 1d7ae06..0000000
--- a/doc/s6-devd.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<html>
-  <head>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <meta http-equiv="Content-Language" content="en" />
-    <title>s6-linux-utils: the s6-devd program</title>
-    <meta name="Description" content="s6-linux-utils: the s6-devd program" />
-    <meta name="Keywords" content="s6 linux administration root utilities devd mdev udev s6-uevent-listener s6-uevent-spawner" />
-    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
-  </head>
-<body>
-
-<p>
-<a href="index.html">s6-linux-utils</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-devd</tt> program </h1>
-
-<p>
-<tt>s6-devd</tt> listens to the netlink interface for udev events, and
-launches a helper program for every event, similarly to what the hotplug
-interface does.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
-     s6-devd [ -q | -v ] [ -b <em>kbufsz</em> ] [ -l <em>linevar</em> ] [ -t l:t:k ] <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-devd rewrites its command line into
-<tt><a href="s6-uevent-listener.html">s6-uevent-listener</a> <tt>|</tt>
-<a href="s6-uevent-spawner.html">s6-uevent-spawner</a> <em>prog...</em></tt>,
-dispatching its options to the appropriate programs; then it execs into
-this new command line. It does nothing else: it's just a wrapper. </li>
- <li> The first executed program,
-<a href="s6-uevent-listener.html">s6-uevent-listener</a>,
-will listen to the netlink and pass the events sequentially to
-<a href="s6-uevent-spawner.html">s6-uevent-spawner</a>, which will
-spawn a <em>prog...</em> helper for every event. </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-q</tt>&nbsp;: be more quiet. </li>
- <li> <tt>-v</tt>&nbsp;: be more verbose. </li>
- <li> <tt>-b</tt>&nbsp;<em>kbufsz</em>&nbsp;: try and reserve a kernel buffer of
-<em>kbufsz</em> bytes for the netlink queue. Too large a buffer wastes kernel memory;
-too small a buffer risks losing events. The default is 65536. </li>
- <li> <tt>-l</tt>&nbsp;<em>linevar</em>&nbsp;: the short description of the
-event, given by the kernel as the first string in the netlink message,
-will be made available to <em>prog</em> under the environment variable
-named <em>linevar</em>. </li>
- <li> <tt>-t</tt> <em>l:t:k</em>&nbsp;: If <em>l</em>, <em>t</em> or <em>k</em> is
-specified, they specify timeouts; by default, they are infinite.
-If <em>prog...</em> is still alive after <em>l</em> milliseconds, s6-devd sends
-it a SIGTERM. Then, if <em>prog...</em> is still alive after <em>t</em> more
-milliseconds, s6-devd sends it a SIGKILL. Then, if <em>prog...</em> is still
-alive after <em>k</em> more milliseconds, s6-devd yells and exits 99. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> s6-devd is a daemon; it should be run under a proper supervision system such
-as <a href="//skarnet.org/software/s6/">s6</a>. The real long-lived
-process is named <a href="s6-uevent-listener.html">s6-uevent-listener</a>;
-ir runs with the same pid as s6-devd. </li>
- <li> The <em>prog...</em> helper, on the other hand, should be very short-lived,
-even if you are not using the <tt>-t</tt> option to s6-devd. Since helpers are
-spawned sequentially, slow helpers can make events queue up and fill buffers
-along the way. </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-uevent-listener.html b/doc/s6-uevent-listener.html
deleted file mode 100644
index cd60639..0000000
--- a/doc/s6-uevent-listener.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<html>
-  <head>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <meta http-equiv="Content-Language" content="en" />
-    <title>s6-linux-utils: the s6-uevent-listener program</title>
-    <meta name="Description" content="s6-linux-utils: the s6-uevent-listener program" />
-    <meta name="Keywords" content="s6 linux administration root utilities devd mdev mdevd udev s6-uevent-listener uevent" />
-    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
-  </head>
-<body>
-
-<p>
-<a href="index.html">s6-linux-utils</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-uevent-listener</tt> program </h1>
-
-<p>
-<tt>s6-uevent-listener</tt> listens to the netlink interface for uevents
-(also called "hotplug" or "udev" events), and writes those uevents to
-its standard output, using a simple format.
-</p>
-
-<p>
-<strong>This program is deprecated</strong>, and will disappear in a
-near future version of s6-linux-utils. It has been replaced with the
-<a href="//skarnet.org/software/mdevd/mdevd-netlink.html">mdevd-netlink</a>
-program, from the <a href="//skarnet.org/software/mdevd/">mdevd</a>
-package.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
-     s6-uevent-listener [ -v <em>verbosity</em> ] [ -b kbufsz ]
-</pre>
-
-<ul>
- <li> s6-uevent-listener binds to the netlink interface and listens for
-hotplug events, as the <em>udev</em> program does. </li>
- <li> It writes event information to its stdout. The output contains
-null characters, so a terminal will not display them correctly. To
-properly use s6-uevent-listener, it should be piped into a handler
-program such as
-<a href="s6-uevent-spawner.html">s6-uevent-spawner</a>.
-or <a href="//skarnet.org/software/mdevd/mdevd.html">mdevd</a>. </li>
- <li> s6-uevent-listener is a long-lived program.
-When it receives a SIGTERM, it stops listening; it will
-exit as soon as it has flushed its event queue to stdout. </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-v</tt>&nbsp;<em>verbosity</em>&nbsp;: be more or less verbose.
-Default verbosity is 1. 0 will only print fatal error messages, 3 will
-print warnings every time the netlink interface sends something
-unexpected. </li>
- <li> <tt>-b</tt>&nbsp;<em>kbufsz</em>&nbsp;: try and reserve a kernel buffer of
-<em>kbufsz</em> bytes for the netlink queue. Too large a buffer wastes kernel memory;
-too small a buffer risks losing events. The default is 65536 (which is on
-the large side). </li>
-</ul>
-
-<h2> Protocol </h2>
-
-<ul>
- <li> An event is a series of null-terminated strings as they are sent by
-the kernel to the netlink; s6-uevent-listener adds a final empty string
-(i.e. an additional null character) to mark the end of the series. </li>
- <li> The first string is a short description of the event; it normally
-contains the string "@/". Other strings after the first are of the form
-"VARIABLE=value", and describe the environment which a hotplug helper
-for the event (registered in <tt>/proc/sys/kernel/hotplug</tt>) would be
-spawned with. </li>
- <li> Example (newlines added for clarity): <pre>
-add@/class/input/input9/mouse2\0
-ACTION=add\0
-DEVPATH=/class/input/input9/mouse2\0
-SUBSYSTEM=input\0
-SEQNUM=106\0
-PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2­2/2­2:1.0
-PHYSDEVBUS=usb\0
-PHYSDEVDRIVER=usbhid\0
-MAJOR=13\0
-MINOR=34\0
-\0 </pre> </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> s6-uevent-listener is a daemon; it should be run under a proper supervision system such
-as <a href="//skarnet.org/software/s6/">s6</a>. </li>
-<li> If you are running s6-uevent-listener, <em>prog...</em> should be the
-only program handling uevents, which means that
-<tt>/proc/sys/kernel/hotplug</tt> should be empty. </li>
- <li> Examples of valid uses of s6-uevent-listener:
-  <ul>
-   <li> <tt>s6-uevent-listener | s6-uevent-spawner mdev</tt> </li>
-   <li> <tt>s6-uevent-listener | mdevd</tt> </li>
-   <li> Those examples can be made safer by using a supervision system:
-under <a href="//skarnet.org/software/s6/">s6</a> or
-<a href="//skarnet.org/software/s6-rc/">s6-rc</a>, write a service
-pipeline where <tt>s6-uevent-listener</tt> is a producer and
-<tt>s6-uevent-spawner mdev</tt> or <tt>mdevd</tt> is a consumer. This
-setup has the advantage, among others, that you can restart the netlink
-listener and the event handler separately. </li>
-  </ul>
- </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-uevent-spawner.html b/doc/s6-uevent-spawner.html
deleted file mode 100644
index 6f2ab87..0000000
--- a/doc/s6-uevent-spawner.html
+++ /dev/null
@@ -1,87 +0,0 @@
-<html>
-  <head>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <meta http-equiv="Content-Language" content="en" />
-    <title>s6-linux-utils: the s6-uevent-spawner program</title>
-    <meta name="Description" content="s6-linux-utils: the s6-uevent-spawner program" />
-    <meta name="Keywords" content="s6 linux administration root utilities devd mdev mdevd udev hotplug" />
-    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
-  </head>
-<body>
-
-<p>
-<a href="index.html">s6-linux-utils</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-uevent-spawner</tt> program </h1>
-
-<p>
-<tt>s6-uevent-spawner</tt> listens to its standard input for
-netlink-style events, and launches a helper program for every event,
-similarly to what the hotplug interface does.
-</p>
-
-<p>
- It is meant to be used together with
-<a href="s6-uevent-listener.html">s6-uevent-listener</a>.
-</p>
-
-<p>
-<strong>This program is deprecated</strong>, and will disappear in a
-future version of s6-linux-utils. The
-<a href="//skarnet.org/software/mdevd/">mdevd</a> package makes it
-obsolete.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
-     s6-uevent-spawner [ -v <em>verbosity</em> ] [ -l <em>linevar</em> ] [ -t <em>l</em>:<em>t</em>:<em>k</em> ] <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-uevent-spawner listens to its stdin for a series of strings
-representing kernel uevents, as formatted by
-<a href="s6-uevent-listener.html">s6-uevent-listener</a>. </li>
- <li> For every event it reads, it spawns <em>prog...</em> with
-the event variables added to the environment, just as if <em>prog...</em>
-had been registered in <tt>/proc/sys/kernel/hotplug</tt>. However,
-it reads the events sequentially, and waits for a <em>prog</em> instance
-to finish before spawning another one. </li>
- <li> When s6-uevent-spawner receives EOF: if an instance of
-<em>prog</em> is alive, it first waits for it to die. Then it exits
-0. </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-v</tt>&nbsp;<em>verbosity</em>&nbsp;: be more or less verbose.
-Default verbosity is 1. 0 only prints fatal error messages. 3 is too much. </li>
- <li> <tt>-l</tt> <em>linevar</em>&nbsp;: make the event description
-(i.e. the first string in the netlink message announcing the event)
-available in <em>prog</em> under the environment variable <em>linevar</em>.
-By default, this first string is ignored - it is not needed, all the
-event information is already in the other variables. </li>
- <li> <tt>-t</tt> <em>l:t:k</em>&nbsp;: If <em>l</em>, <em>t</em> or <em>k</em> is
-specified, they specify timeouts; by default, they are infinite.
-If <em>prog...</em> is still alive after <em>l</em> milliseconds, s6-devd sends
-it a SIGTERM. Then, if <em>prog...</em> is still alive after <em>t</em> more
-milliseconds, s6-devd sends it a SIGKILL. Then, if <em>prog...</em> is still
-alive after <em>k</em> more milliseconds, s6-uevent-spawner yells and exits 99. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> The <em>prog...</em> helper should be very short-lived,
-even if you are not using the <tt>-t</tt> option. Since helpers are
-spawned sequentially, slow helpers can make events queue up and fill up
-buffers. </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 76eac8e..426157c 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,11 +18,14 @@
 
 <h1> What has changed in s6-linux-utils </h1>
 
-<h2> in 2.4.0.3 </h2>
+<h2> in 2.5.0.0 </h2>
 
 <ul>
  <li> skalibs dependency bumped to 2.7.0.0. </li>
  <li> Optional <a href="//skarnet.org/software/nsss/">nsss</a> support added. </li>
+ <li> <tt>s6-devd</tt>, <tt>s6-uevent-listener</tt> and <tt>s6-uevent-spawner</tt>
+have been removed: <a href="//skarnet.org/software/mdevd/">mdevd</a> obsoletes
+them. </li>
 </ul>
 
 <h2> in 2.4.0.2 </h2>
diff --git a/package/deps.mak b/package/deps.mak
index a9773ae..1d187aa 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -3,7 +3,6 @@
 #
 
 src/minutils/s6-chroot.o src/minutils/s6-chroot.lo: src/minutils/s6-chroot.c
-src/minutils/s6-devd.o src/minutils/s6-devd.lo: src/minutils/s6-devd.c src/include/s6-linux-utils/config.h
 src/minutils/s6-fillurandompool.o src/minutils/s6-fillurandompool.lo: src/minutils/s6-fillurandompool.c
 src/minutils/s6-freeramdisk.o src/minutils/s6-freeramdisk.lo: src/minutils/s6-freeramdisk.c
 src/minutils/s6-hostname.o src/minutils/s6-hostname.lo: src/minutils/s6-hostname.c
@@ -13,8 +12,6 @@ src/minutils/s6-pivotchroot.o src/minutils/s6-pivotchroot.lo: src/minutils/s6-pi
 src/minutils/s6-ps.o src/minutils/s6-ps.lo: src/minutils/s6-ps.c src/minutils/s6-ps.h
 src/minutils/s6-swapoff.o src/minutils/s6-swapoff.lo: src/minutils/s6-swapoff.c
 src/minutils/s6-swapon.o src/minutils/s6-swapon.lo: src/minutils/s6-swapon.c
-src/minutils/s6-uevent-listener.o src/minutils/s6-uevent-listener.lo: src/minutils/s6-uevent-listener.c
-src/minutils/s6-uevent-spawner.o src/minutils/s6-uevent-spawner.lo: src/minutils/s6-uevent-spawner.c
 src/minutils/s6-umount.o src/minutils/s6-umount.lo: src/minutils/s6-umount.c
 src/minutils/s6ps_grcache.o src/minutils/s6ps_grcache.lo: src/minutils/s6ps_grcache.c src/minutils/s6-ps.h
 src/minutils/s6ps_otree.o src/minutils/s6ps_otree.lo: src/minutils/s6ps_otree.c src/minutils/s6-ps.h
@@ -26,8 +23,6 @@ src/minutils/s6ps_wchan.o src/minutils/s6ps_wchan.lo: src/minutils/s6ps_wchan.c
 
 s6-chroot: EXTRA_LIBS :=
 s6-chroot: src/minutils/s6-chroot.o -lskarnet
-s6-devd: EXTRA_LIBS :=
-s6-devd: src/minutils/s6-devd.o -lskarnet
 s6-fillurandompool: EXTRA_LIBS :=
 s6-fillurandompool: src/minutils/s6-fillurandompool.o -lskarnet
 s6-freeramdisk: EXTRA_LIBS :=
@@ -46,9 +41,5 @@ s6-swapoff: EXTRA_LIBS :=
 s6-swapoff: src/minutils/s6-swapoff.o -lskarnet
 s6-swapon: EXTRA_LIBS :=
 s6-swapon: src/minutils/s6-swapon.o -lskarnet
-s6-uevent-listener: EXTRA_LIBS := ${SPAWN_LIB}
-s6-uevent-listener: src/minutils/s6-uevent-listener.o -lskarnet
-s6-uevent-spawner: EXTRA_LIBS := ${SPAWN_LIB}
-s6-uevent-spawner: src/minutils/s6-uevent-spawner.o -lskarnet
 s6-umount: EXTRA_LIBS :=
 s6-umount: src/minutils/s6-umount.o -lskarnet
diff --git a/package/info b/package/info
index b9ca69d..919a1fd 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
 package=s6-linux-utils
-version=2.4.0.3
+version=2.5.0.0
 category=admin
 package_macro_name=S6_LINUX_UTILS
diff --git a/package/modes b/package/modes
index b6e43a2..7578bae 100644
--- a/package/modes
+++ b/package/modes
@@ -1,7 +1,4 @@
 s6-chroot		0700
-s6-devd			0700
-s6-uevent-listener	0700
-s6-uevent-spawner	0755
 s6-fillurandompool	0755
 s6-freeramdisk		0700
 s6-hostname		0755
diff --git a/package/targets.mak b/package/targets.mak
index 59b7441..0fa35ef 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,8 +1,5 @@
 BIN_TARGETS := \
 s6-chroot \
-s6-devd \
-s6-uevent-listener \
-s6-uevent-spawner \
 s6-fillurandompool \
 s6-freeramdisk \
 s6-hostname \
diff --git a/src/minutils/deps-exe/s6-devd b/src/minutils/deps-exe/s6-devd
deleted file mode 100644
index e7187fe..0000000
--- a/src/minutils/deps-exe/s6-devd
+++ /dev/null
@@ -1 +0,0 @@
--lskarnet
diff --git a/src/minutils/deps-exe/s6-uevent-listener b/src/minutils/deps-exe/s6-uevent-listener
deleted file mode 100644
index 39597dd..0000000
--- a/src/minutils/deps-exe/s6-uevent-listener
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SPAWN_LIB}
diff --git a/src/minutils/deps-exe/s6-uevent-spawner b/src/minutils/deps-exe/s6-uevent-spawner
deleted file mode 100644
index 39597dd..0000000
--- a/src/minutils/deps-exe/s6-uevent-spawner
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SPAWN_LIB}
diff --git a/src/minutils/s6-devd.c b/src/minutils/s6-devd.c
deleted file mode 100644
index f3b0932..0000000
--- a/src/minutils/s6-devd.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ISC license. */
-
-#include <sys/types.h>
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
-#include <s6-linux-utils/config.h>
-
-#define USAGE "s6-devd [ -q | -v ] [ -b kbufsz ] [ -l linevar ] [ -t maxlife:maxterm:maxkill ] helperprogram..."
-#define dieusage() strerr_dieusage(100, USAGE)
-
-static inline int check_targ (char const *s)
-{
-  size_t pos = 0 ;
-  unsigned int t = 0 ;
-  pos += uint_scan(s + pos, &t) ;
-  if (s[pos] && s[pos++] != ':') return 0 ;
-  if (!t) return 1 ;
-  pos += uint_scan(s + pos, &t) ;
-  if (s[pos] && s[pos++] != ':') return 0 ;
-  if (!t) return 1 ;
-  pos += uint_scan(s + pos, &t) ;
-  if (s[pos]) return 0 ;
-  return 1 ;
-}
-
-int main (int argc, char const *const *argv, char const *const *envp)
-{
-  unsigned int kbufsz = 65536, verbosity = 1 ;
-  char const *linevar = 0 ;
-  char const *targ = 0 ;
-  char fmtv[UINT_FMT] ;
-  PROG = "s6-devd" ;
-  {
-    subgetopt_t l = SUBGETOPT_ZERO ;
-    for (;;)
-    {
-      int opt = subgetopt_r(argc, argv, "qvb:l:t:", &l) ;
-      if (opt == -1) break ;
-      switch (opt)
-      {
-        case 'q' : if (verbosity) verbosity-- ; break ;
-        case 'v' : verbosity++ ; break ;
-        case 'b' : if (!uint0_scan(l.arg, &kbufsz)) dieusage() ; break ;
-        case 'l' : linevar = l.arg ; break ;
-        case 't' : if (!check_targ(l.arg)) dieusage() ; targ = l.arg ; break ;
-        default : dieusage() ;
-      }
-    }
-    argc -= l.ind ; argv += l.ind ;
-  }
-  if (!argc) strerr_dieusage(100, USAGE) ;
-  if (verbosity != 1) fmtv[uint_fmt(fmtv, verbosity)] = 0 ;
-
-  {
-    unsigned int m = 0 ;
-    int fd ;
-    char const *cargv[argc + 9] ;
-    cargv[m++] = S6_LINUX_UTILS_BINPREFIX "s6-uevent-spawner" ;
-    if (verbosity != 1)
-    {
-      cargv[m++] = "-v" ;
-      cargv[m++] = fmtv ;
-    }
-    if (linevar)
-    {
-      cargv[m++] = "-l" ;
-      cargv[m++] = linevar ;
-    }
-    if (targ)
-    {
-      cargv[m++] = "-t" ;
-      cargv[m++] = targ ;
-    }
-    cargv[m++] = "--" ;
-    while (*argv) cargv[m++] = *argv++ ;
-    cargv[m++] = 0 ;
-    if (!child_spawn1_pipe(cargv[0], cargv, envp, &fd, 0))
-      strerr_diefu2sys(111, "spawn ", cargv[0]) ;
-    if (fd_move(1, fd) < 0) strerr_diefu1sys(111, "fd_move") ;
-  }
-
-  {
-    unsigned int m = 0 ;
-    char const *pargv[6] ;
-    char fmtk[UINT_FMT] ;
-    pargv[m++] = S6_LINUX_UTILS_BINPREFIX "s6-uevent-listener" ;
-    if (verbosity != 1)
-    {
-      pargv[m++] = "-v" ;
-      pargv[m++] = fmtv ;
-    }
-    if (kbufsz != 65536)
-    {
-      pargv[m++] = "-b" ;
-      pargv[m++] = fmtk ;
-      fmtk[uint_fmt(fmtk, kbufsz)] = 0 ;
-    }
-    pargv[m++] = 0 ;
-    xpathexec_run(pargv[0], pargv, envp) ;
-  }
-}
diff --git a/src/minutils/s6-uevent-listener.c b/src/minutils/s6-uevent-listener.c
deleted file mode 100644
index 4175b54..0000000
--- a/src/minutils/s6-uevent-listener.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* ISC license. */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <skalibs/types.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/siovec.h>
-#include <skalibs/buffer.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/error.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/iopause.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/sig.h>
-#include <skalibs/selfpipe.h>
-
-#define USAGE "s6-uevent-listener [ -v verbosity ] [ -b kbufsz ]"
-#define dieusage() strerr_dieusage(100, USAGE)
-#define dienomem() strerr_diefu1sys(111, "build string") ;
-
-#define MAXNLSIZE 4096
-
-static unsigned int cont = 1, verbosity = 1 ;
-
-static inline ssize_t fd_recvmsg (int fd, struct msghdr *hdr)
-{
-  ssize_t r ;
-  do r = recvmsg(fd, hdr, MSG_DONTWAIT) ;
-  while ((r == -1) && (errno == EINTR)) ;
-  return r ;
-}
-
-static inline int netlink_init_stdin (unsigned int kbufsz)
-{
-  struct sockaddr_nl nl = { .nl_family = AF_NETLINK, .nl_pad = 0, .nl_groups = 1, .nl_pid = 0 } ;
-  close(0) ;
-  return socket_internal(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT, DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) == 0
-   && bind(0, (struct sockaddr *)&nl, sizeof(struct sockaddr_nl)) == 0
-   && setsockopt(0, SOL_SOCKET, SO_RCVBUFFORCE, &kbufsz, sizeof(unsigned int)) == 0 ;
-}
-
-static inline void handle_signals (void)
-{
-  for (;;)
-  {
-    int c = selfpipe_read() ;
-    switch (c)
-    {
-      case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
-      case 0 : return ;
-      case SIGTERM :
-        cont = 0 ;
-        fd_close(0) ;
-        break ;
-      default :
-        strerr_dief1x(101, "internal error: inconsistent signal state. Please submit a bug-report.") ;
-    }
-  }
-}
-
-static inline void handle_stdout (void)
-{
-  if (!buffer_flush(buffer_1) && !error_isagain(errno))
-    strerr_diefu1sys(111, "flush stdout") ;
-}
-
-static inline void handle_netlink (void)
-{
-  struct sockaddr_nl nl;
-  struct iovec v[2] ;
-  struct msghdr msg =
-  {
-    .msg_name = &nl,
-    .msg_namelen = sizeof(struct sockaddr_nl),
-    .msg_iov = v,
-    .msg_iovlen = 2,
-    .msg_control = 0,
-    .msg_controllen = 0,
-    .msg_flags = 0
-  } ;
-  ssize_t r ;
-  buffer_wpeek(buffer_1, v) ;
-  siovec_trunc(v, 2, siovec_len(v, 2) - 1) ;
-  r = sanitize_read(fd_recvmsg(0, &msg)) ;
-  if (r < 0)
-  {
-    if (errno == EPIPE)
-    {
-      if (verbosity >= 2) strerr_warnw1x("received EOF on netlink") ;
-      cont = 0 ;
-      fd_close(0) ;
-      return ;
-    }
-    else strerr_diefu1sys(111, "receive netlink message") ;
-  }
-  if (!r) return ;
-  if (msg.msg_flags & MSG_TRUNC)
-    strerr_diefu2x(111, "buffer too small for ", "netlink message") ;
-  if (nl.nl_pid)
-  {
-    if (verbosity >= 3)
-    {
-      char fmt[PID_FMT] ;
-      fmt[pid_fmt(fmt, nl.nl_pid)] = 0 ;
-      strerr_warnw3x("netlink message", " from userspace process ", fmt) ;
-    }
-    return ;
-  }
-  buffer_wseek(buffer_1, r) ;
-  buffer_putnoflush(buffer_1, "", 1) ;
-}
-
-
-int main (int argc, char const *const *argv, char const *const *envp)
-{
-  iopause_fd x[3] = { { .events = IOPAUSE_READ }, { .fd = 1 }, { .fd = 0 } } ;
-  PROG = "s6-uevent-listener" ;
-  strerr_warnw1x("this program is deprecated, see https://skarnet.org/software/mdevd/") ;
-  {
-    unsigned int kbufsz = 65536 ;
-    subgetopt_t l = SUBGETOPT_ZERO ;
-    for (;;)
-    {
-      int opt = subgetopt_r(argc, argv, "v:b:", &l) ;
-      if (opt == -1) break ;
-      switch (opt)
-      {
-        case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
-        case 'b' : if (!uint0_scan(l.arg, &kbufsz)) dieusage() ; break ;
-        default : dieusage() ;
-      }
-    }
-    argc -= l.ind ; argv += l.ind ;
-    if (!netlink_init_stdin(kbufsz)) strerr_diefu1sys(111, "init netlink") ;
-  }
-
-  x[0].fd = selfpipe_init() ;
-  if (x[0].fd < 0) strerr_diefu1sys(111, "init selfpipe") ;
-  if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
-  if (selfpipe_trap(SIGTERM) < 0) strerr_diefu1sys(111, "trap SIGTERM") ;
-
-  if (verbosity >= 2) strerr_warni1x("starting") ;
-
-  while (cont || buffer_len(buffer_1))
-  {
-    int r ;
-    x[1].events = buffer_len(buffer_1) ? IOPAUSE_WRITE : 0 ;
-    x[2].events = buffer_available(buffer_1) >= MAXNLSIZE + 1 ? IOPAUSE_READ : 0 ;
-    r = iopause(x, 2 + cont, 0, 0) ;
-    if (r < 0) strerr_diefu1sys(111, "iopause") ;
-    if (!r) continue ;
-    if (x[1].revents & IOPAUSE_EXCEPT) break ;
-    if (x[1].revents & IOPAUSE_WRITE) handle_stdout() ;
-    if (x[0].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ;
-    if (cont && x[2].events & IOPAUSE_READ && x[2].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT))
-      handle_netlink() ;
-  }
-  if (verbosity >= 2) strerr_warni1x("exiting") ;
-  return 0 ;
-}
diff --git a/src/minutils/s6-uevent-spawner.c b/src/minutils/s6-uevent-spawner.c
deleted file mode 100644
index 87dea11..0000000
--- a/src/minutils/s6-uevent-spawner.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* ISC license. */
-
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <spawn.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <skalibs/config.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/bytestr.h>
-#include <skalibs/buffer.h>
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/tai.h>
-#include <skalibs/iopause.h>
-#include <skalibs/env.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/sig.h>
-#include <skalibs/selfpipe.h>
-#include <skalibs/skamisc.h>
-
-#define USAGE "s6-uevent-spawner [ -v verbosity ] [ -l linevar ] [ -t maxlife:maxterm:maxkill ] helperprogram..."
-#define dieusage() strerr_dieusage(100, USAGE)
-#define dienomem() strerr_diefu1sys(111, "build string") ;
-
-static unsigned int cont = 1, state = 0, verbosity = 1 ;
-static pid_t pid = 0 ;
-static tain_t lifetto = TAIN_INFINITE_RELATIVE,
-              termtto = TAIN_INFINITE_RELATIVE,
-              killtto = TAIN_INFINITE_RELATIVE,
-              deadline ;
-
-static inline void on_death (void)
-{
-  pid = 0 ;
-  state = 0 ;
-  tain_add_g(&deadline, &tain_infinite_relative) ;
-}
-
-static inline void on_event (char const *const *argv, char const *const *envp, char const *s, unsigned int len)
-{
-  posix_spawnattr_t attr ;
-  posix_spawn_file_actions_t actions ;
-  size_t envlen = env_len(envp) ;
-  size_t n = envlen + 1 + byte_count(s, len, '\0') ;
-  pid_t mypid ;
-  int e ;
-  char const *v[n] ;
-  if (!env_merge(v, n, envp, envlen, s, len))
-    strerr_diefu1sys(111, "env_merge") ;
-
-  e = posix_spawnattr_init(&attr) ;
-  if (e) { errno = e ; strerr_diefu1sys(111, "posix_spawnattr_init") ; }
-  {
-    sigset_t set ;
-    sigemptyset(&set) ;
-    e = posix_spawnattr_setsigmask(&attr, &set) ;
-    if (e) { errno = e ; strerr_diefu1sys(111, "posix_spawnattr_setsigmask") ; }
-    sigfillset(&set) ;
-    e = posix_spawnattr_setsigdefault(&attr, &set) ;
-    if (e) { errno = e ; strerr_diefu1sys(111, "posix_spawnattr_setsigdefault") ; }
-  }
-  e = posix_spawn_file_actions_init(&actions) ;
-  if (e) { errno = e ; strerr_diefu1sys(111, "posix_spawn_file_actions_init") ; }
-  e = posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDONLY, S_IRUSR) ;
-  if (e) { errno = e ; strerr_diefu1sys(111, "posix_spawn_file_actions_addopen") ; }
-  e = posix_spawnp(&mypid, argv[0], &actions, &attr, (char *const *)argv, (char * const *)v) ;
-  if (e) { errno = e ; strerr_diefu2sys(111, "spawn ", argv[0]) ; }
-  posix_spawn_file_actions_destroy(&actions) ;
-  posix_spawnattr_destroy(&attr) ;
-  state = 1 ;
-  pid = mypid ;
-  tain_add_g(&deadline, &lifetto) ;
-}
-
-static inline void handle_timeout (void)
-{
-  switch (state)
-  {
-    case 0 :
-      tain_add_g(&deadline, &tain_infinite_relative) ;
-      break ;
-    case 1 :
-      kill(pid, SIGTERM) ;
-      tain_add_g(&deadline, &termtto) ;
-      state++ ;
-      break ;
-    case 2 :
-      kill(pid, SIGKILL) ;
-      tain_add_g(&deadline, &killtto) ;
-      state++ ;
-      break ;
-    case 3 :
-      strerr_dief1x(99, "child resisted SIGKILL - check your kernel logs.") ;
-    default :
-      strerr_dief1x(101, "internal error: inconsistent state. Please submit a bug-report.") ;
-  }
-}
-
-static inline void handle_signals (void)
-{
-  for (;;)
-  {
-    int c = selfpipe_read() ;
-    switch (c)
-    {
-      case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
-      case 0 : return ;
-      case SIGCHLD :
-        if (!pid) wait_reap() ;
-        else
-        {
-          int wstat ;
-          int r = wait_pid_nohang(pid, &wstat) ;
-          if (r < 0)
-            if (errno != ECHILD) strerr_diefu1sys(111, "wait_pid_nohang") ;
-            else break ;
-          else if (!r) break ;
-          on_death() ;
-        }
-        break ;
-      default :
-        strerr_dief1x(101, "internal error: inconsistent signal handling. Please submit a bug-report.") ;
-    }
-  }
-}
-
-static inline void handle_stdin (stralloc *sa, char const *linevar, char const *const *argv, char const *const *envp)
-{
-  while (!pid)
-  {
-    size_t start ;
-    ssize_t r ;
-    if (!sa->len && linevar)
-      if (!stralloc_cats(sa, linevar) || !stralloc_catb(sa, "=", 1))
-        dienomem() ;
-    start = sa->len ;
-    r = sanitize_read(skagetln(buffer_0, sa, 0)) ;
-    if (r < 0)
-    {
-      cont = 0 ;
-      if (errno != EPIPE && verbosity) strerr_warnwu1sys("read from stdin") ;
-    }
-    if (r <= 0) break ;
-    if (sa->len == start + 1)
-    {
-      start = linevar ? 0 : strlen(sa->s) + 1 ;
-      if (start >= sa->len)
-      {
-        if (verbosity) strerr_warnw1x("read an empty event!") ;
-      }
-      else on_event(argv, envp, sa->s + start, sa->len - 1 - start) ;
-      sa->len = 0 ;
-    }
-  }
-}
-
-static inline int make_ttos (char const *s)
-{
-  size_t pos = 0 ;
-  unsigned int tlife = 0, tterm = 0, tkill = 0 ;
-  pos += uint_scan(s + pos, &tlife) ;
-  if (s[pos] && s[pos++] != ':') return 0 ;
-  if (!tlife) return 1 ;
-  tain_from_millisecs(&lifetto, tlife) ;
-  pos += uint_scan(s + pos, &tterm) ;
-  if (s[pos] && s[pos++] != ':') return 0 ;
-  if (!tterm) return 1 ;
-  tain_from_millisecs(&termtto, tterm) ;
-  tain_add(&termtto, &termtto, &lifetto) ;
-  pos += uint_scan(s + pos, &tkill) ;
-  if (s[pos]) return 0 ;
-  if (!tkill) return 1 ;
-  tain_from_millisecs(&killtto, tkill) ;
-  tain_add(&killtto, &killtto, &termtto) ;
-  return 1 ;
-}
-
-int main (int argc, char const *const *argv, char const *const *envp)
-{
-  iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = IOPAUSE_READ } } ;
-  char const *linevar = 0 ;
-  stralloc sa = STRALLOC_ZERO ;
-  PROG = "s6-uevent-spawner" ;
-  strerr_warnw1x("this program is deprecated, see https://skarnet.org/software/mdevd/") ;
-  {
-    subgetopt_t l = SUBGETOPT_ZERO ;
-    for (;;)
-    {
-      int opt = subgetopt_r(argc, argv, "l:v:t:", &l) ;
-      if (opt == -1) break ;
-      switch (opt)
-      {
-        case 'l' : linevar = l.arg ; break ;
-        case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
-        case 't' : if (!make_ttos(l.arg)) dieusage() ; break ;
-        default : dieusage() ;
-      }
-    }
-    argc -= l.ind ; argv += l.ind ;
-    if (!argc) strerr_dieusage(100, USAGE) ;
-  }
-  if (linevar && strchr(linevar, '='))
-    strerr_dief2x(100, "invalid variable: ", linevar) ;
-
-  if (ndelay_on(0) < 0) strerr_diefu1sys(111, "set stdin nonblocking") ;
-  x[0].fd = selfpipe_init() ;
-  if (x[0].fd == -1) strerr_diefu1sys(111, "init selfpipe") ;
-  if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
-  if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "trap SIGCHLD") ;
-  if (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)
-    strerr_diefu1sys(111, "setenv PATH") ;
-
-  tain_now_g() ;
-  tain_add_g(&deadline, &tain_infinite_relative) ;
-  if (verbosity >= 2) strerr_warni1x("starting") ;
-
-  while (cont || pid)
-  {
-    int r ;
-    if (buffer_len(buffer_0))
-      handle_stdin(&sa, linevar, argv, envp) ;
-    r = iopause_g(x, 1 + (!pid && cont), &deadline) ;
-    if (r < 0) strerr_diefu1sys(111, "iopause") ;
-    else if (!r) handle_timeout() ;
-    else
-    {
-      if (x[0].revents & IOPAUSE_EXCEPT)
-        strerr_diefu1x(111, "iopause: trouble with selfpipe") ;
-      if (x[0].revents & IOPAUSE_READ)
-        handle_signals() ;
-      else if (cont && !pid && x[1].revents & IOPAUSE_READ)
-        handle_stdin(&sa, linevar, argv, envp) ;
-    }
-  }
-  if (verbosity >= 2) strerr_warni1x("exiting") ;
-  return 0 ;
-}