* prefork-interp [<option>,..],<interpreter> <script> [<args> ...]
* prefork-interp '[<option> ..] <interpreter>' <script> [<args> ...]
*
- * Options must specify argument laundering mode.
- * Currently the only mode supported is:
+ * Options must specify argument mediation approach.
+ * Currently the only argument mediation supported is:
+ *
* -U unlaundered: setup and executor both get all arguments and env vars
* ident covers only env vars specified with -E
* ident covers only arguments interpreter and (if present) script
+ *
+ * Options for setting the operation mode:
+ *
+ * (none) Default: start new server if needed, then run service
+ * -f Force a fresh service (old one is terminated)
+ * --kill Kill any existing service; do not actually run anything
+ *
+ * Options for controlling whether different invocations share a server:
+ *
+ * -E VAR ident includes env var VAR (or its absence)
+ * -G STRING ident includes string STRING
+ * -g IDENT use IDENT rather than hex(SHA256(... identity things ...))
+ *
+ * (Ordering of -E and -G options is relevant; invocations with different
+ * -E -G options are different even if the env var settings are the same)
*/
/*
*/
#include <arpa/inet.h>
+#include <sys/utsname.h>
#include <uv.h>
{ 0 }
};
+static void ident_add_stat(const char *path) {
+ struct stat stab;
+ int r = stat(path, &stab);
+ if (r) diee("failed to stat %s", path);
+
+ IDENT_ADD_OBJ(path[0], stab.st_dev);
+ IDENT_ADD_OBJ('i', stab.st_ino);
+}
+
void ident_addinit(void) {
- char ident_magic[1] = { 0 };
- sha256_update(&identsc, sizeof(ident_magic), ident_magic);
+ ident_add_key_byte(1);
+
+ struct utsname uts = { };
+ size_t utslen = sizeof(uts);
+ int r = uname(&uts);
+ if (r) diee("uname failed!");
+ IDENT_ADD_OBJ('u', utslen);
+ IDENT_ADD_OBJ('u', uts);
+
+ ident_add_stat(".");
+ ident_add_stat("/");
}
static void propagate_exit_status(int status, const char *what) {
int r;
if (WIFEXITED(status)) {
- _exit(status);
+ _exit(WEXITSTATUS(status));
}
if (WIFSIGNALED(status)) {
if (! WCOREDUMP(status) &&
(sig == SIGINT ||
+ sig == SIGTERM ||
sig == SIGHUP ||
sig == SIGPIPE ||
sig == SIGKILL)) {
struct sigaction sa;
FILLZERO(sa);
sa.sa_handler = SIG_DFL;
- 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);
- r = sigprocmask(SIG_UNBLOCK, &sset, 0);
- if (r) diee("failed to reset signal block while propagating %s",
- signame);
+ if (sig != SIGKILL) {
+ 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);
+ r = sigprocmask(SIG_UNBLOCK, &sset, 0);
+ if (r) diee("failed to reset signal block while propagating %s",
+ signame);
+ }
raise(sig);
die("unexpectedly kept running after raising (to propagate) %s",
char got_magic[sizeof(header_magic)];
if (protocol_read_maybe(&got_magic, sizeof(got_magic)) < 0)
- return "initial monitor process quit";
+ return "initial monitor process quit"
+ " (maybe script didn't call preform_initialisation_complete?)";
if (memcmp(got_magic, header_magic, sizeof(header_magic)))
die("got unexpected protocol magic 0x%02x%02x%02x%02x",