#include "fd.h"
#include "sgetopt.h"
#include "readwrite.h"
-#include "subfd.h"
+#include "strerr.h"
#include "substdio.h"
#include "exit.h"
#include "fork.h"
#include "sig.h"
#include "error.h"
-void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
-void die_usage() { die(100,"preline: fatal: incorrect usage\n"); }
-void die_temp() { die(111,"preline: fatal: temporary problem\n"); }
-void die_read() { die(111,"preline: fatal: unable to read message\n"); }
-void die_badcmd() { die(100,"preline: fatal: command not found\n"); }
+#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;
-substdio ssout;
char outbuf[SUBSTDIO_OUTSIZE];
-substdio ssin;
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:
- _exit(100);
+ 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();
+ argc -= optind;
+ argv += optind;
+ if (!*argv) die_usage();
+
+ if (pipe(pi) == -1)
+ strerr_die2sys(111,FATAL,"unable to create pipe: ");
- if (pipe(pi) == -1) die_temp();
+ pid = fork();
+ if (pid == -1)
+ strerr_die2sys(111,FATAL,"unable to fork: ");
- switch(pid = fork())
- {
- case -1:
- die_temp();
- case 0:
- close(pi[1]);
- if (fd_move(0,pi[0])) die_temp();
- sig_pipedefault();
- execvp(*argv,argv);
- if (error_temp(errno)) die_temp();
- die_badcmd();
+ 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]);
-
- substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
- substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
- if (flagufline) substdio_bputs(&ssout,ufline);
- if (flagrpline) substdio_bputs(&ssout,rpline);
- if (flagdtline) substdio_bputs(&ssout,dtline);
- if (substdio_copy(&ssout,&ssin) == -2) die_read();
- substdio_flush(&ssout);
- close(pi[1]);
-
- if (wait_pid(&wstat,pid) == -1) die_temp();
- if (wait_crashed(wstat)) die_temp();
- _exit(wait_exitcode(wstat));
+ 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));
}