|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 6509 (0x196d)
Types: TextFile
Notes: UNIX file
Names: »exec1.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/sh/exec1.c«
/*
* The Bourne shell.
* Shell part of execution.
*/
#include "sh.h"
char *lastcmd = NULL;
/*
* Execute the given node, wait for completion, return status.
*/
command(np)
register NODE *np;
{
register int f; /* Pid of command */
int mynllflag; /* Saved fork not forced flag */
CON con; /* Control link for break/continue */
char *innp, **inlp; /* for NFOR */
NODE *cnode; /* for NCASE */
char *cname; /* for NCASE */
mynllflag = nllflag;
innp = inlp = NULL;
cnode = NULL;
f = 0;
con.c_next = sesp->s_con;
con.c_node = np;
con.c_bpp = savebuf();
sesp->s_con = &con;
switch (setjmp(con.c_envl)) {
case 0: /* initial setjmp */
break;
case 1: /* continue */
np = con.c_node;
break;
case 2: /* break */
goto break2;
default:
panic();
NOTREACHED;
}
for ( ; np; np=np->n_next) {
recover(ICMD);
f = 0;
nllflag = mynllflag;
switch (np->n_type) {
case NCOMS:
f = comscom(np->n_auxp);
break;
case NFOR:
if (innp == NULL) {
innp = np->n_strp;
nargc = 0;
nargv = makargl();
for (np = np->n_next->n_auxp; np; np = np->n_next)
eval(np->n_strp, EARGS);
inlp = nargv;
np = con.c_node;
}
continue;
case NFOR2:
/* do_done_list->n_next == this node */
if (*inlp == NULL || assnvar(innp, *inlp++) == NULL)
break;
continue;
case NWHILE:
/* do_done_list->n_next == this node */
nllflag = 0;
if (command(np->n_auxp))
break;
continue;
case NUNTIL:
/* do_done_list->n_next == this node */
nllflag = 0;
if ( ! command(np->n_auxp))
break;
continue;
case NBRAC:
command(np->n_auxp);
break;
case NPARN:
if (nllflag || (f=clone()) == 0) {
exit(command(np->n_auxp));
NOTREACHED;
}
break;
case NIF:
nllflag = 0;
if ( ! command(np->n_auxp->n_auxp))
np = np->n_auxp;
continue;
case NELSE:
command(np->n_auxp);
break;
case NCASE:
eval(np->n_strp, EWORD);
if (errflag)
break;
cname = duplstr(strt, 0);
continue;
case NCASE2:
cnode = np->n_auxp;
continue;
case NCASE3:
/* end of pattern list == next NCASE2 node */
eval(np->n_strp, EPATT);
if (errflag)
break;
if (match(strt, cname)) {
command(cnode);
break;
}
continue;
case NLIST:
nllflag = 0;
command(np->n_auxp);
continue;
case NANDF:
nllflag = 0;
if (command(np->n_auxp))
break;
continue;
case NORF:
nllflag = 0;
if ( ! command(np->n_auxp))
break;
continue;
case NBACK:
if ((f=clone()) == 0) {
static char *iov[] = { "0</dev/null", NULL };
bckflag++;
dflttrp(IBACK);
redirect(iov);
exit(command(np->n_auxp));
NOTREACHED;
}
sback = f;
prints("%d\n", f);
f = 0;
continue;
case NPIPE:
f = pipecoms(np);
break;
default:
panic();
NOTREACHED;
}
break;
}
break2:
nllflag = mynllflag;
sesp->s_con = sesp->s_con->c_next;
if (f)
waitc(f);
if (slret)
assnvar("LASTERROR", lastcmd);
freebuf(con.c_bpp);
if (eflag && (slret || errflag)) {
reset(RUABORT);
NOTREACHED;
}
return (slret);
}
/*
* Run a simple command.
* Anything but.
*/
#define FARGS 1
#define FIORS 2
#define FASSG 4
comscom(np)
register NODE *np;
{
register int f;
register char **app;
int nputs, nargs;
nargc = 1;
nargv = makargl();
nargv = addargl(nargv, "sh");
niovp = makargl();
nenvp = makargl();
nctlp = NULL;
/*
* Scan for arguments.
* or a control node.
*/
nputs = 0;
f = 0;
for ( ; np; np = np->n_next) {
switch (np->n_type) {
case NIORS:
f |= FIORS;
eval(np->n_strp, EWORD);
niovp = addargl(niovp, duplstr(strt, 0));
if (xflag)
nputs += puta(nputs, strt);
continue;
case NARGS:
f |= FARGS;
nargs = nargc;
eval(np->n_strp, EARGS);
if (xflag)
for (app = nargv+nargs; *app; )
nputs += puta(nputs, *app++);
continue;
case NASSG:
if (kflag || (f&FARGS)==0) {
f |= FASSG;
eval(np->n_strp, EWORD);
nenvp = addargl(nenvp, duplstr(strt, 0));
if (xflag)
nputs += puta(nputs, strt);
} else {
nargs = nargc;
eval(np->n_strp, EARGS);
if (xflag)
for (app = nargv+nargs; *app; )
nputs += puta(nputs, *app++);
}
continue;
case NCTRL:
if (nctlp!=NULL) {
panic();
NOTREACHED;
}
f |= FARGS;
nctlp = np;
continue;
default:
panic();
NOTREACHED;
}
}
if (xflag && nputs)
prints("\n");
#ifdef VERBOSE
if (xflag) {
prints("\t<%o flag, %d put, %d arg, %o arv, %o env, %o iov>\n",
f, nputs, nargc-1, *(nargv+1), *nenvp, *niovp);
}
#endif
nargv += 1; /* Skip over "sh" */
nargc -= 1;
/* Last chance to quit */
#ifdef VERBOSE
if (xflag) prints("errflag = %o\n", errflag);
#endif
if (errflag || nflag)
return (0);
/* And away we go */
sfree(lastcmd);
if (*nargv)
lastcmd = duplstr(*nargv, 1);
else
lastcmd = "";
switch (f) {
case 0:
return (0);
case FARGS:
if (nctlp) {
command(nctlp->n_auxp);
return (0);
}
case FARGS| FIORS:
case FARGS| FASSG:
case FARGS| FIORS| FASSG:
if (inline())
return (0);
break;
case FIORS:
break;
case FASSG:
case FIORS| FASSG:
for (app = nenvp; *app!=NULL; )
setsvar(*app++);
if ((f&~FASSG)==0)
return (0);
break;
default:
panic();
NOTREACHED;
}
if (nllflag || (f=clone()) == 0) {
if (redirect(niovp) < 0) {
slret = 1;
} else if (nargc) {
dflttrp(ICMD);
nenvp = envlvar(nenvp);
flexec();
slret = 1;
} else if (nctlp) {
command(nctlp->n_auxp);
}
exit(slret);
NOTREACHED;
}
return (f);
}
puta(n, p)
char *p;
{
if (n)
prints(" ");
#ifdef VERBOSE
else
prints("<%d> ", getpid());
#endif
prints("%s", p);
return (1);
}
/*
* Execute a pipe command.
* Fork, if necessary, a subshell to execute the pipe.
* Fork each segment off.
* Wait for last, save slret, wait for all, return slret from last.
*/
pipecoms(np)
register NODE *np;
{
register int f;
register int p1st = 0;
int pipev[2];
if ( ! nllflag && (f = clone()) != 0)
return (f);
while (np->n_type == NPIPE) {
if (f = pipeline(pipev)) {
/* Parent takes right hand side */
np = np->n_next;
if (p1st == 0)
p1st = f;
dup2(pipev[0], 0);
close(pipev[0]);
close(pipev[1]);
} else {
/* Child takes left hand side */
np = np->n_auxp;
dup2(pipev[1], 1);
close(pipev[0]);
close(pipev[1]);
exit(command(np));
NOTREACHED;
}
}
if (f = clone()) {
/* Parent waits out pipe line */
spipe = p1st;
close(0);
if (f = waitc(f))
waitc(p1st);
exit(f);
NOTREACHED;
} else {
/* Child takes the pipe tail */
exit(command(np));
NOTREACHED;
}
}