* ident covers only env vars specified with -E
* ident covers only arguments interpreter and (if present) script
*/
+
+/*
+
+
+
+ State during service execution, process parentage and key fds
+
+ ---- pipes, sockets
+ 012 descriptors
+ -==- fds shared
+ || process parentage
+ && session leader (daemon)
+ & process group leader
+
+ CALLER
+ ||
+ ||
+ || listen watch-err/in
+ || call (accept) \ ,------2
+ || ,-----------------------------. SERVER -----0 WATCHER(C)
+ CLIENT 2--=fdpassed>=---------. \ || && | &&
+ (C) 1--=fdpassed>=---------. \ \ || inotify
+ 0--=fdpassed>=---------. \ \ \ || sockpath
+ \ \ \ \ ||
+ | | |\ | ||
+ | | | \ | ||
+ | \ | \ \ ||
+ \ \ \ \ MONITOR &
+ \ \ \ `12 || |
+ \ \ \ || |
+ \ \ \ || |execterm
+ \ \ \ || |
+ \ \ \ || |
+ \ \ 2 || |
+ \ 1 EXECUTOR
+ 0
+
+ Control flow and causality
+
+ | - \ / process control flow
+ ... causes mediated by fds or other IPC etc.
+ && session leader (daemon)
+ & process group leader
+
+ CALLER
+ |
+ |fork/exec
+ |
+ CLIENT(C)
+ tidy up stale sockets etc.
+ acquire lock
+ create listening socket
+ |
+ fork/daemonise
+ | `------------------.
+ | WATCHER(C) &&
+ |
+ make "fake" initial call socketpair
+ |
+ fork/exec
+ | `------.
+ | SCRIPT (setup)
+ | |
+ | script initialisation
+ | |
+ | identify fds from envirnment
+ | open syslog
+ | |
+ | dzemonize
+ | ,...../ |
+ waitpid |
+ | fork for initial service
+ | |child |parent
+ | | |
+ | | SCRIPT [server] &&
+ | | |
+ | | ** accept / event loop **
+ | | / \ \ \
+ | | accepted? \ \ \idle timeout?
+ | | | \ \ \
+ | | fork child \ \ \
+ | | _________/ watch | |watch stderr eof?
+ | |/ stderr| | |
+ | SCRIPT [monitor] | | |
+ | | log msg | |
+ | send greeting | | |
+ read greeting | | | |
+ | | exit
+ release lock |
+ | |
+ send fds.... |
+ | receive fds
+ | |
+ | fork for executor
+ | | \
+ | | \child
+ | | \
+ | | setpgrp &
+ | | execute service
+ | | |
+ | wait for read |
+ | (select) |
+ | | | |
+ | | exits
+ | | kernel closes execterm
+ | | ,......./|
+ | execterm? |
+ | | zombie
+ | | ,....../
+ | waitpid
+ | |
+ | send exit status
+ read exit status
+
+
+ Or, if client is killed
+
+ | | |
+ | wait for read |
+ | (select) |
+ | | | |
+ exits | |
+ | | |
+ kernel closes | |
+ \....| |
+ call? |
+ | |
+ kill whole pgrp... |
+ | killled
+ | zombie
+ | ,....../
+ waitpid
+ |
+ send exit status
+ die due to SIGPIPE
+
+
+ */
/*
* Process structure:
* client (C wrapper) connects to server
* runs in loop accepting and forking,
* reaping and limiting children (incl init monitor)
* reports failures of monitors to syslog
- *
+ *
* [client (C wrapper)] if client connect succeeds:
* now fd: call(client-end)
* sends message with: cmdline, env
r = sigaction(sig, &sa, 0);
if (r) diee("failed to reset signal handler while propagating %s",
signame);
-
+
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, sig);
*buf += dl;
}
}
-
+
static void prepare_length(size_t *len, char **buf, size_t dl_sz) {
if (dl_sz > UINT32_MAX) die_data_overflow();
uint32_t dl = htonl(dl_sz);
static void watcher_cb_stdin(uv_poll_t *handle, int status, int events) {
char c;
int r;
-
+
if ((errno = -status)) diee("watcher: poll stdin");
for (;;) {
r= read(0, &c, 1);
EACH_NEW_ARG( *out++ = arg; );
*out++ = 0;
-}
+}
int main(int argc_unused, const char *const *argv) {
process_opts(&argv);