#include #include "buffer.h" #include "env.h" #include "exit.h" #include "fd.h" #include "getoptb.h" #include "logmsg.h" #include "sig.h" #include "wait.h" #define WHO "preline" void die_usage() { logmsg(WHO, 100, USAGE, "preline cmd [ arg ... ]"); } int flagufline = 1; char *ufline; int flagrpline = 1; char *rpline; int flagdtline = 1; char *dtline; char outbuf[BUFFER_OUTSIZE]; buffer bo = BUFFER_INIT(write, 1, outbuf, sizeof(outbuf)); char inbuf[BUFFER_INSIZE]; buffer bi = BUFFER_INIT(read, 0, inbuf, sizeof(inbuf)); int main(int argc, char **argv) { int opt; int pi[2]; int pid; int wstat; sig_pipeignore(); if (!(ufline = env_get("UFLINE"))) die_usage(); if (!(rpline = env_get("RPLINE"))) die_usage(); if (!(dtline = env_get("DTLINE"))) die_usage(); while ((opt = getopt(argc, argv, "frdFRD")) != opteof) switch (opt) { case 'f': flagufline = 0; break; case 'r': flagrpline = 0; break; case 'd': flagdtline = 0; break; case 'F': flagufline = 1; break; case 'R': flagrpline = 1; break; case 'D': flagdtline = 1; break; default: die_usage(); } argc -= optind; argv += optind; if (!*argv) die_usage(); if (pipe(pi) == -1) logmsg(WHO, 111, FATAL, "unable to create pipe"); pid = fork(); if (pid == -1) logmsg(WHO, 111, FATAL, "unable to fork"); if (pid == 0) { close(pi[1]); if (fd_move(0, pi[0]) == -1) logmsg(WHO, 111, FATAL, "unable to set up fds"); sig_pipedefault(); execvp(*argv, argv); logmsg(WHO, errno, FATAL, B("unable to run: ", *argv)); } close(pi[0]); if (fd_move(1, pi[1]) == -1) logmsg(WHO, 111, FATAL, "unable to set up fds"); if (flagufline) buffer_puts(&bo, ufline); if (flagrpline) buffer_puts(&bo, rpline); if (flagdtline) buffer_puts(&bo, dtline); if (buffer_copy(&bo, &bi) != 0) logmsg(WHO, 111, FATAL, "unable to copy input"); buffer_flush(&bo); close(1); if (wait_pid(&wstat, pid) == -1) logmsg(WHO, 111, FATAL, "wait failed"); if (wait_crashed(wstat)) logmsg(WHO, 111, FATAL, "child crashed"); _exit(wait_exitcode(wstat)); }