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

  1. /*
  2.    exec.c: exec() takes an argument list and does the appropriate thing
  3.    (calls a builtin, calls a function, etc.)
  4. */
  5.  
  6. #include <setjmp.h>
  7. #include <signal.h>
  8. #include "rc.h"
  9. #include "utils.h"
  10. #include "exec.h"
  11. #include "status.h"
  12. #include "hash.h"
  13. #include "builtins.h"
  14. #include "footobar.h"
  15. #include "except.h"
  16. #include "redir.h"
  17.  
  18. void exec(List *s, boolean parent) {
  19.     char **av, **ev;
  20.     int pid, stat;
  21.     builtin_t *b;
  22.     char *path = NULL;
  23.     void (*handler)(int);
  24.     boolean forked;
  25.  
  26.     av = list2array(s, dashex);
  27.     ev = makeenv();
  28.  
  29. again:    if (*av == NULL    || isabsolute(*av)) /* null command or absolute pathname */
  30.         b = NULL;
  31.     else if (fnlookup(*av) != NULL)
  32.         b = funcall;
  33.     else
  34.         b = isbuiltin(*av);
  35.  
  36.     if (b == b_exec) {
  37.         parent = FALSE;
  38.         b(av++);
  39.         if (*av == NULL)
  40.             return; /* return on null exec */
  41.         goto again;    /* go back and evaluate the type of command to be executed */
  42.     }
  43.  
  44.     if (b == NULL) {
  45.         path = which(*av);
  46.         if (path == NULL && *av != NULL) { /* perform null commands for redirections */
  47.             fprint(2,"%s not found\n",*av);
  48.             set(FALSE);
  49.             redirq = NULL;
  50.             empty_fifoq();
  51.             if (parent)
  52.                 return;
  53.             rc_exit(1);
  54.         }
  55.     }
  56.  
  57.     /* if parent & the redirq is nonnull, builtin or not it has to fork. */
  58.  
  59.     if (parent && (b == NULL || redirq != NULL)) {
  60.         pid = fork();
  61.         forked = TRUE;
  62.     } else {
  63.         pid = 0;
  64.         forked = FALSE;
  65.     }
  66.  
  67.     switch (pid) {
  68.     case -1:
  69.         uerror("fork");
  70.         rc_error(NULL);
  71.         /* NOTREACHED */
  72.     case 0:
  73.         if (forked)
  74.             setsigdefaults();
  75.         doredirs();
  76.  
  77.         /* null commands performed for redirections */
  78.         if (*av == NULL || b != NULL) {
  79.             if (b != NULL)
  80.                 b(av);
  81.             empty_fifoq();
  82.             if (!forked && parent)
  83.                 return;
  84.             rc_exit(getstatus());
  85.         }
  86.         execve(path, (const char **) av, (const char **) ev); /* bogus, huh? */
  87.         uerror(*av);
  88.         rc_exit(1);
  89.         /* NOTREACHED */
  90.     default:
  91.         if ((handler = signal(SIGINT, SIG_IGN)) != sig)
  92.             signal(SIGINT, handler); /* don't ignore interrupts in noninteractive mode */
  93.         while (pid != wait(&stat))
  94.             if (pid < 0)
  95.                 uerror("wait");
  96.         signal(SIGINT, handler);
  97.         redirq = NULL;
  98.         empty_fifoq();
  99.         setstatus(stat);
  100.         if (stat == SIGINT) /* interrupted? let the handler deal with it. */
  101.             rc_raise(ERROR);
  102.     }
  103. }
  104.