home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / csh / sh.exec.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  4KB  |  189 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "sh.h"
  3.  
  4. /*
  5.  * C shell
  6.  */
  7.  
  8. /*
  9.  * System level search and execute of a command.
  10.  * We look in each directory for the specified command name.
  11.  * If the name contains a '/' then we execute only the full path name.
  12.  * If there is no search path then we execute only full path names.
  13.  */
  14.  
  15. /* 
  16.  * As we search for the command we note the first non-trivial error
  17.  * message for presentation to the user.  This allows us often
  18.  * to show that a file has the wrong mode/no access when the file
  19.  * is not in the last component of the search path, so we must
  20.  * go on after first detecting the error.
  21.  */
  22. char    *exerr;            /* Execution error message */
  23. char    *expath;        /* Path for exerr */
  24.  
  25. /* Dummy search path for just absolute search when no path */
  26. char    *justabs[] =    { "", 0 };
  27.  
  28. doexec(t)
  29.     register struct command *t;
  30. {
  31.     char *sav;
  32.     register char *dp, **pv, **av;
  33.     register struct varent *v;
  34.     bool slash = any('/', t->t_dcom[0]);
  35.     char *blk[2];
  36.  
  37.     /*
  38.      * Glob the command name.  If this does anything, then we
  39.      * will execute the command only relative to ".".  One special
  40.      * case: if there is no PATH, then we execute only commands
  41.      * which start with '/'.
  42.      */
  43.     dp = globone(t->t_dcom[0]);
  44.     xfree(t->t_dcom[0]);
  45.     exerr = 0; expath = t->t_dcom[0] = dp;
  46.     v = adrof("path");
  47.     if (v == 0 && expath[0] != '/')
  48.         pexerr();
  49.     slash |= gflag;
  50.  
  51.     /*
  52.      * Glob the argument list, if necessary.
  53.      * Otherwise trim off the quote bits.
  54.      */
  55.     gflag = 0; av = &t->t_dcom[1];
  56.     rscan(av, tglob);
  57.     if (gflag) {
  58.         av = glob(av);
  59.         if (av == 0)
  60.             error("No match");
  61.     }
  62.     blk[0] = t->t_dcom[0];
  63.     blk[1] = 0;
  64.     av = blkspl(blk, av);
  65.     scan(av, trim);
  66.  
  67.     xechoit(av);        /* Echo command if -x */
  68.     closech();        /* Close random fd's */
  69.  
  70.     /*
  71.      * If no path, no words in path, or a / in the filename
  72.      * then restrict the command search.
  73.      */
  74.     if (v == 0 || v->vec[0] == 0 || slash)
  75.         pv = justabs;
  76.     else
  77.         pv = v->vec;
  78.     sav = strspl("/", *av);        /* / command name for postpending */
  79.     do {
  80.         if (pv[0][0] == 0 || eq(pv[0], "."))    /* don't make ./xxx */
  81.             texec(*av, av);
  82.         else {
  83.             dp = strspl(*pv, sav);
  84.             texec(dp, av);
  85.             xfree(dp);
  86.         }
  87.         pv++;
  88.     } while (*pv);
  89.     xfree(sav);
  90.     xfree(av);
  91.     pexerr();
  92. }
  93.  
  94. pexerr()
  95. {
  96.  
  97.     /* Couldn't find the damn thing */
  98.     setname(expath);
  99.     xfree(expath);
  100.     if (exerr)
  101.         bferr(exerr);
  102.     bferr("Command not found");
  103. }
  104.  
  105. /* Last resort shell */
  106. char    *lastsh[] =    { SHELLPATH, 0 };
  107.  
  108. /*
  109.  * Execute command f, arg list t.
  110.  * Record error message if not found.
  111.  * Also do shell scripts here.
  112.  */
  113. texec(f, t)
  114.     char *f;
  115.     register char **t;
  116. {
  117.     register struct varent *v;
  118.     register char **vp;
  119.     extern char *sys_errlist[];
  120.  
  121.     execv(f, t);
  122.     switch (errno) {
  123.  
  124.     case ENOEXEC:
  125.         /*
  126.          * If there is an alias for shell, then
  127.          * put the words of the alias in front of the
  128.          * argument list replacing the command name.
  129.          * Note no interpretation of the words at this point.
  130.          */
  131.         v = adrof1("shell", &aliases);
  132.         if (v == 0) {
  133. #ifdef OTHERSH
  134.             register int ff = open(f, 0);
  135.             char ch;
  136. #endif
  137.  
  138.             vp = lastsh;
  139.             vp[0] = adrof("shell") ? value("shell") : SHELLPATH;
  140. #ifdef OTHERSH
  141.             if (ff != -1 && read(ff, &ch, 1) == 1 && ch != '#')
  142.                 vp[0] = OTHERSH;
  143.             close(ff);
  144. #endif
  145.         } else
  146.             vp = v->vec;
  147.         t[0] = f;
  148.         t = blkspl(vp, t);        /* Splice up the new arglst */
  149.         f = *t;
  150.         execv(f, t);
  151.         xfree(t);
  152.         /* The sky is falling, the sky is falling! */
  153.  
  154.     case ENOMEM:
  155.         Perror(f);
  156.  
  157.     case ENOENT:
  158.         break;
  159.  
  160.     default:
  161.         if (exerr == 0) {
  162.             exerr = sys_errlist[errno];
  163.             expath = savestr(f);
  164.         }
  165.     }
  166. }
  167.  
  168. execash(t, kp)
  169.     register struct command *kp;
  170. {
  171.  
  172.     didcch++;
  173.     lshift(kp->t_dcom, 1);
  174.     doexec(kp);
  175.     /*NOTREACHED*/
  176. }
  177.  
  178. xechoit(t)
  179.     char **t;
  180. {
  181.  
  182.     if (adrof("echo")) {
  183.         flush();
  184.         haderr = 1;
  185.         blkpr(t), printf("\n");
  186.         haderr = 0;
  187.     }
  188. }
  189.