nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

preline.c (2262B)


      1 #include "fd.h"
      2 #include "sgetopt.h"
      3 #include "readwrite.h"
      4 #include "strerr.h"
      5 #include "substdio.h"
      6 #include "fork.h"
      7 #include "wait.h"
      8 #include "env.h"
      9 #include "sig.h"
     10 #include "error.h"
     11 
     12 #define FATAL "preline: fatal: "
     13 
     14 void die_usage()
     15 {
     16   strerr_die1x(100,"preline: usage: preline cmd [ arg ... ]");
     17 }
     18 
     19 int flagufline = 1; char *ufline;
     20 int flagrpline = 1; char *rpline;
     21 int flagdtline = 1; char *dtline;
     22 
     23 char outbuf[SUBSTDIO_OUTSIZE];
     24 char inbuf[SUBSTDIO_INSIZE];
     25 substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof(outbuf));
     26 substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof(inbuf));
     27 
     28 int main(int argc, char **argv)
     29 {
     30   int opt;
     31   int pi[2];
     32   int pid;
     33   int wstat;
     34  
     35   sig_pipeignore();
     36  
     37   if (!(ufline = env_get("UFLINE"))) die_usage();
     38   if (!(rpline = env_get("RPLINE"))) die_usage();
     39   if (!(dtline = env_get("DTLINE"))) die_usage();
     40  
     41   while ((opt = getopt(argc,argv,"frdFRD")) != opteof)
     42     switch(opt) {
     43       case 'f': flagufline = 0; break;
     44       case 'r': flagrpline = 0; break;
     45       case 'd': flagdtline = 0; break;
     46       case 'F': flagufline = 1; break;
     47       case 'R': flagrpline = 1; break;
     48       case 'D': flagdtline = 1; break;
     49       default: die_usage();
     50     }
     51   argc -= optind;
     52   argv += optind;
     53   if (!*argv) die_usage();
     54  
     55   if (pipe(pi) == -1)
     56     strerr_die2sys(111,FATAL,"unable to create pipe: ");
     57 
     58   pid = fork();
     59   if (pid == -1)
     60     strerr_die2sys(111,FATAL,"unable to fork: ");
     61 
     62   if (pid == 0) {
     63     close(pi[1]);
     64     if (fd_move(0,pi[0]) == -1)
     65       strerr_die2sys(111,FATAL,"unable to set up fds: ");
     66     sig_pipedefault();
     67     execvp(*argv,argv);
     68     strerr_die4sys(error_temp(errno) ? 111 : 100,FATAL,"unable to run ",*argv,": ");
     69   }
     70   close(pi[0]);
     71   if (fd_move(1,pi[1]) == -1)
     72     strerr_die2sys(111,FATAL,"unable to set up fds: ");
     73  
     74   if (flagufline) substdio_bputs(&ssout,ufline);
     75   if (flagrpline) substdio_bputs(&ssout,rpline);
     76   if (flagdtline) substdio_bputs(&ssout,dtline);
     77   if (substdio_copy(&ssout,&ssin) != 0)
     78     strerr_die2sys(111,FATAL,"unable to copy input: ");
     79   substdio_flush(&ssout);
     80   close(1);
     81  
     82   if (wait_pid(&wstat,pid) == -1)
     83     strerr_die2sys(111,FATAL,"wait failed: ");
     84   if (wait_crashed(wstat))
     85     strerr_die2x(111,FATAL,"child crashed");
     86   return wait_exitcode(wstat);
     87 }