|
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 - 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; } }