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: split on ASCII space (or any whitespace), taking
259      first two words.  There may or may not be further "words".
260      Then split each of the first two words on comma,
261      again taking the initial items as specified.  The items are:
262
263         v1    Protocol version indicator - literal.  If something else,
264               fail (installation is incompatible somehow).
265
266         SECS.NSECS
267               timestamp before script started running, as a decimal
268               time_t.  NSECS is exactly 9 digits.
269               To be used for auto reloading.
270
271      These items are file descriptors:
272
273         LISTEN   listening socket                 nonblocking
274         CALL     call socket for initial call     blocking
275         WATCHE   liveness watcher stderr          nonblocking
276         WATCHI   liveness sentinel                unspecified
277
278   3. Library should do the following:
279
280      1. Read and understand the PREFORK_INTERP env var.
281         If it is not set, initialisation complete should simply return.
282         This allows simple synchronous operation.
283
284      2. Open syslog
285      3. fork/exit (fork and have parent exit) (to make server)
286      4. setsid (to become session leader)
287      5. fork initial service (monitor) child, using CALL (see below)
288      6. Replace stdin/stdout/stderr with /dev/null,
289         and make a note to send all error messages to syslog
290      7. Enter select loop, looking for the following:
291
292          * accept on LISTEN:
293             i. see if we need to reload: is any file forming part
294                of the program newer than the SECS.NSECS ?
295                If so, log at LOG_INFO, and exit immediately
296                (dropping CALL, LISTEN, WATCHI, etc.)
297             ii. see if we can reap any children, possibly waiting
298                for children if we are at our concurrency limit
299                (limit should be configured through library, default 4)
300             iii. fork service (monitor) child, using accepted fd
301
302          * WATCHE is readable:
303             * EOF:: log at LOG_INFO, and exit
304             * data to read: read what is available immediately,
305               log it as a message at LOG_ERR, and exit
306
307   4. service (monitor) child does the following:
308
309       1. close all of LISTEN, WATCHI, WATCHE
310       2. setpgrp
311       3. send a greeting (on CALL) "PFI\n\0\0\0\0" (8 bytes)
312       4. read a single byte, fail if it's not zero
313       5. three times, receive a single byte with a file descriptor
314          attached as ancillary data.  (These descriptors will be
315          service stdin, stdout, stderr.)
316       6. read a 4-byte big-endian length
317       7. read that many bytes, the initial service request message,
318          which contains the following nul-terminated strings:
319             * environment variable settings in the format NAME=value
320             * an empty string
321             * arguments NOT INCLUDING argv[0] or script filename
322          (not that this means the service request must end in a nul)
323       8. make a new pipe EXECTERM
324       9. fork for the service executor; in the child
325             i. redirect stdin/stdout/stderr to the recevied fds
326             ii. replace environment and arguments with those received,
327             iii. close descriptors: close the original received descriptors;
328                  close CALL; keep only the writing end of EXECTERM
329             iv. if the script programming language does things with SIGINT,
330                 set it set back to default handling (immediate termination).
331             v. return back to script, now in the grandchild
332
333       10. in the parent, close EXECTERM writing end, and
334       11. select, looking for one of the following:
335            * CALL is readable
336            * EXECTERM reading end is readable
337           No need to actually read, since these shouldn't produce
338           spurious wakeups (but do loop on EINTR).
339       12. set SIGINT to ignored
340       13. send SIGINT to the entire process group
341       14. wait, blocking, for the executor child
342       15. write the wait status, in 32-bit big-endian, to CALL
343           (this may generate SIGPIPE/EPIPE;
344           if so, die with SIGPIPE or exit 0; do treat that as failure)
345       16. exit 0
346
347 ***************************************************************************
348 \f
349 */
350
351 #include <arpa/inet.h>
352
353 #include <uv.h>
354
355 #include "prefork.h"
356
357 const char our_name[] = "prefork-interp";
358
359 static struct sockaddr_un sockaddr_sun;
360 static FILE *call_sock;
361
362 #define ACK_BYTE '\n'
363
364 static const char *const *executor_argv;
365
366 static const char header_magic[4] = "PFI\n";
367
368 void fusagemessage(FILE *f) {
369   fprintf(f, "usage: #!/usr/bin/prefork-interp [<options>]\n");
370 }
371
372 #define MODE_NORMAL 0
373 #define MODE_KILL   'k'
374 #define MODE_FRESH  'f'
375
376 #define MEDIATION_UNSPECIFIED 0
377 #define MEDIATION_UNLAUNDERED 'U'
378
379 static int mediation = MEDIATION_UNSPECIFIED;
380 static int mode = MODE_NORMAL;
381 static int max_sockets = 100; // maximum entries in the run dir is 2x this
382
383 static struct stat initial_stab;
384
385 const struct cmdinfo cmdinfos[]= {
386   PREFORK_CMDINFOS
387   { 0,         'U',   0, .iassignto= &mediation, .arg= MEDIATION_UNLAUNDERED },
388   { "kill",     0,    0, .iassignto= &mode,      .arg= MODE_KILL   },
389   { 0,         'f',   0, .iassignto= &mode,      .arg= MODE_FRESH  },
390   { 0 }
391 };
392
393 void ident_addinit(void) {
394   char ident_magic[1] = { 0 };
395   sha256_update(&identsc, sizeof(ident_magic), ident_magic);
396 }
397
398 static void propagate_exit_status(int status, const char *what) {
399   int r;
400
401   if (WIFEXITED(status)) {
402     _exit(status);
403   }
404
405   if (WIFSIGNALED(status)) {
406     int sig = WTERMSIG(status);
407     const char *signame = strsignal(sig);
408     if (signame == 0) signame = "unknown signal";
409
410     if (! WCOREDUMP(status) &&
411         (sig == SIGINT ||
412          sig == SIGHUP ||
413          sig == SIGPIPE ||
414          sig == SIGKILL)) {
415       struct sigaction sa;
416       FILLZERO(sa);
417       sa.sa_handler = SIG_DFL;
418       r = sigaction(sig, &sa, 0);
419       if (r) diee("failed to reset signal handler while propagating %s",
420                   signame);
421
422       sigset_t sset;
423       sigemptyset(&sset);
424       sigaddset(&sset, sig);
425       r = sigprocmask(SIG_UNBLOCK, &sset, 0);
426       if (r) diee("failed to reset signal block while propagating %s",
427                   signame);
428
429       raise(sig);
430       die("unexpectedly kept running after raising (to propagate) %s",
431           signame);
432     }
433
434     die("%s failed due to signal %d %s%s", what, sig, signame,
435         WCOREDUMP(status) ? " (core dumped)" : "");
436   }
437
438   die("%s failed with weird wait status %d 0x%x", what, status, status);
439 }
440
441 typedef struct {
442   char *name_hash;
443   time_t atime;
444 } PrecleanEntry;
445
446 static int preclean_entry_compar_name(const void *av, const void *bv) {
447   const PrecleanEntry *a = av;
448   const PrecleanEntry *b = bv;
449   return strcmp(a->name_hash, b->name_hash);
450 }
451
452 static int preclean_entry_compar_atime(const void *av, const void *bv) {
453   const PrecleanEntry *ae = av;  time_t a = ae->atime;
454   const PrecleanEntry *be = bv;  time_t b = be->atime;
455   return (a > b ? +1 :
456           a < b ? -1 : 0);
457 }
458
459 static time_t preclean_stat_atime(const char *s_path) {
460   struct stat stab;
461   int r= lstat(s_path, &stab);
462   if (r) {
463     if (errno!=ENOENT) diee("pre-cleanup: stat socket (%s)", s_path);
464     return 0;
465   }
466   return stab.st_atime;
467 }
468
469 static void preclean(void) {
470   DIR *dir = opendir(run_base);
471   if (!dir) {
472     if (errno == ENOENT) return;
473     diee("pre-cleanup: open run dir (%s)", run_base);
474   }
475
476   PrecleanEntry *entries=0;
477   size_t avail_entries=0;
478   size_t used_entries=0;
479
480   struct dirent *de;
481   while ((errno = 0, de = readdir(dir))) {
482     char c0 = de->d_name[0];
483     if (!(c0 == 'l' || c0 == 's')) continue;
484     char *name_hash = m_asprintf("%s", de->d_name+1);
485     char *s_path = m_asprintf("%s/s%s", run_base, name_hash);
486     time_t atime = preclean_stat_atime(s_path);
487
488     if (avail_entries == used_entries) {
489       assert(avail_entries < INT_MAX / 4 / sizeof(PrecleanEntry));
490       avail_entries <<= 1;
491       avail_entries += 10;
492       entries = realloc(entries, avail_entries * sizeof(PrecleanEntry));
493     }
494     entries[used_entries].name_hash = name_hash;
495     entries[used_entries].atime = atime;
496     used_entries++;
497   }
498   if (errno) diee("pre-cleanup: read run dir (%s)", run_base);
499
500   // First we dedupe (after sorting by path)
501   qsort(entries, used_entries, sizeof(PrecleanEntry),
502         preclean_entry_compar_name);
503   PrecleanEntry *p, *q;
504   for (p=entries, q=entries; p < entries + used_entries; p++) {
505     if (q > entries && !strcmp(p->name_hash, (q-1)->name_hash))
506       continue;
507     *q++ = *p;
508   }
509   used_entries = q - entries;
510
511   // Now maybe delete some things
512   //
513   // Actually this has an off-by-one error since we are about
514   // to create a socket, so the actual number of sockets is one more.
515   // But, *actually*, since there might be multiple of us running at once,
516   // we might have even more than that.  This doesn't really matter.
517   if (used_entries > max_sockets) {
518     qsort(entries, used_entries, sizeof(PrecleanEntry),
519           preclean_entry_compar_atime);
520     for (p=entries; p < entries + max_sockets; p++) {
521       char *l_path = m_asprintf("%s/l%s", run_base, p->name_hash);
522       char *s_path = m_asprintf("%s/s%s", run_base, p->name_hash);
523       int lock_fd = flock_file(l_path);
524       // Recheck atime - we might have raced!
525       time_t atime = preclean_stat_atime(s_path);
526       if (atime != p->atime) {
527         // Raced.  This will leave use deleting too few things.  Whatever.
528       } else {
529         int r= unlink(s_path);
530         if (r && errno!=ENOENT) diee("preclean: delete stale (%s)", s_path);
531         r= unlink(l_path);
532         if (r) diee("preclean: delete stale lock (%s)", s_path);
533         // NB we don't hold the lock any more now.
534       }
535       close(lock_fd);
536       free(l_path);
537       free(s_path);
538     }
539   }
540
541   for (p=entries; p < entries + used_entries; p++)
542     free(p->name_hash);
543   free(entries);
544 }
545
546 static __attribute((noreturn)) void die_data_overflow(void) {
547   die("cannot handle data with length >2^32");
548 }
549
550 static void prepare_data(size_t *len, char **buf,
551                          const void *data, size_t dl) {
552   if (len) {
553     if (dl >= SIZE_MAX - *len)
554       die_data_overflow();
555     *len += dl;
556   }
557   if (buf) {
558     memcpy(*buf, data, dl);
559     *buf += dl;
560   }
561 }
562
563 static void prepare_length(size_t *len, char **buf, size_t dl_sz) {
564   if (dl_sz > UINT32_MAX) die_data_overflow();
565   uint32_t dl = htonl(dl_sz);
566   prepare_data(len, buf, &dl, sizeof(dl));
567 }
568
569 static void prepare_string(size_t *len, char **buf, const char *s) {
570   size_t sl = strlen(s);
571   prepare_data(len, buf, s, sl+1);
572 }
573
574 static void prepare_message(size_t *len, char **buf) {
575   const char *s;
576
577   const char *const *p = (void*)environ;
578   while ((s = *p++)) {
579     if (strchr(s, '='))
580       prepare_string(len, buf, s);
581   }
582
583   prepare_string(len, buf, "");
584
585   p = executor_argv;
586   while ((s = *p++))
587     prepare_string(len, buf, s);
588 }
589
590 static void send_fd(int payload_fd) {
591   int via_fd = fileno(call_sock);
592
593   union {
594     struct cmsghdr align;
595     char buf[CMSG_SPACE(sizeof(payload_fd))];
596   } cmsg_buf;
597
598   struct msghdr msg;
599   FILLZERO(msg);
600   FILLZERO(cmsg_buf);
601
602   char dummy_byte = 0;
603   struct iovec iov;
604   FILLZERO(iov);
605   iov.iov_base = &dummy_byte;
606   iov.iov_len = 1;
607
608   msg.msg_name = 0;
609   msg.msg_iov = &iov;
610   msg.msg_iovlen = 1;
611   msg.msg_control = cmsg_buf.buf;
612   msg.msg_controllen = sizeof(cmsg_buf.buf);
613
614   struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
615   cmsg->cmsg_level = SOL_SOCKET;
616   cmsg->cmsg_type = SCM_RIGHTS;
617   cmsg->cmsg_len = CMSG_LEN(sizeof(payload_fd));
618   *(int*)CMSG_DATA(cmsg) = payload_fd;
619
620   msg.msg_controllen = sizeof(cmsg_buf.buf);
621
622   for (;;) {
623     ssize_t r = sendmsg(via_fd, &msg, 0);
624     if (r == -1) {
625       if (errno == EINTR) continue;
626       diee("send fd");
627     }
628     assert(r == 1);
629     break;
630   }
631 }
632
633 static void send_request(void) {
634   char ibyte= 0;
635   ssize_t sr = fwrite(&ibyte, 1, 1, call_sock);
636   if (sr != 1) diee("write signalling byte");
637
638   // Sending these before the big message makes it easier for the script to
639   // use buffered IO for the message.
640   send_fd(0);
641   send_fd(1);
642   send_fd(2);
643
644   size_t len = 0;
645   prepare_message(&len, 0);
646
647   size_t tlen = len + 4;
648   char *m = xmalloc(tlen);
649   char *p = m;
650   prepare_length(0, &p, len);
651   prepare_message(0, &p);
652   assert(p == m + tlen);
653
654   sr = fwrite(m, tlen, 1, call_sock);
655   if (sr != 1) diee("write request (buffer)");
656
657   if (fflush(call_sock)) diee("write request");
658 }
659
660 static FILE *call_sock_from_fd(int fd) {
661   int r;
662
663   FILE *call_sock = fdopen(fd, "r+");
664   if (!call_sock) diee("fdopen socket");
665
666   r = setvbuf(call_sock, 0, _IONBF, 0);
667   if (r) die("setvbuf socket");
668
669   return call_sock;
670 }
671
672 static bool was_eof(FILE *call_sock) {
673   return feof(call_sock) || errno==ECONNRESET;
674 }
675
676 // Returns -1 on EOF
677 static int protocol_read_maybe(void *data, size_t sz) {
678   if (!sz) return 0;
679   size_t sr = fread(data, sz, 1, call_sock);
680   if (sr != 1) {
681     if (was_eof(call_sock)) return -1;
682     diee("read() on monitor call socket (%zd)", sz);
683   }
684   return 0;
685 }
686
687 static void protocol_read(void *data, size_t sz) {
688   if (protocol_read_maybe(data, sz) < 0)
689     die("monitor process quit unexpectedly");
690 }
691
692 // Returns 0 if OK, error msg if peer was garbage.
693 static const char *read_greeting(void) {
694   char got_magic[sizeof(header_magic)];
695
696   if (protocol_read_maybe(&got_magic, sizeof(got_magic)) < 0)
697     return "initial monitor process quit";
698
699   if (memcmp(got_magic, header_magic, sizeof(header_magic)))
700     die("got unexpected protocol magic 0x%02x%02x%02x%02x",
701         got_magic[0], got_magic[1], got_magic[2], got_magic[3]);
702
703   uint32_t xdata_len;
704   protocol_read(&xdata_len, sizeof(xdata_len));
705   void *xdata = xmalloc(xdata_len);
706   protocol_read(xdata, xdata_len);
707
708   return 0;
709 }
710
711 // Returns: call(client-end), or 0 to mean "is garbage"
712 // find_socket_path must have been called
713 static FILE *connect_existing(void) {
714   int r;
715   int fd = -1;
716
717   if (mode != MODE_NORMAL) return 0;
718
719   fd = socket(AF_UNIX, SOCK_STREAM, 0);
720   if (fd==-1) diee("socket() for client");
721
722   socklen_t salen = sizeof(sockaddr_sun);
723   r = connect(fd, (const struct sockaddr*)&sockaddr_sun, salen);
724   if (r==-1) {
725     if (errno==ECONNREFUSED || errno==ENOENT) goto x_garbage;
726     diee("connect() %s", socket_path);
727   }
728
729   call_sock = call_sock_from_fd(fd);
730   fd = -1;
731
732   if (read_greeting())
733     goto x_garbage;
734
735   return call_sock;
736
737  x_garbage:
738   if (call_sock) { fclose(call_sock); call_sock=0; }
739   if (fd >= 0) close(fd);
740   return 0;
741 }
742
743 static void watcher_cb_stdin(uv_poll_t *handle, int status, int events) {
744   char c;
745   int r;
746
747   if ((errno = -status)) diee("watcher: poll stdin");
748   for (;;) {
749     r= read(0, &c, 1);
750     if (r!=-1) _exit(0);
751     if (!(errno==EINTR || errno==EWOULDBLOCK || errno==EAGAIN))
752       diee("watcher: read sentinel stdin");
753   }
754 }
755
756 static void watcher_cb_sockpath(uv_fs_event_t *handle, const char *filename,
757                                 int events, int status) {
758   int r;
759   struct stat now_stab;
760
761   if ((errno = -status)) diee("watcher: poll stdin");
762   for (;;) {
763     r= stat(socket_path, &now_stab);
764     if (r==-1) {
765       if (errno==ENOENT) _exit(0);
766       if (errno==EINTR) continue;
767       diee("stat socket: %s", socket_path);
768     }
769     if (!stabs_same_inode(&now_stab, &initial_stab))
770       _exit(0);
771   }
772 }
773
774 // On entry, stderr is still inherited, but 0 and 1 are the pipes
775 static __attribute__((noreturn))
776 void become_watcher(void) {
777   uv_loop_t loop;
778   uv_poll_t uvhandle_stdin;
779   uv_fs_event_t uvhandle_sockpath;
780   int r;
781
782   nonblock(0);
783
784   errno= -uv_loop_init(&loop);
785   if (errno) diee("watcher: uv_loop_init");
786
787   errno= -uv_poll_init(&loop, &uvhandle_stdin, 0);
788   if (errno) diee("watcher: uv_poll_init");
789   errno= -uv_poll_start(&uvhandle_stdin,
790                         UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
791                         watcher_cb_stdin);
792   if (errno) diee("watcher: uv_poll_start");
793
794   errno= -uv_fs_event_init(&loop, &uvhandle_sockpath);
795   if (errno) diee("watcher: uv_fs_event_init");
796
797   errno= -uv_fs_event_start(&uvhandle_sockpath, watcher_cb_sockpath,
798                             socket_path, 0);
799   if (errno) diee("watcher: uv_fs_event_start");
800
801   // OK everything is set up, let us daemonise
802   if (dup2(1,2) != 2) diee("watcher: set daemonised stderr");
803   r= setvbuf(stderr, 0, _IOLBF, BUFSIZ);
804   if (r) diee("watcher: setvbuf stderr");
805
806   pid_t child = fork();
807   if (child == (pid_t)-1) diee("watcher: fork");
808   if (child) _exit(0);
809
810   if (setsid() == (pid_t)-1) diee("watcher: setsid");
811
812   r= uv_run(&loop, UV_RUN_DEFAULT);
813   die("uv_run returned (%d)", r);
814 }
815
816 static __attribute__((noreturn))
817 void become_setup(int sfd, int lockfd, int fake_pair[2],
818                   int watcher_stdin, int watcher_stderr) {
819   close(lockfd);
820   close(fake_pair[0]);
821   int call_fd = fake_pair[1];
822
823   int null_0 = open("/dev/null", O_RDONLY);  if (null_0 < 0) diee("open null");
824   if (dup2(null_0, 0)) diee("dup2 /dev/null onto stdin");
825   close(null_0);
826   if (dup2(2, 1) != 1) die("dup2 stderr onto stdout");
827
828   nonblock(sfd);
829
830   // Extension could work like this:
831   //
832   // We could advertise a new protocol (perhaps one which is nearly entirely
833   // different after the connect) by putting a name for it comma-separated
834   // next to "v1".  Simple extension can be done by having the script
835   // side say something about it in the ack xdata, which we currently ignore.
836   // Or we could add other extra data after v1.
837   putenv(m_asprintf("PREFORK_INTERP=v1,%jd.%09ld %d,%d,%d,%d",
838                     (intmax_t)initial_stab.st_mtim.tv_sec,
839                     (long)initial_stab.st_mtim.tv_nsec,
840                     sfd, call_fd, watcher_stdin, watcher_stderr));
841
842   execvp(executor_argv[0], (char**)executor_argv);
843   diee("execute %s", executor_argv[0]);
844 }
845
846 static void connect_or_spawn(void) {
847   int r;
848
849   call_sock = connect_existing();
850   if (call_sock) return;
851
852   // We're going to make a new one, so clean out old ones
853   preclean();
854
855   int lockfd = acquire_lock();
856
857   if (mode == MODE_KILL) {
858     r= unlink(socket_path);
859     if (r && errno != ENOENT) diee("remove socket %s", socket_path);
860
861     r= unlink(lock_path);
862     if (r) diee("rmeove lock %s", lock_path);
863     _exit(0);
864   }
865
866   call_sock = connect_existing();
867   if (call_sock) { close(lockfd); return; }
868
869   // We must start a fresh one, and we hold the lock
870
871   r = unlink(socket_path);
872   if (r<0 && errno!=ENOENT)
873     diee("failed to remove stale socket %s", socket_path);
874
875   int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
876   if (sfd<0) diee("socket() for new listener");
877
878   socklen_t salen = sizeof(sockaddr_sun);
879   r= bind(sfd, (const struct sockaddr*)&sockaddr_sun, salen);
880   if (r<0) diee("bind() on new listener");
881
882   r= stat(socket_path, &initial_stab);
883   if (r<0) diee("stat() fresh socket");
884
885   // We never want callers to get ECONNREFUSED.  But:
886   // There is a race here: from my RTFM they may get ECONNREFUSED
887   // if they try between our bind() and listen().  But if they do, they'll
888   // acquire the lock (serialising with us) and retry, and then it will work.
889   r = listen(sfd, INT_MAX);
890   if (r<0) diee("listen() for new listener");
891
892   // Fork watcher
893
894   int watcher_stdin[2];
895   int watcher_stderr[2];
896   if (pipe(watcher_stdin) || pipe(watcher_stderr))
897     diee("pipe() for socket inode watcher");
898
899   pid_t watcher = fork();
900   if (watcher == (pid_t)-1) diee("fork for watcher");
901   if (!watcher) {
902     close(sfd);
903     close(lockfd);
904     close(watcher_stdin[1]);
905     close(watcher_stderr[0]);
906     if (dup2(watcher_stdin[0], 0) != 0 ||
907         dup2(watcher_stderr[1], 1) != 1)
908       diee("initial dup2() for watcher");
909     close(watcher_stdin[0]);
910     close(watcher_stderr[1]);
911     become_watcher();
912   }
913
914   close(watcher_stdin[0]);
915   close(watcher_stderr[1]);
916   nonblock(watcher_stderr[0]);
917
918   // Fork setup
919
920   int fake_pair[2];
921   r = socketpair(AF_UNIX, SOCK_STREAM, 0, fake_pair);
922   if (r<0) diee("socketpair() for fake initial connection");
923
924   pid_t setup_pid = fork();
925   if (setup_pid == (pid_t)-1) diee("fork for spawn setup");
926   if (!setup_pid) become_setup(sfd, lockfd, fake_pair,
927                                watcher_stdin[1], watcher_stderr[0]);
928   close(fake_pair[1]);
929   close(sfd);
930
931   call_sock = call_sock_from_fd(fake_pair[0]);
932
933   int status;
934   pid_t got = waitpid(setup_pid, &status, 0);
935   if (got == (pid_t)-1) diee("waitpid setup [%ld]", (long)setup_pid);
936   if (got != setup_pid) diee("waitpid setup [%ld] gave [%ld]!",
937                              (long)setup_pid, (long)got);
938   if (status != 0) propagate_exit_status(status, "setup");
939
940   const char *emsg = read_greeting();
941   if (emsg) die("setup failed: %s", emsg);
942
943   close(lockfd);
944   return;
945 }
946
947 static void make_executor_argv(const char *const *argv) {
948   switch (mediation) {
949   case MEDIATION_UNLAUNDERED: break;
950   default: die("need -U (specifying unlaundered argument handling)");
951   }
952
953   const char *arg;
954   #define EACH_NEW_ARG(EACH) {                  \
955     arg = interp; { EACH }                      \
956     if ((arg = script)) { EACH }                \
957     const char *const *walk = argv;             \
958     while ((arg = *walk++)) { EACH }            \
959   }
960
961   size_t count = 1;
962   EACH_NEW_ARG( (void)arg; count++; );
963
964   const char **out = calloc(count, sizeof(char*));
965   executor_argv = (const char* const*)out;
966   if (!executor_argv) diee("allocate for arguments");
967
968   EACH_NEW_ARG( *out++ = arg; );
969   *out++ = 0;
970 }
971
972 int main(int argc_unused, const char *const *argv) {
973   process_opts(&argv);
974
975   // Now we have
976   //  - possibly interp
977   //  - possibly script
978   //  - remaining args
979   // which ought to be passed on to the actual executor.
980   make_executor_argv(argv);
981
982   find_socket_path();
983   FILLZERO(sockaddr_sun);
984   sockaddr_sun.sun_family = AF_UNIX;
985   assert(strlen(socket_path) <= sizeof(sockaddr_sun.sun_path));
986   strncpy(sockaddr_sun.sun_path, socket_path, sizeof(sockaddr_sun.sun_path));
987
988   connect_or_spawn();
989
990   // We're committed now, send the request (or bail out)
991   send_request();
992
993   uint32_t status;
994   protocol_read(&status, sizeof(status));
995
996   status = ntohl(status);
997   if (status > INT_MAX) die("status 0x%lx does not fit in an int",
998                             (unsigned long)status);
999
1000   propagate_exit_status(status, "invocation");
1001 }