|
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: 6301 (0x189d) Types: TextFile Notes: UNIX file Names: »exec3.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/rsh/exec3.c« └─⟦this⟧ »cmd/sh/exec3.c«
/* * Bourne shell. * Builtin commands. */ #include "sh.h" #include <sys/times.h> #include <const.h> /* HZ defined here */ #define HOUR (60L*60L*HZ) #define MINUTE (60L*HZ) #define SECOND HZ extern s_colon(); extern s_dot(); extern s_break(); #define s_continue s_break extern s_cd(); extern s_eval(); extern s_exec(); extern s_exit(); extern s_export(); extern s_login(); #define s_newgrp s_login extern s_read(); #define s_readonly s_export extern s_set(); extern s_shift(); extern s_times(); extern s_trap(); extern s_umask(); extern s_wait(); #define SNULL ((int (*)())0) typedef struct { int i_hash; char *i_name; int (*i_func)(); } INLINE; INLINE inls[] = { 0, ":", s_colon, 0, ".", s_dot, 0, "break", s_break, 0, "continue", s_continue, 0, "cd", s_cd, 0, "eval", s_eval, 0, "exec", s_exec, 0, "exit", s_exit, 0, "export", s_export, 0, "login", s_login, 0, "newgrp", s_newgrp, 0, "read", s_read, 0, "readonly", s_readonly, 0, "set", s_set, 0, "shift", s_shift, 0, "times", s_times, 0, "trap", s_trap, 0, "umask", s_umask, 0, "wait", s_wait, 0, NULL, SNULL, }; inline() { register int (*s_func)(); register INLINE *ip; register int ahash; if (inls[0].i_hash==0) for (ip=inls; ip->i_name!=NULL; ip+=1) ip->i_hash = ihash(ip->i_name); ahash = ihash(nargv[0]); for (ip=inls; ip->i_name!=NULL; ip+=1) if (ip->i_hash==ahash && strcmp(nargv[0], ip->i_name)==0) break; if ((s_func=ip->i_func) == SNULL) return (0); if (*niovp != NULL && s_func != s_exec) { eredir(); slret = 1; } else slret = (*s_func)(); return (1); } ihash(cp) register char *cp; { register int i; for (i=0; *cp; i+=*cp++); return (i); } /* * Actual builtin functions. */ s_colon() { return (0); } s_dot() { if (nargc==2) { ffind(NULL); if (ffind(vpath, nargv[1], 4)) return (session(SFILE, duplstr(strt, 0))); else { ecantfind(nargv[1]); return (1); } } else if (nargc==1) return (0); syntax(); return (1); } s_break() { register CON *cp; register int t; register int n; int ret; ret = nargv[0][0]=='b' ? 2 : 1; n = nargc>1 ? atoi(nargv[1]) : 1; for (cp = sesp->s_con; cp; cp = cp->c_next) { t = cp->c_node->n_type; if ((t==NWHILE || t==NFOR || t==NUNTIL) && --n == 0) { sesp->s_con = cp; longjmp(cp->c_envl, ret); break; } freebuf(cp->c_bpp); } printe("%s out of bounds", ret==1 ? "Continue" : "Break"); reset(RBRKCON); NOTREACHED; } /* s_continue is overlaid with s_break */ s_cd() { register char *cp; cp = nargc<2 ? vhome : nargv[1]; if (chdir(cp) < 0) { printe("%s: bad directory", cp); return (1); } return (0); } s_eval() { if (nargc>1) return (session(SARGV, ++nargv)); else return (0); } s_exec() { if (redirect(niovp) < 0) { if (nargc>1) { exit(1); NOTREACHED; } return (1); } if (nargc==1) return (0); if (no1flag) cleanup(2, NULL); dflttrp(ICMD); ++nargv; --nargc; nenvp = envlvar(nenvp); flexec(); exit(1); NOTREACHED; } s_exit() { if (nargc > 1) slret = atoi(nargv[1]); reset(RUEXITS); NOTREACHED; } s_export() { register int flag; register char **varv; flag = nargv[0][0]=='e' ? VEXP : VRDO; if (nargc < 2) tellvar(flag); else for (varv=++nargv; *varv; ) if (namevar(*varv)) flagvar(*varv++, flag); else eillvar(*varv++); return (0); } s_login() { register char *cmd; cmd = nargv[0][0]=='l' ? "/bin/login" : "/bin/newgrp"; execve(cmd, nargv, envlvar(nenvp)); ecantfind(cmd); return (1); } /* s_newgrp is overlaid with s_login */ s_read() { SES s; register int n, c; register char **vp; int eol; s.s_type = SSTR; s.s_flag = 0; s.s_ifp = stdin; s.s_next = sesp; sesp = &s; for (eol=0, vp=++nargv, n=--nargc; n; n-=1, vp+=1) { if (n==1 && ! eol) { strp = strt; c = collect('\n', 2); if (c == '\n') --strp; *strp = '\0'; } else if (! eol) c = yylex(); else *strt = '\0'; if (namevar(*vp)) assnvar(*vp, duplstr(strt, 0)); else eillvar(*vp); eol = c=='\n' || c==EOF; } sesp = s.s_next; return (c==EOF); } /* s_readonly overlaid with s_export */ s_set() { if (nargc < 2) { tellvar(0); return (0); } return (set(nargc, nargv, 0)); } s_shift() { register int n; n = nargc > 1 ? atoi(nargv[1]) : 1; while (n > 0 && sargc > 0) { n -= 1; sargc -= 1; sargp += 1; } return (n!=0); } s_times() { struct tbuffer tb; times(&tb); ptime(tb.tb_cutime); ptime(tb.tb_cstime); prints("\n"); return (0); } s_trap() { register char **vp; register char *cp; register int err; err = 0; if (nargc==1) return (telltrp()); vp = ++nargv; cp = *vp; if (class(cp[0], MDIGI) && (cp[1]=='\0' || (class(cp[1], MDIGI) && cp[2]=='\0'))) cp = NULL; else ++vp; while (*vp) { if (class(vp[0][0], MDIGI)) err |= setstrp(atoi(*vp++), cp); else { printe("Bad trap: %s", *vp++); err |= 1; } } return (err); } s_umask() { if (nargc < 2) prints("%03o\n", ufmask); else umask(ufmask = atoi(nargv[1])); return (0); } s_wait() { register int f; f = (nargc > 1) ? atoi(nargv[1]) : 0; if (f > 0) f = -f; waitc(f); return (slret); } /* * The set command. This is also called from `main' to set * options from the command line. In this case `flag' is * set. */ set(argc, argv, flag) register char *argv[]; { int n; register char *cp; if (flag) { cflag = 0; iflag = 0; sflag = 0; } n = 0; if (argc > 0) n = 1; if (argc>1 && argv[1][0]=='-') { register char *fp; n++; for (cp = &argv[1][1]; *cp; cp++) { if ((fp=index(shfnams, *cp)) == NULL || (fp+=shflags-shfnams) == NULL || (fp != &lgnflag && fp > &xflag && flag == 0)) printe("-%c: Bad option", *cp); else if (fp != &lgnflag) *fp = *cp; } if (cp == &argv[1][1]) { vflag = 0; xflag = 0; } if (flag == 0 && argc == 2) return (errflag); } if (errflag) return (1); if (sargv != NULL) { vfree(sargv); } sargv = vdupl(argv); sargc = argc - n; sargp = sargv + n; return (0); } /* * print the time as XmX.Xs * as fixed by Randall. */ ptime(t) long t; { register int ticks, tenths, seconds; prints("%Dm", t/MINUTE); ticks = t%MINUTE; seconds = ticks/SECOND; tenths = (ticks%SECOND + SECOND/20)/(SECOND/10); if (tenths == 10) { tenths = 0; seconds++; } prints("%d.%ds ", seconds, tenths); }