Start development on BSD 2
[unix-history] / .ref-BSD-1 / ashell / sh_exec.c
#include "sh.h"
int tglob(), trim();
static int gflag;
static char *exerr, *expath;
char nic[] "nice";
doexec(t)
int *t;
{
register char *cp, *pp;
register char **av;
char slash, pathc;
char *vp;
if (adrof(nic))
nice(getn(value(nic)));
cp = globone(t[DCOM]);
if (cp == 0)
exit(1);
exerr = 0;
expath = t[DCOM] = cp;
slash = gflag || any ('/', cp);
gflag = 0;
av = &t[DCOM+1];
scan(av, &tglob);
if (gflag) {
av = glob(av);
if (av == 0) {
prs("No match\n");
exit(1);
}
}
*--av = t[DCOM];
scan(av, &trim);
pp = value(path);
if (*pp == 0 || slash)
pp = "";
do {
for (cp = pp; *pp && *pp != '-' ; pp++)
*pp =& ~QUOTE;
pathc = *pp;
*pp = 0;
vp = strcpy(calloc(1, strlen(cp) + strlen(*av) + 2), cp);
if (cp == pp || slash == 0) {
if (cp[0])
strcat(vp, "/");
strcat(vp, *av);
texec(vp, av-DCOM);
xfree(vp);
}
} while ((*pp++ = pathc) != 0);
prs(expath);
if (exerr) {
err(exerr);
xfree(exerr);
} else
err(": Cannot find");
exit(1);
}
texec(f, t)
register int *t;
{
extern errno;
register int *t1;
register i;
int w;
execv(f, (t1 = &t[DCOM]));
switch (errno) {
case ENOEXEC:
*t1 = f;
i = open(f, 0);
if (i < 0) {
prs(*t1);
prs(": Cannot open");
exit(1);
}
w = 0;
read(i, &w, 2);
close(i);
f = interp(w);
if (f != 0)
*--t1 = f;
else if (w & 0100200) {
prs(*t1);
prs(": No interpreter\n");
exit(1);
} else
*--t1 = value(shell);
execv(*t1, t1);
prs(*t1);
/*
* should give better message but can't goto
* top because could loop
*/
err(": Execute failed");
exit(1);
case ENOMEM:
prs(*t1);
err(": Not enough core");
exit(1);
case EACCES:
if (exerr == 0) {
expath = savestr(f);
exerr = ": No execute access";
}
return;
}
}
scan(t, f)
register int *t;
int (*f)();
{
register char *p, c;
while (p = *t++)
while (c = *p)
*p++ = (*f)(c);
}
tglob(c)
char c;
{
if (any(c, "[?*"))
gflag = 1;
return (c);
}
trim(c)
char c;
{
return (c & 0177);
}
prn(n)
int n;
{
register a;
a = n / 10;
if (a != 0)
prn(a);
n = n % 10 + '0';
write(2, &n, 1);
}
globone(str)
register char *str;
{
int gv[2];
register char **gvp;
setname(str);
gv[0] = str;
gv[1] = 0;
gflag = 0;
scan(gv, &tglob);
if (gflag) {
gvp = glob(gv);
if (gvp == 0) {
bferr(": No match");
return (0);
}
str = *gvp++;
if (*gvp) {
bferr(": Ambiguous");
return (0);
}
} else {
scan(gv, &trim);
str = gv[0];
}
return (str);
}