summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-08-28 17:18:08 +0000
committerLaurent Bercot <ska@appnovation.com>2021-08-28 17:18:08 +0000
commitfa7f29ff4b5aef142143e9c1d887d73788b703e4 (patch)
tree0ec096b01f94af5a376e37d8720c35f936c449bb
parent8f00f3a276b4fde40bcd0ddaa4dc89d2b5791d89 (diff)
downloads6-fa7f29ff4b5aef142143e9c1d887d73788b703e4.tar.xz
Add s6-svdir-link and s6-svdir-unlink
Not tested yet; not documented yet; to come soon. Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--.gitignore3
-rw-r--r--doc/s6-socklog.html6
-rw-r--r--package/deps.mak15
-rw-r--r--package/modes2
-rw-r--r--package/targets.mak2
-rw-r--r--src/include/s6/s6-supervise.h2
-rw-r--r--src/libs6/deps-lib/s61
-rw-r--r--src/libs6/s6_supervise_link.c158
-rw-r--r--src/libs6/s6_supervise_link_names.c136
-rw-r--r--src/libs6/s6_supervise_unlink.c21
-rw-r--r--src/supervision/deps-exe/s6-svdir-link5
-rw-r--r--src/supervision/deps-exe/s6-svdir-unlink2
-rw-r--r--src/supervision/s6-svdir-link.c104
-rw-r--r--src/supervision/s6-svdir-unlink.c36
14 files changed, 337 insertions, 156 deletions
diff --git a/.gitignore b/.gitignore
index 6084fce..c45d337 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,12 +28,15 @@
/s6-svdt
/s6-svdt-clear
/s6-permafailon
+/s6-svdir-link
+/s6-svdir-unlink
/s6-envdir
/s6-envuidgid
/s6-fghack
/s6-log
/s6-setlock
/s6-setsid
+/s6-socklog
/s6-softlimit
/s6-tai64n
/s6-tai64nlocal
diff --git a/doc/s6-socklog.html b/doc/s6-socklog.html
index d463fbb..3f66cdc 100644
--- a/doc/s6-socklog.html
+++ b/doc/s6-socklog.html
@@ -83,11 +83,11 @@ This allows <tt>s6-socklog</tt> to use the <a href="notifywhenup.html">s6
mechanism to notify readiness</a>. <em>notif</em> cannot be lesser than 3.
If this option is not given, no readiness notification is sent. </li>
<li> <tt>-u&nbsp;<em>uid</em></tt>&nbsp;: drop user id to <em>uid</em> </li>
- <li> <tt>-g&nbsp;<em>gid</em></tt>&nbsp;: drop group ID to <em>gid</em> </li>
+ <li> <tt>-g&nbsp;<em>gid</em></tt>&nbsp;: drop group id to <em>gid</em> </li>
<li> <tt>-G&nbsp;<em>gidlist</em></tt>&nbsp;: set supplementary group list
-to <em>gidlist</em>, which must be given as a comma-separated list of numeric GIDs,
+to <em>gidlist</em>, which must be given as a comma-separated list of numeric gids,
without spaces. </li>
- <li> <tt>-U</tt>&nbsp;: set user ID, group ID and supplementary group list
+ <li> <tt>-U</tt>&nbsp;: set user id, group id and supplementary group list
to the values of the UID, GID and GIDLIST environment variables. If a <tt>-u</tt>,
<tt>-g</tt> or <tt>-G</tt> option is given after <tt>-U</tt>, the command line
value overrides the environment variable. </li>
diff --git a/package/deps.mak b/package/deps.mak
index 2f21727..c2465d4 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -92,7 +92,8 @@ src/libs6/s6_fdholder_setdump.o src/libs6/s6_fdholder_setdump.lo: src/libs6/s6_f
src/libs6/s6_fdholder_start.o src/libs6/s6_fdholder_start.lo: src/libs6/s6_fdholder_start.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_link.o src/libs6/s6_supervise_link.lo: src/libs6/s6_supervise_link.c src/include/s6/ftrigr.h src/include/s6/ftrigw.h src/include/s6/s6-supervise.h
+src/libs6/s6_supervise_link.o src/libs6/s6_supervise_link.lo: src/libs6/s6_supervise_link.c src/include/s6/s6-supervise.h
+src/libs6/s6_supervise_link_names.o src/libs6/s6_supervise_link_names.lo: src/libs6/s6_supervise_link_names.c src/include/s6/ftrigr.h src/include/s6/ftrigw.h src/include/s6/s6-supervise.h
src/libs6/s6_supervise_unlink.o src/libs6/s6_supervise_unlink.lo: src/libs6/s6_supervise_unlink.c src/include/s6/s6-supervise.h
src/libs6/s6_svc_ok.o src/libs6/s6_svc_ok.lo: src/libs6/s6_svc_ok.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
@@ -124,6 +125,8 @@ src/supervision/s6-notifyoncheck.o src/supervision/s6-notifyoncheck.lo: src/supe
src/supervision/s6-permafailon.o src/supervision/s6-permafailon.lo: src/supervision/s6-permafailon.c src/include/s6/s6-supervise.h
src/supervision/s6-supervise.o src/supervision/s6-supervise.lo: src/supervision/s6-supervise.c src/include/s6/ftrigw.h src/include/s6/s6-supervise.h
src/supervision/s6-svc.o src/supervision/s6-svc.lo: src/supervision/s6-svc.c src/include/s6/config.h src/include/s6/s6-supervise.h
+src/supervision/s6-svdir-link.o src/supervision/s6-svdir-link.lo: src/supervision/s6-svdir-link.c src/include/s6/s6-supervise.h
+src/supervision/s6-svdir-unlink.o src/supervision/s6-svdir-unlink.lo: src/supervision/s6-svdir-unlink.c src/include/s6/s6-supervise.h
src/supervision/s6-svdt-clear.o src/supervision/s6-svdt-clear.lo: src/supervision/s6-svdt-clear.c src/include/s6/s6-supervise.h
src/supervision/s6-svdt.o src/supervision/s6-svdt.lo: src/supervision/s6-svdt.c src/include/s6/s6-supervise.h
src/supervision/s6-svlisten.o src/supervision/s6-svlisten.lo: src/supervision/s6-svlisten.c src/supervision/s6-svlisten.h src/include/s6/compat.h
@@ -207,12 +210,12 @@ s6-fdholder-transferdump: src/fdholder/s6-fdholder-transferdump.o ${LIBS6}
s6-fdholderd: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB}
s6-fdholderd: src/fdholder/s6-fdholderd.o ${LIBS6}
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
-libs6.a.xyzzy: src/libs6/ftrigr1_zero.o src/libs6/ftrigr_check.o src/libs6/ftrigr_checksa.o src/libs6/ftrigr_ack.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_updateb.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_params_free.o src/libs6/s6_accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6_compat_el_semicolon.o src/libs6/s6_dtally_pack.o src/libs6/s6_dtally_unpack.o src/libs6/s6_dtally_read.o src/libs6/s6_dtally_write.o src/libs6/s6_svc_ok.o src/libs6/s6_svc_write.o src/libs6/s6_svc_writectl.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_end.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_start.o src/libs6/s6_fdholder_store.o src/libs6/s6_fdholder_store_async.o src/libs6/s6_supervise_link.o src/libs6/s6_supervise_unlink.o
+libs6.a.xyzzy: src/libs6/ftrigr1_zero.o src/libs6/ftrigr_check.o src/libs6/ftrigr_checksa.o src/libs6/ftrigr_ack.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_updateb.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_params_free.o src/libs6/s6_accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6_compat_el_semicolon.o src/libs6/s6_dtally_pack.o src/libs6/s6_dtally_unpack.o src/libs6/s6_dtally_read.o src/libs6/s6_dtally_write.o src/libs6/s6_svc_ok.o src/libs6/s6_svc_write.o src/libs6/s6_svc_writectl.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_end.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_start.o src/libs6/s6_fdholder_store.o src/libs6/s6_fdholder_store_async.o src/libs6/s6_supervise_link.o src/libs6/s6_supervise_link_names.o src/libs6/s6_supervise_unlink.o
else
-libs6.a.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_checksa.lo src/libs6/ftrigr_ack.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_updateb.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_params_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pack.lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s6_dtally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs6/s6_svc_writectl.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_end.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_start.lo src/libs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6_supervise_link.lo src/libs6/s6_supervise_unlink.lo
+libs6.a.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_checksa.lo src/libs6/ftrigr_ack.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_updateb.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_params_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pack.lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s6_dtally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs6/s6_svc_writectl.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_end.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_start.lo src/libs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6_supervise_link.lo src/libs6/s6_supervise_link_names.lo src/libs6/s6_supervise_unlink.lo
endif
libs6.so.xyzzy: EXTRA_LIBS := -lskarnet
-libs6.so.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_checksa.lo src/libs6/ftrigr_ack.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_updateb.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_params_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pack.lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s6_dtally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs6/s6_svc_writectl.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_end.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_start.lo src/libs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6_supervise_link.lo src/libs6/s6_supervise_unlink.lo
+libs6.so.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/libs6/ftrigr_checksa.lo src/libs6/ftrigr_ack.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_updateb.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_params_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules_uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pack.lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s6_dtally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs6/s6_svc_writectl.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_end.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_start.lo src/libs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6_supervise_link.lo src/libs6/s6_supervise_link_names.lo src/libs6/s6_supervise_unlink.lo
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
libs6lockd.a.xyzzy: src/libs6/s6lockd_openandlock.o
else
@@ -244,6 +247,10 @@ s6-supervise: EXTRA_LIBS := -lskarnet ${SYSCLOCK_LIB}
s6-supervise: src/supervision/s6-supervise.o libs6.a.xyzzy
s6-svc: EXTRA_LIBS := -lskarnet
s6-svc: src/supervision/s6-svc.o ${LIBS6}
+s6-svdir-link: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} ${SPAWN_LIB}
+s6-svdir-link: src/supervision/s6-svdir-link.o ${LIBS6}
+s6-svdir-unlink: EXTRA_LIBS := -lskarnet
+s6-svdir-unlink: src/supervision/s6-svdir-unlink.o ${LIBS6}
s6-svdt: EXTRA_LIBS := -lskarnet
s6-svdt: src/supervision/s6-svdt.o ${LIBS6}
s6-svdt-clear: EXTRA_LIBS := -lskarnet
diff --git a/package/modes b/package/modes
index 4678bec..51947c2 100644
--- a/package/modes
+++ b/package/modes
@@ -11,6 +11,8 @@ s6-mkfifodir 0755
s6-svscan 0755
s6-supervise 0755
s6-svc 0755
+s6-svdir-link 0755
+s6-svdir-unlink 0755
s6-svscanctl 0755
s6-svok 0755
s6-svstat 0755
diff --git a/package/targets.mak b/package/targets.mak
index 0f1ebab..5516cf9 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -11,6 +11,8 @@ s6-mkfifodir \
s6-svscan \
s6-supervise \
s6-svc \
+s6-svdir-link \
+s6-svdir-unlink \
s6-svscanctl \
s6-svok \
s6-svstat \
diff --git a/src/include/s6/s6-supervise.h b/src/include/s6/s6-supervise.h
index 9375bec..c0dc1b6 100644
--- a/src/include/s6/s6-supervise.h
+++ b/src/include/s6/s6-supervise.h
@@ -57,6 +57,8 @@ extern int s6_svstatus_write (char const *, s6_svstatus_t const *) ;
extern int s6_supervise_link (char const *, char const *const *, size_t, char const *, uint32_t, tain const *, tain *) ;
#define s6_supervise_link_g(scdir, servicedirs, n, prefix, options, deadline) s6_supervise_link(scdir, servicedirs, n, prefix, options, (deadline), &STAMP)
+extern int s6_supervise_link_names (char const *, char const *const *, char const *const *, size_t, uint32_t, tain const *, tain *) ;
+#define s6_supervise_link_names_g(scdir, servicedirs, names, n, options, deadline) s6_supervise_link_names(scdir, servicedirs, names, n, options, (deadline), &STAMP)
extern void s6_supervise_unlink (char const *, char const *, uint32_t) ;
typedef struct s6_dtally_s s6_dtally_t, *s6_dtally_ref ;
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 45e6c33..94eab87 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -63,5 +63,6 @@ s6_fdholder_start.o
s6_fdholder_store.o
s6_fdholder_store_async.o
s6_supervise_link.o
+s6_supervise_link_names.o
s6_supervise_unlink.o
-lskarnet
diff --git a/src/libs6/s6_supervise_link.c b/src/libs6/s6_supervise_link.c
index 1d2ae15..0c6852c 100644
--- a/src/libs6/s6_supervise_link.c
+++ b/src/libs6/s6_supervise_link.c
@@ -1,156 +1,34 @@
/* ISC license. */
-#include <stdint.h>
#include <string.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <skalibs/bitarray.h>
-#include <skalibs/tai.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
-#include <s6/ftrigr.h>
-#include <s6/ftrigw.h>
#include <s6/s6-supervise.h>
-static inline void do_unlink (char const *scdir, char const *prefix, size_t prefixlen, size_t maxlen, char const *names, size_t nameslen, uint32_t killopts)
-{
- char fn[prefixlen + maxlen + 1] ;
- memcpy(fn, prefix, prefixlen) ;
- while (nameslen)
- {
- size_t len = strlen(names) + 1 ;
- memcpy(fn + prefixlen, names, len) ;
- s6_supervise_unlink(scdir, fn, killopts) ;
- names += len ; nameslen -= len ;
- }
-}
-
-static uint16_t registerit (ftrigr_t *a, char *fn, size_t len, gid_t gid, uint32_t options, tain const *deadline, tain *stamp)
-{
- if (options & 4)
- {
- int fd ;
- memcpy(fn + len, "/down", 6) ;
- fd = open_trunc(fn) ;
- if (fd < 0) return 0 ;
- fd_close(fd) ;
- }
- memcpy(fn + len, "/" S6_SUPERVISE_EVENTDIR, 1 + sizeof(S6_SUPERVISE_EVENTDIR)) ;
- if (!ftrigw_fifodir_make(fn, gid, options & 1)) return 0 ;
- return ftrigr_subscribe(a, fn, "s", 0, deadline, stamp) ;
-}
-
int s6_supervise_link (char const *scdir, char const *const *servicedirs, size_t n, char const *prefix, uint32_t options, tain const *deadline, tain *stamp)
{
- size_t maxlen = 0 ;
- size_t ntotal = n ;
- unsigned char locked[bitarray_div8(n)] ;
- unsigned char logged[bitarray_div8(n)] ;
- if (!n) return 0 ;
- memset(locked, 0, bitarray_div8(n)) ;
- memset(logged, 0, bitarray_div8(n)) ;
-
- for (size_t i = 0 ; i < n ; i++)
+ int r ;
+ size_t prefixlen = strlen(prefix) ;
+ stralloc sa = STRALLOC_ZERO ;
+ char const *names[n ? n : 1] ;
{
- struct stat st ;
- size_t len = strlen(servicedirs[i]) ;
- int h ;
- char subdir[len + 5] ;
- if (len > maxlen) maxlen = len ;
- h = s6_svc_ok(servicedirs[i]) ;
- if (h < 0) return -1 ;
- if (h) bitarray_set(locked, i) ;
- memcpy(subdir, servicedirs[i], len) ;
- memcpy(subdir + len, "/log", 5) ;
- if (stat(subdir, &st) < 0)
- {
- if (errno != ENOENT) return -1 ;
- }
- else
+ size_t indices[n ? n : 1] ;
+ for (size_t i = 0 ; i < n ; i++)
{
- int r ;
- if (!S_ISDIR(st.st_mode)) return (errno = ENOTDIR, -1) ;
- r = s6_svc_ok(subdir) ;
- if (r < 0) return -1 ;
- if (r != h) return (errno = EINVAL, -1) ;
- bitarray_set(logged, i) ;
- ntotal++ ;
+ indices[i] = sa.len ;
+ if (!stralloc_catb(&sa, prefix, prefixlen)
+ || !sabasename(&sa, servicedirs[i], strlen(servicedirs[i]))
+ || !stralloc_0(&sa)) goto err ;
}
- }
-
- {
- stralloc lnames = STRALLOC_ZERO ;
- ftrigr_t a = FTRIGR_ZERO ;
- stralloc rpsa = STRALLOC_ZERO ;
- gid_t gid = options & 2 ? -1 : getegid() ;
- size_t scdirlen = strlen(scdir) ;
- size_t prefixlen = strlen(prefix) ;
- unsigned int m = 0 ;
- size_t i = 0 ;
- size_t lstart = 0 ;
- uint32_t killopts = 0 ;
- int r ;
- uint16_t ids[ntotal] ;
- char lname[scdirlen + prefixlen + maxlen + 2] ;
- char fn[maxlen + 5 + (sizeof(S6_SUPERVISE_EVENTDIR) > 5 ? sizeof(S6_SUPERVISE_EVENTDIR) : 5)] ;
- if (!ftrigr_startf(&a, deadline, stamp)) return -1 ;
- memcpy(lname, scdir, scdirlen) ;
- lname[scdirlen] = '/' ;
- memcpy(lname + scdirlen + 1, prefix, prefixlen) ;
- for (i = 0 ; i < n ; i++)
- {
- char *p ;
- char const *src ;
- size_t len = strlen(servicedirs[i]) ;
- int h = bitarray_peek(locked, i) ;
- memcpy(fn, servicedirs[i], len) ;
- if (!h)
- {
- ids[m] = registerit(&a, fn, len, gid, options, deadline, stamp) ;
- if (!ids[m++]) goto err ;
- if (bitarray_peek(logged, i))
- {
- memcpy(fn + len, "/log", 4) ;
- ids[m] = registerit(&a, fn, len + 4, gid, options, deadline, stamp) ;
- if (!ids[m++]) goto err ;
- }
- }
- fn[len] = 0 ;
- p = basename(fn) ;
- len = strlen(p) ;
- memcpy(lname + scdirlen + 1 + prefixlen, p, len + 1) ;
- lstart = lnames.len ;
- if (!h && !stralloc_catb(&lnames, p, len + 1)) goto err ;
- if (servicedirs[i][0] == '/') src = servicedirs[i] ;
- else
- {
- rpsa.len = 0 ;
- if (sarealpath(&rpsa, servicedirs[i]) < 0 || !stralloc_0(&rpsa)) goto errl ;
- src = rpsa.s ;
- }
- if (symlink(src, lname) < 0 && (!h || errno != EEXIST)) goto errl ;
- }
- stralloc_free(&rpsa) ;
- r = s6_svc_writectl(scdir, S6_SVSCAN_CTLDIR, "a", 1) ;
- if (r <= 0) goto errsa ;
- killopts = 3 ;
- if (ftrigr_wait_and(&a, ids, m, deadline, stamp) < 0) goto errsa ;
- ftrigr_end(&a) ;
- stralloc_free(&lnames) ;
- return m ;
-
- errl:
- lnames.len = lstart ;
- err:
- stralloc_free(&rpsa) ;
- errsa:
- ftrigr_end(&a) ;
- do_unlink(scdir, prefix, prefixlen, maxlen, lnames.s, lnames.len, killopts | (options & 4)) ;
- stralloc_free(&lnames) ;
- return -1 ;
+ for (size_t i = 0 ; i < n ; i++) names[i] = sa.s + indices[i] ;
}
+ r = s6_supervise_link_names(scdir, servicedirs, names, n, options, deadline, stamp) ;
+ stralloc_free(&sa) ;
+ return r ;
+
+ err:
+ stralloc_free(&sa) ;
+ return -1 ;
}
diff --git a/src/libs6/s6_supervise_link_names.c b/src/libs6/s6_supervise_link_names.c
new file mode 100644
index 0000000..8cba399
--- /dev/null
+++ b/src/libs6/s6_supervise_link_names.c
@@ -0,0 +1,136 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <skalibs/bitarray.h>
+#include <skalibs/tai.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/ftrigr.h>
+#include <s6/ftrigw.h>
+#include <s6/s6-supervise.h>
+
+static inline void do_unlink (char const *scdir, char const *const *names, size_t n, uint32_t killopts)
+{
+ for (size_t i = 0 ; i < n ; i++)
+ s6_supervise_unlink(scdir, names[i], killopts) ;
+}
+
+static uint16_t registerit (ftrigr_t *a, char *fn, size_t len, gid_t gid, uint32_t options, tain const *deadline, tain *stamp)
+{
+ if (options & 4)
+ {
+ int fd ;
+ memcpy(fn + len, "/down", 6) ;
+ fd = open_trunc(fn) ;
+ if (fd < 0) return 0 ;
+ fd_close(fd) ;
+ }
+ memcpy(fn + len, "/" S6_SUPERVISE_EVENTDIR, 1 + sizeof(S6_SUPERVISE_EVENTDIR)) ;
+ if (!ftrigw_fifodir_make(fn, gid, options & 1)) return 0 ;
+ return ftrigr_subscribe(a, fn, "s", 0, deadline, stamp) ;
+}
+
+int s6_supervise_link_names (char const *scdir, char const *const *servicedirs, char const *const *names, size_t n, uint32_t options, tain const *deadline, tain *stamp)
+{
+ size_t maxnlen = 0, maxlen = 0 ;
+ size_t ntotal = n ;
+ unsigned char locked[bitarray_div8(n)] ;
+ unsigned char logged[bitarray_div8(n)] ;
+ if (!n) return 0 ;
+ memset(locked, 0, bitarray_div8(n)) ;
+ memset(logged, 0, bitarray_div8(n)) ;
+
+ for (size_t i = 0 ; i < n ; i++)
+ {
+ struct stat st ;
+ size_t len = strlen(servicedirs[i]) ;
+ size_t nlen = strlen(names[i]) ;
+ int h ;
+ char subdir[len + 5] ;
+ if (nlen > maxnlen) maxnlen = nlen ;
+ if (len > maxlen) maxlen = nlen ;
+ h = s6_svc_ok(servicedirs[i]) ;
+ if (h < 0) return -1 ;
+ if (h) bitarray_set(locked, i) ;
+ memcpy(subdir, servicedirs[i], len) ;
+ memcpy(subdir + len, "/log", 5) ;
+ if (stat(subdir, &st) < 0)
+ {
+ if (errno != ENOENT) return -1 ;
+ }
+ else
+ {
+ int r ;
+ if (!S_ISDIR(st.st_mode)) return (errno = ENOTDIR, -1) ;
+ r = s6_svc_ok(subdir) ;
+ if (r < 0) return -1 ;
+ if (r != h) return (errno = EINVAL, -1) ;
+ bitarray_set(logged, i) ;
+ ntotal++ ;
+ }
+ }
+
+ {
+ ftrigr_t a = FTRIGR_ZERO ;
+ stralloc rpsa = STRALLOC_ZERO ;
+ gid_t gid = options & 2 ? -1 : getegid() ;
+ size_t scdirlen = strlen(scdir) ;
+ unsigned int m = 0 ;
+ size_t i = 0 ;
+ uint32_t killopts = 0 ;
+ int r ;
+ uint16_t ids[ntotal] ;
+ char lname[scdirlen + maxnlen + 2] ;
+ char fn[maxlen + 5 + (sizeof(S6_SUPERVISE_EVENTDIR) > 5 ? sizeof(S6_SUPERVISE_EVENTDIR) : 5)] ;
+ if (!ftrigr_startf(&a, deadline, stamp)) return -1 ;
+ memcpy(lname, scdir, scdirlen) ;
+ lname[scdirlen] = '/' ;
+ for (; i < n ; i++)
+ {
+ char const *src = servicedirs[i] ;
+ size_t len = strlen(servicedirs[i]) ;
+ int h = bitarray_peek(locked, i) ;
+ memcpy(fn, servicedirs[i], len) ;
+ if (!h)
+ {
+ ids[m] = registerit(&a, fn, len, gid, options, deadline, stamp) ;
+ if (!ids[m++]) goto err ;
+ if (bitarray_peek(logged, i))
+ {
+ memcpy(fn + len, "/log", 4) ;
+ ids[m] = registerit(&a, fn, len + 4, gid, options, deadline, stamp) ;
+ if (!ids[m++]) goto err ;
+ }
+ }
+ fn[len] = 0 ;
+ strcpy(lname + scdirlen + 1, names[i]) ;
+ if (servicedirs[i][0] != '/')
+ {
+ rpsa.len = 0 ;
+ if (sarealpath(&rpsa, servicedirs[i]) < 0 || !stralloc_0(&rpsa)) goto err ;
+ src = rpsa.s ;
+ }
+ if (symlink(src, lname) < 0 && (!h || errno != EEXIST)) goto err ;
+ }
+ stralloc_free(&rpsa) ;
+ r = s6_svc_writectl(scdir, S6_SVSCAN_CTLDIR, "a", 1) ;
+ if (r <= 0) goto errsa ;
+ killopts = 3 ;
+ if (ftrigr_wait_and(&a, ids, m, deadline, stamp) < 0) goto errsa ;
+ ftrigr_end(&a) ;
+ return m ;
+
+ err:
+ stralloc_free(&rpsa) ;
+ errsa:
+ ftrigr_end(&a) ;
+ do_unlink(scdir, names, i, killopts | (options & 4)) ;
+ }
+ return -1 ;
+}
diff --git a/src/libs6/s6_supervise_unlink.c b/src/libs6/s6_supervise_unlink.c
index 2e5a9ec..cc263e4 100644
--- a/src/libs6/s6_supervise_unlink.c
+++ b/src/libs6/s6_supervise_unlink.c
@@ -3,7 +3,7 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
-#include <limits.h>
+#include <sys/stat.h>
#include <skalibs/posixplz.h>
#include <skalibs/allreadwrite.h>
@@ -11,19 +11,13 @@
#include <s6/s6-supervise.h>
-#ifdef PATH_MAX
-# define S6_PATH_MAX PATH_MAX
-#else
-# define S6_PATH_MAX 4096
-#endif
-
void s6_supervise_unlink (char const *scdir, char const *name, uint32_t options)
{
int e = errno ;
- int fd = -1 ;
+ int fd = -1, fdlog = -1 ;
size_t scdirlen = strlen(scdir) ;
size_t namelen = strlen(name) ;
- char fn[scdirlen + namelen + sizeof(S6_SUPERVISE_CTLDIR) + 10] ;
+ char fn[scdirlen + namelen + sizeof(S6_SUPERVISE_CTLDIR) + 14] ;
memcpy(fn, scdir, scdirlen) ;
fn[scdirlen] = '/' ;
memcpy(fn + scdirlen + 1, name, namelen) ;
@@ -37,7 +31,11 @@ void s6_supervise_unlink (char const *scdir, char const *name, uint32_t options)
memcpy(fn + scdirlen + 1 + namelen, "/" S6_SUPERVISE_CTLDIR, sizeof(S6_SUPERVISE_CTLDIR)) ;
memcpy(fn + scdirlen + 1 + namelen + sizeof(S6_SUPERVISE_CTLDIR), "/control", 9) ;
fd = open_write(fn) ;
+ memcpy(fn + scdirlen + 1 + namelen, "/log/" S6_SUPERVISE_CTLDIR, 4 + sizeof(S6_SUPERVISE_CTLDIR)) ;
+ memcpy(fn + scdirlen + 5 + namelen + sizeof(S6_SUPERVISE_CTLDIR), "/control", 9) ;
+ fdlog = open_write(fn) ;
}
+
fn[scdirlen + 1 + namelen] = 0 ;
unlink_void(fn) ;
if (fd >= 0)
@@ -45,5 +43,10 @@ void s6_supervise_unlink (char const *scdir, char const *name, uint32_t options)
fd_write(fd, "xd", 1 + !!(options & 2)) ;
fd_close(fd) ;
}
+ if (fdlog >= 0)
+ {
+ fd_write(fdlog, "xo", 1 + !!(options & 2)) ;
+ fd_close(fdlog) ;
+ }
errno = e ;
}
diff --git a/src/supervision/deps-exe/s6-svdir-link b/src/supervision/deps-exe/s6-svdir-link
new file mode 100644
index 0000000..16eaae2
--- /dev/null
+++ b/src/supervision/deps-exe/s6-svdir-link
@@ -0,0 +1,5 @@
+${LIBS6}
+-lskarnet
+${SOCKET_LIB}
+${SYSCLOCK_LIB}
+${SPAWN_LIB}
diff --git a/src/supervision/deps-exe/s6-svdir-unlink b/src/supervision/deps-exe/s6-svdir-unlink
new file mode 100644
index 0000000..08815d9
--- /dev/null
+++ b/src/supervision/deps-exe/s6-svdir-unlink
@@ -0,0 +1,2 @@
+${LIBS6}
+-lskarnet
diff --git a/src/supervision/s6-svdir-link.c b/src/supervision/s6-svdir-link.c
new file mode 100644
index 0000000..6eeb0a2
--- /dev/null
+++ b/src/supervision/s6-svdir-link.c
@@ -0,0 +1,104 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <skalibs/types.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/tai.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/s6-supervise.h>
+
+#define USAGE "s6-svdir-link [ -d ] [ -f ] [ -P | -p ] [ -t timeout ] scandir name servicedir"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+static inline void checkscandir (char const *s)
+{
+ int r ;
+ int fd ;
+ size_t len = strlen(s) ;
+ char fn[len + 6 + sizeof(S6_SVSCAN_CTLDIR)] ;
+ memcpy(fn, s, len) ;
+ memcpy(fn + len, "/" S6_SVSCAN_CTLDIR "/lock", 6 + sizeof(S6_SVSCAN_CTLDIR)) ;
+ fd = open_read(fn) ;
+ if (fd < 0) strerr_diefu2sys(111, "open ", fn) ;
+ r = fd_islocked(fd) ;
+ if (r < 0) strerr_diefu2sys(111, "check lock on ", fn) ;
+ if (!r) strerr_dief2x(1, "s6-svscan not running on ", s) ;
+ fd_close(fd) ;
+}
+
+static inline void checkservicedir (char const *s)
+{
+ int r ;
+ struct stat st ;
+ size_t len = strlen(s) ;
+ char fn[len + 9] ;
+ memcpy(fn, s, len) ;
+ memcpy(fn + len, "/run", 4) ;
+ if (stat(fn, &st) == -1) strerr_diefu2sys(111, "stat ", fn) ;
+ if (!(st.st_mode & S_IXUSR)) strerr_dief2x(100, fn, " is not executable") ;
+ r = s6_svc_ok(s) ;
+ if (r < 0) strerr_diefu2sys(111, "check supervision status of ", s) ;
+ if (r) strerr_warnw2x("supervisor already running on ", s) ;
+ memcpy(fn + len + 1, "log", 4) ;
+ if (stat(fn, &st) == -1)
+ {
+ if (errno != ENOENT) strerr_diefu2sys(111, "stat ", fn) ;
+ }
+ else
+ {
+ if (!S_ISDIR(st.st_mode)) strerr_dief2x(100, fn, " is not a directory") ;
+ memcpy(fn + len + 4, "/run", 5) ;
+ if (stat(fn, &st) == -1) strerr_diefu2sys(111, "stat ", fn) ;
+ if (!(st.st_mode & S_IXUSR)) strerr_dief2x(100, fn, " is not executable") ;
+ fn[len + 4] = 0 ;
+ r = s6_svc_ok(fn) ;
+ if (r < 0) strerr_diefu2sys(111, "check supervision status of ", fn) ;
+ if (r) strerr_warnw2x("supervisor already running on ", fn) ;
+ }
+}
+
+int main (int argc, char const *const *argv)
+{
+ tain tto = TAIN_INFINITE_RELATIVE ;
+ uint32_t options = 0 ;
+ PROG = "s6-svdir-link" ;
+ {
+ unsigned int t = 0 ;
+ subgetopt l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "dfPpt:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'd' : options |= 4 ; break ;
+ case 'f' : options |= 1 ; break ;
+ case 'P' : options |= 2 ; break ;
+ case 'p' : options &= ~2U ; break ;
+ case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ if (t) tain_from_millisecs(&tto, t) ;
+ }
+ if (argc < 3) dieusage() ;
+
+ if (!argv[0][0]) strerr_dief1x(100, "invalid scandir") ;
+ if (!argv[1][0]) strerr_dief1x(100, "invalid name") ;
+ if (!argv[2][0]) strerr_dief1x(100, "invalid servicedir") ;
+ checkscandir(argv[0]) ;
+
+ tain_now_set_stopwatch_g() ;
+ tain_add_g(&tto, &tto) ;
+
+ if (s6_supervise_link_names_g(argv[0], argv + 2, argv + 1, 1, options, &tto) == -1)
+ strerr_diefu6sys(111, "link servicedir ", argv[2], " into scandir ", argv[0], " with name ", argv[1]) ;
+ return 0 ;
+}
diff --git a/src/supervision/s6-svdir-unlink.c b/src/supervision/s6-svdir-unlink.c
new file mode 100644
index 0000000..88eedbe
--- /dev/null
+++ b/src/supervision/s6-svdir-unlink.c
@@ -0,0 +1,36 @@
+/* ISC license. */
+
+#include <stdint.h>
+
+#include <skalibs/sgetopt.h>
+#include <skalibs/strerr2.h>
+
+#include <s6/s6-supervise.h>
+
+#define USAGE "s6-svdir-unlink [ -d ] [ -x ] scandir servicename"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+int main (int argc, char const *const *argv)
+{
+ uint32_t options = 0 ;
+ PROG = "s6-svdir-link" ;
+ {
+ subgetopt l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "dx", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'd' : options = 3 ; break ;
+ case 'x' : options = 1 ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+ if (argc < 2) dieusage() ;
+
+ s6_supervise_unlink(argv[0], argv[1], options) ;
+ return 0 ;
+}