chiark / gitweb /
prefork-interp: protocol documentation
[chiark-utils.git] / cprogs / prefork-interp.c
1 /*
2  * "Interpreter" that you can put in #! like this
3  *   #!/usr/bin/prefork-interp [<options>] <interpreter>
4  *
5  * Usages:
6  *   prefork-interp  [<option> ..] <interpreter>  [<script> [<args> ...]]
7  *   prefork-interp  [<option>,..],<interpreter>   <script> [<args> ...]
8  *   prefork-interp '[<option> ..] <interpreter>'  <script> [<args> ...]
9  *
10  * Options must specify argument laundering mode.
11  * Currently the only mode supported is:
12  *   -U    unlaundered: setup and executor both get all arguments and env vars
13  *         ident covers only env vars specified  with -E
14  *         ident covers only arguments interpreter and (if present) script
15  */
16
17 /*
18 ***************************************************************************
19 \f
20   State during service execution, process parentage and key fds
21
22       CALLER
23         ||
24         ||
25         ||                               listen     watch-err/in
26         ||       call                 (accept) \     ,------2
27         || ,-----------------------------.     SERVER -----0 WATCHER(C)
28       CLIENT 2--=fdpassed>=---------.     \      || &&          |      &&
29        (C)  1--=fdpassed>=---------. \     \     ||           inotify
30            0--=fdpassed>=---------. \ \     \    ||           sockpath
31                                    \ \ \     \   ||
32                                    | | |\     |  ||
33                                    | | | \    |  ||
34                                    | \ |  \   \  ||
35                                     \ \ \  \   MONITOR &
36                                      \ \ \  `12  ||  |
37                                       \ \ \      ||  |
38                                        \ \ \     ||  |execterm
39                                         \ \ \    ||  |
40                                          \ \ \   ||  |
41                                           \ \ 2  ||  |
42                                            \ 1 EXECUTOR
43                                             0
44     ----      pipes, sockets
45     012       descriptors
46     -==-      fds shared
47     ||        process parentage
48     &&        session leader (daemon)
49     &         process group leader
50
51 ***************************************************************************
52 \f
53  Control flow and causality
54
55       CALLER
56          |
57          |fork/exec
58          |
59       CLIENT
60          |
61       attempt to connect, and read greeting
62          |failure?                \success?
63          |                         \
64       tidy up stale /run entries    *1 (continue from send_fds, below)
65       acquire lock
66          |
67       retry attempt to connect, and read greeting
68          |failure?                \success?
69          |                         \
70       create listening socket     release lock
71          |                           \
72       fork/daemonise                  *1
73          |    `------------------.
74          |                      WATCHER(C) &&
75          |
76        make "fake" initial call socketpair                               (C)
77          |                                                    prefork-interp
78        fork/exec   #########################################################
79          |      `-------------.                                  application
80          |         #        SCRIPT (setup)
81          |         #          |
82          |         #       script initialisation
83          |         #          |                                  application
84          |         ###########|#############################################
85          |         #          |                               prefork-interp
86          |         #       identify fds from envirnment               (Perl)
87          |         #       open syslog
88          |         #          |
89          |         #       dzemonize
90          |   ,.....<....../   |
91       waitpid      #        fork for initial service
92          |         #          |child?       |parent?
93          |         #          |             |
94          |         #          |         SCRIPT [server] &&
95          |         #          |             |
96          |         #          |         ** accept / event loop **
97          |         #          |        accepted?    \      \ \
98          |         #          |            /         \ watch\ \idle
99          |         #          |        fork child     \stderr\ \timeout?
100          |         #          | _________/            |       | |
101          |         #          |/                      |read?  | |
102          |         #     SCRIPT [monitor]             |   eof?| |
103          |         #       setpgrpt &                 |       | |
104          |         #          |                     log msg   | |
105        read   ,....<.....send greeting                |       | |
106       greeting     #          |                    ___________________
107          |         #          |
108       release      #          |
109       lock    *1   #          |
110          |   /     #          |
111       send fds.....>....      |
112          |         #    \receive fds
113          |         #             |
114          |         #         fork for executor                        (Perl)
115          |         #          |parent?        \child?         prefork-interp
116          |         #          |          ######\############################
117          |         #          |          #  SCRIPT (executor)    application
118          |         #          |          #  execute service
119          |         #    wait for read    #       |
120          |         #      (select)       #   terminates
121          |         #        |   |        #       |
122          |         #            |        #    kernel closes execterm
123          |         #            | ,......<....../|
124          |         #      execterm?      #       |
125          |         #            |        #     zombie
126          |         #        |   | ,......<...../
127          |         #       waitpid       #  _______________
128          |         #          |          #
129          |    ,....<....,..send status   #
130     read status    #  ________________   #
131    _____________   #
132
133
134   ********** Or, if client is killed **********
135
136          |         #          |          #  execute service
137      terminates    #    wait for read    #       |
138          |         #      (select)       #       |
139       kernel       #        |   |        #       |
140      closes call   #        |            #       |
141                 \..>......_ |            #       |
142    _____________   #       \|call?       #       |
143                    #        |            #       |
144                    #  kill whole pgrp... #    killled
145                    #        |            #     zombie
146                    #        |   | ,......<....../
147                    #       waitpid       #  _______________
148                    #          |          #
149                    #   send exit status  #
150                    #  _____SIGPIPE______ #
151
152     | - \ /    process control flow
153     ... < >    causes mediated by fds or other IPC etc.
154     &&         session leader (daemon)
155     &          process group leader
156     #          language/implementation boundary
157     *1         line continued elsewhere
158     event?     condition
159     ______     process termination (after reaping, if shown)
160
161 ***************************************************************************
162 \f
163   Sequence of events and fd pluming.
164   NB INCOMPLETE - does not cover execterm, cleanup
165  
166    client (C wrapper)        connects to server
167                                (including reading ack byte)
168                              if fails or garbage
169                              === acquires lock ===
170                              makes new listening socket
171                              makes watcher pipes
172                              forks watcher and awaits
173                              makes first-instance socketpair
174                              forks setup (script, sock fds indicated in env)
175                              fd0, fd1, fd2: from-outer
176                              other fd: call(client-end)(fake)
177                              reaps setup (and reports error)
178                              (implicitly releases lock)
179  
180       watcher                fd[012]: watcher pipes
181                              starts watch on socket path
182                              sets stderr to line buffered
183                              sets stdin to nonblocking
184                              daemonises (one fork, becomes session leader)
185                              when socket stat changes, quit
186  
187       setup (pre-exec)       fd0: null,
188                              fd[12]: fd2-from-outer
189                              env fds: listener, call(server-end)(fake),
190                                        watcher read, watcher write
191                              close fd: lockfile
192                              possibly clean env, argv
193  
194       setup (script)         runs initialisation parts of the script
195                              at prefork establishment point:
196       setup (pm) [1]         opens syslog
197                              forks for server
198                  [2]         exits
199  
200          server (pm) [1]     [fd0: null],
201                              [fd[12]: fd2-from-outer]
202                              setsid
203                              right away, forks init monitor
204                      [2]     closes outer caller fds and call(fake)
205          [server (pm)]       fd[012]: null
206                              other fds: listener, syslog
207                              runs in loop accepting and forking,
208                              reaping and limiting children (incl init monitor)
209                              reports failures of monitors to syslog
210  
211    [client (C wrapper)]      if client connect succeeds:
212                              now fd: call(client-end)
213                                 sends message with: cmdline, env
214                                 sends fds
215  
216          [server (script)]   accepts, forks subseq monitor
217  
218            monitor [1]       [fd0: null]
219             (init            [fd[12]: init: fd2-from-outer; subseq: null]
220               or             errors: init: fd2; subseq: syslog
221              subseq)         other fds: syslog, call(server-end)
222                              sends ack byte
223                              receives args, env, fds
224                              forks executor
225  
226              executor        sorts out fds:
227                              fd0, fd1, fd2: from-outer
228                              close fds: call(server-end)
229                              retained fds: syslog
230  
231                              sets cmdline, env
232                              runs main part of script
233                              exits normally
234  
235            [monitor]         [fd[012]: null]
236                              [fd[12]: init: fd2-from-outer; subseq: null]
237                              [errors: init: fd2; subseq: syslog]
238                              reaps executor
239                              reports status via socket
240  
241      [client (C wrapper)]    [fd0, fd1, fd2: from-outer]
242                              [other fd: call(client-end)]
243                              receives status, exits appropriately
244                              (if was bad signal, reports to stderr, exits 127)
245
246 ***************************************************************************
247 \f
248   Protocol, and functions of the script
249
250   1. Script interpreter will be spawned apparently as normal;
251      should run synchronously in the normal way until
252      "initialisation complete" point.  At initialisation complete:
253
254   2. Env var PREFORK_INTERP contains:
255
256          v1,SECS.NSECS[,...] LISTEN,CALL,WATCHE,WATCHI[,...][ ???]
257
258      To parse it: treat as bytes and split on ASCII space, taking
259      the first two words.  (There may or may not be
260      further "words"; and if there are they might be binary data.)
261      Then split each of the first two words (which will contain only
262      ASCII printing characters) on comma.  Take the initial items:
263
264         v1    Protocol version indicator - literal.  If something else,
265               fail (means installation is incompatible somehow).
266
267         SECS.NSECS
268               timestamp just before script started running, as a
269               decimal time_t.  NSECS is exactly 9 digits.
270               To be used for auto reloading (see below).
271
272      The 2nd word's items are file descriptors:
273
274         LISTEN   listening socket                 nonblocking
275         CALL     call socket for initial call     blocking
276         WATCHE   liveness watcher stderr          nonblocking
277         WATCHI   liveness sentinel                unspecified
278
279   3. Library should do the following:
280
281      1. Read and understand the PREFORK_INTERP env var.
282         If it is not set, initialisation complete should simply return.
283         (This allows simple synchronous operation.)
284
285      2. Open syslog
286      3. fork/exit (fork and have parent exit) (to make server)
287      4. setsid (to become session leader)
288      5. fork initial service (monitor) child, using CALL (see below)
289      6. Replace stdin/stdout/stderr with /dev/null,
290         and make a note to send all error messages to syslog
291      7. Enter select loop, looking for the following:
292
293          * accept on LISTEN:
294             i. see if we need to reload: is any file forming part
295                of the program newer than the SECS.NSECS ?
296                If so, log at LOG_INFO, and exit immediately
297                (dropping CALL, LISTEN, WATCHI, etc.)
298             ii. see if we can reap any children, possibly waiting
299                for children if we are at our concurrency limit
300                (limit should be configured through library, default 4)
301             iii. fork service (monitor) child, using accepted fd
302
303          * WATCHE is readable:
304             * EOF:: log at LOG_INFO, and exit
305             * data to read: read what is available immediately,
306               log it as a message at LOG_ERR, and exit
307
308   4. service (monitor) child does the following:
309
310       1. close all of LISTEN, WATCHI, WATCHE
311       2. setpgrp
312       3. send a greeting (on CALL) "PFI\n\0\0\0\0" (8 bytes)
313       4. read a single byte, fail if it's not zero
314       5. three times, receive a single byte with a file descriptor
315          attached as ancillary data.  (These descriptors will be
316          service stdin, stdout, stderr.)
317       6. read a 4-byte big-endian length
318       7. read that many bytes, the initial service request message,
319          which contains the following nul-terminated strings:
320             * environment variable settings in the format NAME=value
321             * an empty string
322             * arguments NOT INCLUDING argv[0] or script filename
323          (not that this means the service request must end in a nul)
324       8. make a new pipe EXECTERM
325       9. fork for the service executor; in the child
326             i. redirect stdin/stdout/stderr to the recevied fds
327             ii. replace environment and arguments with those received,
328             iii. close descriptors: close the original received descriptors;
329                  close CALL; keep only the writing end of EXECTERM
330             iv. if the script programming language does things with SIGINT,
331                 set it set back to default handling (immediate termination).
332             v. return back to script, now in the grandchild
333
334       10. in the parent, close EXECTERM writing end, and
335       11. select, looking for one of the following:
336            * CALL is readable
337            * EXECTERM reading end is readable
338           No need to actually read, since these shouldn't produce
339           spurious wakeups (but do loop on EINTR).
340       12. set SIGINT to ignored
341       13. send SIGINT to the entire process group
342       14. wait, blocking, for the executor child
343       15. write the wait status, in 32-bit big-endian, to CALL
344           (this may generate SIGPIPE/EPIPE; if so, die with SIGPIPE
345           or exit 0; do treat SIGPIPE/EPIPE as failure)
346       16. exit 0
347
348      Errors detected in the service monitor should be sent to
349      syslog, or stderr, depending on whether this is the initial
350      service monitor (from part 3 step 5) or an accepted socket
351      service monitor (from part 4 step 9); this can be achieved
352      easily by having a global flag (set at part 3 step 6),
353      or perhaps using logger(8) and redirecting stderr (but
354      then be careful to ensure everyone gets only the necessary fds).
355
356 ***************************************************************************
357 \f
358 */
359
360 #include <arpa/inet.h>
361
362 #include <uv.h>
363
364 #include "prefork.h"
365
366 const char our_name[] = "prefork-interp";
367
368 static struct sockaddr_un sockaddr_sun;
369 static FILE *call_sock;
370
371 #define ACK_BYTE '\n'
372
373 static const char *const *executor_argv;
374
375 static const char header_magic[4] = "PFI\n";
376
377 void fusagemessage(FILE *f) {
378   fprintf(f, "usage: #!/usr/bin/prefork-interp [<options>]\n");
379 }
380
381 #define MODE_NORMAL 0
382 #define MODE_KILL   'k'
383 #define MODE_FRESH  'f'
384
385 #define MEDIATION_UNSPECIFIED 0
386 #define MEDIATION_UNLAUNDERED 'U'
387
388 static int mediation = MEDIATION_UNSPECIFIED;
389 static int mode = MODE_NORMAL;
390 static int max_sockets = 100; // maximum entries in the run dir is 2x this
391
392 static struct stat initial_stab;
393
394 const struct cmdinfo cmdinfos[]= {
395   PREFORK_CMDINFOS
396   { 0,         'U',   0, .iassignto= &mediation, .arg= MEDIATION_UNLAUNDERED },
397   { "kill",     0,    0, .iassignto= &mode,      .arg= MODE_KILL   },
398   { 0,         'f',   0, .iassignto= &mode,      .arg= MODE_FRESH  },
399   { 0 }
400 };
401
402 void ident_addinit(void) {
403   char ident_magic[1] = { 0 };
404   sha256_update(&identsc, sizeof(ident_magic), ident_magic);
405 }
406
407 static void propagate_exit_status(int status, const char *what) {
408   int r;
409
410   if (WIFEXITED(status)) {
411     _exit(status);
412   }
413
414   if (WIFSIGNALED(status)) {
415     int sig = WTERMSIG(status);
416     const char *signame = strsignal(sig);
417     if (signame == 0) signame = "unknown signal";
418
419     if (! WCOREDUMP(status) &&
420         (sig == SIGINT ||
421          sig == SIGHUP ||
422          sig == SIGPIPE ||
423          sig == SIGKILL)) {
424       struct sigaction sa;
425       FILLZERO(sa);
426       sa.sa_handler = SIG_DFL;
427       r = sigaction(sig, &sa, 0);
428       if (r) diee("failed to reset signal handler while propagating %s",
429                   signame);
430
431       sigset_t sset;
432       sigemptyset(&sset);
433       sigaddset(&sset, sig);
434       r = sigprocmask(SIG_UNBLOCK, &sset, 0);
435       if (r) diee("failed to reset signal block while propagating %s",
436                   signame);
437
438       raise(sig);
439       die("unexpectedly kept running after raising (to propagate) %s",
440           signame);
441     }
442
443     die("%s failed due to signal %d %s%s", what, sig, signame,
444         WCOREDUMP(status) ? " (core dumped)" : "");
445   }
446
447   die("%s failed with weird wait status %d 0x%x", what, status, status);
448 }
449
450 typedef struct {
451   char *name_hash;
452   time_t atime;
453 } PrecleanEntry;
454
455 static int preclean_entry_compar_name(const void *av, const void *bv) {
456   const PrecleanEntry *a = av;
457   const PrecleanEntry *b = bv;
458   return strcmp(a->name_hash, b->name_hash);
459 }
460
461 static int preclean_entry_compar_atime(const void *av, const void *bv) {
462   const PrecleanEntry *ae = av;  time_t a = ae->atime;
463   const PrecleanEntry *be = bv;  time_t b = be->atime;
464   return (a > b ? +1 :
465           a < b ? -1 : 0);
466 }
467
468 static time_t preclean_stat_atime(const char *s_path) {
469   struct stat stab;
470   int r= lstat(s_path, &stab);
471   if (r) {
472     if (errno!=ENOENT) diee("pre-cleanup: stat socket (%s)", s_path);
473     return 0;
474   }
475   return stab.st_atime;
476 }
477
478 static void preclean(void) {
479   DIR *dir = opendir(run_base);
480   if (!dir) {
481     if (errno == ENOENT) return;
482     diee("pre-cleanup: open run dir (%s)", run_base);
483   }
484
485   PrecleanEntry *entries=0;
486   size_t avail_entries=0;
487   size_t used_entries=0;
488
489   struct dirent *de;
490   while ((errno = 0, de = readdir(dir))) {
491     char c0 = de->d_name[0];
492     if (!(c0 == 'l' || c0 == 's')) continue;
493     char *name_hash = m_asprintf("%s", de->d_name+1);
494     char *s_path = m_asprintf("%s/s%s", run_base, name_hash);
495     time_t atime = preclean_stat_atime(s_path);
496
497     if (avail_entries == used_entries) {
498       assert(avail_entries < INT_MAX / 4 / sizeof(PrecleanEntry));
499       avail_entries <<= 1;
500       avail_entries += 10;
501       entries = realloc(entries, avail_entries * sizeof(PrecleanEntry));
502     }
503     entries[used_entries].name_hash = name_hash;
504     entries[used_entries].atime = atime;
505     used_entries++;
506   }
507   if (errno) diee("pre-cleanup: read run dir (%s)", run_base);
508
509   // First we dedupe (after sorting by path)
510   qsort(entries, used_entries, sizeof(PrecleanEntry),
511         preclean_entry_compar_name);
512   PrecleanEntry *p, *q;
513   for (p=entries, q=entries; p < entries + used_entries; p++) {
514     if (q > entries && !strcmp(p->name_hash, (q-1)->name_hash))
515       continue;
516     *q++ = *p;
517   }
518   used_entries = q - entries;
519
520   // Now maybe delete some things
521   //
522   // Actually this has an off-by-one error since we are about
523   // to create a socket, so the actual number of sockets is one more.
524   // But, *actually*, since there might be multiple of us running at once,
525   // we might have even more than that.  This doesn't really matter.
526   if (used_entries > max_sockets) {
527     qsort(entries, used_entries, sizeof(PrecleanEntry),
528           preclean_entry_compar_atime);
529     for (p=entries; p < entries + max_sockets; p++) {
530       char *l_path = m_asprintf("%s/l%s", run_base, p->name_hash);
531       char *s_path = m_asprintf("%s/s%s", run_base, p->name_hash);
532       int lock_fd = flock_file(l_path);
533       // Recheck atime - we might have raced!
534       time_t atime = preclean_stat_atime(s_path);
535       if (atime != p->atime) {
536         // Raced.  This will leave use deleting too few things.  Whatever.
537       } else {
538         int r= unlink(s_path);
539         if (r && errno!=ENOENT) diee("preclean: delete stale (%s)", s_path);
540         r= unlink(l_path);
541         if (r) diee("preclean: delete stale lock (%s)", s_path);
542         // NB we don't hold the lock any more now.
543       }
544       close(lock_fd);
545       free(l_path);
546       free(s_path);
547     }
548   }
549
550   for (p=entries; p < entries + used_entries; p++)
551     free(p->name_hash);
552   free(entries);
553 }
554
555 static __attribute((noreturn)) void die_data_overflow(void) {
556   die("cannot handle data with length >2^32");
557 }
558
559 static void prepare_data(size_t *len, char **buf,
560                          const void *data, size_t dl) {
561   if (len) {
562     if (dl >= SIZE_MAX - *len)
563       die_data_overflow();
564     *len += dl;
565   }
566   if (buf) {
567     memcpy(*buf, data, dl);
568     *buf += dl;
569   }
570 }
571
572 static void prepare_length(size_t *len, char **buf, size_t dl_sz) {
573   if (dl_sz > UINT32_MAX) die_data_overflow();
574   uint32_t dl = htonl(dl_sz);
575   prepare_data(len, buf, &dl, sizeof(dl));
576 }
577
578 static void prepare_string(size_t *len, char **buf, const char *s) {
579   size_t sl = strlen(s);
580   prepare_data(len, buf, s, sl+1);
581 }
582
583 static void prepare_message(size_t *len, char **buf) {
584   const char *s;
585
586   const char *const *p = (void*)environ;
587   while ((s = *p++)) {
588     if (strchr(s, '='))
589       prepare_string(len, buf, s);
590   }
591
592   prepare_string(len, buf, "");
593
594   p = executor_argv;
595   while ((s = *p++))
596     prepare_string(len, buf, s);
597 }
598
599 static void send_fd(int payload_fd) {
600   int via_fd = fileno(call_sock);
601
602   union {
603     struct cmsghdr align;
604     char buf[CMSG_SPACE(sizeof(payload_fd))];
605   } cmsg_buf;
606
607   struct msghdr msg;
608   FILLZERO(msg);
609   FILLZERO(cmsg_buf);
610
611   char dummy_byte = 0;
612   struct iovec iov;
613   FILLZERO(iov);
614   iov.iov_base = &dummy_byte;
615   iov.iov_len = 1;
616
617   msg.msg_name = 0;
618   msg.msg_iov = &iov;
619   msg.msg_iovlen = 1;
620   msg.msg_control = cmsg_buf.buf;
621   msg.msg_controllen = sizeof(cmsg_buf.buf);
622
623   struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
624   cmsg->cmsg_level = SOL_SOCKET;
625   cmsg->cmsg_type = SCM_RIGHTS;
626   cmsg->cmsg_len = CMSG_LEN(sizeof(payload_fd));
627   *(int*)CMSG_DATA(cmsg) = payload_fd;
628
629   msg.msg_controllen = sizeof(cmsg_buf.buf);
630
631   for (;;) {
632     ssize_t r = sendmsg(via_fd, &msg, 0);
633     if (r == -1) {
634       if (errno == EINTR) continue;
635       diee("send fd");
636     }
637     assert(r == 1);
638     break;
639   }
640 }
641
642 static void send_request(void) {
643   char ibyte= 0;
644   ssize_t sr = fwrite(&ibyte, 1, 1, call_sock);
645   if (sr != 1) diee("write signalling byte");
646
647   // Sending these before the big message makes it easier for the script to
648   // use buffered IO for the message.
649   send_fd(0);
650   send_fd(1);
651   send_fd(2);
652
653   size_t len = 0;
654   prepare_message(&len, 0);
655
656   size_t tlen = len + 4;
657   char *m = xmalloc(tlen);
658   char *p = m;
659   prepare_length(0, &p, len);
660   prepare_message(0, &p);
661   assert(p == m + tlen);
662
663   sr = fwrite(m, tlen, 1, call_sock);
664   if (sr != 1) diee("write request (buffer)");
665
666   if (fflush(call_sock)) diee("write request");
667 }
668
669 static FILE *call_sock_from_fd(int fd) {
670   int r;
671
672   FILE *call_sock = fdopen(fd, "r+");
673   if (!call_sock) diee("fdopen socket");
674
675   r = setvbuf(call_sock, 0, _IONBF, 0);
676   if (r) die("setvbuf socket");
677
678   return call_sock;
679 }
680
681 static bool was_eof(FILE *call_sock) {
682   return feof(call_sock) || errno==ECONNRESET;
683 }
684
685 // Returns -1 on EOF
686 static int protocol_read_maybe(void *data, size_t sz) {
687   if (!sz) return 0;
688   size_t sr = fread(data, sz, 1, call_sock);
689   if (sr != 1) {
690     if (was_eof(call_sock)) return -1;
691     diee("read() on monitor call socket (%zd)", sz);
692   }
693   return 0;
694 }
695
696 static void protocol_read(void *data, size_t sz) {
697   if (protocol_read_maybe(data, sz) < 0)
698     die("monitor process quit unexpectedly");
699 }
700
701 // Returns 0 if OK, error msg if peer was garbage.
702 static const char *read_greeting(void) {
703   char got_magic[sizeof(header_magic)];
704
705   if (protocol_read_maybe(&got_magic, sizeof(got_magic)) < 0)
706     return "initial monitor process quit";
707
708   if (memcmp(got_magic, header_magic, sizeof(header_magic)))
709     die("got unexpected protocol magic 0x%02x%02x%02x%02x",
710         got_magic[0], got_magic[1], got_magic[2], got_magic[3]);
711
712   uint32_t xdata_len;
713   protocol_read(&xdata_len, sizeof(xdata_len));
714   void *xdata = xmalloc(xdata_len);
715   protocol_read(xdata, xdata_len);
716
717   return 0;
718 }
719
720 // Returns: call(client-end), or 0 to mean "is garbage"
721 // find_socket_path must have been called
722 static FILE *connect_existing(void) {
723   int r;
724   int fd = -1;
725
726   if (mode != MODE_NORMAL) return 0;
727
728   fd = socket(AF_UNIX, SOCK_STREAM, 0);
729   if (fd==-1) diee("socket() for client");
730
731   socklen_t salen = sizeof(sockaddr_sun);
732   r = connect(fd, (const struct sockaddr*)&sockaddr_sun, salen);
733   if (r==-1) {
734     if (errno==ECONNREFUSED || errno==ENOENT) goto x_garbage;
735     diee("connect() %s", socket_path);
736   }
737
738   call_sock = call_sock_from_fd(fd);
739   fd = -1;
740
741   if (read_greeting())
742     goto x_garbage;
743
744   return call_sock;
745
746  x_garbage:
747   if (call_sock) { fclose(call_sock); call_sock=0; }
748   if (fd >= 0) close(fd);
749   return 0;
750 }
751
752 static void watcher_cb_stdin(uv_poll_t *handle, int status, int events) {
753   char c;
754   int r;
755
756   if ((errno = -status)) diee("watcher: poll stdin");
757   for (;;) {
758     r= read(0, &c, 1);
759     if (r!=-1) _exit(0);
760     if (!(errno==EINTR || errno==EWOULDBLOCK || errno==EAGAIN))
761       diee("watcher: read sentinel stdin");
762   }
763 }
764
765 static void watcher_cb_sockpath(uv_fs_event_t *handle, const char *filename,
766                                 int events, int status) {
767   int r;
768   struct stat now_stab;
769
770   if ((errno = -status)) diee("watcher: poll stdin");
771   for (;;) {
772     r= stat(socket_path, &now_stab);
773     if (r==-1) {
774       if (errno==ENOENT) _exit(0);
775       if (errno==EINTR) continue;
776       diee("stat socket: %s", socket_path);
777     }
778     if (!stabs_same_inode(&now_stab, &initial_stab))
779       _exit(0);
780   }
781 }
782
783 // On entry, stderr is still inherited, but 0 and 1 are the pipes
784 static __attribute__((noreturn))
785 void become_watcher(void) {
786   uv_loop_t loop;
787   uv_poll_t uvhandle_stdin;
788   uv_fs_event_t uvhandle_sockpath;
789   int r;
790
791   nonblock(0);
792
793   errno= -uv_loop_init(&loop);
794   if (errno) diee("watcher: uv_loop_init");
795
796   errno= -uv_poll_init(&loop, &uvhandle_stdin, 0);
797   if (errno) diee("watcher: uv_poll_init");
798   errno= -uv_poll_start(&uvhandle_stdin,
799                         UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
800                         watcher_cb_stdin);
801   if (errno) diee("watcher: uv_poll_start");
802
803   errno= -uv_fs_event_init(&loop, &uvhandle_sockpath);
804   if (errno) diee("watcher: uv_fs_event_init");
805
806   errno= -uv_fs_event_start(&uvhandle_sockpath, watcher_cb_sockpath,
807                             socket_path, 0);
808   if (errno) diee("watcher: uv_fs_event_start");
809
810   // OK everything is set up, let us daemonise
811   if (dup2(1,2) != 2) diee("watcher: set daemonised stderr");
812   r= setvbuf(stderr, 0, _IOLBF, BUFSIZ);
813   if (r) diee("watcher: setvbuf stderr");
814
815   pid_t child = fork();
816   if (child == (pid_t)-1) diee("watcher: fork");
817   if (child) _exit(0);
818
819   if (setsid() == (pid_t)-1) diee("watcher: setsid");
820
821   r= uv_run(&loop, UV_RUN_DEFAULT);
822   die("uv_run returned (%d)", r);
823 }
824
825 static __attribute__((noreturn))
826 void become_setup(int sfd, int lockfd, int fake_pair[2],
827                   int watcher_stdin, int watcher_stderr) {
828   close(lockfd);
829   close(fake_pair[0]);
830   int call_fd = fake_pair[1];
831
832   int null_0 = open("/dev/null", O_RDONLY);  if (null_0 < 0) diee("open null");
833   if (dup2(null_0, 0)) diee("dup2 /dev/null onto stdin");
834   close(null_0);
835   if (dup2(2, 1) != 1) die("dup2 stderr onto stdout");
836
837   nonblock(sfd);
838
839   // Extension could work like this:
840   //
841   // We could advertise a new protocol (perhaps one which is nearly entirely
842   // different after the connect) by putting a name for it comma-separated
843   // next to "v1".  Simple extension can be done by having the script
844   // side say something about it in the ack xdata, which we currently ignore.
845   // Or we could add other extra data after v1.
846   putenv(m_asprintf("PREFORK_INTERP=v1,%jd.%09ld %d,%d,%d,%d",
847                     (intmax_t)initial_stab.st_mtim.tv_sec,
848                     (long)initial_stab.st_mtim.tv_nsec,
849                     sfd, call_fd, watcher_stdin, watcher_stderr));
850
851   execvp(executor_argv[0], (char**)executor_argv);
852   diee("execute %s", executor_argv[0]);
853 }
854
855 static void connect_or_spawn(void) {
856   int r;
857
858   call_sock = connect_existing();
859   if (call_sock) return;
860
861   // We're going to make a new one, so clean out old ones
862   preclean();
863
864   int lockfd = acquire_lock();
865
866   if (mode == MODE_KILL) {
867     r= unlink(socket_path);
868     if (r && errno != ENOENT) diee("remove socket %s", socket_path);
869
870     r= unlink(lock_path);
871     if (r) diee("rmeove lock %s", lock_path);
872     _exit(0);
873   }
874
875   call_sock = connect_existing();
876   if (call_sock) { close(lockfd); return; }
877
878   // We must start a fresh one, and we hold the lock
879
880   r = unlink(socket_path);
881   if (r<0 && errno!=ENOENT)
882     diee("failed to remove stale socket %s", socket_path);
883
884   int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
885   if (sfd<0) diee("socket() for new listener");
886
887   socklen_t salen = sizeof(sockaddr_sun);
888   r= bind(sfd, (const struct sockaddr*)&sockaddr_sun, salen);
889   if (r<0) diee("bind() on new listener");
890
891   r= stat(socket_path, &initial_stab);
892   if (r<0) diee("stat() fresh socket");
893
894   // We never want callers to get ECONNREFUSED.  But:
895   // There is a race here: from my RTFM they may get ECONNREFUSED
896   // if they try between our bind() and listen().  But if they do, they'll
897   // acquire the lock (serialising with us) and retry, and then it will work.
898   r = listen(sfd, INT_MAX);
899   if (r<0) diee("listen() for new listener");
900
901   // Fork watcher
902
903   int watcher_stdin[2];
904   int watcher_stderr[2];
905   if (pipe(watcher_stdin) || pipe(watcher_stderr))
906     diee("pipe() for socket inode watcher");
907
908   pid_t watcher = fork();
909   if (watcher == (pid_t)-1) diee("fork for watcher");
910   if (!watcher) {
911     close(sfd);
912     close(lockfd);
913     close(watcher_stdin[1]);
914     close(watcher_stderr[0]);
915     if (dup2(watcher_stdin[0], 0) != 0 ||
916         dup2(watcher_stderr[1], 1) != 1)
917       diee("initial dup2() for watcher");
918     close(watcher_stdin[0]);
919     close(watcher_stderr[1]);
920     become_watcher();
921   }
922
923   close(watcher_stdin[0]);
924   close(watcher_stderr[1]);
925   nonblock(watcher_stderr[0]);
926
927   // Fork setup
928
929   int fake_pair[2];
930   r = socketpair(AF_UNIX, SOCK_STREAM, 0, fake_pair);
931   if (r<0) diee("socketpair() for fake initial connection");
932
933   pid_t setup_pid = fork();
934   if (setup_pid == (pid_t)-1) diee("fork for spawn setup");
935   if (!setup_pid) become_setup(sfd, lockfd, fake_pair,
936                                watcher_stdin[1], watcher_stderr[0]);
937   close(fake_pair[1]);
938   close(sfd);
939
940   call_sock = call_sock_from_fd(fake_pair[0]);
941
942   int status;
943   pid_t got = waitpid(setup_pid, &status, 0);
944   if (got == (pid_t)-1) diee("waitpid setup [%ld]", (long)setup_pid);
945   if (got != setup_pid) diee("waitpid setup [%ld] gave [%ld]!",
946                              (long)setup_pid, (long)got);
947   if (status != 0) propagate_exit_status(status, "setup");
948
949   const char *emsg = read_greeting();
950   if (emsg) die("setup failed: %s", emsg);
951
952   close(lockfd);
953   return;
954 }
955
956 static void make_executor_argv(const char *const *argv) {
957   switch (mediation) {
958   case MEDIATION_UNLAUNDERED: break;
959   default: die("need -U (specifying unlaundered argument handling)");
960   }
961
962   const char *arg;
963   #define EACH_NEW_ARG(EACH) {                  \
964     arg = interp; { EACH }                      \
965     if ((arg = script)) { EACH }                \
966     const char *const *walk = argv;             \
967     while ((arg = *walk++)) { EACH }            \
968   }
969
970   size_t count = 1;
971   EACH_NEW_ARG( (void)arg; count++; );
972
973   const char **out = calloc(count, sizeof(char*));
974   executor_argv = (const char* const*)out;
975   if (!executor_argv) diee("allocate for arguments");
976
977   EACH_NEW_ARG( *out++ = arg; );
978   *out++ = 0;
979 }
980
981 int main(int argc_unused, const char *const *argv) {
982   process_opts(&argv);
983
984   // Now we have
985   //  - possibly interp
986   //  - possibly script
987   //  - remaining args
988   // which ought to be passed on to the actual executor.
989   make_executor_argv(argv);
990
991   find_socket_path();
992   FILLZERO(sockaddr_sun);
993   sockaddr_sun.sun_family = AF_UNIX;
994   assert(strlen(socket_path) <= sizeof(sockaddr_sun.sun_path));
995   strncpy(sockaddr_sun.sun_path, socket_path, sizeof(sockaddr_sun.sun_path));
996
997   connect_or_spawn();
998
999   // We're committed now, send the request (or bail out)
1000   send_request();
1001
1002   uint32_t status;
1003   protocol_read(&status, sizeof(status));
1004
1005   status = ntohl(status);
1006   if (status > INT_MAX) die("status 0x%lx does not fit in an int",
1007                             (unsigned long)status);
1008
1009   propagate_exit_status(status, "invocation");
1010 }