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 }