⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osh.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
/* */#include <setjmp.h>#define	INTR	2#define	QUIT	3#define LINSIZ 1000#define ARGSIZ 50#define TRESIZ 100#define QUOTE 0200#define FAND 1#define FCAT 2#define FPIN 4#define FPOU 8#define FPAR 16#define FINT 32#define FPRS 64#define TCOM 1#define TPAR 2#define TFIL 3#define TLST 4#define DTYP 0#define DLEF 1#define DRIT 2#define DFLG 3#define DSPR 4#define DCOM 5#define	ENOMEM	12#define	ENOEXEC 8int errval;char	*dolp;char	pidp[6];char	**dolv;jmp_buf	jmpbuf;int	dolc;char	*promp;char	*linep;char	*elinep;char	**argp;char	**eargp;int	*treep;int	*treeend;char	peekc;char	gflg;char	error;char	uid;char	setintr;char	*arginp;int	onelflg;int	stoperr;#define	NSIG	16char	*mesg[NSIG] {	0,	"Hangup",	0,	"Quit",	"Illegal instruction",	"Trace/BPT trap",	"IOT trap",	"EMT trap",	"Floating exception",	"Killed",	"Bus error",	"Memory fault",	"Bad system call",	0,	"Alarm clock",	"Terminated",};char	line[LINSIZ];char	*args[ARGSIZ];int	trebuf[TRESIZ];main(c, av)int c;char **av;{	register f;	register char *acname, **v;	for(f=3; f<15; f++)		close(f);	dolc = getpid();	for(f=4; f>=0; f--) {		dolc = dolc/10;		pidp[f] = dolc%10 + '0';	}	v = av;	acname = "<none>";	promp = "% ";	if((uid = getuid()) == 0)		promp = "# ";	if(c>1 && v[1][0]=='-' && v[1][1]=='e') {		++stoperr;		v[1] = v[0];		++v;		--c;	}	if(c > 1) {		promp = 0;		if (*v[1]=='-') {			**v = '-';			if (v[1][1]=='c' && c>2)				arginp = v[2];			else if (v[1][1]=='t')				onelflg = 2;		} else {			close(0);			f = open(v[1], 0);			if(f < 0) {				prs(v[1]);				err(": cannot open",255);			}		}	}	if(**v == '-') {		signal(QUIT, 1);		f = signal(INTR, 1);		if ((arginp==0&&onelflg==0) || (f&01)==0)			setintr++;	}	dolv = v+1;	dolc = c-1;loop:	if(promp != 0)		prs(promp);	peekc = getc();	main1();	goto loop;}main1(){	register char  *cp;	register *t;	argp = args;	eargp = args+ARGSIZ-5;	linep = line;	elinep = line+LINSIZ-5;	error = 0;	gflg = 0;	do {		cp = linep;		word();	} while(*cp != '\n');	treep = trebuf;	treeend = &trebuf[TRESIZ];	if(gflg == 0) {		if(error == 0) {			setjmp(jmpbuf);			if (error)				return;			t = syntax(args, argp);		}		if(error != 0)			err("syntax error",255); else			execute(t);	}}word(){	register char c, c1;	*argp++ = linep;loop:	switch(c = getc()) {	case ' ':	case '\t':		goto loop;	case '\'':	case '"':		c1 = c;		while((c=readc()) != c1) {			if(c == '\n') {				error++;				peekc = c;				return;			}			*linep++ = c|QUOTE;		}		goto pack;	case '&':	case ';':	case '<':	case '>':	case '(':	case ')':	case '|':	case '^':	case '\n':		*linep++ = c;		*linep++ = '\0';		return;	}	peekc = c;pack:	for(;;) {		c = getc();		if(any(c, " '\"\t;&<>()|^\n")) {			peekc = c;			if(any(c, "\"'"))				goto loop;			*linep++ = '\0';			return;		}		*linep++ = c;	}}tree(n)int n;{	register *t;	t = treep;	treep =+ n;	if (treep>treeend) {		prs("Command line overflow\n");		error++;		longjmp(jmpbuf, 1);	}	return(t);}getc(){	register char c;	if(peekc) {		c = peekc;		peekc = 0;		return(c);	}	if(argp > eargp) {		argp =- 10;		while((c=getc()) != '\n');		argp =+ 10;		err("Too many args",255);		gflg++;		return(c);	}	if(linep > elinep) {		linep =- 10;		while((c=getc()) != '\n');		linep =+ 10;		err("Too many characters",255);		gflg++;		return(c);	}getd:	if(dolp) {		c = *dolp++;		if(c != '\0')			return(c);		dolp = 0;	}	c = readc();	if(c == '\\') {		c = readc();		if(c == '\n')			return(' ');		return(c|QUOTE);	}	if(c == '$') {		c = readc();		if(c>='0' && c<='9') {			if(c-'0' < dolc)				dolp = dolv[c-'0'];			goto getd;		}		if(c == '$') {			dolp = pidp;			goto getd;		}	}	return(c&0177);}readc(){	int rdstat;	char cc;	register c;	if (arginp) {		if (arginp == 1)			exit(errval);		if ((c = *arginp++) == 0) {			arginp = 1;			c = '\n';		}		return(c);	}	if (onelflg==1)		exit(255);	if((rdstat = read(0, &cc, 1)) != 1)		if(rdstat==0) exit(errval); /* end of file*/		else exit(255); /* error */	if (cc=='\n' && onelflg)		onelflg--;	return(cc);}/* * syntax *	empty *	syn1 */syntax(p1, p2)char **p1, **p2;{	while(p1 != p2) {		if(any(**p1, ";&\n"))			p1++; else			return(syn1(p1, p2));	}	return(0);}/* * syn1 *	syn2 *	syn2 & syntax *	syn2 ; syntax */syn1(p1, p2)char **p1, **p2;{	register char **p;	register *t, *t1;	int l;	l = 0;	for(p=p1; p!=p2; p++)	switch(**p) {	case '(':		l++;		continue;	case ')':		l--;		if(l < 0)			error++;		continue;	case '&':	case ';':	case '\n':		if(l == 0) {			l = **p;			t = tree(4);			t[DTYP] = TLST;			t[DLEF] = syn2(p1, p);			t[DFLG] = 0;			if(l == '&') {				t1 = t[DLEF];				t1[DFLG] =| FAND|FPRS|FINT;			}			t[DRIT] = syntax(p+1, p2);			return(t);		}	}	if(l == 0)		return(syn2(p1, p2));	error++;	return(0);}/* * syn2 *	syn3 *	syn3 | syn2 */syn2(p1, p2)char **p1, **p2;{	register char **p;	register int l, *t;	l = 0;	for(p=p1; p!=p2; p++)	switch(**p) {	case '(':		l++;		continue;	case ')':		l--;		continue;	case '|':	case '^':		if(l == 0) {			t = tree(4);			t[DTYP] = TFIL;			t[DLEF] = syn3(p1, p);			t[DRIT] = syn2(p+1, p2);			t[DFLG] = 0;			return(t);		}	}	return(syn3(p1, p2));}/* * syn3 *	( syn1 ) [ < in  ] [ > out ] *	word word* [ < in ] [ > out ] */syn3(p1, p2)char **p1, **p2;{	register char **p;	char **lp, **rp;	register *t;	int n, l, i, o, c, flg;	flg = 0;	if(**p2 == ')')		flg =| FPAR;	lp = 0;	rp = 0;	i = 0;	o = 0;	n = 0;	l = 0;	for(p=p1; p!=p2; p++)	switch(c = **p) {	case '(':		if(l == 0) {			if(lp != 0)				error++;			lp = p+1;		}		l++;		continue;	case ')':		l--;		if(l == 0)			rp = p;		continue;	case '>':		p++;		if(p!=p2 && **p=='>')			flg =| FCAT; else			p--;	case '<':		if(l == 0) {			p++;			if(p == p2) {				error++;				p--;			}			if(any(**p, "<>("))				error++;			if(c == '<') {				if(i != 0)					error++;				i = *p;				continue;			}			if(o != 0)				error++;			o = *p;		}		continue;	default:		if(l == 0)			p1[n++] = *p;	}	if(lp != 0) {		if(n != 0)			error++;		t = tree(5);		t[DTYP] = TPAR;		t[DSPR] = syn1(lp, rp);		goto out;	}	if(n == 0)		error++;	p1[n++] = 0;	t = tree(n+5);	t[DTYP] = TCOM;	for(l=0; l<n; l++)		t[l+DCOM] = p1[l];out:	t[DFLG] = flg;	t[DLEF] = i;	t[DRIT] = o;	return(t);}scan(at, f)int *at;int (*f)();{	register char *p, c;	register *t;	t = at+DCOM;	while(p = *t++)		while(c = *p)			*p++ = (*f)(c);}tglob(c)int c;{	if(any(c, "[?*"))		gflg = 1;	return(c);}trim(c)int c;{	return(c&0177);}execute(t, pf1, pf2)int *t, *pf1, *pf2;{	int i, f, pv[2];	register *t1;	register char *cp1, *cp2;	extern errno;	if(t != 0)	switch(t[DTYP]) {	case TCOM:		cp1 = t[DCOM];		if(equal(cp1, "chdir")) {			if(t[DCOM+1] != 0) {				if(chdir(t[DCOM+1]) < 0)					err("chdir: bad directory",255);			} else				err("chdir: arg count",255);			return;		}		if(equal(cp1, "shift")) {			if(dolc < 1) {				prs("shift: no args\n");				return;			}			dolv[1] = dolv[0];			dolv++;			dolc--;			return;		}		if(equal(cp1, "login")) {			if(promp != 0) {				execv("/bin/login", t+DCOM);			}			prs("login: cannot execute\n");			return;		}		if(equal(cp1, "newgrp")) {			if(promp != 0) {				execv("/bin/newgrp", t+DCOM);			}			prs("newgrp: cannot execute\n");			return;		}		if(equal(cp1, "wait")) {			pwait(-1, 0);			return;		}		if(equal(cp1, ":"))			return;	case TPAR:		f = t[DFLG];		i = 0;		if((f&FPAR) == 0)			i = fork();		if(i == -1) {			err("try again",255);			return;		}		if(i != 0) {			if((f&FPIN) != 0) {				close(pf1[0]);				close(pf1[1]);			}			if((f&FPRS) != 0) {				prn(i);				prs("\n");			}			if((f&FAND) != 0)				return;			if((f&FPOU) == 0)				pwait(i, t);			return;		}		if(t[DLEF] != 0) {			close(0);			i = open(t[DLEF], 0);			if(i < 0) {				prs(t[DLEF]);				err(": cannot open",255);				exit(255);			}		}		if(t[DRIT] != 0) {			if((f&FCAT) != 0) {				i = open(t[DRIT], 1);				if(i >= 0) {					lseek(i, 0L, 2);					goto f1;				}			}			i = creat(t[DRIT], 0666);			if(i < 0) {				prs(t[DRIT]);				err(": cannot create",255);				exit(255);			}		f1:			close(1);			dup(i);			close(i);		}		if((f&FPIN) != 0) {			close(0);			dup(pf1[0]);			close(pf1[0]);			close(pf1[1]);		}		if((f&FPOU) != 0) {			close(1);			dup(pf2[1]);			close(pf2[0]);			close(pf2[1]);		}		if((f&FINT)!=0 && t[DLEF]==0 && (f&FPIN)==0) {			close(0);			open("/dev/null", 0);		}		if((f&FINT) == 0 && setintr) {			signal(INTR, 0);			signal(QUIT, 0);		}		if(t[DTYP] == TPAR) {			if(t1 = t[DSPR])				t1[DFLG] =| f&FINT;			execute(t1);			exit(255);		}		gflg = 0;		scan(t, tglob);		if(gflg) {			t[DSPR] = "/etc/glob";			execv(t[DSPR], t+DSPR);			prs("glob: cannot execute\n");			exit(255);		}		scan(t, trim);		*linep = 0;		texec(t[DCOM], t);		cp1 = linep;		cp2 = "/usr/bin/";		while(*cp1 = *cp2++)			cp1++;		cp2 = t[DCOM];		while(*cp1++ = *cp2++);		texec(linep+4, t);		texec(linep, t);		prs(t[DCOM]);		err(": not found",255);		exit(255);	case TFIL:		f = t[DFLG];		pipe(pv);		t1 = t[DLEF];		t1[DFLG] =| FPOU | (f&(FPIN|FINT|FPRS));		execute(t1, pf1, pv);		t1 = t[DRIT];		t1[DFLG] =| FPIN | (f&(FPOU|FINT|FAND|FPRS));		execute(t1, pv, pf2);		return;	case TLST:		f = t[DFLG]&FINT;		if(t1 = t[DLEF])			t1[DFLG] =| f;		execute(t1);		if(t1 = t[DRIT])			t1[DFLG] =| f;		execute(t1);		return;	}}texec(f, at)int *at;{	extern errno;	register int *t;	t = at;	execv(f, t+DCOM);	if (errno==ENOEXEC) {		if (*linep)			t[DCOM] = linep;		t[DSPR] = "/usr/bin/osh";		execv(t[DSPR], t+DSPR);		prs("No shell!\n");		exit(255);	}	if (errno==ENOMEM) {		prs(t[DCOM]);		err(": too large",255);		exit(255);	}}err(s, exitno)char *s;int exitno;{	prs(s);	prs("\n");	if(promp == 0) {		lseek(0, 0L, 2);		exit(exitno);	}}prs(as)char *as;{	register char *s;	s = as;	while(*s)		putc(*s++);}putc(c){	char cc;	cc = c;	write(2, &cc, 1);}prn(n)int n;{	register a;	if (a = n/10)		prn(a);	putc(n%10 + '0');}any(c, as)int c;char *as;{	register char *s;	s = as;	while(*s)		if(*s++ == c)			return(1);	return(0);}equal(as1, as2)char *as1, *as2;{	register char *s1, *s2;	s1 = as1;	s2 = as2;	while(*s1++ == *s2)		if(*s2++ == '\0')			return(1);	return(0);}pwait(i, t)int i, *t;{	register p, e;	int s;	if(i != 0)	for(;;) {		p = wait(&s);		if(p == -1)			break;		e = s&0177;		if (e>=NSIG || mesg[e]) {			if(p != i) {				prn(p);				prs(": ");			}			if (e < NSIG)				prs(mesg[e]);			else {				prs("Signal ");				prn(e);			}			if(s&0200)				prs(" -- Core dumped");		}		if (e || s&&stoperr)			err("", (s>>8)|e );		errval =| (s>>8);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -