home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / rc / part06 / redir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-30  |  2.0 KB  |  78 lines

  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. }
  78.