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