URI: 
       respawn.c - ubase - suckless linux base utils
  HTML git clone git://git.suckless.org/ubase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       respawn.c (1914B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <sys/stat.h>
            3 #include <sys/time.h>
            4 #include <sys/types.h>
            5 #include <sys/wait.h>
            6 
            7 #include <errno.h>
            8 #include <fcntl.h>
            9 #include <poll.h>
           10 #include <signal.h>
           11 #include <stdio.h>
           12 #include <stdlib.h>
           13 #include <unistd.h>
           14 
           15 #include "util.h"
           16 
           17 static void
           18 sigterm(int sig)
           19 {
           20         if (sig == SIGTERM) {
           21                 kill(0, SIGTERM);
           22                 _exit(0);
           23         }
           24 }
           25 
           26 static void
           27 usage(void)
           28 {
           29         eprintf("usage: %s [-l fifo] [-d N] cmd [args...]\n", argv0);
           30 }
           31 
           32 int
           33 main(int argc, char *argv[])
           34 {
           35         char *fifo = NULL;
           36         unsigned int delay = 0;
           37         pid_t pid;
           38         char buf[BUFSIZ];
           39         int savederrno;
           40         ssize_t n;
           41         struct pollfd pollset[1];
           42         int polln;
           43 
           44         ARGBEGIN {
           45         case 'd':
           46                 delay = estrtol(EARGF(usage()), 0);
           47                 break;
           48         case 'l':
           49                 fifo = EARGF(usage());
           50                 break;
           51         default:
           52                 usage();
           53         } ARGEND;
           54 
           55         if (argc < 1)
           56                 usage();
           57 
           58         if (fifo && delay > 0)
           59                 usage();
           60 
           61         setsid();
           62 
           63         signal(SIGTERM, sigterm);
           64 
           65         if (fifo) {
           66                 pollset->fd = open(fifo, O_RDONLY | O_NONBLOCK);
           67                 if (pollset->fd < 0)
           68                         eprintf("open %s:", fifo);
           69                 pollset->events = POLLIN;
           70         }
           71 
           72         while (1) {
           73                 if (fifo) {
           74                         pollset->revents = 0;
           75                         polln = poll(pollset, 1, -1);
           76                         if (polln <= 0) {
           77                                 if (polln == 0 || errno == EAGAIN)
           78                                         continue;
           79                                 eprintf("poll:");
           80                         }
           81                         while ((n = read(pollset->fd, buf, sizeof(buf))) > 0)
           82                                 ;
           83                         if (n < 0)
           84                                 if (errno != EAGAIN)
           85                                         eprintf("read %s:", fifo);
           86                         if (n == 0) {
           87                                 close(pollset->fd);
           88                                 pollset->fd = open(fifo, O_RDONLY | O_NONBLOCK);
           89                                 if (pollset->fd < 0)
           90                                         eprintf("open %s:", fifo);
           91                                 pollset->events = POLLIN;
           92                         }
           93                 }
           94                 pid = fork();
           95                 if (pid < 0)
           96                         eprintf("fork:");
           97                 switch (pid) {
           98                 case 0:
           99                         execvp(argv[0], argv);
          100                         savederrno = errno;
          101                         weprintf("execvp %s:", argv[0]);
          102                         _exit(savederrno == ENOENT ? 127 : 126);
          103                         break;
          104                 default:
          105                         waitpid(pid, NULL, 0);
          106                         break;
          107                 }
          108                 if (!fifo)
          109                         sleep(delay);
          110         }
          111         /* not reachable */
          112         return 0;
          113 }