redir.c (2097B)
1 /* redir.c: code for opening files and piping heredocs after fork but before exec. */ 2 3 #include "rc.h" 4 5 /* 6 Walk the redirection queue, and open files and dup2 to them. Also, 7 here-documents are treated here by dumping them down a pipe. (this 8 should make here-documents fast on systems with lots of memory which 9 do pipes right. Under sh, a file is copied to /tmp, and then read 10 out of /tmp again. I'm interested in knowing how much faster, say, 11 shar runs when unpacking when invoked with rc instead of sh. On my 12 sun4/280, it runs in about 60-75% of the time of sh for unpacking 13 the rc source distribution.) 14 */ 15 16 extern void doredirs() { 17 List *fname; 18 int fd, p[2]; 19 Rq *r; 20 for (r = redirq; r != NULL; r = r->n) { 21 switch(r->r->type) { 22 default: 23 panic("unexpected node in doredirs"); 24 /* NOTREACHED */ 25 case nRedir: 26 if (r->r->u[0].i == rHerestring) { 27 fname = flatten(glom(r->r->u[2].p)); /* fname is really a string */ 28 if (pipe(p) < 0) { 29 uerror("pipe"); 30 rc_error(NULL); 31 } 32 if (rc_fork() == 0) { /* child writes to pipe */ 33 setsigdefaults(FALSE); 34 close(p[0]); 35 if (fname != NULL) 36 writeall(p[1], fname->w, strlen(fname->w)); 37 exit(0); 38 } else { 39 close(p[1]); 40 if (mvfd(p[0], r->r->u[1].i) < 0) 41 rc_error(NULL); 42 } 43 } else { 44 fname = glob(glom(r->r->u[2].p)); 45 if (fname == NULL) 46 rc_error("null filename in redirection"); 47 if (fname->n != NULL) 48 rc_error("multi-word filename in redirection"); 49 switch (r->r->u[0].i) { 50 default: 51 panic("unexpected node in doredirs"); 52 /* NOTREACHED */ 53 case rCreate: case rAppend: case rFrom: 54 fd = rc_open(fname->w, r->r->u[0].i); 55 break; 56 } 57 if (fd < 0) { 58 uerror(fname->w); 59 rc_error(NULL); 60 } 61 if (mvfd(fd, r->r->u[1].i) < 0) 62 rc_error(NULL); 63 } 64 break; 65 case nDup: 66 if (r->r->u[2].i == -1) 67 close(r->r->u[1].i); 68 else if (r->r->u[2].i != r->r->u[1].i) { 69 if (dup2(r->r->u[2].i, r->r->u[1].i) < 0) { 70 uerror("dup2"); 71 rc_error(NULL); 72 } 73 } 74 } 75 } 76 redirq = NULL; 77 }