summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/deps.mak7
-rw-r--r--src/include/s6/s6-supervise.h11
-rw-r--r--src/libs6/deps-lib/s62
-rw-r--r--src/libs6/s6_supervise_link.c124
-rw-r--r--src/libs6/s6_supervise_unlink.c45
5 files changed, 180 insertions, 9 deletions
diff --git a/package/deps.mak b/package/deps.mak
index 5c43a12..f654105 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -91,6 +91,7 @@ src/libs6/s6_fdholder_start.o src/libs6/s6_fdholder_start.lo: src/libs6/s6_fdhol
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/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
src/libs6/s6_svc_writectl.o src/libs6/s6_svc_writectl.lo: src/libs6/s6_svc_writectl.c src/include/s6/s6-supervise.h
@@ -200,12 +201,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
+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
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
+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
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
+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
s6-ftrigrd: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB}
s6-ftrigrd: src/libs6/s6-ftrigrd.o src/libs6/ftrig1_free.o src/libs6/ftrig1_make.o
s6lockd: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} ${SPAWN_LIB}
diff --git a/src/include/s6/s6-supervise.h b/src/include/s6/s6-supervise.h
index 187bc20..77280e7 100644
--- a/src/include/s6/s6-supervise.h
+++ b/src/include/s6/s6-supervise.h
@@ -3,7 +3,9 @@
#ifndef S6_SUPERVISE_H
#define S6_SUPERVISE_H
+#include <stdint.h>
#include <sys/types.h>
+
#include <skalibs/tai.h>
#define S6_SUPERVISE_CTLDIR "supervise"
@@ -19,9 +21,6 @@ extern int s6_svc_write (char const *, char const *, size_t) ;
extern int s6_svc_writectl (char const *, char const *, char const *, size_t) ;
extern int s6_svc_main (int, char const *const *, char const *, char const *, char const *) ;
-extern int s6_svc_lock_take (char const *) ;
-extern void s6_svc_lock_release(int) ;
-
typedef struct s6_svstatus_s s6_svstatus_t, *s6_svstatus_t_ref ;
struct s6_svstatus_s
{
@@ -56,9 +55,9 @@ extern void s6_svstatus_unpack (char const *, s6_svstatus_t *) ;
extern int s6_svstatus_read (char const *, s6_svstatus_t *) ;
extern int s6_svstatus_write (char const *, s6_svstatus_t const *) ;
-/* These functions leak a fd, that's intended */
-extern int s6_supervise_lock (char const *) ;
-extern int s6_supervise_lock_mode (char const *, unsigned int, unsigned int) ;
+extern int s6_supervise_link (char const *, char const *const *, size_t, char const *, uint32_t, tain_t const *, tain_t *) ;
+#define s6_supervise_link_g(scandir, servicedirs, n, prefix, options, deadline) s6_supervise_link(scandir, servicedirs, n, prefix, 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 ;
struct s6_dtally_s
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index d9d4341..45e6c33 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -62,4 +62,6 @@ s6_fdholder_setdump.o
s6_fdholder_start.o
s6_fdholder_store.o
s6_fdholder_store_async.o
+s6_supervise_link.o
+s6_supervise_unlink.o
-lskarnet
diff --git a/src/libs6/s6_supervise_link.c b/src/libs6/s6_supervise_link.c
new file mode 100644
index 0000000..4724421
--- /dev/null
+++ b/src/libs6/s6_supervise_link.c
@@ -0,0 +1,124 @@
+/* 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 *const scandir, char const *names, size_t nameslen, uint32_t killopts)
+{
+ while (nameslen)
+ {
+ size_t len = strlen(names) + 1 ;
+ s6_supervise_unlink(scandir, names, killopts) ;
+ names += len ; nameslen -= len ;
+ }
+}
+
+int s6_supervise_link (char const *scandir, char const *const *servicedirs, size_t n, char const *prefix, uint32_t options, tain_t const *deadline, tain_t *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++)
+ {
+ 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
+ {
+ 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 ;
+ stralloc lnames = STRALLOC_ZERO ;
+ gid_t gid = options & 2 ? -1 : getegid() ;
+ size_t scandirlen = strlen(scandir) ;
+ 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[scandirlen + prefixlen + maxlen + 2] ;
+ char fn[maxlen + 1 + sizeof(S6_SUPERVISE_EVENTDIR)] ;
+ char *p ;
+ if (!ftrigr_startf(&a, deadline, stamp)) return -1 ;
+ memcpy(lname, scandir, scandirlen) ;
+ lname[scandirlen] = '/' ;
+ memcpy(lname + scandirlen + 1, prefix, prefixlen) ;
+ for (i = 0 ; i < n ; i++) if (!bitarray_peek(locked, i))
+ {
+ size_t len = strlen(servicedirs[i]) ;
+ memcpy(fn, servicedirs[i], len) ;
+ memcpy(fn + len, S6_SUPERVISE_EVENTDIR, sizeof(S6_SUPERVISE_EVENTDIR)) ;
+ if (!ftrigw_fifodir_make(fn, gid, options & 1)) goto err ;
+ ids[m] = ftrigr_subscribe(&a, fn, "s", 0, deadline, stamp) ;
+ if (!ids[m++]) goto err ;
+ fn[len] = 0 ;
+ p = basename(fn) ;
+ len = strlen(p) ;
+ memcpy(lname + scandirlen + 1 + prefixlen, p, len + 1) ;
+ rpsa.len = 0 ;
+ lstart = lnames.len ;
+ if (!sarealpath(&rpsa, servicedirs[i]) || !stralloc_0(&rpsa)) goto err ;
+ if (!stralloc_catb(&lnames, lname + scandirlen + 1, prefixlen + len + 1)) goto err ;
+ if (symlink(rpsa.s, lname) < 0) goto errl ;
+ }
+ stralloc_free(&rpsa) ;
+ r = s6_svc_writectl(scandir, 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(scandir, lnames.s, lnames.len, killopts) ;
+ stralloc_free(&lnames) ;
+ return -1 ;
+ }
+}
diff --git a/src/libs6/s6_supervise_unlink.c b/src/libs6/s6_supervise_unlink.c
new file mode 100644
index 0000000..d4bbe73
--- /dev/null
+++ b/src/libs6/s6_supervise_unlink.c
@@ -0,0 +1,45 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <skalibs/posixplz.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/djbunix.h>
+
+#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 *scandir, char const *name, uint32_t options)
+{
+ int e = errno ;
+ int fd = -1 ;
+ size_t scandirlen = strlen(scandir) ;
+ size_t namelen = strlen(name) ;
+ char fn[scandirlen + namelen + sizeof(S6_SUPERVISE_CTLDIR) + 10] ;
+ memcpy(fn, scandir, scandirlen) ;
+ fn[scandirlen] = '/' ;
+ memcpy(fn + scandirlen + 1, name, namelen) ;
+ if (options & 1)
+ {
+ fn[scandirlen + 1 + namelen] = '/' ;
+ memcpy(fn + scandirlen + 1 + namelen + 1, S6_SUPERVISE_CTLDIR, sizeof(S6_SUPERVISE_CTLDIR) - 1) ;
+ memcpy(fn + scandirlen + 1 + namelen + sizeof(S6_SUPERVISE_CTLDIR), "/control", 9) ;
+ fd = open_write(fn) ;
+ }
+ fn[scandirlen + 1 + namelen] = 0 ;
+ unlink_void(fn) ;
+ if (fd >= 0)
+ {
+ fd_write(fd, "xd", 1 + !!(options & 2)) ;
+ fd_close(fd) ;
+ }
+ errno = e ;
+}