diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-01-19 16:11:24 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-01-19 16:11:24 +0000 |
commit | 701540827e27a4f07ac725db3ce361d3be0c106f (patch) | |
tree | 98c4b2fb8ba8f69ef791feebdcd61cd5bca34140 /src/libs6 | |
parent | 83853a80eb18238796154164f9ea776b0c167ab7 (diff) | |
download | s6-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/s6 | 14 | ||||
-rw-r--r-- | src/libs6/ftrigw_notifyb.c | 55 | ||||
-rw-r--r-- | src/libs6/ftrigw_notifyb_nosig.c | 62 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_delete.c | 21 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_delete_async.c | 18 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_getdump.c | 73 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_list.c | 19 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_list_async.c | 11 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_list_cb.c | 31 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_retrieve.c | 18 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_retrieve_async.c | 20 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_retrieve_cb.c | 26 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_setdump.c | 74 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_store.c | 21 | ||||
-rw-r--r-- | src/libs6/s6_fdholder_store_async.c | 20 | ||||
-rw-r--r-- | src/libs6/s6_svc_main.c | 39 | ||||
-rw-r--r-- | src/libs6/s6_svstatus_pack.c | 2 | ||||
-rw-r--r-- | src/libs6/s6_svstatus_read.c | 2 | ||||
-rw-r--r-- | src/libs6/s6_svstatus_unpack.c | 8 |
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]) |