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

⟦e3e2de93f⟧ TextFile

    Length: 5255 (0x1487)
    Types: TextFile
    Notes: UNIX file
    Names: »exec2.c«

Derivation

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

TextFile

/*
 * Bourne shell.
 * System part of execution.
 */
#include "sh.h"
#include <errno.h>
#include <param.h>
#include <signal.h>
#include <stat.h>

/*
 * Wait for the given process to complete.
 */
waitc(pid)
int pid;
{
	register int f;
	unsigned s;
	register int w, n;
	int	(*ssig)();

	if (pid < 0)
		f = -pid;
	else
		f = pid;
	if ((ssig=signal(SIGINT, SIG_IGN)) != SIG_IGN)
		signal(SIGINT, sigintr);
	for (;;) {
		if ((w=wait(&s)) >= 0) {
			if (n = (s&0177)) {
				if (n==SIGINT)
					sigintr(n);
				else if (n==SIGPIPE && spipe
					 && (w >= spipe && w <= f))
					;
				else {
					if (w != f)
						prints("%d: ", w);
					if (n==SIGSYS && (s&0200)==0)
					    prints("exec failed");
					else if (n>0 && n<=NSIG)
						prints("%s", signame[n]);
					else
						prints("status %d", n);
					if (s & 0200)
						prints(" -- core dumped");
					prints("\n");
				}
				s = 200 + n;
			} else
				s >>= 8;
			if (w == f) {
				slret = s;
				break;
			}
		} else if (errno==EINTR) {
			if (pid > 0)
				continue;
			else {
				slret = 0;
				break;
			}
		} else if (errno==ECHILD) {
			if (pid == 0)	
				slret = 0;
			else
				slret = ECHILD;
			break;
		} else {
			panic();
			NOTREACHED;
		}
	}
	signal(SIGINT, ssig);
	return (slret);
}

/*
 * Make an imperfect copy of ourself.
 */
clone()
{
	register int f;
	register SES *sp;

	if ((f=fork()) < 0) {
		prints("Try again\n");
		reset(RSYSER);
		NOTREACHED;
	} else if (f == 0) {
		nllflag = 1;
		sflag = iflag = cflag = no1flag = lgnflag = 0;
		slret = spipe = 0;
		sp = sesp;
		sp->s_con->c_next = NULL;
		while (sp) {
			if (sp->s_type == SFILE)
				fclose(sp->s_ifp);
			sp = sp->s_next;
		}
		dflttrp(IFORK);
	}
	return (f);
}

/*
 * Open a pipe, panic on failure.
 * Otherwise return as a clone.
 */
pipeline(pv)
int *pv;
{
	if (pipe(pv) < 0) {
		prints("Pipe failed\n");
		reset(RSYSER);
		NOTREACHED;
	}
	return (clone());
}

/*
 * Try to execute a file in several ways.
 *	A return is always an error.
 *	Used by exec in inline.
 */
flexec()
{
	ffind(NULL);
	while (ffind(vpath, *nargv, 1)) {
		execve(strt, nargv, nenvp);
		if (errno==ENOEXEC) {
			*nargv = duplstr(strt, 0);
			nargc += 1;
			nargv -= 1;
			nargv = vdupl(nargv);
			nenvp = vdupl(nenvp);
			while (sesp) {
				freebuf(sesp->s_bpp);
				sesp = sesp->s_next;
			}
			longjmp(restart, 1);
		}
	}
	ecantfind(nargv[0]);
	return (-1);
}

/*
 * Process a redirection vector.
 * Abort and return -1 at the first failure, return 0 for success.
 */
redirect(iovp)
char **iovp;
{
	register char **iopp;
	register char *io;
	register int op;
	int u1, u2;

	for (iopp = iovp;(io = *iopp++)!=NULL; ) {
		if (class(*io, MDIGI))
			u1 = *io++ - '0';
		else
			u1 = *io=='<' ? 0 : 1;
		for (op=0; ; io+=1)
			if (*io=='>')
				op += 1;
			else if (*io=='<')
				op -= 1;
			else
				break;
		if (*io++ == '&') {
			if (op != 1 && op != -1) {
				panic();
				NOTREACHED;
			}
			u2 = *io++;
			if (u2 == '-') {
				close(u1);
				continue;
			} else if (!class(u2, MDIGI)) {
				eredir();
				return (-1);
			} else {
				u2 -= '0';
				dup2(u2, u1);
				continue;
			}
		}
		for (io-=1; *io==' '||*io=='\t'; io+=1);
		switch (op) {
		case -2:	/* Unquoted here */
				/* Fall through */
		case -1:	/* Input file, quoted here */
			if ((u2 = open(io, 0)) < 0) {
				ecantopen(io);
				return (-1);
			}
			if (op == -2 && (u2 = evalhere(u2)) < 0)
				return (-1);
			dup2(u2, u1);
			close(u2);
			continue;
		case 2:		/* Append to output */
			if ((u2 = open(io, 1)) >= 0) {
				lseek(u2, 0L, 2);
				dup2(u2, u1);
				close(u2);
				continue;
			} /* else fall through */
		case 1:		/* Output file */
			if ((u2 = creat(io, 0666)) < 0) {
				ecantmake(io);
				return (-1);
			}
			dup2(u2, u1);
			close(u2);
			continue;
		default:
			panic();
			NOTREACHED;
		}
	}
	return (0);
}

#ifdef NAMEPIPE
/*
 * Create a named pipe.
 */
npipe(np)
register NODE *np;
{
	register char *tmp;
	register int f;
	char *tvec[2];

	tmp = shtmp();
	mknod(tmp, S_IFPIP, 0);
	if ((f = clone()) == 0) {
		if (np->n_type==NRPIPE)
			strt[0] = '<';
		else
			strt[0] = '>';
		strt[1] = '\0';
		tvec[0] = strcat(strt, tmp);
		tvec[1] = NULL;
		redirect(tvec);
		command(np->n_auxp);
		exit(slret);
		NOTREACHED;
	}
	cleanup(0, tmp);
	strcpy(strt, tmp);
	return;
}
#endif

/*
 * Search a path, perhaps repeatedly, for a file with access mode.
 * Is called with paths == NULL to reset pointers.
 * UGLY, but it works.
 */
ffind(paths, file, mode)
char *paths, *file;
{
	register char c, *cp1, *cp2;
	static char *fp, *ff, *fcp;

	if (paths==NULL) {
		fp = ff = fcp = NULL;
		return (0);
	}
	if (ff!=file) {
		fp = fcp = paths;
		ff = file;
		if (index(ff, '/')!=NULL)
			fcp = "";
	}
	for (c=':'; c==':'; ) {
		cp1 = fcp;
		cp2 = strt;
		while (*cp1 && *cp1!=':')
			*cp2++ = *cp1++;
		if (cp2 != strt)
			*cp2++ = '/';
		c = *cp1++;
		fcp = cp1;
		cp1 = ff;
		while (*cp2++ = *cp1++);
		if (access(strt, mode)>=0)
			return (1);
	}
	return (0);
}

/*
 * Check to see if we have mail.
 */
checkmail()
{
	static long mailsize = -1;
	struct stat sbuf;

	if (*vmail == '\0')
		return;
	if (stat(vmail, &sbuf)<0) {
		mailsize = 0;
	} else {
		if (sbuf.st_size > mailsize
		 && mailsize != -1)
			prints("You have mail.\n");
		mailsize = sbuf.st_size;
	}
}