summaryrefslogtreecommitdiff
path: root/src/libs6/ftrigr_checksa.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-06-14 04:09:00 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-06-14 04:09:00 +0000
commit0445f2a3590f67441602a05fe3924ab677c79ff0 (patch)
tree1a011697fbd92ca53468efe019c8c93c364ad6a8 /src/libs6/ftrigr_checksa.c
parentf287ac765101f21b530f1a9886e06976c165c922 (diff)
downloads6-0445f2a3590f67441602a05fe3924ab677c79ff0.tar.xz
Add ftrigr_checksa(), rewrite s6_svlisten_loop() around it
- Fixes the race condition hit by permanent failure, i.e. two ftrig events close to each other - Requires storing the sequence of events client-side, so an additional stralloc, bleh - The visible struct ftrigr_s changes, so a major bump is needed -> prepare for 2.6.0.0 - ftrigr_check() is now a trivial wrapper around ftrigr_checksa()
Diffstat (limited to 'src/libs6/ftrigr_checksa.c')
-rw-r--r--src/libs6/ftrigr_checksa.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/libs6/ftrigr_checksa.c b/src/libs6/ftrigr_checksa.c
new file mode 100644
index 0000000..6573182
--- /dev/null
+++ b/src/libs6/ftrigr_checksa.c
@@ -0,0 +1,45 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/gensetdyn.h>
+#include <s6/ftrigr.h>
+
+int ftrigr_checksa (ftrigr_t *a, uint16_t id, stralloc *sa)
+{
+ ftrigr1_t *p ;
+ if (!id--) return (errno = EINVAL, -1) ;
+ p = GENSETDYN_P(ftrigr1_t, &a->data, id) ;
+ if (!p) return (errno = EINVAL, -1) ;
+ switch (p->state)
+ {
+ case FR1STATE_WAITACKDATA :
+ {
+ if (!stralloc_catb(sa, p->what.s, p->what.len)) return -1 ;
+ stralloc_free(&p->what) ;
+ *p = ftrigr1_zero ;
+ gensetdyn_delete(&a->data, id) ;
+ return 1 ;
+ }
+ case FR1STATE_LISTENING :
+ {
+ if (!p->what.len) break ;
+ if (!stralloc_catb(sa, p->what.s, p->what.len)) return -1 ;
+ p->what.len = 0 ;
+ return 1 ;
+ }
+ case FR1STATE_WAITACK :
+ {
+ int e ;
+ if (!stralloc_catb(sa, p->what.s, p->what.len - 1)) return -1 ;
+ e = p->what.s[p->what.len - 1] ;
+ stralloc_free(&p->what) ;
+ *p = ftrigr1_zero ;
+ gensetdyn_delete(&a->data, id) ;
+ errno = e ;
+ return -1 ;
+ }
+ default: return (errno = EINVAL, -1) ;
+ }
+ return 0 ;
+}