BSD 4_4_Lite1 development
[unix-history] / usr / src / contrib / rc-1.4 / redir.c
/* redir.c: code for opening files and piping heredocs after fork but before exec. */
#include "rc.h"
/*
Walk the redirection queue, and open files and dup2 to them. Also,
here-documents are treated here by dumping them down a pipe. (this
should make here-documents fast on systems with lots of memory which
do pipes right. Under sh, a file is copied to /tmp, and then read
out of /tmp again. I'm interested in knowing how much faster, say,
shar runs when unpacking when invoked with rc instead of sh. On my
sun4/280, it runs in about 60-75% of the time of sh for unpacking
the rc source distribution.)
*/
extern void doredirs() {
List *fname;
int fd, p[2];
Rq *r;
for (r = redirq; r != NULL; r = r->n) {
switch(r->r->type) {
default:
panic("unexpected node in doredirs");
/* NOTREACHED */
case nRedir:
if (r->r->u[0].i == rHerestring) {
fname = flatten(glom(r->r->u[2].p)); /* fname is really a string */
if (pipe(p) < 0) {
uerror("pipe");
rc_error(NULL);
}
if (rc_fork() == 0) { /* child writes to pipe */
setsigdefaults(FALSE);
close(p[0]);
if (fname != NULL)
writeall(p[1], fname->w, strlen(fname->w));
exit(0);
} else {
close(p[1]);
if (mvfd(p[0], r->r->u[1].i) < 0)
rc_error(NULL);
}
} else {
fname = glob(glom(r->r->u[2].p));
if (fname == NULL)
rc_error("null filename in redirection");
if (fname->n != NULL)
rc_error("multi-word filename in redirection");
switch (r->r->u[0].i) {
default:
panic("unexpected node in doredirs");
/* NOTREACHED */
case rCreate: case rAppend: case rFrom:
fd = rc_open(fname->w, r->r->u[0].i);
break;
}
if (fd < 0) {
uerror(fname->w);
rc_error(NULL);
}
if (mvfd(fd, r->r->u[1].i) < 0)
rc_error(NULL);
}
break;
case nDup:
if (r->r->u[2].i == -1)
close(r->r->u[1].i);
else if (r->r->u[2].i != r->r->u[1].i) {
if (dup2(r->r->u[2].i, r->r->u[1].i) < 0) {
uerror("dup2");
rc_error(NULL);
}
}
}
}
redirq = NULL;
}