summaryrefslogtreecommitdiff
path: root/preline.c
diff options
context:
space:
mode:
Diffstat (limited to 'preline.c')
-rw-r--r--preline.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/preline.c b/preline.c
new file mode 100644
index 0000000..1a4cef8
--- /dev/null
+++ b/preline.c
@@ -0,0 +1,90 @@
+#include "fd.h"
+#include "sgetopt.h"
+#include "readwrite.h"
+#include "strerr.h"
+#include "substdio.h"
+#include "exit.h"
+#include "fork.h"
+#include "wait.h"
+#include "env.h"
+#include "sig.h"
+#include "error.h"
+
+#define FATAL "preline: fatal: "
+
+void die_usage()
+{
+ strerr_die1x(100,"preline: usage: preline cmd [ arg ... ]");
+}
+
+int flagufline = 1; char *ufline;
+int flagrpline = 1; char *rpline;
+int flagdtline = 1; char *dtline;
+
+char outbuf[SUBSTDIO_OUTSIZE];
+char inbuf[SUBSTDIO_INSIZE];
+substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof outbuf);
+substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf);
+
+void main(argc,argv)
+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)
+ strerr_die2sys(111,FATAL,"unable to create pipe: ");
+
+ pid = fork();
+ if (pid == -1)
+ strerr_die2sys(111,FATAL,"unable to fork: ");
+
+ if (pid == 0) {
+ close(pi[1]);
+ if (fd_move(0,pi[0]) == -1)
+ strerr_die2sys(111,FATAL,"unable to set up fds: ");
+ sig_pipedefault();
+ execvp(*argv,argv);
+ strerr_die4sys(error_temp(errno) ? 111 : 100,FATAL,"unable to run ",*argv,": ");
+ }
+ close(pi[0]);
+ if (fd_move(1,pi[1]) == -1)
+ strerr_die2sys(111,FATAL,"unable to set up fds: ");
+
+ if (flagufline) substdio_bputs(&ssout,ufline);
+ if (flagrpline) substdio_bputs(&ssout,rpline);
+ if (flagdtline) substdio_bputs(&ssout,dtline);
+ if (substdio_copy(&ssout,&ssin) != 0)
+ strerr_die2sys(111,FATAL,"unable to copy input: ");
+ substdio_flush(&ssout);
+ close(1);
+
+ if (wait_pid(&wstat,pid) == -1)
+ strerr_die2sys(111,FATAL,"wait failed: ");
+ if (wait_crashed(wstat))
+ strerr_die2x(111,FATAL,"child crashed");
+ _exit(wait_exitcode(wstat));
+}