github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/stubimpl/main.c (about)

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <signal.h>
     4  #include <unistd.h>
     5  #include <string.h>
     6  
     7  void must(int ok, char *s) {
     8      if (!ok) {
     9          perror(s);
    10          exit(1);
    11      }
    12  }
    13  
    14  void handler(int signum) {
    15      char s[5] = "   \n";
    16      char *p = &s[3];
    17      while (signum > 0) {
    18          p--;
    19          *p = (signum % 10) + '0';
    20          signum /= 10;
    21      }
    22      must(write(1, p, s+4-p) != -1, "write signum");
    23  }
    24  
    25  enum { ARGV0MAX = 32 };
    26  
    27  void badmsg() {
    28      must(write(1, "bad msg\n", 8), "write bad msg");
    29  }
    30  
    31  // read as much as possible, but no more than n.
    32  int readn(int fd, char *buf, int n) {
    33      int nr, nrall;
    34      nrall = 0;
    35      while (n > 0 && (nr = read(fd, buf, n)) > 0) {
    36          buf += nr;
    37          nrall += nr;
    38          n -= nr;
    39      }
    40      return nrall;
    41  }
    42  
    43  int main(int argc, char **argv) {
    44      int i;
    45      for (i = 1; i <= 64; i++) {
    46          signal(i, handler);
    47      }
    48      signal(SIGTTIN, SIG_IGN);
    49      signal(SIGTTOU, SIG_IGN);
    50  
    51      must(write(1, "ok\n", 3) != -1, "write ok");
    52  
    53      int nr;
    54      char opbuf[6] = "12345";
    55      while ((nr = readn(0, opbuf, 5)) == 5) {
    56          char opcode = opbuf[0];
    57          int len = atoi(opbuf+1);
    58          char *buf = malloc(len+1);
    59          buf[len] = '\0';
    60          //fprintf(stderr, "code = %c, len = %d\n", opcode, len);
    61          if (readn(0, buf, len) < len) {
    62              free(buf);
    63              break;
    64          }
    65          //fprintf(stderr, "data = %s\n", buf);
    66          switch (opcode) {
    67          case 'd':
    68              // Change directory.
    69              chdir(buf);
    70              break;
    71          case 't':
    72              if (len > ARGV0MAX) {
    73                  buf[ARGV0MAX] = '\0';
    74              }
    75              strcpy(argv[0], buf);
    76              break;
    77          default:
    78              badmsg();
    79          }
    80          free(buf);
    81      }
    82  
    83      if (nr != 0) {
    84          badmsg();
    85      }
    86  
    87      return 0;
    88  }