DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦b86e3ddcc⟧ TextFile

    Length: 6727 (0x1a47)
    Types: TextFile
    Notes: UNIX file
    Names: »exec1.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »cmd/rsh/exec1.c« 

TextFile

/*
 * The Bourne shell.
 * Shell part of execution.
 */
#include "sh.h"

static char lnargv[30] = "                     ";

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 */
	printf("sh: cmd exec\n");
	printf("sh: cmd = %s\n", nargv[0]);
	if (pnmatch(nargv[0], "!!", 1) ) {
		printf("match\n");
		nargv[0] = *lnargv;
	}
	*lnargv = nargv[0];
	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;
	}
}