--- /dev/null
+/*
+ * "Interpreter" that you can put in #! like this
+ * #!/usr/bin/prefork-interp [<options>] <interpreter>
+ */
+
+/*
+ * Process structure:
+ * client (C wrapper) connects to server
+ * if fails or garbage
+ * === acquire lock ===
+ * makes new listening socket
+ * makes first-instance socketpair
+ * forks setup (script, sock fds indicated in env)
+ * fd0, fd1, fd2: from-outer-caller
+ * other fd: call(client-end)(fake)
+ * reaps setup (and reports error)
+ * (implicitly releases lock)
+ *
+ * setup (pre-exec) fd0: null,
+ * fd[12: fd2-from-outer-caller
+ * env fds: orig-fd[01], listener,
+ * env fds: call(server-end)(fake)
+ * close fd: lockfile
+ *
+ * setup (script) runs initialisation parts of the script
+ * at prefork establishment point:
+ * forks to logger(1)
+ * forks for server, now becomes like monitor below
+ * exits
+ *
+ * server (script) fd0: null, fd[12]: syslog
+ * other fds: orig-fd[01], listener,
+ * other fds: call(server-end)(fake)
+ *
+ * right away, forks one fake-accepted monitor:
+ * f-a monitor [fd0: null, fd[12]: syslgo]
+ * other fds: call(server-end)(fake)
+ * runs as monitor, below
+ *
+ * [server (script)] fd0: null, fd[12]: syslog
+ * other fds: listener
+ * closes fds: orig-fd[01], call(server-end)fake)
+ * runs in loop accepting and forking,
+ * reaping and limiting children
+ * reports failures of monitors to syslog
+ *
+ * [client (C wrapper)] if client connect succeeds:
+ * now fd: call(client-end)
+ * sends message with: cmdline, env
+ * sends fds
+ *
+ * [server (script)] accepts, forks monitor
+ *
+ * monitor [fd0: null, fd[12]: syslgo]
+ * other fds: call(server-end)
+ * receives args, env, fds
+ * forks executor
+ *
+ * executor sorts out fds:
+ * fd0, fd1, fd2: from-outer-caller
+ * close fds: call(server-end)
+ * implicitly closed fds: syslog
+ *
+ * sets cmdline, env
+ * runs main part of script
+ * exits normally
+ *
+ * [monitor] [fd0: null, fd[12]: syslgo]
+ * [other fds: call(server-end)]
+ * reaps executor
+ * reports status via socket
+ *
+ * [client (C wrapper)] [fd0, fd1, fd2: from-outer-caller]
+ * [other fd: call(client-end)]
+ * receives status, exits appropriately
+ * (if was bad signal, reports to stderr, exits 127)
+ */
+
+struct sockaddr_un sun;
+
+int main(int argc, const char *const *argv) {
+ script = process_opts(argc, argv);
+
+ find_socket_path();
+ FILLZERO(sun);
+ sun.sun_family = AF_UNIX;
+ assert(strlen(socket_path) <= sizeof(sun.sun_path));
+ strncpy(sun.sun_path, socket_path, sizeof(sun.sun_path));
+
+ bool isgarbage = check_garbage();
+
+ int client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (client_fd==-1) diee("socket() for client");
+
+ salen_t salen = sizeof(sun);
+ r = connect(client, (const struct sockaddr*)sun, salen);
+ if (r==-1) {
+ if (errno==ECONNREFUSED || errno==ENOENT) {
+
+}