summaryrefslogtreecommitdiff
path: root/src/libs6
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-01-19 16:11:24 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-01-19 16:11:24 +0000
commit701540827e27a4f07ac725db3ce361d3be0c106f (patch)
tree98c4b2fb8ba8f69ef791feebdcd61cd5bca34140 /src/libs6
parent83853a80eb18238796154164f9ea776b0c167ab7 (diff)
downloads6-701540827e27a4f07ac725db3ce361d3be0c106f.tar.xz
- added the s6_fdholder library to libs6. (Nothing useful yet.)
- fixed execline invocation in s6-log with slashpackage - integrated s6_svc_main.c's functionality into s6-svscanctl and deleted it - integrated Olivier Brunel's suggestions for wstat report in supervise/status - minor fixes to s6-supervise's status reports - separated sigaction calls in ftrigw_notifyb, this spares a few syscalls in s6-supervise - updated doc to reflect the changes - version bumped to 2.1.0.0 because API breakage (./finish, s6-svstat)
Diffstat (limited to 'src/libs6')
-rw-r--r--src/libs6/deps-lib/s614
-rw-r--r--src/libs6/ftrigw_notifyb.c55
-rw-r--r--src/libs6/ftrigw_notifyb_nosig.c62
-rw-r--r--src/libs6/s6_fdholder_delete.c21
-rw-r--r--src/libs6/s6_fdholder_delete_async.c18
-rw-r--r--src/libs6/s6_fdholder_getdump.c73
-rw-r--r--src/libs6/s6_fdholder_list.c19
-rw-r--r--src/libs6/s6_fdholder_list_async.c11
-rw-r--r--src/libs6/s6_fdholder_list_cb.c31
-rw-r--r--src/libs6/s6_fdholder_retrieve.c18
-rw-r--r--src/libs6/s6_fdholder_retrieve_async.c20
-rw-r--r--src/libs6/s6_fdholder_retrieve_cb.c26
-rw-r--r--src/libs6/s6_fdholder_setdump.c74
-rw-r--r--src/libs6/s6_fdholder_store.c21
-rw-r--r--src/libs6/s6_fdholder_store_async.c20
-rw-r--r--src/libs6/s6_svc_main.c39
-rw-r--r--src/libs6/s6_svstatus_pack.c2
-rw-r--r--src/libs6/s6_svstatus_read.c2
-rw-r--r--src/libs6/s6_svstatus_unpack.c8
19 files changed, 440 insertions, 94 deletions
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 579d844..35a3296 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -13,6 +13,7 @@ ftrigw_clean.o
ftrigw_fifodir_make.o
ftrigw_notify.o
ftrigw_notifyb.o
+ftrigw_notifyb_nosig.o
s6_accessrules_backend_cdb.o
s6_accessrules_backend_fs.o
s6_accessrules_keycheck_ip4.o
@@ -23,7 +24,6 @@ s6_accessrules_uidgid_cdb.o
s6_accessrules_uidgid_fs.o
s6_supervise_lock.o
s6_supervise_lock_mode.o
-s6_svc_main.o
s6_svc_write.o
s6_svstatus_pack.o
s6_svstatus_read.o
@@ -39,3 +39,15 @@ s6lock_update.o
s6lock_wait_and.o
s6lock_wait_or.o
s6lock_zero.o
+s6_fdholder_delete.o
+s6_fdholder_delete_async.o
+s6_fdholder_getdump.o
+s6_fdholder_list.o
+s6_fdholder_list_async.o
+s6_fdholder_list_cb.o
+s6_fdholder_retrieve.o
+s6_fdholder_retrieve_async.o
+s6_fdholder_retrieve_cb.o
+s6_fdholder_setdump.o
+s6_fdholder_store.o
+s6_fdholder_store_async.o
diff --git a/src/libs6/ftrigw_notifyb.c b/src/libs6/ftrigw_notifyb.c
index 345a3cc..ddd1116 100644
--- a/src/libs6/ftrigw_notifyb.c
+++ b/src/libs6/ftrigw_notifyb.c
@@ -1,67 +1,20 @@
/* ISC license. */
-#include <unistd.h>
#include <errno.h>
#include <signal.h>
-#include <skalibs/direntry.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/bytestr.h>
#include <skalibs/sig.h>
-#include <skalibs/djbunix.h>
-#include "ftrig1.h"
#include <s6/ftrigw.h>
int ftrigw_notifyb (char const *path, char const *s, unsigned int len)
{
- unsigned int i = 0 ;
struct skasigaction old ;
- DIR *dir = opendir(path) ;
- if (!dir) return -1 ;
+ int r ;
if (skasigaction(SIGPIPE, &SKASIG_IGN, &old) < 0) return -1 ;
- {
- unsigned int pathlen = str_len(path) ;
- char tmp[pathlen + FTRIG1_PREFIXLEN + 45] ;
- byte_copy(tmp, pathlen, path) ;
- tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 44] = 0 ;
- for (;;)
- {
- direntry *d ;
- int fd ;
- errno = 0 ;
- d = readdir(dir) ;
- if (!d) break ;
- if (str_diffn(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ;
- if (str_len(d->d_name) != FTRIG1_PREFIXLEN + 43) continue ;
- byte_copy(tmp + pathlen + 1, FTRIG1_PREFIXLEN + 43, d->d_name) ;
- fd = open_write(tmp) ;
- if (fd == -1)
- {
- if (errno == ENXIO) unlink(tmp) ;
- }
- else
- {
- register int r = fd_write(fd, s, len) ;
- if ((r < 0) || (unsigned int)r < len)
- {
- if (errno == EPIPE) unlink(tmp) ;
- /* what to do if EGAIN ? full fifo -> fix the reader !
- There's a race condition in extreme cases though ;
- but it's still better to be nonblocking - the writer
- shouldn't get in trouble because of a bad reader. */
- fd_close(fd) ;
- }
- else
- {
- fd_close(fd) ;
- i++ ;
- }
- }
- }
- }
+ r = ftrigw_notifyb_nosig(path, s, len) ;
{
int e = errno ;
skasigaction(SIGPIPE, &old, 0) ;
- dir_close(dir) ;
- return e ? (errno = e, -1) : (int)i ;
+ errno = e ;
}
+ return r ;
}
diff --git a/src/libs6/ftrigw_notifyb_nosig.c b/src/libs6/ftrigw_notifyb_nosig.c
new file mode 100644
index 0000000..0d7b565
--- /dev/null
+++ b/src/libs6/ftrigw_notifyb_nosig.c
@@ -0,0 +1,62 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <errno.h>
+#include <skalibs/direntry.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/djbunix.h>
+#include "ftrig1.h"
+#include <s6/ftrigw.h>
+
+int ftrigw_notifyb_nosig (char const *path, char const *s, unsigned int len)
+{
+ unsigned int i = 0 ;
+ DIR *dir = opendir(path) ;
+ if (!dir) return -1 ;
+ {
+ unsigned int pathlen = str_len(path) ;
+ char tmp[pathlen + FTRIG1_PREFIXLEN + 45] ;
+ byte_copy(tmp, pathlen, path) ;
+ tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 44] = 0 ;
+ for (;;)
+ {
+ direntry *d ;
+ int fd ;
+ errno = 0 ;
+ d = readdir(dir) ;
+ if (!d) break ;
+ if (str_diffn(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ;
+ if (str_len(d->d_name) != FTRIG1_PREFIXLEN + 43) continue ;
+ byte_copy(tmp + pathlen + 1, FTRIG1_PREFIXLEN + 43, d->d_name) ;
+ fd = open_write(tmp) ;
+ if (fd == -1)
+ {
+ if (errno == ENXIO) unlink(tmp) ;
+ }
+ else
+ {
+ register int r = fd_write(fd, s, len) ;
+ if ((r < 0) || (unsigned int)r < len)
+ {
+ if (errno == EPIPE) unlink(tmp) ;
+ /* what to do if EGAIN ? full fifo -> fix the reader !
+ There's a race condition in extreme cases though ;
+ but it's still better to be nonblocking - the writer
+ shouldn't get in trouble because of a bad reader. */
+ fd_close(fd) ;
+ }
+ else
+ {
+ fd_close(fd) ;
+ i++ ;
+ }
+ }
+ }
+ }
+ {
+ int e = errno ;
+ dir_close(dir) ;
+ return e ? (errno = e, -1) : (int)i ;
+ }
+}
diff --git a/src/libs6/s6_fdholder_delete.c b/src/libs6/s6_fdholder_delete.c
new file mode 100644
index 0000000..0432421
--- /dev/null
+++ b/src/libs6/s6_fdholder_delete.c
@@ -0,0 +1,21 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_delete (s6_fdholder_t *a, char const *id, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ if (!s6_fdholder_delete_async(a, id)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ return m.s[0] ? (errno = m.s[0], 0) : 1 ;
+}
diff --git a/src/libs6/s6_fdholder_delete_async.c b/src/libs6/s6_fdholder_delete_async.c
new file mode 100644
index 0000000..6452efa
--- /dev/null
+++ b/src/libs6/s6_fdholder_delete_async.c
@@ -0,0 +1,18 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_delete_async (s6_fdholder_t *a, char const *id)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[2] = "D" ;
+ siovec_t v[2] = { { .s = pack, .len = 2 }, { .s = (char *)id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = 0, .nfds = 0 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = (unsigned char)idlen ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_getdump.c b/src/libs6/s6_fdholder_getdump.c
new file mode 100644
index 0000000..3fce3a7
--- /dev/null
+++ b/src/libs6/s6_fdholder_getdump.c
@@ -0,0 +1,73 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/error.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_getdump (s6_fdholder_t *a, genalloc *g, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m = { .s = "?", .len = 1, .fds = 0, .nfds = 0 } ;
+ uint32 ntot, n ;
+ unsigned int oldlen = genalloc_len(s6_fdholder_fd_t, g) ;
+ unsigned int i = 0 ;
+ int ok ;
+ if (!unixmessage_put(&a->connection.out, &m)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (!m.len || m.nfds) return (errno = EPROTO, 0) ;
+ if (m.s[0]) return (errno = m.s[0], 0) ;
+ if (m.len != 9) return (errno = EPROTO, 0) ;
+ uint32_unpack_big(m.s + 1, &n) ;
+ uint32_unpack_big(m.s + 5, &ntot) ;
+ if (!ntot) return 1 ;
+ if (n != 1 + (ntot-1) / UNIXMESSAGE_MAXFDS) return (errno = EPROTO, 0) ;
+ ok = genalloc_readyplus(s6_fdholder_fd_t, g, ntot) ;
+
+ for (; i < n ; i++)
+ {
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) goto err ;
+ if (genalloc_len(s6_fdholder_fd_t, g) + m.nfds > ntot) goto droperr ;
+ if (ok)
+ {
+ s6_fdholder_fd_t *tab = genalloc_s(s6_fdholder_fd_t, g) + genalloc_len(s6_fdholder_fd_t, g) ;
+ unsigned int i = 0 ;
+ for (; i < m.nfds ; i++)
+ {
+ unsigned char thislen ;
+ if (m.len < TAIN_PACK + 3) goto droperr ;
+ tain_unpack(m.s, &tab[i].limit) ;
+ m.s += TAIN_PACK ; m.len -= TAIN_PACK + 1 ;
+ thislen = *m.s++ ;
+ if (thislen > m.len - 1 || thislen > S6_FDHOLDER_ID_SIZE || m.s[thislen]) goto droperr ;
+ byte_copy(tab[i].id, thislen, m.s) ;
+ byte_zero(tab[i].id + thislen, S6_FDHOLDER_ID_SIZE + 1 - thislen) ;
+ m.s += (unsigned int)thislen + 1 ; m.len -= (unsigned int)thislen + 1 ;
+ tab[i].fd = m.fds[i] ;
+ }
+ genalloc_setlen(s6_fdholder_fd_t, g, genalloc_len(s6_fdholder_fd_t, g) + m.nfds) ;
+ }
+ else unixmessage_drop(&m) ;
+ }
+
+ if (!ok) return (errno = ENOMEM, 0) ;
+ return 1 ;
+
+ droperr:
+ unixmessage_drop(&m) ;
+ errno = EPROTO ;
+ err:
+ {
+ int e = errno ;
+ i = genalloc_len(s6_fdholder_fd_t, g) ;
+ while (i-- > oldlen) fd_close(genalloc_s(s6_fdholder_fd_t, g)[i].fd) ;
+ genalloc_setlen(s6_fdholder_fd_t, g, oldlen) ;
+ errno = e ;
+ }
+ return 0 ;
+}
diff --git a/src/libs6/s6_fdholder_list.c b/src/libs6/s6_fdholder_list.c
new file mode 100644
index 0000000..4f804aa
--- /dev/null
+++ b/src/libs6/s6_fdholder_list.c
@@ -0,0 +1,19 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list (s6_fdholder_t *a, stralloc *sa, tain_t const *deadline, tain_t *stamp)
+{
+ s6_fdholder_list_result_t res = { .sa = sa } ;
+ unixmessage_t m ;
+ if (!s6_fdholder_list_async(a)) return -1 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return -1 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return -1 ;
+ if (!s6_fdholder_list_cb(&m, &res)) return -1 ;
+ if (res.err) return (errno = res.err, -1) ;
+ return (int)res.n ;
+}
diff --git a/src/libs6/s6_fdholder_list_async.c b/src/libs6/s6_fdholder_list_async.c
new file mode 100644
index 0000000..fc62ff8
--- /dev/null
+++ b/src/libs6/s6_fdholder_list_async.c
@@ -0,0 +1,11 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list_async (s6_fdholder_t *a)
+{
+ unixmessage_t m = { .s = "L", .len = 1, .fds = 0, .nfds = 0 } ;
+ return unixmessage_put(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_list_cb.c b/src/libs6/s6_fdholder_list_cb.c
new file mode 100644
index 0000000..bfdee50
--- /dev/null
+++ b/src/libs6/s6_fdholder_list_cb.c
@@ -0,0 +1,31 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/error.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_list_cb (unixmessage_t const *m, void *p)
+{
+ uint32 n ;
+ register s6_fdholder_list_result_t *res = p ;
+ if (m->nfds) goto droperr ;
+ if (m->len < 5) goto err ;
+ if (m->s[0])
+ {
+ res->err = m->s[0] ;
+ return 1 ;
+ }
+ uint32_unpack_big(m->s + 1, &n) ;
+ if (!stralloc_catb(res->sa, m->s + 5, m->len - 5)) return 0 ;
+ res->n = n ;
+ res->err = 0 ;
+ return 1 ;
+
+ droperr:
+ unixmessage_drop(m) ;
+ err:
+ return (errno = EPROTO, 0) ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve.c b/src/libs6/s6_fdholder_retrieve.c
new file mode 100644
index 0000000..e2888a9
--- /dev/null
+++ b/src/libs6/s6_fdholder_retrieve.c
@@ -0,0 +1,18 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_maybe_delete (s6_fdholder_t *a, char const *id, int dodelete, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ s6_fdholder_retrieve_result_t res ;
+ if (!s6_fdholder_retrieve_maybe_delete_async(a, id, dodelete)) return -1 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return -1 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return -1 ;
+ if (!s6_fdholder_retrieve_cb(&m, &res)) return -1 ;
+ if (res.err) return (errno = res.err, -1) ;
+ return res.fd ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve_async.c b/src/libs6/s6_fdholder_retrieve_async.c
new file mode 100644
index 0000000..bc7077c
--- /dev/null
+++ b/src/libs6/s6_fdholder_retrieve_async.c
@@ -0,0 +1,20 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_maybe_delete_async (s6_fdholder_t *a, char const *id, int dodelete)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[3] = "R" ;
+ siovec_t v[2] = { { .s = pack, .len = 3 }, { .s = (char *)id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = 0, .nfds = 0 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = !!dodelete ;
+ pack[2] = (unsigned char)idlen ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_fdholder_retrieve_cb.c b/src/libs6/s6_fdholder_retrieve_cb.c
new file mode 100644
index 0000000..9197b22
--- /dev/null
+++ b/src/libs6/s6_fdholder_retrieve_cb.c
@@ -0,0 +1,26 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_retrieve_cb (unixmessage_t const *m, void *p)
+{
+ register s6_fdholder_retrieve_result_t *res = p ;
+ if (m->len != 1) goto err ;
+ if (m->s[0])
+ {
+ if (m->nfds) goto err ;
+ res->err = m->s[0] ;
+ return 1 ;
+ }
+ if (m->nfds != 1) goto err ;
+ res->fd = m->fds[0] ;
+ res->err = 0 ;
+ return 1 ;
+
+ err:
+ unixmessage_drop(m) ;
+ return (errno = EPROTO, 0) ;
+}
diff --git a/src/libs6/s6_fdholder_setdump.c b/src/libs6/s6_fdholder_setdump.c
new file mode 100644
index 0000000..e5825dc
--- /dev/null
+++ b/src/libs6/s6_fdholder_setdump.c
@@ -0,0 +1,74 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_setdump (s6_fdholder_t *a, s6_fdholder_fd_t const *list, unsigned int ntot, tain_t const *deadline, tain_t *stamp)
+{
+ uint32 trips ;
+ if (!ntot) return 1 ;
+ unsigned int i = 0 ;
+ for (; i < ntot ; i++)
+ {
+ unsigned int zpos = byte_chr(list[i].id, S6_FDHOLDER_ID_SIZE + 1, 0) ;
+ if (!zpos || zpos >= S6_FDHOLDER_ID_SIZE + 1) return (errno = EINVAL, 0) ;
+ }
+ {
+ char pack[5] = "!" ;
+ unixmessage_t m = { .s = pack, .len = 5, .fds = 0, .nfds = 0 } ;
+ uint32_pack_big(pack+1, ntot) ;
+ if (!unixmessage_put(&a->connection.out, &m)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (!m.len || m.nfds) { unixmessage_drop(&m) ; return (errno = EPROTO, 0) ; }
+ if (m.s[0]) return (errno = m.s[0], 0) ;
+ if (m.len != 5) return (errno = EPROTO, 0) ;
+ uint32_unpack_big(pack + 1, &trips) ;
+ if (trips != 1 + (ntot-1) / UNIXMESSAGE_MAXFDS) return (errno = EPROTO, 0) ;
+ }
+ for (i = 0 ; i < trips ; i++, ntot -= UNIXMESSAGE_MAXFDS)
+ {
+ {
+ unsigned int n = ntot > UNIXMESSAGE_MAXFDS ? UNIXMESSAGE_MAXFDS : ntot ;
+ unsigned int j = 0 ;
+ siovec_t v[1 + (n<<1)] ;
+ int fds[n] ;
+ unixmessage_v_t m = { .v = v, .vlen = 1 + (n<<1), .fds = fds, .nfds = n } ;
+ char pack[n * (TAIN_PACK+1)] ;
+ v[0].s = "." ; v[0].len = 1 ;
+ for (; j < n ; j++, list++, ntot--)
+ {
+ unsigned int len = str_len(list->id) ;
+ v[1 + (j<<1)].s = pack + j * (TAIN_PACK+1) ;
+ v[1 + (j<<1)].len = TAIN_PACK + 1 ;
+ tain_pack(pack + j * (TAIN_PACK+1), &list->limit) ;
+ pack[j * (TAIN_PACK+1) + TAIN_PACK] = (unsigned char)len + 1 ;
+ v[2 + (j<<1)].s = (char *)list->id ;
+ v[2 + (j<<1)].len = len ;
+ fds[j] = list->fd ;
+ }
+ if (!unixmessage_putv(&a->connection.out, &m)) return 0 ;
+ }
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ {
+ unixmessage_t m ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ if (!error_isagain(m.s[0]) && i < trips-1)
+ return errno = m.s[0] ? m.s[0] : EPROTO, 0 ;
+ if (i == trips - 1 && m.s[0])
+ return errno = error_isagain(m.s[0]) ? EPROTO : m.s[0], 0 ;
+ }
+ }
+ return 1 ;
+}
diff --git a/src/libs6/s6_fdholder_store.c b/src/libs6/s6_fdholder_store.c
new file mode 100644
index 0000000..4241d8d
--- /dev/null
+++ b/src/libs6/s6_fdholder_store.c
@@ -0,0 +1,21 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/tai.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_store (s6_fdholder_t *a, int fd, char const *id, tain_t const *limit, tain_t const *deadline, tain_t *stamp)
+{
+ unixmessage_t m ;
+ if (!s6_fdholder_store_async(a, fd, id, limit)) return 0 ;
+ if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ;
+ if (!unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) return 0 ;
+ if (m.len != 1 || m.nfds)
+ {
+ unixmessage_drop(&m) ;
+ return (errno = EPROTO, 0) ;
+ }
+ return m.s[0] ? (errno = m.s[0], 0) : 1 ;
+}
diff --git a/src/libs6/s6_fdholder_store_async.c b/src/libs6/s6_fdholder_store_async.c
new file mode 100644
index 0000000..dfaab05
--- /dev/null
+++ b/src/libs6/s6_fdholder_store_async.c
@@ -0,0 +1,20 @@
+ /* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unixmessage.h>
+#include <s6/s6-fdholder.h>
+
+int s6_fdholder_store_async (s6_fdholder_t *a, int fd, char const *id, tain_t const *limit)
+{
+ unsigned int idlen = str_len(id) ;
+ char pack[2 + TAIN_PACK] = "S" ;
+ siovec_t v[2] = { { .s = pack, .len = 2 + TAIN_PACK }, { .s = id, .len = idlen + 1 } } ;
+ unixmessage_v_t m = { .v = v, .vlen = 2, .fds = &fd, .nfds = 1 } ;
+ if (idlen > S6_FDHOLDER_ID_SIZE) return (errno = ENAMETOOLONG, 0) ;
+ pack[1] = (unsigned char)idlen ;
+ tain_pack(pack + 2, limit) ;
+ return unixmessage_putv(&a->connection.out, &m) ;
+}
diff --git a/src/libs6/s6_svc_main.c b/src/libs6/s6_svc_main.c
deleted file mode 100644
index ead74cd..0000000
--- a/src/libs6/s6_svc_main.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/bytestr.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr2.h>
-#include <s6/s6-supervise.h>
-
-#define DATASIZE 256
-
-int s6_svc_main (int argc, char const *const *argv, char const *optstring, char const *usage, char const *controldir)
-{
- char data[DATASIZE] ;
- unsigned int datalen = 0 ;
- register int r ;
- for (;;)
- {
- register int opt = subgetopt(argc, argv, optstring) ;
- if (opt == -1) break ;
- if (opt == '?') strerr_dieusage(100, usage) ;
- if (datalen >= DATASIZE) strerr_dief1x(100, "too many commands") ;
- data[datalen++] = opt ;
- }
- argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
- if (!argc) strerr_dieusage(100, usage) ;
-
- {
- unsigned int arglen = str_len(*argv) ;
- unsigned int cdirlen = str_len(controldir) ;
- char tmp[arglen + cdirlen + 10] ;
- byte_copy(tmp, arglen, *argv) ;
- tmp[arglen] = '/' ;
- byte_copy(tmp + arglen + 1, cdirlen, controldir) ;
- byte_copy(tmp + arglen + 1 + cdirlen, 9, "/control") ;
- r = s6_svc_write(tmp, data, datalen) ;
- }
- if (r < 0) strerr_diefu2sys(111, "control ", *argv) ;
- else if (!r) strerr_diefu3x(100, "control ", *argv, ": supervisor not listening") ;
- return 0 ;
-}
diff --git a/src/libs6/s6_svstatus_pack.c b/src/libs6/s6_svstatus_pack.c
index 2d5baf6..2b1f102 100644
--- a/src/libs6/s6_svstatus_pack.c
+++ b/src/libs6/s6_svstatus_pack.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/tai.h>
#include <s6/s6-supervise.h>
@@ -10,4 +11,5 @@ void s6_svstatus_pack (char *pack, s6_svstatus_t const *sv)
uint32_pack(pack + 12, (uint32)sv->pid) ;
pack[16] = sv->flagpaused | (sv->flagfinishing << 1) ;
pack[17] = sv->flagwant ? sv->flagwantup ? 'u' : 'd' : 0 ;
+ uint64_pack(pack + 18, (uint64)sv->wstat) ;
}
diff --git a/src/libs6/s6_svstatus_read.c b/src/libs6/s6_svstatus_read.c
index 32ec660..59a31a5 100644
--- a/src/libs6/s6_svstatus_read.c
+++ b/src/libs6/s6_svstatus_read.c
@@ -4,7 +4,7 @@
#include <skalibs/djbunix.h>
#include <s6/s6-supervise.h>
-int s6_svstatus_read (char const *dir, s6_svstatus_t_ref status)
+int s6_svstatus_read (char const *dir, s6_svstatus_t *status)
{
unsigned int n = str_len(dir) ;
char pack[S6_SVSTATUS_SIZE] ;
diff --git a/src/libs6/s6_svstatus_unpack.c b/src/libs6/s6_svstatus_unpack.c
index cce6989..3fbc205 100644
--- a/src/libs6/s6_svstatus_unpack.c
+++ b/src/libs6/s6_svstatus_unpack.c
@@ -1,15 +1,19 @@
/* ISC license. */
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/tai.h>
#include <s6/s6-supervise.h>
-void s6_svstatus_unpack (char const *pack, s6_svstatus_t_ref sv)
+void s6_svstatus_unpack (char const *pack, s6_svstatus_t *sv)
{
uint32 pid ;
+ uint64 wstat ;
tain_unpack(pack, &sv->stamp) ;
uint32_unpack(pack + 12, &pid) ;
- sv->pid = (int)pid ;
+ sv->pid = (unsigned int)pid ;
+ uint64_unpack(pack + 18, &wstat) ;
+ sv->wstat = (unsigned int)wstat ;
sv->flagpaused = pack[16] & 1 ;
sv->flagfinishing = (pack[16] >> 1) & 1 ;
switch (pack[17])