# 2.11BSD#431 - /usr/src/bin/csh/sh.exec.c

##### Functions

    doexec            X
    dohash            X
    dounhash          X
    execash           X
    hashname          X
    hashstat          X
    pexerr            X
    texec             X
    xechoit           X

##### Variables

    exerr             X
    expath            X
    justabs           X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley Software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)sh.exec.c	5.2.2 (2.11BSD) 1996/9/20";
       9: #endif
      10:
      11: #include "sh.h"
      12: #include <string.h>
      13: #include <sys/dir.h>
      14:
      15: /*
      16:  * C shell
      17:  */
      18:
      19: /*
      20:  * System level search and execute of a command.
      21:  * We look in each directory for the specified command name.
      22:  * If the name contains a '/' then we execute only the full path name.
      23:  * If there is no search path then we execute only full path names.
      24:  */
      25:
      26: /*
      27:  * As we search for the command we note the first non-trivial error
      28:  * message for presentation to the user.  This allows us often
      29:  * to show that a file has the wrong mode/no access when the file
      30:  * is not in the last component of the search path, so we must
      31:  * go on after first detecting the error.
      32:  */
      33: char    *exerr;         /* Execution error message */
      34: char    *expath;        /* Path for exerr */
      35:
      36: #include "sh.exec.h"
      37:
      38: /* Dummy search path for just absolute search when no path */
      39: char    *justabs[] =    { "", 0 };
      40:
      41: doexec(t)
      42:     register struct command *t;
      43: {
      44:     char *sav;
      45:     register char *dp, **pv, **av;
      46:     register struct varent *v;
      47:     bool slash = any('/', t->t_dcom[0]);
      48:     int hashval, hashval1, i;
      49:     char *blk[2];
      50:
      51:     /*
      52: 	 * Glob the command name.  If this does anything, then we
      53: 	 * will execute the command only relative to ".".  One special
      54: 	 * case: if there is no PATH, then we execute only commands
      55: 	 * which start with '/'.
      56: 	 */
      57:     dp = globone(t->t_dcom[0]);
      58:     sav = t->t_dcom[0];
      59:     exerr = 0; expath = t->t_dcom[0] = dp;
      60:     xfree(sav);
      61:     v = adrof("path");
      62:     if (v == 0 && expath[0] != '/')
      63:         pexerr();
      64:     slash |= gflag;
      65:
      66:     /*
      67: 	 * Glob the argument list, if necessary.
      68: 	 * Otherwise trim off the quote bits.
      69: 	 */
      70:     gflag = 0; av = &t->t_dcom[1];
      71:     tglob(av);
      72:     if (gflag) {
      73:         av = glob(av);
      74:         if (av == 0)
      75:             error("No match");
      76:     }
      77:     blk[0] = t->t_dcom[0];
      78:     blk[1] = 0;
      79:     av = blkspl(blk, av);
      80: #ifdef VFORK
      81:     Vav = av;
      82: #endif
      83:     trim(av);
      84:
      85:     xechoit(av);        /* Echo command if -x */
      86:     /*
      87: 	 * Since all internal file descriptors are set to close on exec,
      88: 	 * we don't need to close them explicitly here.  Just reorient
      89: 	 * ourselves for error messages.
      90: 	 */
      91:     SHIN = 0; SHOUT = 1; SHDIAG = 2; OLDSTD = 0;
      92:
      93:     /*
      94: 	 * We must do this AFTER any possible forking (like `foo`
      95: 	 * in glob) so that this shell can still do subprocesses.
      96: 	 */
      97:     (void) sigsetmask(0L);
      98:
      99:     /*
     100: 	 * If no path, no words in path, or a / in the filename
     101: 	 * then restrict the command search.
     102: 	 */
     103:     if (v == 0 || v->vec[0] == 0 || slash)
     104:         pv = justabs;
     105:     else
     106:         pv = v->vec;
     107:     sav = strspl("/", *av);     /* / command name for postpending */
     108: #ifdef VFORK
     109:     Vsav = sav;
     110: #endif
     111:     if (havhash)
     112:         hashval = hashname(*av);
     113:     i = 0;
     114: #ifdef VFORK
     115:     hits++;
     116: #endif
     117:     do {
     118:         if (!slash && pv[0][0] == '/' && havhash) {
     119:             hashval1 = hash(hashval, i);
     120:             if (!bit(xhash, hashval1))
     121:                 goto cont;
     122:         }
     123:         if (pv[0][0] == 0 || eq(pv[0], "."))    /* don't make ./xxx */
     124:             texec(*av, av);
     125:         else {
     126:             dp = strspl(*pv, sav);
     127: #ifdef VFORK
     128:             Vdp = dp;
     129: #endif
     130:             texec(dp, av);
     131: #ifdef VFORK
     132:             Vdp = 0;
     133: #endif
     134:             xfree(dp);
     135:         }
     136: #ifdef VFORK
     137:         misses++;
     138: #endif
     139: cont:
     140:         pv++;
     141:         i++;
     142:     } while (*pv);
     143: #ifdef VFORK
     144:     hits--;
     145: #endif
     146: #ifdef VFORK
     147:     Vsav = 0;
     148:     Vav = 0;
     149: #endif
     150:     xfree(sav);
     151:     xfree((char *)av);
     152:     pexerr();
     153: }
     154:
     155: pexerr()
     156: {
     157:
     158:     /* Couldn't find the damn thing */
     159:     setname(expath);
     160:     /* xfree(expath); */
     161:     if (exerr)
     162:         bferr(exerr);
     163:     bferr("Command not found");
     164: }
     165:
     166: /*
     167:  * Execute command f, arg list t.
     168:  * Record error message if not found.
     169:  * Also do shell scripts here.
     170:  */
     171: texec(f, t)
     172:     char *f;
     173:     register char **t;
     174: {
     175:     register struct varent *v;
     176:     register char **vp;
     177:     char *lastsh[2];
     178:
     179:     execv(f, t);
     180:     switch (errno) {
     181:
     182:     case ENOEXEC:
     183:         /*
     184: 		 * If there is an alias for shell, then
     185: 		 * put the words of the alias in front of the
     186: 		 * argument list replacing the command name.
     187: 		 * Note no interpretation of the words at this point.
     188: 		 */
     189:         v = adrof1("shell", &aliases);
     190:         if (v == 0) {
     191: #ifdef OTHERSH
     192:             register int ff = open(f, 0);
     193:             char ch;
     194: #endif
     195:
     196:             vp = lastsh;
     197:             vp[0] = adrof("shell") ? value("shell") : SHELLPATH;
     198:             vp[1] = (char *) NULL;
     199: #ifdef OTHERSH
     200:             if (ff != -1 && read(ff, &ch, 1) == 1 && ch != '#')
     201:                 vp[0] = OTHERSH;
     202:             (void) close(ff);
     203: #endif
     204:         } else
     205:             vp = v->vec;
     206:         t[0] = f;
     207:         t = blkspl(vp, t);      /* Splice up the new arglst */
     208:         f = *t;
     209:         xfree((char *)t);
     210:         execv(f, t);
     211:         /* The sky is falling, the sky is falling! */
     212:
     213:     case ENOMEM:
     214:         Perror(f);
     215:
     216:     case ENOENT:
     217:         break;
     218:
     219:     default:
     220:         if (exerr == 0) {
     221:             exerr = syserrlst(errno);
     222:             expath = savestr(f);
     223:         }
     224:     }
     225: }
     226:
     227: /*ARGSUSED*/
     228: execash(t, kp)
     229:     char **t;
     230:     register struct command *kp;
     231: {
     232:
     233:     rechist();
     234:     (void) signal(SIGINT, parintr);
     235:     (void) signal(SIGQUIT, parintr);
     236:     (void) signal(SIGTERM, parterm);    /* if doexec loses, screw */
     237:     lshift(kp->t_dcom, 1);
     238:     exiterr++;
     239:     doexec(kp);
     240:     /*NOTREACHED*/
     241: }
     242:
     243: xechoit(t)
     244:     char **t;
     245: {
     246:
     247:     if (adrof("echo")) {
     248:         flush();
     249:         haderr = 1;
     250:         blkpr(t), putchar('\n');
     251:         haderr = 0;
     252:     }
     253: }
     254:
     255: /*VARARGS0*//*ARGSUSED*/
     256: dohash()
     257: {
     258:     struct stat stb;
     259:     DIR *dirp;
     260:     register struct direct *dp;
     261:     register int cnt;
     262:     int i = 0;
     263:     struct varent *v = adrof("path");
     264:     char **pv;
     265:     int hashval;
     266:
     267:     havhash = 1;
     268:     for (cnt = 0; cnt < sizeof xhash; cnt++)
     269:         xhash[cnt] = 0;
     270:     if (v == 0)
     271:         return;
     272:     for (pv = v->vec; *pv; pv++, i++) {
     273:         if (pv[0][0] != '/')
     274:             continue;
     275:         dirp = opendir(*pv);
     276:         if (dirp == NULL)
     277:             continue;
     278:         if (fstat(dirp->dd_fd, &stb) < 0 || !S_ISDIR(stb.st_mode)) {
     279:             closedir(dirp);
     280:             continue;
     281:         }
     282:         while ((dp = readdir(dirp)) != NULL) {
     283:             if (dp->d_ino == 0)
     284:                 continue;
     285:             if (dp->d_name[0] == '.' &&
     286:                 (dp->d_name[1] == '\0' ||
     287:                  dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
     288:                 continue;
     289:             hashval = hash(hashname(dp->d_name), i);
     290:             bis(xhash, hashval);
     291:         }
     292:         closedir(dirp);
     293:     }
     294: }
     295:
     296: dounhash()
     297: {
     298:
     299:     havhash = 0;
     300: }
     301:
     302: #ifdef VFORK
     303: hashstat()
     304: {
     305:
     306:     if (hits+misses)
     307:         printf("%d hits, %d misses, %d%%\n",
     308:             hits, misses,
     309:             (int)(100L * hits / (hits + misses)));
     310: }
     311: #endif
     312:
     313: /*
     314:  * Hash a command name.
     315:  */
     316: hashname(cp)
     317:     register char *cp;
     318: {
     319:     register long h = 0;
     320:
     321:     while (*cp)
     322:         h = hash(h, *cp++);
     323:     return ((int) h);
     324: }

#### Defined functions

doexec defined in line 41; used 2 times

- in line 239
- in /usr/src/bin/csh/sh.sem.c line 246

dohash defined in line 256; used 6 times

- in /usr/src/bin/csh/sh.c line 327
- in /usr/src/bin/csh/sh.func.c line 788
- in /usr/src/bin/csh/sh.init.c line 34, 144
- in /usr/src/bin/csh/sh.set.c line 78, 212

dounhash defined in line 296; used 2 times

- in /usr/src/bin/csh/sh.init.c line 79, 156

execash defined in line 228; used 2 times

- in /usr/src/bin/csh/sh.init.c line 71, 111

hashname defined in line 316; used 3 times

- in line 112, 289
- in /usr/src/bin/csh/sh.exec2.c line 35

hashstat defined in line 303; used 2 times

- in /usr/src/bin/csh/sh.init.c line 74, 121

pexerr defined in line 155; used 2 times

- in line 63, 152

texec defined in line 171; used 2 times

- in line 124, 130

xechoit defined in line 243; used 2 times

- in line 85
- in /usr/src/bin/csh/sh.func.c line 68

#### Defined variables

exerr defined in line 33; used 5 times

- in line 59, 161-162(2), 220-221(2)

expath defined in line 34; used 4 times

- in line 59-62(2), 159, 222

justabs defined in line 39; used 3 times

- in line 104
- in /usr/src/bin/csh/sh.exec2.c line 30, 217

sccsid defined in line 8; never used

Last modified: 1996-09-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1912 |