home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume20 / rc / part03 / redir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-22  |  2.4 KB  |  104 lines

  1. /* redir.c: code for opening files and piping heredocs after fork but before exec. */
  2.  
  3. #include "rc.h"
  4. #include "lex.h"
  5. #include "glom.h"
  6. #include "glob.h"
  7. #include "open.h"
  8. #include "exec.h"
  9. #include "utils.h"
  10. #include "redir.h"
  11. #include "hash.h"
  12.  
  13. /*
  14.    Walk the redirection queue, and open files and dup2 to them. Also, here-documents are treated
  15.    here by dumping them down a pipe. (this should make here-documents fast on systems with lots
  16.    of memory which do pipes right. Under sh, a file is copied to /tmp, and then read out of /tmp
  17.    again. I'm interested in knowing how much faster, say, shar runs when unpacking when invoked
  18.    with rc instead of sh. On my sun4/280, it runs in about 60-75% of the time of sh for unpacking
  19.    the rc source distribution.)
  20. */
  21.  
  22. void doredirs() {
  23.     List *fname;
  24.     int fd, p[2];
  25.     Rq *r;
  26.  
  27.     for (r = redirq; r != NULL; r = r->n) {
  28.         switch(r->r->type) {
  29.         default:
  30.             fprint(2,"%d: bad node in doredirs\n", r->r->type);
  31.             exit(1);
  32.             /* NOTREACHED */
  33.         case rREDIR:
  34.             if (r->r->u[0].i == HERESTRING) {
  35.                 fname = flatten(glom(r->r->u[2].p)); /* fname is really a string */
  36.                 if (fname == NULL) {
  37.                     close(r->r->u[1].i); /* feature? */
  38.                     break;
  39.                 }
  40.                 if (pipe(p) < 0) {
  41.                     uerror("pipe");
  42.                     exit(1);
  43.                 }
  44.                 switch (fork()) {
  45.                 case -1:
  46.                     uerror("fork");
  47.                     exit(1);
  48.                     /* NOTREACHED */
  49.                 case 0:    /* child writes to pipe */
  50.                     setsigdefaults();
  51.                     close(p[0]);
  52.                     writeall(p[1], fname->w, strlen(fname->w));
  53.                     exit(0);
  54.                     /* NOTREACHED */
  55.                 default:
  56.                     close(p[1]);
  57.                     if (dup2(p[0], r->r->u[1].i) < 0) {
  58.                         uerror("dup");
  59.                         exit(1);
  60.                     }
  61.                     close(p[0]);
  62.                 }
  63.             } else {
  64.                 fname = glob(glom(r->r->u[2].p));
  65.                 if (fname == NULL) {
  66.                     fprint(2,"null filename in redirection\n");
  67.                     exit(1);
  68.                 }
  69.                 if (fname->n != NULL) {
  70.                     fprint(2,"multi-word filename in redirection\n");
  71.                     exit(1);
  72.                 }
  73.                 switch (r->r->u[0].i) {
  74.                 default:
  75.                     fprint(2,"doredirs: this can't happen\n");
  76.                     exit(1);
  77.                     /* NOTREACHED */
  78.                 case CREATE: case APPEND: case FROM:
  79.                     fd = rc_open(fname->w, r->r->u[0].i);
  80.                     break;
  81.                 }
  82.                 if (fd < 0) {
  83.                     uerror(fname->w);
  84.                     exit(1);
  85.                 }
  86.                 if (dup2(fd, r->r->u[1].i) < 0) {
  87.                     uerror("dup");
  88.                     exit(1);
  89.                 }
  90.                 close(fd);
  91.             }
  92.             break;
  93.         case rDUP:
  94.             if (r->r->u[2].i == -1)
  95.                 close(r->r->u[1].i);
  96.             else if (dup2(r->r->u[2].i, r->r->u[1].i) < 0) {
  97.                 uerror("dup");
  98.                 exit(1);
  99.             }
  100.         }
  101.     }
  102.     redirq = NULL;
  103. }
  104.