/*
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include "sh.h"
#include <dirent.h>
#include <string.h>
#include "sh.tconst.h"
/*
* C shell
*/
/*
* System level search and execute of a command.
* We look in each directory for the specified command name.
* If the name contains a '/' then we execute only the full path name.
* If there is no search path then we execute only full path names.
*/
/*
* As we search for the command we note the first non-trivial error
* message for presentation to the user. This allows us often
* is not in the last component of the search path, so we must
* go on after first detecting the error.
*/
void pexerr(void);
void dohash(char []);
void
{
struct varent *v;
bool slash;
#ifdef TRACE
tprintf("TRACE- doexec()\n");
#endif
/*
* Glob the command name. If this does anything, then we
* will execute the command only relative to ".". One special
* case: if there is no PATH, then we execute only commands
* which start with '/'.
*/
if (v == 0 && dp[0] != '/') {
pexerr();
}
/*
* Glob the argument list, if necessary.
* Otherwise trim off the quote bits.
*/
if (gflag) {
if (av == 0)
error("No match");
}
blk[1] = 0;
#ifdef VFORK
#endif
/*
* Since all internal file descriptors are set to close on exec,
* we don't need to close them explicitly here. Just reorient
* ourselves for error messages.
*/
/*
* We must do this AFTER any possible forking (like `foo`
* in glob) so that this shell can still do subprocesses.
*/
(void) sigsetmask(0);
/*
* If no path, no words in path, or a / in the filename
* then restrict the command search.
*/
else
/* / command name for postpending */
#ifdef VFORK
#endif
if (havhash)
i = 0;
#ifdef VFORK
hits++;
#endif
do {
goto cont;
}
/* don't make ./xxx */
} else {
#ifdef VFORK
#endif
#ifdef VFORK
Vdp = 0;
#endif
}
#ifdef VFORK
misses++;
#endif
cont:
pv++;
i++;
} while (*pv);
#ifdef VFORK
hits--;
#endif
#ifdef VFORK
Vsav = 0;
Vav = 0;
#endif
pexerr();
}
void
pexerr(void)
{
#ifdef TRACE
tprintf("TRACE- pexerr()\n");
#endif
/* Couldn't find the damn thing */
if (exerr)
bferr("Command not found");
}
/*
* Execute command f, arg list t.
* Record error message if not found.
* Also do shell scripts here.
*/
void
{
struct varent *v;
#ifdef TRACE
tprintf("TRACE- texec()\n");
#endif
/* convert cfname and cargs from tchar to char */
/*
* exec returned, free up allocations from above
* tconvert(), zero cfname and cargs to prevent
* duplicate free() in freesyn()
*/
switch (errno) {
case ENOEXEC:
/* check that this is not a binary file */
{
printf("Cannot execute binary file.\n");
Perror(f);
return;
}
}
/*
* If there is an alias for shell, then
* put the words of the alias in front of the
* argument list replacing the command name.
* Note no interpretation of the words at this point.
*/
if (v == 0) {
#ifdef OTHERSH
#endif
S_SHELLPATH /* SHELLPATH */;
#ifdef OTHERSH
#endif
} else
t[0] = f;
f = *t;
/*
* now done with tchar arg list t,
* free the space calloc'd by above blkspl()
*/
xfree((char *)t);
/* exec returned, same free'ing as above */
/* The sky is falling, the sky is falling! */
case ENOMEM:
Perror(f);
case ENOENT:
break;
default:
if (exerr == 0) {
setname(f);
}
}
}
static void
{
char **rc;
int len;
while (len--)
}
/*ARGSUSED*/
void
{
#ifdef TRACE
tprintf("TRACE- execash()\n");
#endif
rechist();
exiterr++;
/*NOTREACHED*/
}
void
{
#ifdef TRACE
tprintf("TRACE- xechoit()\n");
#endif
flush();
haderr = 1;
haderr = 0;
}
}
/*
* This routine called when user enters "rehash".
* Both the path and cdpath caching arrays will
* be rehashed, via calling dohash. If either
* variable is not set with a value, then dohash
* just exits.
*/
void
dorehash(void)
{
}
/*
* Fill up caching arrays for path and cdpath
*/
void
{
int cnt;
int i = 0;
struct varent *v;
int hashval;
#ifdef TRACE
tprintf("TRACE- dohash()\n");
#endif
/* Caching $path */
if (cachearray == xhash) {
havhash = 1;
} else { /* Caching $cdpath */
havhash2 = 1;
}
cachearray[cnt] = 0;
if (v == 0)
return;
if (pv[0][0] != '/')
continue;
continue;
continue;
}
continue;
continue;
i);
}
}
}
void
dounhash(void)
{
#ifdef TRACE
tprintf("TRACE- dounhash()\n");
#endif
havhash = 0;
havhash2 = 0;
}
#ifdef VFORK
void
hashstat(void)
{
#ifdef TRACE
tprintf("TRACE- hashstat_()\n");
#endif
printf("%d hits, %d misses, %d%%\n",
}
#endif
/*
* Hash a command name.
*/
int
{
long h = 0;
#ifdef TRACE
tprintf("TRACE- hashname()\n");
#endif
while (*cp)
return ((int)h);
}