aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-03-18 12:23:41 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-03-18 12:23:41 +0000
commite296c0405b813f4d19ae7efaf6eb1b4117b1e333 (patch)
treef3aa5282f817b68471d93e9f7be2b40500e52c68
parent9e63925306dd86243c13becd93ab6d211c9b5010 (diff)
parent6a00734ff583507e906ded535eb6ac6a01a2ecec (diff)
downloads6-e296c0405b813f4d19ae7efaf6eb1b4117b1e333.tar.gz
Merge branch '2.15.0.0'
-rw-r--r--CONTRIBUTING28
-rw-r--r--INSTALL2
-rw-r--r--Makefile3
-rw-r--r--NEWS13
-rw-r--r--doc/index.html6
-rw-r--r--doc/libs6/ftrigr.html132
-rw-r--r--doc/libs6/s6-ftrigrd.html37
-rw-r--r--doc/s6-setsid.html3
-rw-r--r--doc/s6-svscan.html14
-rw-r--r--doc/upgrade.html17
-rw-r--r--package/deps-build4
-rw-r--r--package/deps.mak40
-rw-r--r--package/info2
-rw-r--r--package/targets.mak4
-rw-r--r--src/daemontools-extras/s6-setsid.c106
-rw-r--r--src/include/s6/ftrigr.h103
-rwxr-xr-xsrc/libs6/deps-exe/s6-ftrigrd3
-rw-r--r--src/libs6/deps-lib/s67
-rw-r--r--src/libs6/ftrig1.h23
-rw-r--r--src/libs6/ftrig1_free.c25
-rw-r--r--src/libs6/ftrig1_make.c45
-rw-r--r--src/libs6/ftrigr-internal.h20
-rw-r--r--src/libs6/ftrigr1_zero.c5
-rw-r--r--src/libs6/ftrigr_ack.c19
-rw-r--r--src/libs6/ftrigr_check.c20
-rw-r--r--src/libs6/ftrigr_checksa.c45
-rw-r--r--src/libs6/ftrigr_end.c22
-rw-r--r--src/libs6/ftrigr_peek.c25
-rw-r--r--src/libs6/ftrigr_release.c18
-rw-r--r--src/libs6/ftrigr_start.c10
-rw-r--r--src/libs6/ftrigr_startf.c11
-rw-r--r--src/libs6/ftrigr_subscribe.c51
-rw-r--r--src/libs6/ftrigr_unsubscribe.c37
-rw-r--r--src/libs6/ftrigr_update.c20
-rw-r--r--src/libs6/ftrigr_updateb.c68
-rw-r--r--src/libs6/ftrigr_wait_and.c28
-rw-r--r--src/libs6/ftrigr_wait_or.c24
-rw-r--r--src/libs6/ftrigr_zero.c5
-rw-r--r--src/libs6/ftrigw_clean.c20
-rw-r--r--src/libs6/ftrigw_notifyb_nosig.c11
-rw-r--r--src/libs6/s6-ftrigrd.c312
-rw-r--r--src/libs6/s6_compat_el_semicolon.c34
-rw-r--r--src/libs6/s6_supervise_link_names.c16
-rw-r--r--src/libs6/s6_supervise_unlink_names.c20
-rw-r--r--src/pipe-tools/s6-ftrig-listen.c100
-rw-r--r--src/pipe-tools/s6-ftrig-listen1.c75
-rw-r--r--src/pipe-tools/s6-ftrig-wait.c64
-rw-r--r--src/supervision/s6-notifyoncheck.c210
-rw-r--r--src/supervision/s6-svlisten.c10
-rw-r--r--src/supervision/s6-svlisten.h6
-rw-r--r--src/supervision/s6-svlisten1.c10
-rw-r--r--src/supervision/s6-svscan.c154
-rw-r--r--src/supervision/s6-svwait.c5
-rw-r--r--src/supervision/s6_svlisten_loop.c34
54 files changed, 993 insertions, 1133 deletions
diff --git a/CONTRIBUTING b/CONTRIBUTING
index 6279422..3173998 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -1,5 +1,31 @@
- Please add a Signed-Off-By: line at the end of your commit,
+- License
+
+ Your contributions to this project are governed by the ISC license.
+ Please review the COPYING file for this project.
+
+
+- Contribution terms
+
+ When making a contribution you agree to the following terms:
+
+ * I, the contributor, am the copyright owner of these changes
+ * I submit these changes according to the project's license
+with no additionam requirements
+ * I understand these changes in full and will be able to respond
+to review comments.
+
+ Please add a Signed-Off-By: line at the end of your commits,
which certifies that you have the right and authority to pass
it on as an open-source patch, as explicited in the Developer's
Certificate of Origin available in this project's DCO file,
or at https://developercertificate.org/
+
+
+- AI policy
+
+ This project does not accept contributions generated by LLMs
+(large language models), sometimes also referred to as "AI".
+ This policy is not open to discussion. Any content submitted that is
+clearly labelled as LLM-generated will be immediately closed, and any
+attempt to bypass this policy in any way will result in a ban from the
+project.
diff --git a/INSTALL b/INSTALL
index dd6bdaf..2cb405e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Build Instructions
- A POSIX-compliant C development environment
- GNU make version 3.81 or later
- - skalibs version 2.14.5.1 or later: https://skarnet.org/software/skalibs/
+ - skalibs version 2.14.6.0 or later: https://skarnet.org/software/skalibs/
- Recommended: execline version 2.9.8.1 or later: https://skarnet.org/software/execline/
(You can disable this requirement at configure time, but will
lose some functionality.)
diff --git a/Makefile b/Makefile
index 62bc1a1..f519a87 100644
--- a/Makefile
+++ b/Makefile
@@ -190,6 +190,9 @@ lib%.a.xyzzy:
lib%.so.xyzzy:
exec $(CC) -o $@ $(CFLAGS_ALL) $(CFLAGS_SHARED) $(LDFLAGS_ALL) $(LDFLAGS_SHARED) -Wl,-soname,$(patsubst lib%.so.xyzzy,lib%.so.$(version_M),$@) -Wl,-rpath=$(dynlibdir) $^ $(EXTRA_LIBS) $(LDLIBS)
+-lskarnet:
+ $(error Unable to link against skalibs. Check that you are using the correct --with-lib or --with-dynlib options; see ./configure --help)
+
.PHONY: it all clean distclean tests check tgz strip install install-dynlib install-bin install-lib install-include install-pkgconfig
.DELETE_ON_ERROR:
diff --git a/NEWS b/NEWS
index 061674f..a2f6592 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,18 @@
Changelog for s6.
+In 2.15.0.0
+-----------
+
+ - Bugfixes.
+ - s6-svscan's scandir argument is now mandatory.
+ - s6-setsid now autodetects its controlling terminal by default.
+ - Complete ftrigr refactor. This doesn't impact CLI programs,
+except the next point.
+ - s6-ftrig-wait and s6-ftrig-listen1 now print the whole
+sequence of events (followed by a newline) to stdout, rather than
+just the triggering event.
+
+
In 2.14.0.1
-----------
diff --git a/doc/index.html b/doc/index.html
index 1baa6ab..925661e 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -83,7 +83,7 @@ with s6</a> </li>
<li> A POSIX-compliant system with a standard C development environment </li>
<li> GNU make, version 3.81 or later </li>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version
-2.14.5.1 or later. It's a build-time requirement. It's also a run-time
+2.14.6.0 or later. It's a build-time requirement. It's also a run-time
requirement if you link against the shared version of the skalibs
library. </li>
<li> (Optional, but really recommended for full functionality):
@@ -115,8 +115,8 @@ want nsswitch-like functionality:
<h3> Download </h3>
<ul>
- <li> The current released version of s6 is <a href="s6-2.14.0.1.tar.gz">2.14.0.1</a>.
-You can access its checksum <a href="s6-2.14.0.1.tar.gz.sha256">here</a>. </li>
+ <li> The current released version of s6 is <a href="s6-2.15.0.0.tar.gz">2.15.0.0</a>.
+You can access its checksum <a href="s6-2.15.0.0.tar.gz.sha256">here</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6/">s6
git repository</a>:
diff --git a/doc/libs6/ftrigr.html b/doc/libs6/ftrigr.html
index 052d7bf..a8cf98b 100644
--- a/doc/libs6/ftrigr.html
+++ b/doc/libs6/ftrigr.html
@@ -43,11 +43,6 @@ and to <em>always</em> use <tt>wait_nohang()</tt> to reap children,
simply ignoring pids you don't know.
</p>
-<p>
- If your application has trouble handling unknown
-children, consider using an ftrigrd service. (And fix your application!)
-</p>
-
<h3> A programming example </h3>
<p>
@@ -61,8 +56,8 @@ for instance, illustrate how to use the ftrigr library.
</a>
<ul>
- <li> Synchronous functions take a <tt>tain_t const *</tt>
-(<em>deadline</em>) parameter and a <tt>tain_t *</tt> (<em>stamp</em>)
+ <li> Synchronous functions take a <tt>tain const *</tt>
+(<em>deadline</em>) parameter and a <tt>tain *</tt> (<em>stamp</em>)
parameter. Those are pointers to tain_t structures containing absolute times;
the former represents a deadline (in most cases, this time will be in the
future) and the latter must be an accurate enough timestamp. These
@@ -100,28 +95,25 @@ control on. </li>
<h3> Starting and ending a session </h3>
<pre>
-ftrigr_t a = FTRIGR_ZERO ;
+ftrigr a = FTRIGR_ZERO ;
tain_t deadline, stamp ;
tain_now(&amp;stamp) ;
tain_addsec(&amp;deadline, &amp;stamp, 2)
-// char const *path = FTRIGR_IPCPATH ;
-// ftrigr_start(&amp;a, path, &amp;deadline, &amp;stamp) ;
ftrigr_startf(&amp;a, &amp;deadline, &amp;stamp) ;
</pre>
<p>
-<tt>ftrigr_start</tt> starts a session with an ftrigrd service listening on
-<em>path</em>. <br />
<tt>ftrigr_startf</tt> starts a session with an ftrigrd process as a child
(which is the simplest usage). <br />
-<tt>a</tt> is an ftrigr_t structure that must be declared in the stack and
-initialized to FTRIGR_ZERO.
+<tt>a</tt> is an ftrigr structure that can be declared in the stack and
+must be initialized to FTRIGR_ZERO.
<tt>stamp</tt> must be an accurate enough timestamp. <br />
If the session initialization fails, the function returns 0 and errno is set;
else the function returns 1.
</p>
+
<p>
If the absolute time <tt>deadline</tt> is reached and the function
has not returned yet, it immediately returns 0 with errno set to ETIMEDOUT.
@@ -135,8 +127,8 @@ problem with the underlying processes.
<p>
You can have more than one session open in parallel, by declaring
-several distinct <tt>ftrigr_t</tt> structures and calling
-<tt>ftrigr_startf</tt> (or <tt>ftrigr_start</tt>) more than once.
+several distinct <tt>ftrigr</tt> structures and calling
+<tt>ftrigr_startf</tt> more than once.
However, this is useless, since one single session can handle
virtually as many concurrent fifodirs as your application needs.
</p>
@@ -156,8 +148,10 @@ ftrigr_end(&amp;a) ;
char const *path = "/var/lib/myservice/fifodir" ;
char const *re = "a.*b|c*d" ;
uint32_t options = 0 ;
+uint32_t timeout = 60000 ;
+uint32_t id ;
-uint16_t id = ftrigr_subscribe (&amp;a, path, re, options, &amp;deadline, &amp;stamp) ;
+int r = ftrigr_subscribe(&amp;a, &amp;id, options, timeout, path, re, options, &amp;deadline, &amp;stamp) ;
</pre>
<p>
@@ -165,7 +159,9 @@ uint16_t id = ftrigr_subscribe (&amp;a, path, re, options, &amp;deadline, &amp;s
<a href="s6-ftrigrd.html">s6-ftrigrd daemon</a>, related to the open
session represented by the <tt>a</tt> structure, to subscribe to the
<tt>path</tt> fifodir, and to notify the application when it receives
-a series of events that matches the <tt>re</tt> regexp.
+a series of events that matches the <tt>re</tt> regexp. </p>
+
+<p>
<tt>options</tt> can be 0 or FTRIGR_REPEAT. If it is 0, the daemon will
automatically unsubscribe from <tt>path</tt> once <tt>re</tt> has been
matched by a series of events. If it is FTRIGR_REPEAT, it will remain
@@ -173,8 +169,16 @@ subscribed until told otherwise.
</p>
<p>
- <tt>ftrigr_subscribe()</tt> returns 0 and sets errno in case of failure, or
-a nonzero 16-bit number identifying the subscription in case of success.
+ If <tt>timeout</tt> is nonzero, it represents a number of milliseconds;
+after this delay, the daemon will automatically unsubscribe from
+<tt>path</tt> and report an ETIMEDOUT error to the client. It is not
+advised to use a nonzero timeout along with the FTRIGR_REPEAT option.
+</p>
+
+<p>
+ If it fails, <tt>ftrigr_subscribe()</tt> returns 0 and sets errno. If
+it succeeds, it returns 1 and stores a number identifying the subscription
+into <tt>id</tt>.
</p>
<p>
@@ -188,26 +192,29 @@ and events can be sent without the risk of a race condition.
<h3> Synchronously waiting for events </h3>
<pre>
-uint16_t list[1] ;
+uint32_t list[1] = { id } ;
unsigned int n = 1 ;
-char trigger ;
-list[0] = id ;
+ftrigr_string fs ;
// r = ftrigr_wait_and(&amp;a, list, n, &amp;deadline, &amp;stamp) ;
-r = ftrigr_wait_or(&amp;a, list, n, &amp;deadline, &amp;stamp, &amp;trigger) ;
+r = ftrigr_wait_or(&amp;a, list, n, &amp;deadline, &amp;stamp, &amp;fs) ;
</pre>
<p>
<tt>ftrigr_wait_and()</tt> waits for <em>all</em> the <tt>n</tt> fifodirs
whose ids are listed in <tt>list</tt> to receive an event. It returns -1
-in case of error or timeout, or a non-negative integer in case of success. <br />
+in case of error or timeout, or a non-negative integer in case of success.
+</p>
+
+<p>
<tt>ftrigr_wait_or()</tt> waits for <em>one</em> of the <tt>n</tt> fifodirs
whose ids are listed in <tt>list</tt> to receive an event. It returns -1
in case of error or timeout; if it succeeds, the return value is the
position in <tt>list</tt>, starting at 0, of the identifier that received
-an event; and <tt>trigger</tt> is set to the character that triggered that
-event, i.e. the last character of a sequence that matched the regular
-expression <tt>re</tt> used in the subscription.
+an event; and <tt>fs</tt> is the list of events that were received
+since the subscription and matched the <tt>re</tt> regular expression.
+<tt>fs.s</tt> is a <tt>char *</tt> pointing to the (not null-terminated)
+string of events, and <tt>fs.len</tt> is its length.
</p>
<h3> Asynchronously waiting for events </h3>
@@ -218,7 +225,7 @@ of usage examples.) </em>
</p>
<pre>
-int ftrigr_fd (ftrigr_t const *a)
+int ftrigr_fd (ftrigr const *a)
</pre>
<p>
@@ -227,30 +234,19 @@ int ftrigr_fd (ftrigr_t const *a)
</p>
<pre>
-int ftrigr_updateb (ftrigr_t *a)
+int ftrigr_update (ftrigr *a)
</pre>
<p>
Call this function whenever the fd checks readability: it will
update <em>a</em>'s internal structures with information from the
-<a href="s6-ftrigrd.html">s6-ftrigrd</a> daemon. It returns -1 if an error
-occurs; in case of success, it returns the number of identifiers for
-which something happened.
-</p>
-
-<p>
- When <tt>ftrigr_updateb</tt> returns,
-<tt>genalloc_s(uint16_t, &amp;a-&gt;list)</tt> points to an array of
-<tt>genalloc_len(uint16_t, &amp;a-&gt;list)</tt> 16-bit unsigned
-integers. Those integers are ids waiting to be passed to
-<tt>ftrigr_check</tt> or <tt>ftrigr_checksa</tt>.
-The number of ids already acknowledged is stored in
-<tt>a-&gt;head</tt>, so the first unacknowledged id is
-<tt>genalloc_s(uint16_t, &amp;a-&gt;list)[a-&gt;head]</tt>.
+<a href="s6-ftrigrd.html">s6-ftrigrd</a> daemon. It returns -1 (and sets
+errno) if an error occurs, 0 if there were no events, and 1 if events
+were received.
</p>
<pre>
-int ftrigr_check (ftrigr_t *a, uint16_t id, char *what)
+int ftrigr_peek (ftrigr *a, uint32_t id, ftrigr_string *fs)
</pre>
<p>
@@ -263,49 +259,39 @@ call to <tt>ftrigr_updateb()</tt>.
number may have been transmitted from
<a href="s6-ftrigrd.html">s6-ftrigrd</a>. </li>
<li> If no notification happened yet, returns 0. </li>
- <li> If something happened, writes the character that triggered the
-latest notification into <em>what</em> and returns the number of
-times that an event happened to this identifier since the last
-call to <tt>ftrigr_check()</tt>. </li>
+ <li> If something happened, returns 1, and <tt>fs</tt> contains
+the string of events that were received since the subscription or
+since the last call to <tt>ftrigr_ack</tt> (see below).
+<tt>fs-&gt;s</tt> is a pointer to the non-null-terminated string,
+and <tt>fs-&gt;len</tt> is its length. </li>
</ul>
<pre>
-int ftrigr_checksa (ftrigr_t *a, uint16_t id, stralloc *what)
+void ftrigr_ack (ftrigr *a, uint32_t id)
</pre>
<p>
- Checks whether an event happened to <em>id</em>. Use after a
-call to <tt>ftrigr_update()</tt>, as an alternative to <tt>ftrigr_check()</tt>.
+ Resets the stored string of events. The next invocation of
+<tt>ftrigr_peek()</tt> will only show new events, if any.
</p>
-<ul>
- <li> If an error occurred, returns -1 and sets errno. The error
-number may have been transmitted from
-<a href="s6-ftrigrd.html">s6-ftrigrd</a>. </li>
- <li> If no notification happened yet, returns 0. </li>
- <li> If something happened, appends one character to the end of the <em>what</em>
-<a href="//skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>
-for every time a notification was triggered since the last call
-to <tt>ftrigr_check()</tt>. Each character is the one that triggered
-a notification. The function then returns 1. </li>
-</ul>
-
<pre>
-void ftrigr_ack (ftrigr_t *a, size_t n)
+int ftrigr_release (ftrigr *a, uint32_t id)
</pre>
<p>
- Acknowledges reading <em>n</em> ids from the id list updated by
-<tt>ftrigr_updateb</tt>.
+ Frees the resources used by subscription <tt>id</tt>. Use this
+after getting an event from a subscription done without the
+FTRIGR_REPEAT flag and reading its results, if you want to
+keep the session open and perform more subscriptions.
</p>
-<pre>
-int ftrigr_update (ftrigr_t *a)
-</pre>
-
<p>
- Acknowledges all the pending ids (i.e. clears the stored id list)
-then calls <tt>ftrigr_updateb()</tt>.
+ If subscription <tt>id</tt> was given the FTRIGR_REPEAT flag,
+use <tt>ftrigr_unsubscribe()</tt> instead. If you're not going
+to perform other subscriptions, <tt>ftrigr_end()</tt> will
+free all the resources without you needing to call
+<tt>ftrigr_release()</tt> first.
</p>
</body>
diff --git a/doc/libs6/s6-ftrigrd.html b/doc/libs6/s6-ftrigrd.html
index 7325c72..672b660 100644
--- a/doc/libs6/s6-ftrigrd.html
+++ b/doc/libs6/s6-ftrigrd.html
@@ -17,7 +17,7 @@
<a href="//skarnet.org/">skarnet.org</a>
</p>
-<h1> The s6-ftrigrd program </h1>
+<h1> The s6-ftrigrd internal program </h1>
<p>
s6-ftrigrd is a helper program that manages a set of subscriptions to fifodirs as well
@@ -29,24 +29,17 @@ events happen.
<h2> Interface </h2>
<p>
- s6-ftrigrd is not meant to be called directly.
-</p>
-
-<ul>
- <li> If the client program uses <tt>ftrigr_startf()</tt>, it spawns an instance of
+ s6-ftrigrd is not meant to be called directly. When the client calls
+<tt>ftrigr_start()</tt> or <tt>ftrigr_startf</tt>, it spawns an instance of
s6-ftrigrd as a child. s6-ftrigrd's stdin is a pipe reading from the client; its
stdout is a pipe writing to the client; its stderr is the same as the client's; and
there's an additional pipe from s6-ftrigrd to the client, used for asynchronous
-notifications. </li>
- <li> If the client program uses <tt>ftrigr_start()</tt>, then it tries to connect
-to a Unix domain socket. An ftrigrd <a href="../localservice.html">local service</a> should be listening to that
-socket, i.e. a Unix domain super-server such as
-<a href="s6-ipcserver.html">s6-ipcserver</a>
-spawning an s6-ftrigrd program on every connection. Then an s6-ftrigrd instance is created
-for the client. </li>
- <li> When the client uses <tt>ftrigr_end()</tt>, or closes s6-ftrigrd's stdin in
-any way, s6-ftrigrd exits 0. </li>
-</ul>
+notifications.
+</p>
+
+<p> When the client uses <tt>ftrigr_end()</tt>, or closes s6-ftrigrd's stdin in
+any way, s6-ftrigrd exits 0.
+</p>
<p>
s6-ftrigrd handles the grunt work of creating fifos in a
@@ -60,7 +53,7 @@ the client.
<p>
The connection management between the client and s6-ftrigrd is entirely done
-by the <em>textclient</em> library from skalibs.
+by the <em>sassclient</em> library from skalibs.
</p>
<p>
@@ -71,9 +64,13 @@ to read them. To avoid uncontrolled growth, make sure your client calls
</p>
<p>
- An s6-ftrigrd instance can only handle up to FTRIGRD_MAX (defined in <tt>s6/ftrigr.h</tt>)
-subscriptions at once. By default, this number is 1000, which is more than enough for
-any reasonable system.
+ The number of concurrent subscriptions that an s6-ftrigrd instance can handle is
+only limited by RAM and open file descriptors. It is likely that the latter is the
+bottleneck: s6-ftrigrd uses two file descriptors per fifodir. With a default
+limit of 1024 open file descriptors per process, it means that s6-ftrigrd can
+handle around 500 concurrent fifodirs, which is reasonable for most systems, but
+make sure to increase the open files resource limit before starting an ftrigr
+session if you need more.
</p>
</body>
diff --git a/doc/s6-setsid.html b/doc/s6-setsid.html
index 2a9e3d3..af10a57 100644
--- a/doc/s6-setsid.html
+++ b/doc/s6-setsid.html
@@ -69,7 +69,8 @@ message; it will exec into <em>prog</em> even if it cannot perform the
operations. </li>
<li> <tt>-d&nbsp;<em>ctty</em></tt>&nbsp;: assume file descriptor
number <em>ctty</em> is
-the controlling terminal for the current session. Default is 0.
+the controlling terminal for the current session. (By default, the
+value is obtained from <tt>/dev/tty</tt>.)
This is only useful when used with the <tt>-f</tt> or
<tt>-g</tt> options. </li>
</ul>
diff --git a/doc/s6-svscan.html b/doc/s6-svscan.html
index 5570d99..306d5b1 100644
--- a/doc/s6-svscan.html
+++ b/doc/s6-svscan.html
@@ -27,12 +27,12 @@ the root or a branch of a <em>supervision tree</em>.
<h2> Interface </h2>
<pre>
- s6-svscan [ -d <em>notif</em> ] [ -X <em>consoleholder</em> ] [ -c max | -C services_max ] [ -L name_max ] [ -t <em>rescan</em> ] [ <em>scandir</em> ]
+ s6-svscan [ -d <em>notif</em> ] [ -X <em>consoleholder</em> ] [ -C services_max ] [ -L name_max ] [ -t <em>rescan</em> ] <em>scandir</em>
</pre>
<ul>
- <li> If given a <em>scandir</em> argument, s6-svscan switches to it. Else it uses
-its current directory as the <a href="scandir.html">scan directory</a>. </li>
+ <li> s6-svscan changes its working directory to <em>scandir</em>, which will serve
+as its <a href="scandir.html">scan directory</a>. </li>
<li> It exits 100 if another s6-svscan process is already monitoring this
<a href="scandir.html">scan directory</a>. </li>
<li> If the <tt>./.s6-svscan</tt> control directory does not exist,
@@ -89,14 +89,6 @@ up to 200 bytes per service, also depending on the value of <em>name_max</em>. <
descriptors to function properly and does not exceed its stack limit. The default
of 1000 is safe and provides enough room for every reasonable system. </li>
- <li> <tt>-c&nbsp;<em>max</em></tt>&nbsp;: a deprecated way of setting <em>services_max</em>.
-If the <tt>-c</tt> option is given, the value of <em>max</em> is doubled, and the result
-is used as <em>services_max</em>. The reason for the change is that previous versions
-of s6-svscan handled services+loggers as a single entity; but this version of s6-svscan
-handles services and loggers in the same way, so with the default values it's now possible
-to handle e.g. 600 unlogged services, whereas previously you were limited to 500 because
-s6-svscan was reserving room for the loggers. </li>
-
<li> <tt>-L&nbsp;<em>name_max</em></tt>&nbsp;: the maximum length of a name in the
scan directory. Names longer than <em>name_max</em> won't be taken into account.
Default is 251. It cannot be set lower than 11 or higher than 1019. </li>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index ce8d682..8ae86f5 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,23 @@
<h1> What has changed in s6 </h1>
+<h2> in 2.15.0.0 </h2>
+
+<ul>
+ <li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
+dependency bumped to 2.14.6.0 </li>
+ <li> Large changes around the <a href="libs6/ftrigr.html">ftrigr library</a>:
+ <ul>
+ <li> <a href="s6-ftrigrd.html">s6-ftrigrd</a> is now an
+internal program </li>
+ <li> Local ftrigrd services are not supported anymore,
+s6-ftrigrd now always runs as a child of the client </li>
+ <li> The API of the <a href="libs6/ftrigr.html">ftrigr library</a>
+is somewhat different. </li>.
+ </ul> </li>
+</ul>
+
+
<h2> in 2.14.0.1 </h2>
<ul>
diff --git a/package/deps-build b/package/deps-build
index 17924a1..f285248 100644
--- a/package/deps-build
+++ b/package/deps-build
@@ -1,3 +1,3 @@
-true true /package/prog/skalibs 2.14.5.0 libskarnet
+true true /package/prog/skalibs 2.14.6.0 libskarnet
$usensss false /package/admin/nsss 0.2.1.1 libnsss
-$useexecline $useexecline /package/admin/execline 2.9.8.0 libexecline
+$useexecline $useexecline /package/admin/execline 2.9.8.1 libexecline
diff --git a/package/deps.mak b/package/deps.mak
index e01e3b4..b6bae62 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -3,7 +3,6 @@
#
src/include/s6/compat.h: src/include/s6/config.h
-src/include/s6/ftrigr.h: src/include/s6/config.h
src/include/s6/s6.h: src/include/s6/accessrules.h src/include/s6/auto.h src/include/s6/compat.h src/include/s6/ftrigr.h src/include/s6/ftrigw.h src/include/s6/supervise.h
src/supervision/s6-svlisten.h: src/include/s6/ftrigr.h
src/alias/s6-alias-chpst.o src/alias/s6-alias-chpst.lo: src/alias/s6-alias-chpst.c src/include/s6/config.h
@@ -50,28 +49,23 @@ src/instance/s6-instance-delete.o src/instance/s6-instance-delete.lo: src/instan
src/instance/s6-instance-list.o src/instance/s6-instance-list.lo: src/instance/s6-instance-list.c src/include/s6/supervise.h
src/instance/s6-instance-maker.o src/instance/s6-instance-maker.lo: src/instance/s6-instance-maker.c src/include/s6/auto.h src/include/s6/config.h
src/instance/s6-instance-status.o src/instance/s6-instance-status.lo: src/instance/s6-instance-status.c src/include/s6/config.h
-src/libs6/ftrig1_free.o src/libs6/ftrig1_free.lo: src/libs6/ftrig1_free.c src/libs6/ftrig1.h
-src/libs6/ftrig1_make.o src/libs6/ftrig1_make.lo: src/libs6/ftrig1_make.c src/libs6/ftrig1.h
-src/libs6/ftrigr1_zero.o src/libs6/ftrigr1_zero.lo: src/libs6/ftrigr1_zero.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_ack.o src/libs6/ftrigr_ack.lo: src/libs6/ftrigr_ack.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_check.o src/libs6/ftrigr_check.lo: src/libs6/ftrigr_check.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_checksa.o src/libs6/ftrigr_checksa.lo: src/libs6/ftrigr_checksa.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_end.o src/libs6/ftrigr_end.lo: src/libs6/ftrigr_end.c src/include/s6/ftrigr.h
+src/libs6/ftrigr_ack.o src/libs6/ftrigr_ack.lo: src/libs6/ftrigr_ack.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_end.o src/libs6/ftrigr_end.lo: src/libs6/ftrigr_end.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_peek.o src/libs6/ftrigr_peek.lo: src/libs6/ftrigr_peek.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_release.o src/libs6/ftrigr_release.lo: src/libs6/ftrigr_release.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
src/libs6/ftrigr_start.o src/libs6/ftrigr_start.lo: src/libs6/ftrigr_start.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_startf.o src/libs6/ftrigr_startf.lo: src/libs6/ftrigr_startf.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_subscribe.o src/libs6/ftrigr_subscribe.lo: src/libs6/ftrigr_subscribe.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_unsubscribe.o src/libs6/ftrigr_unsubscribe.lo: src/libs6/ftrigr_unsubscribe.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_update.o src/libs6/ftrigr_update.lo: src/libs6/ftrigr_update.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_updateb.o src/libs6/ftrigr_updateb.lo: src/libs6/ftrigr_updateb.c src/include/s6/ftrigr.h
+src/libs6/ftrigr_startf.o src/libs6/ftrigr_startf.lo: src/libs6/ftrigr_startf.c src/libs6/ftrigr-internal.h src/include/s6/config.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_subscribe.o src/libs6/ftrigr_subscribe.lo: src/libs6/ftrigr_subscribe.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_unsubscribe.o src/libs6/ftrigr_unsubscribe.lo: src/libs6/ftrigr_unsubscribe.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
+src/libs6/ftrigr_update.o src/libs6/ftrigr_update.lo: src/libs6/ftrigr_update.c src/libs6/ftrigr-internal.h src/include/s6/ftrigr.h
src/libs6/ftrigr_wait_and.o src/libs6/ftrigr_wait_and.lo: src/libs6/ftrigr_wait_and.c src/include/s6/ftrigr.h
src/libs6/ftrigr_wait_or.o src/libs6/ftrigr_wait_or.lo: src/libs6/ftrigr_wait_or.c src/include/s6/ftrigr.h
-src/libs6/ftrigr_zero.o src/libs6/ftrigr_zero.lo: src/libs6/ftrigr_zero.c src/include/s6/ftrigr.h
-src/libs6/ftrigw_clean.o src/libs6/ftrigw_clean.lo: src/libs6/ftrigw_clean.c src/libs6/ftrig1.h src/include/s6/ftrigw.h
+src/libs6/ftrigw_clean.o src/libs6/ftrigw_clean.lo: src/libs6/ftrigw_clean.c src/include/s6/ftrigw.h
src/libs6/ftrigw_fifodir_make.o src/libs6/ftrigw_fifodir_make.lo: src/libs6/ftrigw_fifodir_make.c src/include/s6/ftrigw.h
src/libs6/ftrigw_notify.o src/libs6/ftrigw_notify.lo: src/libs6/ftrigw_notify.c src/include/s6/ftrigw.h
src/libs6/ftrigw_notifyb.o src/libs6/ftrigw_notifyb.lo: src/libs6/ftrigw_notifyb.c src/include/s6/ftrigw.h
-src/libs6/ftrigw_notifyb_nosig.o src/libs6/ftrigw_notifyb_nosig.lo: src/libs6/ftrigw_notifyb_nosig.c src/libs6/ftrig1.h src/include/s6/ftrigw.h
-src/libs6/s6-ftrigrd.o src/libs6/s6-ftrigrd.lo: src/libs6/s6-ftrigrd.c src/libs6/ftrig1.h src/include/s6/ftrigr.h
+src/libs6/ftrigw_notifyb_nosig.o src/libs6/ftrigw_notifyb_nosig.lo: src/libs6/ftrigw_notifyb_nosig.c src/include/s6/ftrigw.h
+src/libs6/s6-ftrigrd.o src/libs6/s6-ftrigrd.lo: src/libs6/s6-ftrigrd.c src/libs6/ftrigr-internal.h
src/libs6/s6_accessrules_backend_cdb.o src/libs6/s6_accessrules_backend_cdb.lo: src/libs6/s6_accessrules_backend_cdb.c src/include/s6/accessrules.h
src/libs6/s6_accessrules_backend_fs.o src/libs6/s6_accessrules_backend_fs.lo: src/libs6/s6_accessrules_backend_fs.c src/include/s6/accessrules.h
src/libs6/s6_accessrules_keycheck_ip4.o src/libs6/s6_accessrules_keycheck_ip4.lo: src/libs6/s6_accessrules_keycheck_ip4.c src/include/s6/accessrules.h
@@ -234,15 +228,15 @@ s6-instance-maker: src/instance/s6-instance-maker.o libs6auto.a.xyzzy -lskarnet
s6-instance-status: EXTRA_LIBS :=
s6-instance-status: src/instance/s6-instance-status.o -lskarnet
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_instance_chdirservice.o src/libs6/s6_servicedir_file_list.o src/libs6/s6_servicedir_instances_recreate_offline.o src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.o
+libs6.a.xyzzy: src/libs6/ftrigr_ack.o src/libs6/ftrigr_end.o src/libs6/ftrigr_peek.o src/libs6/ftrigr_release.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_wait_and.o src/libs6/ftrigr_wait_or.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_instance_chdirservice.o src/libs6/s6_servicedir_file_list.o src/libs6/s6_servicedir_instances_recreate_offline.o src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
+libs6.a.xyzzy:src/libs6/ftrigr_ack.lo src/libs6/ftrigr_end.lo src/libs6/ftrigr_peek.lo src/libs6/ftrigr_release.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_wait_and.lo src/libs6/ftrigr_wait_or.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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
endif
libs6.pc: EXTRA_LIBS := -lskarnet
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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
+libs6.so.xyzzy:src/libs6/ftrigr_ack.lo src/libs6/ftrigr_end.lo src/libs6/ftrigr_peek.lo src/libs6/ftrigr_release.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_wait_and.lo src/libs6/ftrigr_wait_or.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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
libs6.dylib.xyzzy: EXTRA_LIBS := -lskarnet
-libs6.dylib.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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
+libs6.dylib.xyzzy:src/libs6/ftrigr_ack.lo src/libs6/ftrigr_end.lo src/libs6/ftrigr_peek.lo src/libs6/ftrigr_release.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_wait_and.lo src/libs6/ftrigr_wait_or.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_instance_chdirservice.lo src/libs6/s6_servicedir_file_list.lo src/libs6/s6_servicedir_instances_recreate_offline.lo src/libs6/s6_servicedir_instances_recreate_offline_tmp.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/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 src/libs6/s6_supervise_unlink_names.lo
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
libs6auto.a.xyzzy: src/libs6/s6_auto_write_logger.o src/libs6/s6_auto_write_logger_tmp.o src/libs6/s6_auto_write_logrun.o src/libs6/s6_auto_write_logrun_tmp.o src/libs6/s6_auto_write_service.o
else
@@ -253,8 +247,8 @@ libs6auto.so.xyzzy: EXTRA_LIBS := -lexecline -lskarnet
libs6auto.so.xyzzy:src/libs6/s6_auto_write_logger.lo src/libs6/s6_auto_write_logger_tmp.lo src/libs6/s6_auto_write_logrun.lo src/libs6/s6_auto_write_logrun_tmp.lo src/libs6/s6_auto_write_service.lo
libs6auto.dylib.xyzzy: EXTRA_LIBS := -lexecline -lskarnet
libs6auto.dylib.xyzzy:src/libs6/s6_auto_write_logger.lo src/libs6/s6_auto_write_logger_tmp.lo src/libs6/s6_auto_write_logrun.lo src/libs6/s6_auto_write_logrun_tmp.lo src/libs6/s6_auto_write_service.lo
-s6-ftrigrd: EXTRA_LIBS := ${SOCKET_LIB} ${SYSCLOCK_LIB}
-s6-ftrigrd: src/libs6/s6-ftrigrd.o src/libs6/ftrig1_free.o src/libs6/ftrig1_make.o -lskarnet
+s6-ftrigrd: EXTRA_LIBS := ${SYSCLOCK_LIB}
+s6-ftrigrd: src/libs6/s6-ftrigrd.o -lskarnet
s6-cleanfifodir: EXTRA_LIBS :=
s6-cleanfifodir: src/pipe-tools/s6-cleanfifodir.o ${LIBS6} -lskarnet
s6-ftrig-listen: EXTRA_LIBS := ${EXECLINE_LIB} ${SOCKET_LIB} ${SYSCLOCK_LIB} ${SPAWN_LIB}
diff --git a/package/info b/package/info
index 8c56c0c..edaa30f 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6
-version=2.14.0.1
+version=2.15.0.0
category=admin
package_macro_name=S6
diff --git a/package/targets.mak b/package/targets.mak
index d281923..0dfcd04 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,6 +1,5 @@
BIN_TARGETS := \
ucspilogd \
-s6-ftrigrd \
s6-ftrig-listen1 \
s6-ftrig-listen \
s6-ftrig-notify \
@@ -63,6 +62,9 @@ s6-instance-status \
s6-instance-list \
s6-background-watch \
+LIBEXEC_TARGETS := \
+s6-ftrigrd \
+
LIB_DEFS := S6=s6
S6_DESCRIPTION :=
diff --git a/src/daemontools-extras/s6-setsid.c b/src/daemontools-extras/s6-setsid.c
index 6fd42dd..21662d0 100644
--- a/src/daemontools-extras/s6-setsid.c
+++ b/src/daemontools-extras/s6-setsid.c
@@ -1,69 +1,97 @@
/* ISC license. */
+#include <stdint.h>
#include <unistd.h>
#include <signal.h>
+#include <skalibs/uint64.h>
#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr.h>
+#include <skalibs/envexec.h>
#include <skalibs/sig.h>
-#include <skalibs/exec.h>
+#include <skalibs/djbunix.h>
#define USAGE "s6-setsid [ -s | -b | -f | -g ] [ -i | -I | -q ] [ -d ctty ] prog..."
#define dieusage() strerr_dieusage(100, USAGE)
+enum golb_e
+{
+ GOLB_PGRP = 0x01,
+ GOLB_FG = 0x02,
+ GOLB_GRAB = 0x04,
+ GOLB_STRICT = 0x08,
+ GOLB_SILENT = 0x10,
+} ;
+
+enum gola_e
+{
+ GOLA_CTTY,
+ GOLA_N
+} ;
+
int main (int argc, char const *const *argv)
{
- unsigned int ctty = 0, what = 0, insist = 1 ;
+ static gol_bool const rgolb[] =
+ {
+ { .so = 's', .lo = "session", .clear = GOLB_PGRP | GOLB_FG | GOLB_GRAB, .set = 0 },
+ { .so = 0, .lo = "process-group", .clear = 0, .set = GOLB_PGRP },
+ { .so = 'b', .lo = "background-process-group", .clear = GOLB_FG | GOLB_GRAB, .set = GOLB_PGRP },
+ { .so = 0, .lo = "foreground", .clear = 0, .set = GOLB_FG },
+ { .so = 'f', .lo = "foreground-process-group", .clear = GOLB_GRAB, .set = GOLB_PGRP | GOLB_FG },
+ { .so = 0, .lo = "grab", .clear = 0, .set = GOLB_GRAB },
+ { .so = 'g', .lo = "foreground-process-group-grab", .clear = 0, .set = GOLB_PGRP | GOLB_FG | GOLB_GRAB },
+ { .so = 'I', .lo = "no-strict", .clear = GOLB_STRICT, .set = 0 },
+ { .so = 'i', .lo = "strict", .clear = 0, .set = GOLB_STRICT },
+ { .so = 'q', .lo = "quiet", .clear = 0, .set = GOLB_SILENT }
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'd', .lo = "ctty", .i = GOLA_CTTY },
+ } ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ uint64_t wgolb = 0 ;
+ unsigned int ctty = 0 ;
+ unsigned int golc ;
PROG = "s6-setsid" ;
+
+ golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (!argc) dieusage() ;
+ if (wgola[GOLA_CTTY])
{
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "sbfgiIqd:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 's' : what = 0 ; break ;
- case 'b' : what = 1 ; break ;
- case 'f' : what = 2 ; break ;
- case 'g' : what = 3 ; break ;
- case 'i' : insist = 2 ; break ;
- case 'I' : insist = 1 ; break ;
- case 'q' : insist = 0 ; break ;
- case 'd' : if (!uint0_scan(l.arg, &ctty)) dieusage() ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
+ if (!uint0_scan(wgola[GOLA_CTTY], &ctty)) dieusage() ;
+ }
+ else if (wgolb & (GOLB_PGRP | GOLB_FG))
+ {
+ int fd = openc_read("/dev/tty") ;
+ if (fd == -1) strerr_diefu2sys(111, "open ", "/dev/tty") ;
+ ctty = fd ;
}
- if (!argc) dieusage() ;
- if (what)
+ if (wgolb & GOLB_PGRP)
{
- if (setpgid(0, 0) < 0) switch (insist)
+ if (setpgid(0, 0) == -1)
{
- case 2 : strerr_diefu1sys(111, "setpgid") ;
- case 1 : strerr_warnwu1sys("setpgid") ; break ;
- default : break ;
+ if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "setpgid") ;
+ if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("setpgid") ;
}
- if (what >= 2)
+ if (wgolb & GOLB_FG)
{
- if (what == 3) sig_altignore(SIGTTOU) ;
- if (tcsetpgrp(ctty, getpid()) < 0) switch (insist)
+ if (wgolb & GOLB_GRAB) sig_altignore(SIGTTOU) ;
+ if (tcsetpgrp(ctty, getpid()) == -1)
{
- case 2 : strerr_diefu1sys(111, "tcsetpgrp") ;
- case 1 : strerr_warnwu1sys("tcsetpgrp") ; break ;
- default : break ;
+ if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "tcsetpgrp") ;
+ if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("tcsetpgrp") ;
}
}
}
- else if (setsid() < 0) switch (insist)
+ else
{
- case 2 : strerr_diefu1sys(111, "setsid") ;
- case 1 : strerr_warnwu1sys("setsid") ; break ;
- default : break ;
+ if (setsid() == -1)
+ {
+ if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "setsid") ;
+ if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("setsid") ;
+ }
}
xexec(argv) ;
diff --git a/src/include/s6/ftrigr.h b/src/include/s6/ftrigr.h
index a7b8f3d..2e0f340 100644
--- a/src/include/s6/ftrigr.h
+++ b/src/include/s6/ftrigr.h
@@ -1,99 +1,52 @@
/* ISC license. */
-#ifndef FTRIGR_H
-#define FTRIGR_H
+#ifndef S6_FTRIGR_H
+#define S6_FTRIGR_H
-#include <sys/types.h>
#include <stdint.h>
-#include <skalibs/config.h>
#include <skalibs/tai.h>
-#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
+#include <skalibs/sass.h>
+#include <skalibs/sassclient.h>
-#include <s6/config.h>
+#define FTRIGR_REPEAT SASS_FLAG_KEEP
-
- /* Constants */
-
-#define FTRIGR_IPCPATH SKALIBS_SPROOT "/run/service/ftrigrd/s"
-
-#define FTRIGRD_PROG S6_EXTBINPREFIX "s6-ftrigrd"
-#define FTRIGR_BANNER1 "ftrigr v1.0 (b)\n"
-#define FTRIGR_BANNER1_LEN (sizeof FTRIGR_BANNER1 - 1)
-#define FTRIGR_BANNER2 "ftrigr v1.0 (a)\n"
-#define FTRIGR_BANNER2_LEN (sizeof FTRIGR_BANNER2 - 1)
-
-
- /* Internals of the ftrigr_t */
-
-typedef enum fr1state_e fr1state_t, *fr1state_t_ref ;
-enum fr1state_e
-{
- FR1STATE_WAITACK,
- FR1STATE_WAITACKDATA,
- FR1STATE_LISTENING,
- FR1STATE_ERROR
-} ;
-
-typedef struct ftrigr1_s ftrigr1_t, *ftrigr1_t_ref ;
-struct ftrigr1_s
+typedef struct ftrigr_s ftrigr, *ftrigr_ref ;
+struct ftrigr_s
{
- uint32_t options ;
- fr1state_t state ;
- stralloc what ;
+ sassclient client ;
+ genalloc data ; /* ftrigr_data */
} ;
-#define FTRIGR1_ZERO { .options = 0, .state = FR1STATE_ERROR, .what = STRALLOC_ZERO }
-extern ftrigr1_t const ftrigr1_zero ;
+#define FTRIGR_ZERO { .client = SASSCLIENT_ZERO, .data = GENALLOC_ZERO }
-
- /* The ftrigr_t itself */
-
-typedef struct ftrigr_s ftrigr, ftrigr_t, *ftrigr_ref, *ftrigr_t_ref ;
-struct ftrigr_s
+typedef struct ftrigr_string_s ftrigr_string, *ftrigr_string_ref ;
+struct ftrigr_string_s
{
- textclient connection ;
- genalloc list ; /* array of uint16_t */
- size_t head ;
- gensetdyn data ; /* set of ftrigr1_t */
+ char *s ;
+ uint32_t len ;
} ;
-#define FTRIGR_ZERO { .connection = TEXTCLIENT_ZERO, .list = GENALLOC_ZERO, .head = 0, .data = GENSETDYN_INIT(ftrigr1_t, 2, 0, 1) }
-extern ftrigr_t const ftrigr_zero ;
-
- /* Starting and ending a session */
-
-extern int ftrigr_start (ftrigr_t *, char const *, tain const *, tain *) ;
-#define ftrigr_start_g(a, path, deadline) ftrigr_start(a, path, (deadline), &STAMP)
-extern int ftrigr_startf (ftrigr_t *, tain const *, tain *) ;
+extern int ftrigr_startf (ftrigr *, tain const *, tain *) ;
#define ftrigr_startf_g(a, deadline) ftrigr_startf(a, (deadline), &STAMP)
-extern void ftrigr_end (ftrigr_t *) ;
-
-
- /* Instant primitives for async programming */
-
-#define ftrigr_fd(a) textclient_fd(&(a)->connection)
-extern int ftrigr_updateb (ftrigr_t *) ;
-extern int ftrigr_update (ftrigr_t *) ;
-extern int ftrigr_check (ftrigr_t *, uint16_t, char *) ;
-extern int ftrigr_checksa (ftrigr_t *, uint16_t, stralloc *) ;
-extern void ftrigr_ack (ftrigr_t *, size_t) ;
-
+extern int ftrigr_start (ftrigr *, unsigned int) ;
+extern void ftrigr_end (ftrigr *) ;
- /* Synchronous functions with timeouts */
+#define ftrigr_fd(a) sassclient_fd(&(a)->client)
+extern int ftrigr_update (ftrigr *) ;
+extern int ftrigr_peek (ftrigr *, uint32_t, ftrigr_string *) ;
+extern int ftrigr_ack (ftrigr *, uint32_t) ;
+extern void ftrigr_release (ftrigr *, uint32_t) ;
-#define FTRIGR_REPEAT 0x0001
+extern int ftrigr_subscribe (ftrigr *, uint32_t *, uint32_t, uint32_t, char const *, char const *, tain const *, tain *) ;
+#define ftrigr_subscribe_g(a, id, flags, timeout, path, re, deadline) ftrigr_subscribe(a, id, flags, timeout, path, re, (deadline), &STAMP)
-extern uint16_t ftrigr_subscribe (ftrigr_t *, char const *, char const *, uint32_t, tain const *, tain *) ;
-#define ftrigr_subscribe_g(a, path, re, options, deadline) ftrigr_subscribe(a, path, re, options, (deadline), &STAMP)
-extern int ftrigr_unsubscribe (ftrigr_t *, uint16_t, tain const *, tain *) ;
+extern int ftrigr_unsubscribe (ftrigr *, uint32_t, tain const *, tain *) ;
#define ftrigr_unsubscribe_g(a, id, deadline) ftrigr_unsubscribe(a, id, (deadline), &STAMP)
-extern int ftrigr_wait_and (ftrigr_t *, uint16_t const *, unsigned int, tain const *, tain *) ;
+extern int ftrigr_wait_and (ftrigr *, uint32_t const *, unsigned int, tain const *, tain *) ;
#define ftrigr_wait_and_g(a, list, len, deadline) ftrigr_wait_and(a, list, len, (deadline), &STAMP)
-extern int ftrigr_wait_or (ftrigr_t *, uint16_t const *, unsigned int, tain const *, tain *, char *) ;
-#define ftrigr_wait_or_g(a, list, len, deadline, what) ftrigr_wait_or(a, list, len, deadline, &STAMP, what)
+extern int ftrigr_wait_or (ftrigr *, uint32_t const *, unsigned int, ftrigr_string *, tain const *, tain *) ;
+#define ftrigr_wait_or_g(a, list, n, v, deadline) ftrigr_wait_or(a, list, n, v, (deadline), &STAMP)
#endif
diff --git a/src/libs6/deps-exe/s6-ftrigrd b/src/libs6/deps-exe/s6-ftrigrd
index e6238ab..a11a5f4 100755
--- a/src/libs6/deps-exe/s6-ftrigrd
+++ b/src/libs6/deps-exe/s6-ftrigrd
@@ -1,5 +1,2 @@
-ftrig1_free.o
-ftrig1_make.o
-lskarnet
-${SOCKET_LIB}
${SYSCLOCK_LIB}
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 9b1d285..6590d83 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -1,17 +1,14 @@
-ftrigr1_zero.o
-ftrigr_check.o
-ftrigr_checksa.o
ftrigr_ack.o
ftrigr_end.o
+ftrigr_peek.o
+ftrigr_release.o
ftrigr_start.o
ftrigr_startf.o
ftrigr_subscribe.o
ftrigr_unsubscribe.o
ftrigr_update.o
-ftrigr_updateb.o
ftrigr_wait_and.o
ftrigr_wait_or.o
-ftrigr_zero.o
ftrigw_clean.o
ftrigw_fifodir_make.o
ftrigw_notify.o
diff --git a/src/libs6/ftrig1.h b/src/libs6/ftrig1.h
deleted file mode 100644
index 229de66..0000000
--- a/src/libs6/ftrig1.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ISC license. */
-
-#ifndef FTRIG1_H
-#define FTRIG1_H
-
-#include <skalibs/stralloc.h>
-
-#define FTRIG1_PREFIX "ftrig1"
-#define FTRIG1_PREFIXLEN (sizeof FTRIG1_PREFIX - 1)
-
-typedef struct ftrig1_s ftrig1_t, *ftrig1_t_ref ;
-struct ftrig1_s
-{
- int fd ;
- int fdw ;
- stralloc name ;
-} ;
-#define FTRIG1_ZERO { .fd = -1, .fdw = -1, .name = STRALLOC_ZERO }
-
-extern int ftrig1_make (ftrig1_t *, char const *) ;
-extern void ftrig1_free (ftrig1_t *) ;
-
-#endif
diff --git a/src/libs6/ftrig1_free.c b/src/libs6/ftrig1_free.c
deleted file mode 100644
index 61c0d1d..0000000
--- a/src/libs6/ftrig1_free.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/posixplz.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-#include "ftrig1.h"
-
-void ftrig1_free (ftrig1_t *p)
-{
- if (p->name.s)
- {
- unlink_void(p->name.s) ;
- stralloc_free(&p->name) ;
- }
- if (p->fd >= 0)
- {
- fd_close(p->fd) ;
- p->fd = -1 ;
- }
- if (p->fdw >= 0)
- {
- fd_close(p->fdw) ;
- p->fdw = -1 ;
- }
-}
diff --git a/src/libs6/ftrig1_make.c b/src/libs6/ftrig1_make.c
deleted file mode 100644
index 5c38e4b..0000000
--- a/src/libs6/ftrig1_make.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ISC license. */
-
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include <skalibs/posixplz.h>
-#include <skalibs/tai.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-
-#include "ftrig1.h"
-
-int ftrig1_make (ftrig1_t *f, char const *path)
-{
- ftrig1_t ff = FTRIG1_ZERO ;
- size_t pathlen = strlen(path) ;
- char tmp[pathlen + FTRIG1_PREFIXLEN + 36] ;
-
- memcpy(tmp, path, pathlen) ;
- tmp[pathlen] = '/' ; tmp[pathlen+1] = '.' ;
- memcpy(tmp + pathlen + 2, FTRIG1_PREFIX, FTRIG1_PREFIXLEN) ;
- tmp[pathlen + 2 + FTRIG1_PREFIXLEN] = ':' ;
- if (!timestamp(tmp + pathlen + 3 + FTRIG1_PREFIXLEN)) return 0 ;
- memcpy(tmp + pathlen + FTRIG1_PREFIXLEN + 28, ":XXXXXX", 8) ;
- ff.fd = mkptemp3(tmp, 0622, O_NONBLOCK|O_CLOEXEC) ;
- if (ff.fd == -1) return 0 ;
- ff.fdw = open_write(tmp) ;
- if (ff.fdw == -1) goto err1 ;
- if (!stralloc_ready(&ff.name, pathlen + FTRIG1_PREFIXLEN + 36)) goto err2 ;
- stralloc_copyb(&ff.name, tmp, pathlen + 1) ;
- stralloc_catb(&ff.name, tmp + pathlen + 2, FTRIG1_PREFIXLEN + 34) ;
- if (rename(tmp, ff.name.s) == -1) goto err3 ;
- *f = ff ;
- return 1 ;
-
- err3:
- stralloc_free(&ff.name) ;
- err2:
- fd_close(ff.fdw) ;
- err1:
- fd_close(ff.fd) ;
- unlink_void(tmp) ;
- return 0 ;
-}
diff --git a/src/libs6/ftrigr-internal.h b/src/libs6/ftrigr-internal.h
new file mode 100644
index 0000000..dc9e442
--- /dev/null
+++ b/src/libs6/ftrigr-internal.h
@@ -0,0 +1,20 @@
+/* ISC license. */
+
+#ifndef FTRIGR_INTERNAL_H
+#define FTRIGR_INTERNAL_H
+
+#include <skalibs/stralloc.h>
+
+#define FTRIGR_BANNER1 "ftrigr v2.0 (b)\n"
+#define FTRIGR_BANNER2 "ftrigr v2.0 (a)\n"
+
+typedef struct ftrigr_data_s ftrigr_data, *ftrigr_data_ref ;
+struct ftrigr_data_s
+{
+ int status ;
+ stralloc sa ;
+} ;
+#define FTRIGR_DATA_ZERO { .id = 0, .status = 0, .sa = STRALLOC_ZERO }
+
+
+#endif
diff --git a/src/libs6/ftrigr1_zero.c b/src/libs6/ftrigr1_zero.c
deleted file mode 100644
index 967b4e0..0000000
--- a/src/libs6/ftrigr1_zero.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* ISC license. */
-
-#include <s6/ftrigr.h>
-
-ftrigr1_t const ftrigr1_zero = FTRIGR1_ZERO ;
diff --git a/src/libs6/ftrigr_ack.c b/src/libs6/ftrigr_ack.c
index 5c9a9f3..ac5ee7c 100644
--- a/src/libs6/ftrigr_ack.c
+++ b/src/libs6/ftrigr_ack.c
@@ -1,17 +1,16 @@
/* ISC license. */
-#include <stdint.h>
+#include <errno.h>
+
#include <skalibs/genalloc.h>
+
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
-void ftrigr_ack (ftrigr_t *a, size_t n)
+int ftrigr_ack (ftrigr *a, uint32_t id)
{
- size_t len = genalloc_len(uint16_t, &a->list) ;
- a->head += n ;
- if (a->head > len) a->head = len ;
- if (a->head == len)
- {
- a->head = 0 ;
- genalloc_setlen(uint16_t, &a->list, 0) ;
- }
+ ftrigr_data *p = genalloc_s(ftrigr_data, &a->data) + id ;
+ if (p->status && p->status != EAGAIN) return (errno = p->status, 0) ;
+ p->sa.len = 0 ;
+ return 1 ;
}
diff --git a/src/libs6/ftrigr_check.c b/src/libs6/ftrigr_check.c
deleted file mode 100644
index 30be701..0000000
--- a/src/libs6/ftrigr_check.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-#include <skalibs/stralloc.h>
-#include <s6/ftrigr.h>
-
-int ftrigr_check (ftrigr_t *a, uint16_t id, char *c)
-{
- stralloc sa = STRALLOC_ZERO ;
- int r = ftrigr_checksa(a, id, &sa) ;
-
- if (r && sa.len)
- {
- int e = errno ;
- *c = sa.s[sa.len - 1] ;
- stralloc_free(&sa) ;
- errno = e ;
- }
- return r ;
-}
diff --git a/src/libs6/ftrigr_checksa.c b/src/libs6/ftrigr_checksa.c
deleted file mode 100644
index 6573182..0000000
--- a/src/libs6/ftrigr_checksa.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 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 ;
-}
diff --git a/src/libs6/ftrigr_end.c b/src/libs6/ftrigr_end.c
index 555053f..5c0eb13 100644
--- a/src/libs6/ftrigr_end.c
+++ b/src/libs6/ftrigr_end.c
@@ -1,15 +1,21 @@
/* ISC license. */
-#include <stdint.h>
+#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
+#include <skalibs/sassclient.h>
+
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
+
+static void ftrigr_data_free (void *x)
+{
+ ftrigr_data *p = x ;
+ stralloc_free(&p->sa) ;
+}
-void ftrigr_end (ftrigr_ref a)
+void ftrigr_end (ftrigr *a)
{
- gensetdyn_free(&a->data) ;
- genalloc_free(uint16_t, &a->list) ;
- textclient_end(&a->connection) ;
- *a = ftrigr_zero ;
+ sassclient_end(&a->client) ;
+ a->data.len = a->data.a ;
+ genalloc_deepfree(ftrigr_data, &a->data, &ftrigr_data_free) ;
}
diff --git a/src/libs6/ftrigr_peek.c b/src/libs6/ftrigr_peek.c
new file mode 100644
index 0000000..5107bae
--- /dev/null
+++ b/src/libs6/ftrigr_peek.c
@@ -0,0 +1,25 @@
+/* ISC license. */
+
+#include <errno.h>
+
+#include <skalibs/genalloc.h>
+
+#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
+
+int ftrigr_peek (ftrigr *a, uint32_t id, ftrigr_string *fs)
+{
+ ftrigr_data *p = genalloc_s(ftrigr_data, &a->data) + id ;
+ switch (p->status)
+ {
+ case EAGAIN : return 0 ;
+ case 0 :
+ {
+ fs->s = p->sa.s ;
+ fs->len = p->sa.len ;
+ return 1 ;
+ }
+ default: break ;
+ }
+ return (errno = p->status, -1) ;
+}
diff --git a/src/libs6/ftrigr_release.c b/src/libs6/ftrigr_release.c
new file mode 100644
index 0000000..fdcd9d0
--- /dev/null
+++ b/src/libs6/ftrigr_release.c
@@ -0,0 +1,18 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <errno.h>
+
+#include <skalibs/genalloc.h>
+#include <skalibs/sassclient.h>
+
+#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
+
+void ftrigr_release (ftrigr *a, uint32_t id)
+{
+ ftrigr_data *p = genalloc_s(ftrigr_data, &a->data) + id ;
+ sassclient_release(&a->client, id) ;
+ p->status = EINVAL ;
+ p->sa.len = 0 ;
+}
diff --git a/src/libs6/ftrigr_start.c b/src/libs6/ftrigr_start.c
index c4422dc..cf73573 100644
--- a/src/libs6/ftrigr_start.c
+++ b/src/libs6/ftrigr_start.c
@@ -1,9 +1,13 @@
/* ISC license. */
-#include <skalibs/textclient.h>
+#include <skalibs/tai.h>
+
#include <s6/ftrigr.h>
-int ftrigr_start (ftrigr_t *a, char const *path, tain const *deadline, tain *stamp)
+int ftrigr_start (ftrigr *a, unsigned int sec)
{
- return textclient_start(&a->connection, path, 0, FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, deadline, stamp) ;
+ tain deadline = TAIN_INFINITE ;
+ if (!tain_now_set_stopwatch_g()) return 0 ;
+ if (sec) tain_addsec_g(&deadline, sec) ;
+ return ftrigr_startf_g(a, &deadline) ;
}
diff --git a/src/libs6/ftrigr_startf.c b/src/libs6/ftrigr_startf.c
index bc503ba..5ebf6ce 100644
--- a/src/libs6/ftrigr_startf.c
+++ b/src/libs6/ftrigr_startf.c
@@ -1,12 +1,13 @@
/* ISC license. */
-#include <skalibs/posixplz.h>
-#include <skalibs/textclient.h>
+#include <skalibs/sassclient.h>
+#include <s6/config.h>
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
-int ftrigr_startf (ftrigr_t *a, tain const *deadline, tain *stamp)
+int ftrigr_startf (ftrigr *a, tain const *deadline, tain *stamp)
{
- static char const *const cargv[2] = { FTRIGRD_PROG, 0 } ;
- return textclient_startf(&a->connection, cargv, (char const *const *)environ, TEXTCLIENT_OPTION_WAITPID, FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, deadline, stamp) ;
+ char const *argv[2] = { S6_LIBEXECPREFIX "s6-ftrigrd", 0 } ;
+ return sassclient_start(&a->client, argv, FTRIGR_BANNER1, FTRIGR_BANNER2, deadline, stamp) ;
}
diff --git a/src/libs6/ftrigr_subscribe.c b/src/libs6/ftrigr_subscribe.c
index 1dc86e7..eb1d365 100644
--- a/src/libs6/ftrigr_subscribe.c
+++ b/src/libs6/ftrigr_subscribe.c
@@ -2,41 +2,42 @@
#include <sys/uio.h>
#include <string.h>
-#include <stdint.h>
#include <errno.h>
-#include <skalibs/uint16.h>
-#include <skalibs/uint32.h>
-#include <skalibs/tai.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
+
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
+
+static int ftrigr_cb (char const *s, size_t len, uint32_t id, void *x)
+{
+ ftrigr_data *p = genalloc_s(ftrigr_data, (genalloc *)x) + id ;
+ if (!stralloc_catb(&p->sa, s, len)) return errno ;
+ p->status = 0 ;
+ return 0 ;
+}
-uint16_t ftrigr_subscribe (ftrigr_t *a, char const *path, char const *re, uint32_t options, tain const *deadline, tain *stamp)
+int ftrigr_subscribe (ftrigr *a, uint32_t *i, uint32_t flags, uint32_t timeout, char const *path, char const *re, tain const *deadline, tain *stamp)
{
+ ftrigr_data *p ;
+ uint32_t id ;
size_t pathlen = strlen(path) ;
size_t relen = strlen(re) ;
- ftrigr1_t ft = { .options = options, .state = FR1STATE_LISTENING, .what = STRALLOC_ZERO } ;
- uint32_t i ;
- char tmp[15] = "--L" ;
- struct iovec v[3] = { { .iov_base = tmp, .iov_len = 15 }, { .iov_base = (char *)path, .iov_len = pathlen + 1 }, { .iov_base = (char *)re, .iov_len = relen + 1 } } ;
- if (!gensetdyn_new(&a->data, &i)) return 0 ;
- if (i >= UINT16_MAX)
+
+ struct iovec v[2] =
{
- gensetdyn_delete(&a->data, i) ;
- return (errno = EMFILE, 0) ;
- }
- uint16_pack_big(tmp, (uint16_t)i) ;
- uint32_pack_big(tmp+3, options) ;
- uint32_pack_big(tmp+7, (uint32_t)pathlen) ;
- uint32_pack_big(tmp+11, (uint32_t)relen) ;
- if (!textclient_commandv(&a->connection, v, 3, deadline, stamp))
+ { .iov_base = (char *)path, .iov_len = pathlen + 1 },
+ { .iov_base = (char *)re, .iov_len = relen + 1 }
+ } ;
+ if (!sassclient_sendv(&a->client, &id, flags, timeout, 0, v, 2, &ftrigr_cb, &a->data, deadline, stamp)) return 0 ;
+ if (!genalloc_ready(ftrigr_data, &a->data, id + 1))
{
int e = errno ;
- gensetdyn_delete(&a->data, i) ;
+ sassclient_cancel(&a->client, id, deadline, stamp) ;
errno = e ;
return 0 ;
}
- *GENSETDYN_P(ftrigr1_t, &a->data, i) = ft ;
- return (uint16_t)(i+1) ;
+ p = genalloc_s(ftrigr_data, &a->data) + id ;
+ p->sa.len = 0 ;
+ p->status = EAGAIN ;
+ *i = id ;
+ return 1 ;
}
diff --git a/src/libs6/ftrigr_unsubscribe.c b/src/libs6/ftrigr_unsubscribe.c
index 8a716d5..9aa5595 100644
--- a/src/libs6/ftrigr_unsubscribe.c
+++ b/src/libs6/ftrigr_unsubscribe.c
@@ -1,33 +1,18 @@
/* ISC license. */
#include <errno.h>
-#include <skalibs/uint16.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
+
+#include <skalibs/sassclient.h>
+
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
-int ftrigr_unsubscribe (ftrigr_t *a, uint16_t i, tain const *deadline, tain *stamp)
+int ftrigr_unsubscribe (ftrigr *a, uint32_t id, tain const *deadline, tain *stamp)
{
- ftrigr1_t *p ;
- char pack[3] = "--U" ;
- if (!i--) return (errno = EINVAL, 0) ;
- p = GENSETDYN_P(ftrigr1_t, &a->data, i) ;
- if (!p) return (errno = EINVAL, 0) ;
- switch (p->state)
- {
- case FR1STATE_WAITACK :
- case FR1STATE_WAITACKDATA :
- {
- char dummy ;
- ftrigr_check(a, i+1, &dummy) ;
- return 1 ;
- }
- default : break ;
- }
- uint16_pack_big(pack, i) ;
- if (!textclient_command(&a->connection, pack, 3, deadline, stamp)) return 0 ;
- stralloc_free(&p->what) ;
- *p = ftrigr1_zero ;
- return gensetdyn_delete(&a->data, i) ;
+ ftrigr_data *p ;
+ if (!sassclient_cancel(&a->client, id, deadline, stamp)) return 0 ;
+ p = genalloc_s(ftrigr_data, &a->data) + id ;
+ p->sa.len = 0 ;
+ p->status = EINVAL ;
+ return 1 ;
}
diff --git a/src/libs6/ftrigr_update.c b/src/libs6/ftrigr_update.c
index 674d8cb..afae759 100644
--- a/src/libs6/ftrigr_update.c
+++ b/src/libs6/ftrigr_update.c
@@ -1,11 +1,25 @@
/* ISC license. */
#include <stdint.h>
+
#include <skalibs/genalloc.h>
+#include <skalibs/sassclient.h>
+
#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
-int ftrigr_update (ftrigr_t *a)
+int ftrigr_update (ftrigr *a)
{
- genalloc_setlen(uint16_t, &a->list, 0) ;
- return ftrigr_updateb(a) ;
+ int r = sassclient_update(&a->client) ;
+ if (r <= 0) return r ;
+ for (;;)
+ {
+ uint32_t id ;
+ int status ;
+ r = sassclient_ack(&a->client, &id, &status) ;
+ if (r == -1) return -1 ;
+ if (!r) break ;
+ genalloc_s(ftrigr_data, &a->data)[id].status = status ;
+ }
+ return 1 ;
}
diff --git a/src/libs6/ftrigr_updateb.c b/src/libs6/ftrigr_updateb.c
deleted file mode 100644
index 2a47e49..0000000
--- a/src/libs6/ftrigr_updateb.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ISC license. */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include <skalibs/gccattributes.h>
-#include <skalibs/uint16.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
-#include <s6/ftrigr.h>
-
-#include <skalibs/posixishard.h>
-
-static inline int appears (uint16_t, uint16_t const *, size_t) gccattr_pure ;
-
-static inline int appears (uint16_t id, uint16_t const *list, size_t len)
-{
- while (len) if (id == list[--len]) return 1 ;
- return 0 ;
-}
-
-static int msghandler (struct iovec const *v, void *context)
-{
- ftrigr_t *a = (ftrigr_t *)context ;
- ftrigr1_t *p ;
- int addit = 1 ;
- char const *s = v->iov_base ;
- uint16_t id ;
- if (v->iov_len != 4) return (errno = EPROTO, 0) ;
- uint16_unpack_big(s, &id) ;
- p = GENSETDYN_P(ftrigr1_t, &a->data, id) ;
- if (!p) return 1 ;
- if (p->state != FR1STATE_LISTENING) return (errno = EINVAL, 0) ;
- if (!genalloc_readyplus(uint16_t, &a->list, 1)) return 0 ;
- switch (s[2])
- {
- case 'd' :
- if (!stralloc_catb(&p->what, s + 3, 1)) return 0 ;
- p->state = FR1STATE_WAITACK ;
- break ;
- case '!' :
- if (!stralloc_catb(&p->what, s + 3, 1)) return 0 ;
- if (p->options & FTRIGR_REPEAT)
- {
- if (p->what.len > 1
- && appears(id+1, genalloc_s(uint16_t, &a->list), genalloc_len(uint16_t, &a->list)))
- addit = 0 ;
- }
- else p->state = FR1STATE_WAITACKDATA ;
- break ;
- default : return (errno = EPROTO, 0) ;
- }
- if (addit)
- {
- id++ ; genalloc_append(uint16_t, &a->list, &id) ;
- }
- return 1 ;
-}
-
-int ftrigr_updateb (ftrigr_t *a)
-{
- size_t curlen = genalloc_len(uint16_t, &a->list) ;
- int r = textclient_update(&a->connection, &msghandler, a) ;
- return r < 0 ? r : (int)(genalloc_len(uint16_t, &a->list) - curlen) ;
-}
diff --git a/src/libs6/ftrigr_wait_and.c b/src/libs6/ftrigr_wait_and.c
index ebdbde0..0619b08 100644
--- a/src/libs6/ftrigr_wait_and.c
+++ b/src/libs6/ftrigr_wait_and.c
@@ -1,27 +1,29 @@
/* ISC license. */
+#include <sys/uio.h>
#include <errno.h>
+
#include <skalibs/iopause.h>
+
#include <s6/ftrigr.h>
-int ftrigr_wait_and (ftrigr_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp)
+int ftrigr_wait_and (ftrigr *a, uint32_t const *list, unsigned int n, tain const *deadline, tain *stamp)
{
- iopause_fd x = { -1, IOPAUSE_READ, 0 } ;
- x.fd = ftrigr_fd(a) ;
- for (; n ; n--, idlist++)
+ iopause_fd x = { .fd = ftrigr_fd(a), .events = IOPAUSE_READ } ;
+ for (unsigned int i = 0 ; i < n ; i++)
{
for (;;)
{
- char dummy ;
- int r = ftrigr_check(a, *idlist, &dummy) ;
- if (r < 0) return r ;
- else if (r) break ;
+ ftrigr_string fs ;
+ int r = ftrigr_peek(a, list[i], &fs) ;
+ if (r == -1) return -1 ;
+ if (r) break ;
r = iopause_stamp(&x, 1, deadline, stamp) ;
- if (r < 0) return r ;
- else if (!r) return (errno = ETIMEDOUT, -1) ;
- else if (ftrigr_updateb(a) < 0) return -1 ;
+ if (r == -1) return -1 ;
+ if (!r) return (errno = ETIMEDOUT, -1) ;
+ if (ftrigr_update(a) == -1) return -1 ;
}
+ ftrigr_ack(a, list[i]) ;
}
-
- return 1 ;
+ return 0 ;
}
diff --git a/src/libs6/ftrigr_wait_or.c b/src/libs6/ftrigr_wait_or.c
index efe6e14..799e2e0 100644
--- a/src/libs6/ftrigr_wait_or.c
+++ b/src/libs6/ftrigr_wait_or.c
@@ -6,27 +6,21 @@
#include <s6/ftrigr.h>
-#include <skalibs/posixishard.h>
-
-int ftrigr_wait_or (ftrigr_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp, char *c)
+int ftrigr_wait_or (ftrigr *a, uint32_t const *list, unsigned int n, ftrigr_string *fs, tain const *deadline, tain *stamp)
{
- iopause_fd x = { -1, IOPAUSE_READ | IOPAUSE_EXCEPT, 0 } ;
- x.fd = ftrigr_fd(a) ;
- if (x.fd < 0) return -1 ;
+ iopause_fd x = { .fd = ftrigr_fd(a), .events = IOPAUSE_READ } ;
for (;;)
{
- unsigned int i = 0 ;
int r ;
- for (; i < n ; i++)
+ for (unsigned int i = 0 ; i < n ; i++)
{
- r = ftrigr_check(a, idlist[i], c) ;
- if (r < 0) return r ;
- else if (r) return i ;
+ r = ftrigr_peek(a, list[i], fs) ;
+ if (r == -1) return -1 ;
+ if (r) return i ;
}
r = iopause_stamp(&x, 1, deadline, stamp) ;
- if (r < 0) return 0 ;
- else if (!r) return (errno = ETIMEDOUT, -1) ;
- else if (ftrigr_update(a) < 0) return -1 ;
+ if (r == -1) return -1 ;
+ if (!r) return (errno = ETIMEDOUT, -1) ;
+ if (ftrigr_update(a) == -1) return -1 ;
}
- return (errno = EPROTO, -1) ; /* can't happen */
}
diff --git a/src/libs6/ftrigr_zero.c b/src/libs6/ftrigr_zero.c
deleted file mode 100644
index b09ddb6..0000000
--- a/src/libs6/ftrigr_zero.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* ISC license. */
-
-#include <s6/ftrigr.h>
-
-ftrigr_t const ftrigr_zero = FTRIGR_ZERO ;
diff --git a/src/libs6/ftrigw_clean.c b/src/libs6/ftrigw_clean.c
index e540aba..301fd39 100644
--- a/src/libs6/ftrigw_clean.c
+++ b/src/libs6/ftrigw_clean.c
@@ -3,21 +3,22 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+
+#include <skalibs/posixplz.h>
#include <skalibs/direntry.h>
#include <skalibs/djbunix.h>
-#include "ftrig1.h"
+
#include <s6/ftrigw.h>
int ftrigw_clean (char const *path)
{
size_t pathlen = strlen(path) ;
- int e = 0 ;
DIR *dir = opendir(path) ;
if (!dir) return 0 ;
{
- char tmp[pathlen + FTRIG1_PREFIXLEN + 35] ;
+ char tmp[pathlen + 41] ;
memcpy(tmp, path, pathlen) ;
- tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 34] = 0 ;
+ tmp[pathlen] = '/' ; tmp[pathlen + 40] = 0 ;
for (;;)
{
direntry *d ;
@@ -25,15 +26,14 @@ int ftrigw_clean (char const *path)
errno = 0 ;
d = readdir(dir) ;
if (!d) break ;
- if (strncmp(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ;
- if (strlen(d->d_name) != FTRIG1_PREFIXLEN + 33) continue ;
- memcpy(tmp + pathlen + 1, d->d_name, FTRIG1_PREFIXLEN + 33) ;
+ if (strncmp(d->d_name, "ftrig1", 6)) continue ;
+ if (strlen(d->d_name) != 39) continue ;
+ memcpy(tmp + pathlen + 1, d->d_name, 39) ;
fd = open_write(tmp) ;
if (fd >= 0) fd_close(fd) ;
- else if ((errno == ENXIO) && (unlink(tmp) < 0)) e = errno ;
+ else if (errno == ENXIO) unlink_void(tmp) ;
}
}
dir_close(dir) ;
- if (errno) e = errno ;
- return e ? (errno = e, 0) : 1 ;
+ return !errno ;
}
diff --git a/src/libs6/ftrigw_notifyb_nosig.c b/src/libs6/ftrigw_notifyb_nosig.c
index 103e2b9..06abae6 100644
--- a/src/libs6/ftrigw_notifyb_nosig.c
+++ b/src/libs6/ftrigw_notifyb_nosig.c
@@ -10,7 +10,6 @@
#include <skalibs/djbunix.h>
#include <s6/ftrigw.h>
-#include "ftrig1.h"
int ftrigw_notifyb_nosig (char const *path, char const *s, size_t len)
{
@@ -19,10 +18,10 @@ int ftrigw_notifyb_nosig (char const *path, char const *s, size_t len)
if (!dir) return -1 ;
{
size_t pathlen = strlen(path) ;
- char tmp[pathlen + FTRIG1_PREFIXLEN + 35] ;
+ char tmp[pathlen + 41] ;
memcpy(tmp, path, pathlen) ;
tmp[pathlen] = '/' ;
- tmp[pathlen + FTRIG1_PREFIXLEN + 34] = 0 ;
+ tmp[pathlen + 40] = 0 ;
for (;;)
{
direntry *d ;
@@ -30,9 +29,9 @@ int ftrigw_notifyb_nosig (char const *path, char const *s, size_t len)
errno = 0 ;
d = readdir(dir) ;
if (!d) break ;
- if (strncmp(d->d_name, FTRIG1_PREFIX ":@", FTRIG1_PREFIXLEN + 2)) continue ;
- if (strlen(d->d_name) != FTRIG1_PREFIXLEN + 33) continue ;
- memcpy(tmp + pathlen + 1, d->d_name, FTRIG1_PREFIXLEN + 33) ;
+ if (strncmp(d->d_name, "ftrig1:@", 8)) continue ;
+ if (strlen(d->d_name) != 39) continue ;
+ memcpy(tmp + pathlen + 1, d->d_name, 39) ;
fd = open_write(tmp) ;
if (fd == -1)
{
diff --git a/src/libs6/s6-ftrigrd.c b/src/libs6/s6-ftrigrd.c
index 5b5ffd9..a037e31 100644
--- a/src/libs6/s6-ftrigrd.c
+++ b/src/libs6/s6-ftrigrd.c
@@ -1,293 +1,207 @@
/* ISC license. */
-#include <sys/uio.h>
#include <string.h>
#include <stdint.h>
+#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
#include <signal.h>
#include <regex.h>
+#include <stdio.h>
#include <skalibs/posixplz.h>
-#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
-#include <skalibs/error.h>
-#include <skalibs/strerr.h>
#include <skalibs/buffer.h>
-#include <skalibs/alloc.h>
+#include <skalibs/strerr.h>
#include <skalibs/stralloc.h>
-#include <skalibs/genalloc.h>
#include <skalibs/sig.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/iopause.h>
-#include <skalibs/textmessage.h>
-#include <skalibs/textclient.h>
+#include <skalibs/sassserver.h>
-#include "ftrig1.h"
-#include <s6/ftrigr.h>
+#include "ftrigr-internal.h"
#include <skalibs/posixishard.h>
#define FTRIGRD_MAXREADS 32
-#define FTRIGRD_BUFSIZE 16
+#define FTRIGRD_BUFSIZE 32
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
typedef struct ftrigio_s ftrigio, *ftrigio_ref ;
struct ftrigio_s
{
+ ftrigio_ref prev ;
+ ftrigio_ref next ;
unsigned int xindex ;
- ftrig1_t trig ;
+ uint32_t id ;
+ uint32_t flags ;
buffer b ;
- regex_t re ;
+ char buf[FTRIGRD_BUFSIZE] ;
+ int fdw ;
+ size_t start ;
stralloc sa ;
- uint32_t options ;
- uint16_t id ; /* given by client */
+ regex_t re ;
} ;
-#define FTRIGIO_ZERO { .xindex = 0, .trig = FTRIG1_ZERO, .b = BUFFER_INIT(0, -1, 0, 0), .buf = "", .sa = STRALLOC_ZERO, .options = 0, .id = 0 }
+#define FTRIGIO_ZERO { .prev = 0, .next = 0, .xindex = 0, .id = 0, .flags = 0, .b = BUFFER_INIT(0, -1, 0, 0), .buf = "", .fdw = -1, .start = 0, .sa = STRALLOC_ZERO }
-static genalloc g = GENALLOC_ZERO ; /* ftrigio */
+static ftrigio ftrigio_head = { .prev = &ftrigio_head, .next = &ftrigio_head, .start = 0, .sa = STRALLOC_ZERO } ;
+#define numio (ftrigio_head.start)
-static void ftrigio_free (ftrigio *p)
+static void cleanup (void *x)
{
- alloc_free(p->b.c.x) ;
- ftrig1_free(&p->trig) ;
- stralloc_free(&p->sa) ;
- regfree(&p->re) ;
+ (void)x ;
+ for (ftrigio *p = ftrigio_head.next ; p != &ftrigio_head ; p = p->next)
+ unlink_void(p->sa.s) ;
}
-static void cleanup (void)
+static void ftrigio_remove (void *x)
{
- size_t n = genalloc_len(ftrigio, &g) ;
- ftrigio *a = genalloc_s(ftrigio, &g) ;
- for (size_t i = 0 ; i < n ; i++) ftrigio_free(a + i) ;
- genalloc_setlen(ftrigio, &g, 0) ;
+ ftrigio *p = x ;
+ p->next->prev = p->prev ;
+ p->prev->next = p->next ;
+ numio-- ;
+ p->prev = p->next = 0 ;
+ unlink_void(p->sa.s) ;
+ fd_close(p->fdw) ;
+ fd_close(buffer_fd(&p->b)) ;
+ p->sa.len = 0 ;
+ regfree(&p->re) ;
}
-static void trig (uint16_t id, char what, char info)
+static int ftrigio_add (void *x, uint32_t id, uint32_t flags, uint32_t opcode, char const *s, size_t len)
{
- char pack[4] ;
- uint16_pack_big(pack, id) ;
- pack[2] = what ; pack[3] = info ;
- if (!textmessage_put(textmessage_sender_x, pack, 4))
- {
- cleanup() ;
- strerr_diefu1sys(111, "build answer") ;
- }
-}
+ ftrigio *p = x ;
+ size_t pathlen ;
+ if (len < 3 || s[len - 1]) return EPROTO ;
+ pathlen = strlen(s) ;
+ if (pathlen + 1 >= len) return EPROTO ;
+ p->start = pathlen + 41 ;
+ if (!stralloc_ready(&p->sa, p->start)) { cleanup(0) ; dienomem() ; }
-static void answer (unsigned char c)
-{
- if (!textmessage_put(textmessage_sender_1, (char *)&c, 1))
{
- cleanup() ;
- strerr_diefu1sys(111, "textmessage_put") ;
+ char tmp[p->start + 1] ;
+ int r = skalibs_regcomp(&p->re, s + pathlen + 1, REG_EXTENDED) ;
+ if (r) return r == REG_ESPACE ? ENOMEM : EINVAL ;
+ memcpy(tmp, s, pathlen) ;
+ memcpy(tmp + pathlen, "/.ftrig1:", 9) ;
+ if (!timestamp(tmp + pathlen + 9)) goto err0 ;
+ memcpy(tmp + pathlen + 34, ":XXXXXX", 8) ;
+ r = mkptemp3(tmp, 0622, O_NONBLOCK | O_CLOEXEC) ;
+ if (r == -1) goto err0 ;
+ buffer_init(&p->b, &buffer_read, r, p->buf, FTRIGRD_BUFSIZE) ;
+ p->fdw = open_write(tmp) ;
+ if (p->fdw == -1) { unlink_void(tmp) ; goto err1 ; }
+ stralloc_copyb(&p->sa, tmp, pathlen + 1) ;
+ stralloc_catb(&p->sa, tmp + pathlen + 2, 40) ;
+ if (rename(tmp, p->sa.s) == -1) { unlink_void(tmp) ; goto err2 ; }
}
-}
+
+ p->id = id ;
+ p->flags = flags ;
+ p->prev = &ftrigio_head ;
+ p->next = ftrigio_head.next ;
+ ftrigio_head.next = p ;
+ numio++ ;
+ (void)opcode ;
+ return 0 ;
-static void ftrigio_remove (size_t i)
-{
- size_t n = genalloc_len(ftrigio, &g) ;
- ftrigio *a = genalloc_s(ftrigio, &g) ;
- ftrigio_free(a + i) ;
- a[i] = a[--n] ;
- genalloc_setlen(ftrigio, &g, n) ;
+ err2:
+ fd_close(p->fdw) ;
+ err1:
+ fd_close(buffer_fd(&p->b)) ;
+ err0:
+ regfree(&p->re) ;
+ return errno ;
}
-static inline int ftrigio_read (ftrigio *p)
+static inline int ftrigio_read (sassserver *a, ftrigio *p)
{
unsigned int i = FTRIGRD_MAXREADS ;
while (i--)
{
- regmatch_t pmatch ;
size_t blen ;
ssize_t r = sanitize_read(buffer_fill(&p->b)) ;
if (!r) break ;
- if (r < 0) return (trig(p->id, 'd', errno), 0) ;
- blen = buffer_len(&p->b) ;
- if (!stralloc_readyplus(&p->sa, blen+1))
+ if (r == -1)
{
- cleanup() ;
- dienomem() ;
+ sassserver_async_failure(a, p->id, errno) ;
+ return 0 ;
}
+ blen = buffer_len(&p->b) ;
+ if (!stralloc_readyplus(&p->sa, blen+1)) { cleanup(0) ; dienomem() ; }
buffer_getnofill(&p->b, p->sa.s + p->sa.len, blen) ;
p->sa.len += blen ;
p->sa.s[p->sa.len] = 0 ;
- while (!regexec(&p->re, p->sa.s, 1, &pmatch, REG_NOTBOL | REG_NOTEOL))
- {
- trig(p->id, '!', p->sa.s[pmatch.rm_eo - 1]) ;
- if (!(p->options & FTRIGR_REPEAT)) return 0 ;
- memmove(p->sa.s, p->sa.s + pmatch.rm_eo, p->sa.len + 1 - pmatch.rm_eo) ;
- p->sa.len -= pmatch.rm_eo ;
- }
- }
- return 1 ;
-}
-
-static int parse_protocol (struct iovec const *v, void *context)
-{
- char const *s = v->iov_base ;
- uint16_t id ;
- if (v->iov_len < 3)
- {
- cleanup() ;
- strerr_dief1x(100, "invalid client request") ;
- }
- uint16_unpack_big(s, &id) ;
- switch (s[2])
- {
- case 'U' : /* unsubscribe */
- {
- size_t n = genalloc_len(ftrigio, &g) ;
- size_t i = 0 ;
- for (; i < n ; i++) if (genalloc_s(ftrigio, &g)[i].id == id) break ;
- if (i < n)
- {
- ftrigio_remove(i) ;
- answer(0) ;
- }
- else answer(EINVAL) ;
- break ;
- }
- case 'L' : /* subscribe to path and match re */
+ if (!regexec(&p->re, p->sa.s + p->start, 0, 0, 0))
{
- size_t n = genalloc_len(ftrigio, &g) ;
- ftrigio *p ;
- char *x ;
- uint32_t options, pathlen, relen ;
- int r ;
- if (v->iov_len < 19)
- {
- answer(EPROTO) ;
- break ;
- }
- uint32_unpack_big(s + 3, &options) ;
- uint32_unpack_big(s + 7, &pathlen) ;
- uint32_unpack_big(s + 11, &relen) ;
- if (((pathlen + relen + 17) != v->iov_len) || s[15 + pathlen] || s[v->iov_len - 1])
- {
- answer(EPROTO) ;
- break ;
- }
- if (!genalloc_readyplus(ftrigio, &g, 1))
- {
- answer(ENOMEM) ;
- break ;
- }
- x = alloc(FTRIGRD_BUFSIZE) ;
- if (!x)
- {
- answer(ENOMEM) ;
- break ;
- }
- p = genalloc_s(ftrigio, &g) + n ;
- r = skalibs_regcomp(&p->re, s + 16 + pathlen, REG_EXTENDED) ;
- if (r)
- {
- alloc_free(x) ;
- answer(r == REG_ESPACE ? ENOMEM : EINVAL) ;
- break ;
- }
- if (!ftrig1_make(&p->trig, s + 15))
- {
- regfree(&p->re) ;
- alloc_free(x) ;
- answer(errno) ;
- break ;
- }
- buffer_init(&p->b, &buffer_read, p->trig.fd, x, FTRIGRD_BUFSIZE) ;
- p->options = options ;
- p->id = id ;
- p->sa = stralloc_zero ;
- genalloc_setlen(ftrigio, &g, n+1) ;
- answer(0) ;
- break ;
+ sassserver_async_success(a, p->id, p->flags, p->sa.s + p->start, p->sa.len - p->start) ;
+ p->sa.len = p->start ;
}
- default :
- cleanup() ;
- strerr_dief1x(100, "invalid client request") ;
}
- (void)context ;
return 1 ;
}
int main (void)
{
+ sassserver a = SASSSERVER_ZERO ;
+ int r = 0 ;
PROG = "s6-ftrigrd" ;
if (ndelay_on(0) == -1 || ndelay_on(1) == -1)
strerr_diefu1sys(111, "make fds nonblocking") ;
if (!sig_altignore(SIGPIPE))
strerr_diefu1sys(111, "ignore SIGPIPE") ;
+ if (!tain_now_set_stopwatch_g())
+ strerr_diefu1sys(111, "tain_now_set_stopwatch") ;
{
tain deadline ;
- tain_now_set_stopwatch_g() ;
- tain_addsec_g(&deadline, 2) ;
- if (!textclient_server_01x_init_g(FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, &deadline))
- strerr_diefu1sys(111, "sync with client") ;
+ tain_addsec_g(&deadline, 5) ;
+ sassserver_init_g(&a, FTRIGR_BANNER1, FTRIGR_BANNER2, &ftrigio_add, &ftrigio_remove, sizeof(ftrigio), &cleanup, 0, &deadline) ;
}
- for (;;)
+ while (!r)
{
- size_t n = genalloc_len(ftrigio, &g) ;
- size_t i = 0 ;
- iopause_fd x[3 + n] ;
+ tain deadline = TAIN_INFINITE ;
+ iopause_fd x[3 + numio] ;
+
+ sassserver_prepare_iopause(&a, x, &deadline) ;
- x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ;
- x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_1) ? 0 : IOPAUSE_WRITE) ;
- x[2].fd = textmessage_sender_fd(textmessage_sender_x) ;
- x[2].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_x) ? 0 : IOPAUSE_WRITE) ;
- for (; i < n ; i++)
+ for (ftrigio *p = ftrigio_head.next ; p != &ftrigio_head ; p = p->next, r++)
{
- ftrigio *p = genalloc_s(ftrigio, &g) + i ;
- p->xindex = 3+i ;
- x[3+i].fd = p->trig.fd ;
- x[3+i].events = IOPAUSE_READ ;
+ p->xindex = 3+r ;
+ x[3+r].fd = buffer_fd(&p->b) ;
+ x[3+r].events = IOPAUSE_READ ;
}
- if (iopause(x, 3 + n, 0, 0) < 0)
+ r = iopause_g(x, 3 + numio, &deadline) ;
+ if (r == -1)
{
- cleanup() ;
+ cleanup(0) ;
strerr_diefu1sys(111, "iopause") ;
}
-
- /* client closed */
- if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ;
-
- /* client is reading */
- if (x[1].revents & IOPAUSE_WRITE)
- if (!textmessage_sender_flush(textmessage_sender_1) && !error_isagain(errno))
- {
- cleanup() ;
- strerr_diefu1sys(111, "flush stdout") ;
- }
- if (x[2].revents & IOPAUSE_WRITE)
- if (!textmessage_sender_flush(textmessage_sender_x) && !error_isagain(errno))
- {
- cleanup() ;
- return 1 ;
- }
-
- /* scan listening ftrigs */
- for (i = 0 ; i < genalloc_len(ftrigio, &g) ; i++)
+ if (!r)
{
- ftrigio *p = genalloc_s(ftrigio, &g) + i ;
- if (x[p->xindex].revents & IOPAUSE_READ)
- if (!ftrigio_read(p)) ftrigio_remove(i--) ;
+ sassserver_timeout(&a) ;
+ continue ;
}
- /* client is writing */
- if (!textmessage_receiver_isempty(textmessage_receiver_0) || x[0].revents & IOPAUSE_READ)
+ sassserver_write_event(&a, x) ;
+
+ for (ftrigio *p = ftrigio_head.next ; p != &ftrigio_head ; p = p->next) if (x[p->xindex].revents & IOPAUSE_READ)
{
- if (textmessage_handle(textmessage_receiver_0, &parse_protocol, 0) < 0)
+ if (!ftrigio_read(&a, p))
{
- if (errno == EPIPE) break ; /* normal exit */
- cleanup() ;
- strerr_diefu1sys(111, "handle messages from client") ;
+ p = p->prev ;
+ ftrigio_remove(p->next) ;
}
}
+
+ r = sassserver_read_event(&a, x) ;
}
- cleanup() ;
- return 0 ;
+
+ cleanup(0) ;
+ _exit(0) ;
}
diff --git a/src/libs6/s6_compat_el_semicolon.c b/src/libs6/s6_compat_el_semicolon.c
index fe4787e..8d214dd 100644
--- a/src/libs6/s6_compat_el_semicolon.c
+++ b/src/libs6/s6_compat_el_semicolon.c
@@ -25,30 +25,26 @@ static unsigned int el_getstrict (void)
int s6_compat_el_semicolon (char const **argv)
{
static unsigned int nblock = 0 ;
- int argc1 = 0 ;
+ unsigned int strict = el_getstrict() ;
nblock++ ;
- for (;; argc1++, argv++)
+ unsigned int i = 0 ;
+ for (; argv[i] ; i++)
{
- char const *arg = *argv ;
- if (!arg) return argc1 + 1 ;
- if (!arg[0]) return argc1 ;
- else if (arg[0] == ' ') ++*argv ;
- else
+ if (!argv[i][0]) return i ;
+ else if (argv[i][0] == ' ') argv[i]++ ;
+ else if (strict)
{
- unsigned int strict = el_getstrict() ;
- if (strict)
- {
- char fmt1[UINT_FMT] ;
- char fmt2[UINT_FMT] ;
- fmt1[uint_fmt(fmt1, nblock)] = 0 ;
- fmt2[uint_fmt(fmt2, (unsigned int)argc1)] = 0 ;
- if (strict >= 2)
- strerr_dief6x(100, "unquoted argument ", arg, " at block ", fmt1, " position ", fmt2) ;
- else
- strerr_warnw6x("unquoted argument ", arg, " at block ", fmt1, " position ", fmt2) ;
- }
+ char fmt1[UINT_FMT] ;
+ char fmt2[UINT_FMT] ;
+ fmt1[uint_fmt(fmt1, nblock)] = 0 ;
+ fmt2[uint_fmt(fmt2, i)] = 0 ;
+ if (strict >= 2)
+ strerr_dief6x(100, "unquoted argument ", argv[i], " at block ", fmt1, " position ", fmt2) ;
+ else
+ strerr_warnw6x("unquoted argument ", argv[i], " at block ", fmt1, " position ", fmt2) ;
}
}
+ return i + 1 ;
}
#endif
diff --git a/src/libs6/s6_supervise_link_names.c b/src/libs6/s6_supervise_link_names.c
index de8e5c5..1002cc4 100644
--- a/src/libs6/s6_supervise_link_names.c
+++ b/src/libs6/s6_supervise_link_names.c
@@ -22,19 +22,19 @@ static inline void do_unlink (char const *scdir, char const *const *names, size_
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)
+static int registerit (ftrigr *a, uint32_t *id, 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 ;
+ if (fd == -1) 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) ;
+ return ftrigr_subscribe(a, id, 0, 0, fn, "s", deadline, stamp) ;
}
/*
@@ -86,7 +86,7 @@ int s6_supervise_link_names (char const *scdir, char const *const *servicedirs,
}
{
- ftrigr_t a = FTRIGR_ZERO ;
+ ftrigr a = FTRIGR_ZERO ;
stralloc rpsa = STRALLOC_ZERO ;
gid_t gid = options & 2 ? -1 : getegid() ;
size_t scdirlen = strlen(scdir) ;
@@ -94,7 +94,7 @@ int s6_supervise_link_names (char const *scdir, char const *const *servicedirs,
size_t i = 0 ;
uint32_t killopts = 0 ;
int r ;
- uint16_t ids[ntotal] ;
+ uint32_t ids[ntotal] ;
char lname[scdirlen + maxnlen + 7] ;
char fn[maxlen + 5 + (sizeof(S6_SUPERVISE_EVENTDIR) > 5 ? sizeof(S6_SUPERVISE_EVENTDIR) : 5)] ;
if (!ftrigr_startf(&a, deadline, stamp)) return -1 ;
@@ -108,13 +108,11 @@ int s6_supervise_link_names (char const *scdir, char const *const *servicedirs,
memcpy(fn, servicedirs[i], len) ;
if (!h)
{
- ids[m] = registerit(&a, fn, len, gid, options, deadline, stamp) ;
- if (!ids[m++]) goto err ;
+ if (!registerit(&a, ids + m++, fn, len, gid, options, deadline, stamp)) 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 ;
+ if (!registerit(&a, ids + m++, fn, len + 4, gid, options, deadline, stamp)) goto err ;
}
}
fn[len] = 0 ;
diff --git a/src/libs6/s6_supervise_unlink_names.c b/src/libs6/s6_supervise_unlink_names.c
index a0b424d..a6c7be5 100644
--- a/src/libs6/s6_supervise_unlink_names.c
+++ b/src/libs6/s6_supervise_unlink_names.c
@@ -8,14 +8,18 @@
#include <skalibs/posixplz.h>
#include <skalibs/bitarray.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
#include <s6/ftrigr.h>
#include <s6/supervise.h>
-static uint16_t registerit (ftrigr_t *a, char *fn, size_t len, tain const *deadline, tain *stamp)
+static int registerit (ftrigr *a, uint32_t *id, char *fn, size_t len, stralloc *sa, tain const *deadline, tain *stamp)
{
memcpy(fn + len, "/" S6_SUPERVISE_EVENTDIR, sizeof(S6_SUPERVISE_EVENTDIR) + 1) ;
- return ftrigr_subscribe(a, fn, "x", 0, deadline, stamp) ;
+ sa->len = 0 ;
+ if (sarealpath(sa, fn) == -1) return 0 ;
+ return ftrigr_subscribe(a, id, 0, 0, sa->s, "x", deadline, stamp) ;
}
/*
@@ -62,9 +66,10 @@ int s6_supervise_unlink_names (char const *scdir, char const *const *names, size
}
{
- ftrigr_t a = FTRIGR_ZERO ;
+ ftrigr a = FTRIGR_ZERO ;
+ stralloc sa = STRALLOC_ZERO ;
unsigned int m = 0 ;
- uint16_t ids[ntotal] ;
+ uint32_t ids[ntotal] ;
if (options & 1 && !ftrigr_startf(&a, deadline, stamp)) return -1 ;
for (size_t i = 0 ; i < n ; i++)
{
@@ -75,13 +80,11 @@ int s6_supervise_unlink_names (char const *scdir, char const *const *names, size
memcpy(fn + scdirlen + 1, names[i], nlen) ;
if (options & 1 && bitarray_peek(locked, i))
{
- ids[m] = registerit(&a, fn, scdirlen + 1 + nlen, deadline, stamp) ;
- if (ids[m]) m++ ;
+ if (registerit(&a, ids + m, fn, scdirlen + 1 + nlen, &sa, deadline, stamp)) m++ ;
if (bitarray_peek(logged, i))
{
memcpy(fn + scdirlen + 1 + nlen, "/log", 4) ;
- ids[m] = registerit(&a, fn, scdirlen + 5 + nlen, deadline, stamp) ;
- if (ids[m]) m++ ;
+ if (registerit(&a, ids + m, fn, scdirlen + 5 + nlen, &sa, deadline, stamp)) m++ ;
}
}
fn[scdirlen + 1 + nlen] = 0 ;
@@ -90,6 +93,7 @@ int s6_supervise_unlink_names (char const *scdir, char const *const *names, size
s6_svc_writectl(scdir, S6_SVSCAN_CTLDIR, "an", 2) ;
if (options & 1)
{
+ stralloc_free(&sa) ;
ftrigr_wait_and(&a, ids, m, deadline, stamp) ;
ftrigr_end(&a) ;
}
diff --git a/src/pipe-tools/s6-ftrig-listen.c b/src/pipe-tools/s6-ftrig-listen.c
index 041226e..48f5f6b 100644
--- a/src/pipe-tools/s6-ftrig-listen.c
+++ b/src/pipe-tools/s6-ftrig-listen.c
@@ -5,9 +5,11 @@
#include <signal.h>
#include <unistd.h>
-#include <skalibs/sgetopt.h>
+#include <skalibs/posixplz.h>
+#include <skalibs/uint64.h>
#include <skalibs/types.h>
#include <skalibs/strerr.h>
+#include <skalibs/gol.h>
#include <skalibs/tai.h>
#include <skalibs/iopause.h>
#include <skalibs/djbunix.h>
@@ -21,6 +23,17 @@
#define USAGE "s6-ftrig-listen [ -a | -o ] [ -t timeout ] fifodir1 regexp1 ... \"\" prog..."
#define dieusage() strerr_dieusage(100, USAGE)
+enum golb_e
+{
+ GOLB_OR = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_TIMEOUT,
+ GOLA_N
+} ;
+
static void handle_signals (void)
{
for (;;) switch (selfpipe_read())
@@ -32,37 +45,42 @@ static void handle_signals (void)
}
}
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
{
- iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ;
- tain deadline, tto ;
- ftrigr_t a = FTRIGR_ZERO ;
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'a', .lo = "and", .clear = GOLB_OR, .set = 0 },
+ { .so = 'o', .lo = "or", .clear = 0, .set = GOLB_OR },
+ } ;
+ static gol_arg const rgola[GOLA_N] =
+ {
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ uint64_t wgolb = 0 ;
+ iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ } } ;
+ tain deadline ;
+ tain tto = TAIN_INFINITE_RELATIVE ;
+ ftrigr a = FTRIGR_ZERO ;
int argc1 ;
- unsigned int i = 0 ;
- char or = 0 ;
+ unsigned int golc ;
+
PROG = "s6-ftrig-listen" ;
+ golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (argc < 4) dieusage() ;
+ if (wgola[GOLA_TIMEOUT])
{
unsigned int t = 0 ;
- for (;;)
- {
- int opt = lgetopt(argc, argv, "aot:") ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'a' : or = 0 ; break ;
- case 'o' : or = 1 ; break ;
- case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
- default : dieusage() ;
- }
- }
- if (t) tain_from_millisecs(&tto, t) ; else tto = tain_infinite_relative ;
- argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
+ strerr_dief1x(100, "timeout must be an unsigned integer") ;
+ if (t) tain_from_millisecs(&tto, t) ;
}
- if (argc < 4) dieusage() ;
+
argc1 = s6_el_semicolon(argv) ;
if (!argc1 || (argc1 & 1) || (argc == argc1 + 1)) dieusage() ;
if (argc1 >= argc) strerr_dief1x(100, "unterminated fifodir+regex block") ;
- tain_now_set_stopwatch_g() ;
+ if (!tain_now_set_stopwatch_g()) strerr_diefu1sys(111, "tain_now") ;
tain_add_g(&deadline, &tto) ;
x[0].fd = selfpipe_init() ;
if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
@@ -74,33 +92,31 @@ int main (int argc, char const **argv, char const *const *envp)
{
pid_t pid = 0 ;
- unsigned int idlen = argc1 >> 1 ;
- uint16_t ids[idlen] ;
- for (; i < idlen ; i++)
- {
- ids[i] = ftrigr_subscribe_g(&a, argv[i<<1], argv[(i<<1)+1], 0, &deadline) ;
- if (!ids[i]) strerr_diefu4sys(111, "subscribe to ", argv[i<<1], " with regexp ", argv[(i<<1)+1]) ;
- }
+ unsigned int n = argc1 >> 1 ;
+ uint32_t ids[n] ;
+ for (unsigned int i = 0 ; i < n ; i++)
+ if (!ftrigr_subscribe_g(&a, ids + i, 0, 0, argv[i<<1], argv[(i<<1)+1], &deadline))
+ strerr_diefu4sys(111, "subscribe to ", argv[i<<1], " with regexp ", argv[(i<<1)+1]) ;
- pid = cspawn(argv[argc1 + 1], argv + argc1 + 1, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+ pid = cspawn(argv[argc1 + 1], argv + argc1 + 1, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
for (;;)
{
int r ;
- i = 0 ;
- while (i < idlen)
+ unsigned int i = 0 ;
+ while (i < n)
{
- char dummy ;
- r = ftrigr_check(&a, ids[i], &dummy) ;
- if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
+ ftrigr_string fs ;
+ r = ftrigr_peek(&a, ids[i], &fs) ;
+ if (r == -1) strerr_diefu1sys(111, "ftrigr_check") ;
else if (!r) i++ ;
- else if (or) idlen = 0 ;
- else ids[i] = ids[--idlen] ;
+ else if (wgolb & GOLB_OR) n = 0 ;
+ else ids[i] = ids[--n] ;
}
- if (!idlen) break ;
+ if (!n) break ;
r = iopause_g(x, 2, &deadline) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
+ if (r == -1) strerr_diefu1sys(111, "iopause") ;
else if (!r)
{
errno = ETIMEDOUT ;
@@ -108,10 +124,8 @@ int main (int argc, char const **argv, char const *const *envp)
}
if (x[0].revents & IOPAUSE_READ) handle_signals() ;
if (x[1].revents & IOPAUSE_READ)
- {
if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
- }
}
}
- return 0 ;
+ _exit(0) ;
}
diff --git a/src/pipe-tools/s6-ftrig-listen1.c b/src/pipe-tools/s6-ftrig-listen1.c
index 4c42820..9ebd5ca 100644
--- a/src/pipe-tools/s6-ftrig-listen1.c
+++ b/src/pipe-tools/s6-ftrig-listen1.c
@@ -1,13 +1,15 @@
/* ISC license. */
+#include <sys/uio.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
-#include <skalibs/sgetopt.h>
+#include <skalibs/posixplz.h>
#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
+#include <skalibs/gol.h>
#include <skalibs/strerr.h>
#include <skalibs/tai.h>
#include <skalibs/iopause.h>
@@ -20,6 +22,12 @@
#define USAGE "s6-ftrig-listen1 [ -t timeout ] fifodir regexp prog..."
+enum gola_e
+{
+ GOLA_TIMEOUT,
+ GOLA_N
+} ;
+
static void handle_signals (void)
{
for (;;) switch (selfpipe_read())
@@ -31,55 +39,57 @@ static void handle_signals (void)
}
}
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
- iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ;
- tain deadline, tto ;
- ftrigr_t a = FTRIGR_ZERO ;
+ static gol_arg const rgola[GOLA_N] =
+ {
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ } } ;
+ tain deadline ;
+ tain tto = TAIN_INFINITE_RELATIVE ;
+ ftrigr a = FTRIGR_ZERO ;
pid_t pid ;
- uint16_t id ;
- char pack[2] = " \n" ;
+ uint32_t id ;
+ ftrigr_string fs ;
+ unsigned int golc ;
+
PROG = "s6-ftrig-listen1" ;
+ golc = gol_main(argc, argv, 0, 0, rgola, GOLA_N, 0, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (argc < 3) strerr_dieusage(100, USAGE) ;
+ if (wgola[GOLA_TIMEOUT])
{
unsigned int t = 0 ;
- for (;;)
- {
- int opt = lgetopt(argc, argv, "t:") ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
- default : strerr_dieusage(100, USAGE) ;
- }
- }
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
+ strerr_dief1x(100, "timeout must be an unsigned integer") ;
if (t) tain_from_millisecs(&tto, t) ;
- else tto = tain_infinite_relative ;
- argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
}
- if (argc < 3) strerr_dieusage(100, USAGE) ;
- tain_now_set_stopwatch_g() ;
+ if (!tain_now_set_stopwatch_g()) strerr_diefu1sys(111, "tain_now") ;
tain_add_g(&deadline, &tto) ;
+
if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "sig_ignore") ;
if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ;
- id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ;
- if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;
+ if (!ftrigr_subscribe_g(&a, &id, 0, 0, argv[0], argv[1], &deadline))
+ strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;
x[0].fd = selfpipe_init() ;
- if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
+ if (x[0].fd == -1) strerr_diefu1sys(111, "selfpipe_init") ;
if (!selfpipe_trap(SIGCHLD)) strerr_diefu1sys(111, "selfpipe_trap") ;
x[1].fd = ftrigr_fd(&a) ;
- pid = cspawn(argv[2], argv+2, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+ pid = cspawn(argv[2], argv+2, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
if (!pid) strerr_diefu2sys(111, "spawn ", argv[2]) ;
for (;;)
{
- int r = ftrigr_check(&a, id, &pack[0]) ;
- if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
+ int r = ftrigr_peek(&a, id, &fs) ;
+ if (r == -1) strerr_diefu1sys(111, "ftrigr_peek") ;
if (r) break ;
r = iopause_g(x, 2, &deadline) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
+ if (r == -1) strerr_diefu1sys(111, "iopause") ;
else if (!r)
{
errno = ETIMEDOUT ;
@@ -87,11 +97,10 @@ int main (int argc, char const *const *argv, char const *const *envp)
}
if (x[0].revents & IOPAUSE_READ) handle_signals() ;
if (x[1].revents & IOPAUSE_READ)
- {
- if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
- }
+ if (ftrigr_update(&a) == -1) strerr_diefu1sys(111, "ftrigr_update") ;
}
- if (allwrite(1, pack, 2) < 2) strerr_diefu1sys(111, "write to stdout") ;
- return 0 ;
+ struct iovec v[2] = { { .iov_base = fs.s, .iov_len = fs.len }, { .iov_base = "\n", .iov_len = 1 } } ;
+ if (allwritev(1, v, 2) < 2) strerr_diefu1sys(111, "write to stdout") ;
+ _exit(0) ;
}
diff --git a/src/pipe-tools/s6-ftrig-wait.c b/src/pipe-tools/s6-ftrig-wait.c
index d0e3a1a..e36fa2d 100644
--- a/src/pipe-tools/s6-ftrig-wait.c
+++ b/src/pipe-tools/s6-ftrig-wait.c
@@ -1,49 +1,63 @@
/* ISC license. */
+#include <sys/uio.h>
#include <stdint.h>
+#include <unistd.h>
#include <errno.h>
+
#include <skalibs/allreadwrite.h>
-#include <skalibs/sgetopt.h>
+#include <skalibs/gol.h>
#include <skalibs/types.h>
#include <skalibs/strerr.h>
#include <skalibs/tai.h>
+#include <skalibs/siovec.h>
+
#include <s6/ftrigr.h>
#define USAGE "s6-ftrig-wait [ -t timeout ] fifodir regexp"
+enum gola_e
+{
+ GOLA_TIMEOUT,
+ GOLA_N
+} ;
+
int main (int argc, char const *const *argv)
{
- tain deadline, tto ;
- ftrigr_t a = FTRIGR_ZERO ;
- uint16_t id ;
- char pack[2] = " \n" ;
+ static gol_arg const rgola[GOLA_N] =
+ {
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ tain deadline ;
+ tain tto = TAIN_INFINITE_RELATIVE ;
+ ftrigr a = FTRIGR_ZERO ;
+ ftrigr_string fs ;
+ uint32_t id ;
+ unsigned int golc ;
+
PROG = "s6-ftrig-wait" ;
+ golc = gol_main(argc, argv, 0, 0, rgola, GOLA_N, 0, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (argc < 2) strerr_dieusage(100, USAGE) ;
+ if (wgola[GOLA_TIMEOUT])
{
unsigned int t = 0 ;
- for (;;)
- {
- int opt = lgetopt(argc, argv, "t:") ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
- default : strerr_dieusage(100, USAGE) ;
- }
- }
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
+ strerr_dief1x(100, "timeout must be an unsigned integer") ;
if (t) tain_from_millisecs(&tto, t) ;
- else tto = tain_infinite_relative ;
- argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
}
- if (argc < 2) strerr_dieusage(100, USAGE) ;
- tain_now_set_stopwatch_g() ;
+ if (!tain_now_set_stopwatch_g()) strerr_diefu1sys(111, "tain_now") ;
tain_add_g(&deadline, &tto) ;
if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ;
- id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ;
- if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;
- if (ftrigr_wait_or_g(&a, &id, 1, &deadline, &pack[0]) == -1)
- strerr_diefu2sys((errno == ETIMEDOUT) ? 1 : 111, "match regexp on ", argv[1]) ;
- if (allwrite(1, pack, 2) < 2) strerr_diefu1sys(111, "write to stdout") ;
- return 0 ;
+ if (!ftrigr_subscribe_g(&a, &id, 0, 0, argv[0], argv[1], &deadline))
+ strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;
+ if (ftrigr_wait_or_g(&a, &id, 1, &fs, &deadline) == -1)
+ strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "match regexp on ", argv[1]) ;
+
+ struct iovec v[2] = { { .iov_base = fs.s, .iov_len = fs.len }, { .iov_base = "\n", .iov_len = 1 } } ;
+ if (allwritev(1, v, 2) < siovec_len(v, 2)) strerr_diefu1sys(111, "write to stdout") ;
+ _exit(0) ;
}
diff --git a/src/supervision/s6-notifyoncheck.c b/src/supervision/s6-notifyoncheck.c
index 8c139af..ba8e91d 100644
--- a/src/supervision/s6-notifyoncheck.c
+++ b/src/supervision/s6-notifyoncheck.c
@@ -7,10 +7,11 @@
#include <limits.h>
#include <sys/wait.h>
+#include <skalibs/posixplz.h>
#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/bytestr.h>
-#include <skalibs/sgetopt.h>
+#include <skalibs/gol.h>
#include <skalibs/strerr.h>
#include <skalibs/tai.h>
#include <skalibs/cspawn.h>
@@ -23,15 +24,31 @@
#ifdef S6_USE_EXECLINE
#include <execline/config.h>
-#define USAGE "s6-notifyoncheck [ -d ] [ -3 fd ] [ -s initialsleep ] [ -T globaltimeout ] [ -t localtimeout ] [ -w waitingtime ] [ -n tries ] [ -c \"checkprog...\" ] prog..."
-#define OPTIONS "d3:s:T:t:w:n:c:"
+# define USAGE "s6-notifyoncheck [ -d ] [ -3 fd ] [ -s initialsleep ] [ -T globaltimeout ] [ -t localtimeout ] [ -w waitingtime ] [ -n tries ] [ -c \"checkprog...\" ] prog..."
#else
-#define USAGE "s6-notifyoncheck [ -d ] [ -3 fd ] [ -s initialsleep ] [ -T globaltimeout ] [ -t localtimeout ] [ -w waitingtime ] [ -n tries ] prog..."
-#define OPTIONS "d3:s:T:t:w:n:"
+# define USAGE "s6-notifyoncheck [ -d ] [ -3 fd ] [ -s initialsleep ] [ -T globaltimeout ] [ -t localtimeout ] [ -w waitingtime ] [ -n tries ] prog..."
#endif
#define dieusage() strerr_dieusage(100, USAGE)
+enum golb_e
+{
+ GOLB_DOUBLEFORK = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_NOTIF,
+ GOLA_INITIALSLEEP,
+ GOLA_GLOBALTIMEOUT,
+ GOLA_LOCALTIMEOUT,
+ GOLA_WAITINGTIME,
+ GOLA_TRIES,
+#ifdef S6_USE_EXECLINE
+ GOLA_CHECKPROG,
+#endif
+ GOLA_N
+} ;
static inline int read_uint (char const *file, unsigned int *fd)
{
@@ -65,97 +82,128 @@ static inline int handle_signals (pid_t pid, int *w)
}
}
-static int handle_event (ftrigr_t *a, uint16_t id, pid_t pid)
+static int handle_event (ftrigr *a, uint32_t id, pid_t pid)
{
int r ;
- char what ;
- if (ftrigr_update(a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
- r = ftrigr_check(a, id, &what) ;
- if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
- if (r && what == 'd')
+ ftrigr_string fs ;
+ if (ftrigr_update(a) == -1) strerr_diefu1sys(111, "ftrigr_update") ;
+ r = ftrigr_peek(a, id, &fs) ;
+ if (r == -1) strerr_diefu1sys(111, "ftrigr_check") ;
+ if (r)
{
- if (pid) kill(pid, SIGTERM) ;
- return 1 ;
+ if (memchr(fs.s, 'd', fs.len))
+ {
+ if (pid) kill(pid, SIGTERM) ;
+ ftrigr_ack(a, id) ;
+ return 1 ;
+ }
+ ftrigr_ack(a, id) ;
}
return 0 ;
}
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
- ftrigr_t a = FTRIGR_ZERO ;
- iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ } } ;
- char const *childargv[4] = { "./data/check", 0, 0, 0 } ;
+ static gol_bool rgolb[] =
+ {
+ { .so = 'd', .lo = "doublefork", .clear = 0, .set = GOLB_DOUBLEFORK },
+ } ;
+ static gol_arg rgola[] =
+ {
+ { .so = '3', .lo = "notification-fd", .i = GOLA_NOTIF },
+ { .so = 's', .lo = "initial-sleep", .i = GOLA_INITIALSLEEP },
+ { .so = 'T', .lo = "global-timeout", .i = GOLA_GLOBALTIMEOUT },
+ { .so = 't', .lo = "local-timeout", .i = GOLA_LOCALTIMEOUT },
+ { .so = 'w', .lo = "waiting-time", .i = GOLA_WAITINGTIME },
+ { .so = 'n', .lo = "tries", .i = GOLA_TRIES },
#ifdef S6_USE_EXECLINE
- char const *checkprog = 0 ;
+ { .so = 'c', .lo = "check-program", .i = GOLA_CHECKPROG },
#endif
+ } ;
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ ftrigr a = FTRIGR_ZERO ;
+ iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ } } ;
+ char const *childargv[4] = { "./data/check", 0, 0, 0 } ;
unsigned int fd ;
- int df = 0 ;
- int autodetect = 1 ;
int p[2] ;
- tain globaldeadline, sleeptto, localtto, waittto ;
- unsigned int tries = 7 ;
- uint16_t id ;
+ tain sleeptto ;
+ tain globaldeadline = TAIN_INFINITE_RELATIVE ;
+ tain localtto = TAIN_INFINITE_RELATIVE ;
+ tain waittto = TAIN_INFINITE_RELATIVE ;
+ unsigned int tries ;
+ uint32_t id ;
+ unsigned int golc ;
+
PROG = "s6-notifyoncheck" ;
+ golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (!argc) dieusage() ;
+ if (wgola[GOLA_NOTIF])
{
- subgetopt l = SUBGETOPT_ZERO ;
- unsigned int initialsleep = 10, globaltimeout = 0, localtimeout = 0, waitingtime = 1000 ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, OPTIONS, &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'd' : df = 1 ; break ;
- case '3' : if (!uint0_scan(l.arg, &fd)) dieusage() ; autodetect = 0 ; break ;
- case 's' : if (!uint0_scan(l.arg, &initialsleep)) dieusage() ; break ;
- case 'T' : if (!uint0_scan(l.arg, &globaltimeout)) dieusage() ; break ;
- case 't' : if (!uint0_scan(l.arg, &localtimeout)) dieusage() ; break ;
- case 'w' : if (!uint0_scan(l.arg, &waitingtime)) dieusage() ; break ;
- case 'n' : if (!uint0_scan(l.arg, &tries)) dieusage() ; break ;
-#ifdef S6_USE_EXECLINE
- case 'c' : checkprog = l.arg ; break ;
-#endif
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (!argc) dieusage() ;
-
- if (!tain_from_millisecs(&sleeptto, initialsleep)) dieusage() ;
- if (globaltimeout) tain_from_millisecs(&globaldeadline, globaltimeout) ;
- else globaldeadline = tain_infinite_relative ;
- if (localtimeout) tain_from_millisecs(&localtto, localtimeout) ;
- else localtto = tain_infinite_relative ;
- if (waitingtime) tain_from_millisecs(&waittto, waitingtime) ;
- else waittto = tain_infinite_relative ;
- if (!tries) tries = UINT_MAX ;
+ if (!uint0_scan(wgola[GOLA_NOTIF], &fd))
+ strerr_dief2x(100, "notification-fd", " must be an unsigned integer") ;
}
+ else
+ {
+ int r = read_uint("notification-fd", &fd) ;
+ if (r < 0) strerr_diefu2sys(111, "read ", "./notification-fd") ;
+ if (!r) strerr_dief2x(100, "invalid ", "./notification-fd") ;
+ }
+ if (fcntl(fd, F_GETFD) < 0)
+ strerr_dief2sys(111, "notification-fd", " sanity check failed") ;
+ if (wgola[GOLA_INITIALSLEEP])
+ {
+ if (!uint0_scan(wgola[GOLA_INITIALSLEEP], &tries))
+ strerr_dief2x(100, "initial-sleep", " must be an unsigned integer") ;
+ }
+ else tries = 10 ;
+ if (!tain_from_millisecs(&sleeptto, tries)) dieusage() ;
+ if (wgola[GOLA_GLOBALTIMEOUT])
{
- int r = s6_svc_ok(".") ;
- if (r < 0) strerr_diefu1sys(111, "sanity-check current service directory") ;
- if (!r) strerr_dief1x(100, "s6-supervise not running.") ;
+ if (!uint0_scan(wgola[GOLA_GLOBALTIMEOUT], &tries))
+ strerr_dief2x(100, "global-timeout", " must be an unsigned integer") ;
+ if (tries) tain_from_millisecs(&globaldeadline, tries) ;
+ }
+ if (wgola[GOLA_LOCALTIMEOUT])
+ {
+ if (!uint0_scan(wgola[GOLA_LOCALTIMEOUT], &tries))
+ strerr_dief2x(100, "local-timeout", " must be an unsigned integer") ;
+ if (tries) tain_from_millisecs(&localtto, tries) ;
+ }
+ if (wgola[GOLA_WAITINGTIME])
+ {
+ if (!uint0_scan(wgola[GOLA_WAITINGTIME], &tries))
+ strerr_dief2x(100, "waiting-time", " must be an unsigned integer") ;
}
+ else tries = 1000 ;
+ if (!tain_from_millisecs(&waittto, tries)) dieusage() ;
+ if (wgola[GOLA_TRIES])
+ {
+ if (!uint0_scan(wgola[GOLA_TRIES], &tries))
+ strerr_dief2x(100, "waiting-time", " must be an unsigned integer") ;
+ if (!tries) tries = UINT_MAX ;
+ }
+ else tries = 7 ;
+
#ifdef S6_USE_EXECLINE
- if (checkprog)
+ if (wgola[GOLA_CHECKPROG])
{
childargv[0] = EXECLINE_EXTBINPREFIX "execlineb" ;
childargv[1] = "-Pc" ;
- childargv[2] = checkprog ;
+ childargv[2] = wgola[GOLA_CHECKPROG] ;
}
#endif
- if (autodetect)
{
- int r = read_uint("notification-fd", &fd) ;
- if (r < 0) strerr_diefu2sys(111, "read ", "./notification-fd") ;
- if (!r) strerr_dief2x(100, "invalid ", "./notification-fd") ;
+ int r = s6_svc_ok(".") ;
+ if (r < 0) strerr_diefu1sys(111, "sanity-check current service directory") ;
+ if (!r) strerr_dief1x(100, "s6-supervise not running.") ;
}
- if (fcntl(fd, F_GETFD) < 0)
- strerr_dief2sys(111, "notification-fd", " sanity check failed") ;
- tain_now_set_stopwatch_g() ;
+ if (!tain_now_set_stopwatch_g()) strerr_diefu1sys(111, "tain_now") ;
tain_add_g(&globaldeadline, &globaldeadline) ;
@@ -179,16 +227,16 @@ int main (int argc, char const *const *argv, char const *const *envp)
*/
if (pipecoe(p) < 0) strerr_diefu1sys(111, "pipe") ;
- switch (df ? doublefork() : fork())
+ switch (wgolb & GOLB_DOUBLEFORK ? doublefork() : fork())
{
- case -1: strerr_diefu1sys(111, df ? "doublefork" : "fork") ;
+ case -1 : strerr_diefu1sys(111, wgolb & GOLB_DOUBLEFORK ? "doublefork" : "fork") ;
case 0 : break ;
default:
{
char c ;
- close((int)fd) ;
+ close(fd) ;
if (read(p[0], &c, 1) < 1) strerr_diefu1x(111, "synchronize with child") ;
- xexec_e(argv, envp) ;
+ xexec(argv) ;
}
}
@@ -197,11 +245,11 @@ int main (int argc, char const *const *argv, char const *const *envp)
close(p[0]) ;
if (!ftrigr_startf_g(&a, &globaldeadline))
strerr_diefu1sys(111, "ftrigr_startf") ;
- id = ftrigr_subscribe_g(&a, "event", "d", 0, &globaldeadline) ;
- if (!id) strerr_diefu1sys(111, "ftrigr_subscribe to event fifodir") ;
+ if (!ftrigr_subscribe_g(&a, &id, 0, 0, "event", "d", &globaldeadline))
+ strerr_diefu1sys(111, "ftrigr_subscribe to event fifodir") ;
x[0].fd = selfpipe_init() ;
- if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
+ if (x[0].fd == -1) strerr_diefu1sys(111, "selfpipe_init") ;
if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "trap SIGCHLD") ;
x[1].fd = ftrigr_fd(&a) ;
@@ -225,13 +273,13 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (r < 0) strerr_diefu1sys(111, "iopause") ;
if (!r)
{
- if (!tain_future(&globaldeadline)) return 3 ;
+ if (!tain_future(&globaldeadline)) _exit(3) ;
else break ;
}
- if (handle_event(&a, id, 0)) return 2 ;
+ if (handle_event(&a, id, 0)) _exit(2) ;
}
- pid = cspawn(childargv[0], childargv, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+ pid = cspawn(childargv[0], childargv, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
if (!pid)
{
strerr_warnwu2sys("spawn ", childargv[0]) ;
@@ -249,7 +297,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (!tain_future(&globaldeadline))
{
kill(pid, SIGTERM) ;
- return 3 ;
+ _exit(3) ;
}
else break ;
}
@@ -261,14 +309,14 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (WIFEXITED(wstat) && !WEXITSTATUS(wstat))
{
fd_write((int)fd, "\n", 1) ;
- return 0 ;
+ _exit(0) ;
}
else break ;
}
}
- if (x[1].revents & IOPAUSE_READ && handle_event(&a, id, pid)) return 2 ;
+ if (x[1].revents & IOPAUSE_READ && handle_event(&a, id, pid)) _exit(2) ;
}
}
- return 1 ;
+ _exit(1) ;
}
diff --git a/src/supervision/s6-svlisten.c b/src/supervision/s6-svlisten.c
index 0774ef2..f2d5ddf 100644
--- a/src/supervision/s6-svlisten.c
+++ b/src/supervision/s6-svlisten.c
@@ -1,7 +1,9 @@
/* ISC license. */
#include <stdint.h>
+#include <unistd.h>
+#include <skalibs/posixplz.h>
#include <skalibs/sgetopt.h>
#include <skalibs/types.h>
#include <skalibs/bitarray.h>
@@ -17,7 +19,7 @@
#define USAGE "s6-svlisten [ -U | -u | -d | -D | -r | -R ] [ -a | -o ] [ -t timeout ] servicedir... \"\" prog..."
#define dieusage() strerr_dieusage(100, USAGE)
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
{
tain deadline, tto ;
int argc1 ;
@@ -67,11 +69,11 @@ int main (int argc, char const **argv, char const *const *envp)
s6_svlisten_t foo = S6_SVLISTEN_ZERO ;
pid_t pid ;
unsigned int e ;
- uint16_t ids[argc1] ;
+ uint32_t ids[argc1] ;
unsigned char upstate[bitarray_div8(argc1)] ;
unsigned char readystate[bitarray_div8(argc1)] ;
s6_svlisten_init(argc1, argv, &foo, ids, upstate, readystate, &deadline) ;
- pid = cspawn(argv[argc1 + 1], argv + argc1 + 1, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+ pid = cspawn(argv[argc1 + 1], argv + argc1 + 1, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
if (wantup == 2)
{
@@ -82,5 +84,5 @@ int main (int argc, char const **argv, char const *const *envp)
e = s6_svlisten_loop(&foo, wantup, wantready, or, &deadline, selfpipe_fd(), &s6_svlisten_signal_handler) ;
if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ;
}
- return 0 ;
+ _exit(0) ;
}
diff --git a/src/supervision/s6-svlisten.h b/src/supervision/s6-svlisten.h
index a0aa591..a90febc 100644
--- a/src/supervision/s6-svlisten.h
+++ b/src/supervision/s6-svlisten.h
@@ -13,9 +13,9 @@ typedef action_func *action_func_ref ;
typedef struct s6_svlisten_s s6_svlisten_t, *s6_svlisten_t_ref ;
struct s6_svlisten_s
{
- ftrigr_t a ;
+ ftrigr a ;
unsigned int n ;
- uint16_t *ids ;
+ uint32_t *ids ;
unsigned char *upstate ;
unsigned char *readystate ;
} ;
@@ -23,7 +23,7 @@ struct s6_svlisten_s
extern void s6_svlisten_signal_handler (void) ;
extern void s6_svlisten_selfpipe_init (void) ;
-extern void s6_svlisten_init (int, char const *const *, s6_svlisten_t *, uint16_t *, unsigned char *, unsigned char *, tain const *) ;
+extern void s6_svlisten_init (int, char const *const *, s6_svlisten_t *, uint32_t *, unsigned char *, unsigned char *, tain const *) ;
extern unsigned int s6_svlisten_loop (s6_svlisten_t *, int, int, int, tain const *, int, action_func_ref) ;
#endif
diff --git a/src/supervision/s6-svlisten1.c b/src/supervision/s6-svlisten1.c
index 4289e8c..cfda1af 100644
--- a/src/supervision/s6-svlisten1.c
+++ b/src/supervision/s6-svlisten1.c
@@ -1,7 +1,9 @@
/* ISC license. */
#include <stdint.h>
+#include <unistd.h>
+#include <skalibs/posixplz.h>
#include <skalibs/sgetopt.h>
#include <skalibs/types.h>
#include <skalibs/tai.h>
@@ -14,13 +16,13 @@
#define USAGE "s6-svlisten1 [ -U | -u | -d | -D | -r | -R ] [ -t timeout ] servicedir prog..."
#define dieusage() strerr_dieusage(100, USAGE)
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
s6_svlisten_t foo = S6_SVLISTEN_ZERO ;
tain deadline, tto ;
pid_t pid ;
int wantup = 1, wantready = 0, wantrestart = 0 ;
- uint16_t id ;
+ uint32_t id ;
unsigned char upstate, readystate ;
PROG = "s6-svlisten1" ;
{
@@ -50,12 +52,12 @@ int main (int argc, char const *const *argv, char const *const *envp)
tain_add_g(&deadline, &tto) ;
s6_svlisten_selfpipe_init() ;
s6_svlisten_init(1, argv, &foo, &id, &upstate, &readystate, &deadline) ;
- pid = cspawn(argv[1], argv + 1, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+ pid = cspawn(argv[1], argv + 1, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ;
if (wantrestart)
if (s6_svlisten_loop(&foo, 0, 1, 1, &deadline, selfpipe_fd(), &s6_svlisten_signal_handler))
strerr_dief2x(1, argv[0], " failed permanently or its supervisor died") ;
if (s6_svlisten_loop(&foo, wantup, wantready, 1, &deadline, selfpipe_fd(), &s6_svlisten_signal_handler))
strerr_dief2x(1, argv[0], " failed permanently or its supervisor died") ;
- return 0 ;
+ _exit(0) ;
}
diff --git a/src/supervision/s6-svscan.c b/src/supervision/s6-svscan.c
index cb30829..1325be5 100644
--- a/src/supervision/s6-svscan.c
+++ b/src/supervision/s6-svscan.c
@@ -10,10 +10,9 @@
#include <skalibs/posixplz.h>
#include <skalibs/uint32.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/sgetopt.h>
#include <skalibs/types.h>
-#include <skalibs/strerr.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/envexec.h>
#include <skalibs/tai.h>
#include <skalibs/iopause.h>
#include <skalibs/devino.h>
@@ -22,7 +21,6 @@
#include <skalibs/direntry.h>
#include <skalibs/sig.h>
#include <skalibs/selfpipe.h>
-#include <skalibs/exec.h>
#include <skalibs/bitarray.h>
#include <skalibs/genset.h>
#include <skalibs/avltreen.h>
@@ -32,7 +30,7 @@
#include <skalibs/posixishard.h>
-#define USAGE "s6-svscan [ -c services_max | -C services_max ] [ -L name_max ] [ -t timeout ] [ -d notif ] [ -X consoleholder ] [ dir ]"
+#define USAGE "s6-svscan [ -C services_max ] [ -L name_max ] [ -t timeout ] [ -d notif ] [ -X consoleholder ] scandir"
#define dieusage() strerr_dieusage(100, USAGE)
#define CTL S6_SVSCAN_CTLDIR "/control"
@@ -43,6 +41,16 @@
#define SIGNAL_PROG_LEN (sizeof(SIGNAL_PROG) - 1)
#define SPECIAL_LOGGER_SERVICE "s6-svscan-log"
+enum gola_e
+{
+ GOLA_MAX,
+ GOLA_NAMEMAX,
+ GOLA_TIMEOUT,
+ GOLA_NOTIF,
+ GOLA_CONSOLE,
+ GOLA_N
+} ;
+
typedef struct service_s service, *service_ref ;
struct service_s
{
@@ -650,82 +658,92 @@ static inline int control_init (void)
int main (int argc, char const *const *argv)
{
+ static gol_arg const rgola[GOLA_N] =
+ {
+ { .so = 'C', .lo = "services-max", .i = GOLA_MAX },
+ { .so = 'L', .lo = "name-max", .i = GOLA_NAMEMAX },
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ { .so = 'd', .lo = "notification-fd", .i = GOLA_NOTIF },
+ { .so = 'X', .lo = "console-holder", .i = GOLA_CONSOLE },
+ } ;
iopause_fd x[2] = { { .fd = -1, .events = IOPAUSE_READ }, { .fd = -1, .events = IOPAUSE_READ } } ;
- PROG = "s6-svscan" ;
+ unsigned int notif = 0 ;
+ sigset_t set ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ unsigned int golc ;
+ PROG = "s6-svscan" ;
+ golc = gol_main(argc, argv, 0, 0, rgola, GOLA_N, 0, wgola) ;
+ argc -= golc ; argv += golc ;
+ if (!argc) dieusage() ;
+ if (wgola[GOLA_MAX])
{
- subgetopt l = SUBGETOPT_ZERO ;
- unsigned int notif = 0 ;
- unsigned int t = 0 ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "c:C:L:t:d:X:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'c' : if (!uint320_scan(l.arg, &max)) dieusage() ; max <<= 1 ; break ;
- case 'C' : if (!uint320_scan(l.arg, &max)) dieusage() ; break ;
- case 'L' : if (!uint320_scan(l.arg, &namemax)) dieusage() ; break ;
- case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
- case 'd' : if (!uint0_scan(l.arg, &notif)) dieusage() ; break ;
- case 'X' : if (!uint0_scan(l.arg, &consoleholder)) dieusage() ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (t) tain_from_millisecs(&scantto, t) ;
+ if (!uint320_scan(wgola[GOLA_MAX], &max))
+ strerr_dief2x(100, "services_max", " must be an unsigned integer") ;
if (max < 4) max = 4 ;
if (max > 160000) max = 160000 ;
- special = max ;
+ }
+ if (wgola[GOLA_NAMEMAX])
+ {
+ if (!uint320_scan(wgola[GOLA_NAMEMAX], &max))
+ strerr_dief2x(100, "name_max", " must be an unsigned integer") ;
if (namemax < 11) namemax = 11 ;
if (namemax > 1019) namemax = 1019 ;
+ }
+ if (wgola[GOLA_TIMEOUT])
+ {
+ unsigned int t = 0 ;
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
+ strerr_dief2x(100, "timeout", " must be an unsigned integer") ;
+ if (t) tain_from_millisecs(&scantto, t) ;
+ }
+ if (wgola[GOLA_NOTIF])
+ {
+ if (!uint0_scan(wgola[GOLA_NOTIF], &notif))
+ strerr_dief2x(100, "notif", " must be an unsigned integer") ;
+ if (notif < 3) strerr_dief2x(100, "notif", " must be 3 or more") ;
+ if (fcntl(notif, F_GETFD) == -1) strerr_dief1sys(100, "invalid notification fd") ;
+ }
+ if (wgola[GOLA_CONSOLE])
+ {
+ if (!uint0_scan(wgola[GOLA_CONSOLE], &consoleholder))
+ strerr_dief2x(100, "consoleholder", " must be an unsigned integer") ;
+ if (consoleholder < 3) strerr_dief2x(100, "consoleholder", " must be 3 or more") ;
+ if (fcntl(consoleholder, F_GETFD) == -1) strerr_dief1sys(100, "invalid console holder fd") ;
+ if (coe(consoleholder) == -1) strerr_diefu1sys(111, "coe console holder") ;
+ }
- if (notif)
- {
- if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
- if (fcntl(notif, F_GETFD) == -1) strerr_dief1sys(100, "invalid notification fd") ;
- }
- if (consoleholder)
- {
- if (consoleholder < 3) strerr_dief1x(100, "console holder fd must be 3 or more") ;
- if (fcntl(consoleholder, F_GETFD) < 0) strerr_dief1sys(100, "invalid console holder fd") ;
- if (coe(consoleholder) == -1) strerr_diefu1sys(111, "coe console holder") ;
- }
- if (!fd_sanitize()) strerr_diefu1x(100, "sanitize standard fds") ;
-
- if (argc && (chdir(argv[0]) == -1)) strerr_diefu1sys(111, "chdir") ;
- x[1].fd = control_init() ;
- x[0].fd = selfpipe_init() ;
- if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
- if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ;
+ special = max ;
+ if (!fd_sanitize()) strerr_diefu1x(100, "sanitize standard fds") ;
+ if (chdir(argv[0]) == -1) strerr_diefu2sys(111, "chdir to ", argv[0]) ;
+ x[1].fd = control_init() ;
+ x[0].fd = selfpipe_init() ;
+ if (x[0].fd == -1) strerr_diefu1sys(111, "selfpipe_init") ;
+ if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ;
- {
- sigset_t set ;
- sigemptyset(&set) ;
- sigaddset(&set, SIGCHLD) ;
- sigaddset(&set, SIGALRM) ;
- sigaddset(&set, SIGABRT) ;
- sigaddset(&set, SIGHUP) ;
- sigaddset(&set, SIGINT) ;
- sigaddset(&set, SIGTERM) ;
- sigaddset(&set, SIGQUIT) ;
- sigaddset(&set, SIGUSR1) ;
- sigaddset(&set, SIGUSR2) ;
+ sigemptyset(&set) ;
+ sigaddset(&set, SIGCHLD) ;
+ sigaddset(&set, SIGALRM) ;
+ sigaddset(&set, SIGABRT) ;
+ sigaddset(&set, SIGHUP) ;
+ sigaddset(&set, SIGINT) ;
+ sigaddset(&set, SIGTERM) ;
+ sigaddset(&set, SIGQUIT) ;
+ sigaddset(&set, SIGUSR1) ;
+ sigaddset(&set, SIGUSR2) ;
#ifdef SIGPWR
- sigaddset(&set, SIGPWR) ;
+ sigaddset(&set, SIGPWR) ;
#endif
#ifdef SIGWINCH
- sigaddset(&set, SIGWINCH) ;
+ sigaddset(&set, SIGWINCH) ;
#endif
- if (!selfpipe_trapset(&set)) strerr_diefu1sys(111, "trap signals") ;
- }
+ if (!selfpipe_trapset(&set)) strerr_diefu1sys(111, "trap signals") ;
- initial_cleanup() ;
- if (notif)
- {
- write(notif, "\n", 1) ;
- close(notif) ;
- }
+ initial_cleanup() ;
+ if (notif)
+ {
+ write(notif, "\n", 1) ;
+ close(notif) ;
}
{
@@ -794,5 +812,5 @@ int main (int argc, char const *const *argv)
execv(eargv[0], (char **)eargv) ;
if (errno != ENOENT) panicnosp("exec finish script " FINISH_PROG) ;
}
- return 0 ;
+ _exit(0) ;
}
diff --git a/src/supervision/s6-svwait.c b/src/supervision/s6-svwait.c
index 78f5c3f..ca0fd35 100644
--- a/src/supervision/s6-svwait.c
+++ b/src/supervision/s6-svwait.c
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <signal.h>
+#include <unistd.h>
#include <skalibs/sgetopt.h>
#include <skalibs/types.h>
@@ -52,7 +53,7 @@ int main (int argc, char const *const *argv)
{
s6_svlisten_t foo = S6_SVLISTEN_ZERO ;
unsigned int e ;
- uint16_t ids[argc] ;
+ uint32_t ids[argc] ;
unsigned char upstate[bitarray_div8(argc)] ;
unsigned char readystate[bitarray_div8(argc)] ;
if (!sig_ignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ;
@@ -66,5 +67,5 @@ int main (int argc, char const *const *argv)
e = s6_svlisten_loop(&foo, wantup, wantready, or, &deadline, -1, 0) ;
if (e) strerr_dief1x(e, "some services reported permanent failure or their supervisor died") ;
}
- return 0 ;
+ _exit(0) ;
}
diff --git a/src/supervision/s6_svlisten_loop.c b/src/supervision/s6_svlisten_loop.c
index d7234b1..60e77ad 100644
--- a/src/supervision/s6_svlisten_loop.c
+++ b/src/supervision/s6_svlisten_loop.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <string.h>
+#include <sys/uio.h>
#include <unistd.h>
#include <skalibs/bytestr.h>
@@ -16,7 +17,7 @@
#include <s6/supervise.h>
#include "s6-svlisten.h"
-void s6_svlisten_init (int argc, char const *const *argv, s6_svlisten_t *foo, uint16_t *ids, unsigned char *upstate, unsigned char *readystate, tain const *deadline)
+void s6_svlisten_init (int argc, char const *const *argv, s6_svlisten_t *foo, uint32_t *ids, unsigned char *upstate, unsigned char *readystate, tain const *deadline)
{
gid_t gid = getegid() ;
unsigned int i = 0 ;
@@ -34,8 +35,8 @@ void s6_svlisten_init (int argc, char const *const *argv, s6_svlisten_t *foo, ui
s[len] = '/' ;
memcpy(s + len + 1, S6_SUPERVISE_EVENTDIR, sizeof(S6_SUPERVISE_EVENTDIR)) ;
ftrigw_fifodir_make(s, gid, 0) ;
- foo->ids[i] = ftrigr_subscribe_g(&foo->a, s, "[DuUdOx]", FTRIGR_REPEAT, deadline) ;
- if (!foo->ids[i]) strerr_diefu2sys(111, "subscribe to events for ", argv[i]) ;
+ if (!ftrigr_subscribe_g(&foo->a, foo->ids + i, FTRIGR_REPEAT, 0, s, "[DuUdOx]", deadline))
+ strerr_diefu2sys(111, "subscribe to events for ", argv[i]) ;
if (!s6_svstatus_read(argv[i], &status)) strerr_diefu1sys(111, "s6_svstatus_read") ;
bitarray_poke(foo->upstate, i, status.pid && !status.flagfinishing) ;
bitarray_poke(foo->readystate, i, status.flagready) ;
@@ -56,7 +57,6 @@ unsigned int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, in
{
iopause_fd x[2] = { { .fd = ftrigr_fd(&foo->a), .events = IOPAUSE_READ }, { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } } ;
unsigned int e = 0 ;
- stralloc sa = STRALLOC_ZERO ;
if (got(foo, wantup, wantready, or)) return 0 ;
for (;;)
@@ -67,19 +67,17 @@ unsigned int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, in
if (x[1].revents & IOPAUSE_READ) (*handler)() ;
if (x[0].revents & IOPAUSE_READ)
{
- unsigned int i = 0 ;
if (ftrigr_update(&foo->a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
- for (; i < foo->n ; i++)
+ for (unsigned int i = 0 ; i < foo->n ; i++)
{
- sa.len = 0 ;
- r = ftrigr_checksa(&foo->a, foo->ids[i], &sa) ;
- if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
+ ftrigr_string fs ;
+ r = ftrigr_peek(&foo->a, foo->ids[i], &fs) ;
+ if (r == -1) strerr_diefu1sys(111, "ftrigr_check") ;
else if (r)
{
- size_t j = 0 ;
- for (; j < sa.len ; j++)
+ for (uint32_t j = 0 ; j < fs.len ; j++)
{
- if (sa.s[j] == 'x')
+ if (fs.s[j] == 'x')
{
if (bitarray_peek(foo->upstate, i) != wantup
|| bitarray_peek(foo->readystate, i) != wantready)
@@ -87,7 +85,7 @@ unsigned int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, in
bitarray_poke(foo->upstate, i, wantup) ;
bitarray_poke(foo->readystate, i, wantready) ;
}
- else if (sa.s[j] == 'O')
+ else if (fs.s[j] == 'O')
{
if (wantup)
{
@@ -98,17 +96,21 @@ unsigned int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, in
}
else
{
- unsigned int d = byte_chr("dDuU", 4, sa.s[j]) ;
+ unsigned int d = byte_chr("dDuU", 4, fs.s[j]) ;
bitarray_poke(foo->upstate, i, d & 2) ;
bitarray_poke(foo->readystate, i, d & 1) ;
}
- if (got(foo, wantup, wantready, or)) goto gotit ;
+ if (got(foo, wantup, wantready, or))
+ {
+ ftrigr_ack(&foo->a, foo->ids[i]) ;
+ goto gotit ;
+ }
}
+ ftrigr_ack(&foo->a, foo->ids[i]) ;
}
}
}
}
gotit:
- stralloc_free(&sa) ;
return e ;
}