|
|
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: 5255 (0x1487)
Types: TextFile
Notes: UNIX file
Names: »exec2.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/rsh/exec2.c«
└─⟦this⟧ »cmd/sh/exec2.c«
/*
* 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;
}
}