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

📄 exec.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "rc.h"#include "getflags.h"#include "exec.h"#include "io.h"#include "fns.h"/* * Start executing the given code at the given pc with the given redirection */char *argv0="rc";voidstart(code *c, int pc, var *local){	struct thread *p = new(struct thread);	p->code = codecopy(c);	p->pc = pc;	p->argv = 0;	p->redir = p->startredir = runq?runq->redir:0;	p->local = local;	p->cmdfile = 0;	p->cmdfd = 0;	p->eof = 0;	p->iflag = 0;	p->lineno = 1;	p->ret = runq;	runq = p;}word*newword(char *wd, word *next){	word *p = new(word);	p->word = strdup(wd);	p->next = next;	return p;}voidpushword(char *wd){	if(runq->argv==0)		panic("pushword but no argv!", 0);	runq->argv->words = newword(wd, runq->argv->words);}voidpopword(void){	word *p;	if(runq->argv==0)		panic("popword but no argv!", 0);	p = runq->argv->words;	if(p==0)		panic("popword but no word!", 0);	runq->argv->words = p->next;	efree(p->word);	efree((char *)p);}voidfreelist(word *w){	word *nw;	while(w){		nw = w->next;		efree(w->word);		efree((char *)w);		w = nw;	}}voidpushlist(void){	list *p = new(list);	p->next = runq->argv;	p->words = 0;	runq->argv = p;}voidpoplist(void){	list *p = runq->argv;	if(p==0)		panic("poplist but no argv", 0);	freelist(p->words);	runq->argv = p->next;	efree((char *)p);}intcount(word *w){	int n;	for(n = 0;w;n++) w = w->next;	return n;}voidpushredir(int type, int from, int to){	redir * rp = new(redir);	rp->type = type;	rp->from = from;	rp->to = to;	rp->next = runq->redir;	runq->redir = rp;}var*newvar(char *name, var *next){	var *v = new(var);	v->name = name;	v->val = 0;	v->fn = 0;	v->changed = 0;	v->fnchanged = 0;	v->next = next;	return v;}/* * get command line flags, initialize keywords & traps. * get values from environment. * set $pid, $cflag, $* * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*) * start interpreting code */voidmain(int argc, char *argv[]){	code bootstrap[17];	char num[12], *rcmain;	int i;	argc = getflags(argc, argv, "SsrdiIlxepvVc:1m:1[command]", 1);	if(argc==-1)		usage("[file [arg ...]]");	if(argv[0][0]=='-')		flag['l'] = flagset;	if(flag['I'])		flag['i'] = 0;	else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;	rcmain = flag['m']?flag['m'][0]:Rcmain; 	err = openfd(2);	kinit();	Trapinit();	Vinit();	inttoascii(num, mypid = getpid());	setvar("pid", newword(num, (word *)0));	setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)				:(word *)0);	setvar("rcname", newword(argv[0], (word *)0));	i = 0;	bootstrap[i++].i = 1;	bootstrap[i++].f = Xmark;	bootstrap[i++].f = Xword;	bootstrap[i++].s="*";	bootstrap[i++].f = Xassign;	bootstrap[i++].f = Xmark;	bootstrap[i++].f = Xmark;	bootstrap[i++].f = Xword;	bootstrap[i++].s="*";	bootstrap[i++].f = Xdol;	bootstrap[i++].f = Xword;	bootstrap[i++].s = rcmain;	bootstrap[i++].f = Xword;	bootstrap[i++].s=".";	bootstrap[i++].f = Xsimple;	bootstrap[i++].f = Xexit;	bootstrap[i].i = 0;	start(bootstrap, 1, (var *)0);	/* prime bootstrap argv */	pushlist();	argv0 = strdup(argv[0]);	for(i = argc-1;i!=0;--i) pushword(argv[i]);	for(;;){		if(flag['r'])			pfnc(err, runq);		runq->pc++;		(*runq->code[runq->pc-1].f)();		if(ntrap)			dotrap();	}}/* * Opcode routines * Arguments on stack (...) * Arguments in line [...] * Code in line with jump around {...} * * Xappend(file)[fd]			open file to append * Xassign(name, val)			assign val to name * Xasync{... Xexit}			make thread for {}, no wait * Xbackq{... Xreturn}			make thread for {}, push stdout * Xbang				complement condition * Xcase(pat, value){...}		exec code on match, leave (value) on * 					stack * Xclose[i]				close file descriptor * Xconc(left, right)			concatenate, push results * Xcount(name)				push var count * Xdelfn(name)				delete function definition * Xdeltraps(names)			delete named traps * Xdol(name)				get variable value * Xqdol(name)				concatenate variable components * Xdup[i j]				dup file descriptor * Xexit				rc exits with status * Xfalse{...}				execute {} if false * Xfn(name){... Xreturn}			define function * Xfor(var, list){... Xreturn}		for loop * Xjump[addr]				goto * Xlocal(name, val)			create local variable, assign value * Xmark				mark stack * Xmatch(pat, str)			match pattern, set status * Xpipe[i j]{... Xreturn}{... Xreturn}	construct a pipe between 2 new threads, * 					wait for both * Xpipefd[type]{... Xreturn}		connect {} to pipe (input or output, * 					depending on type), push /dev/fd/?? * Xpopm(value)				pop value from stack * Xrdwr(file)[fd]			open file for reading and writing * Xread(file)[fd]			open file to read * Xsettraps(names){... Xreturn}		define trap functions * Xshowtraps				print trap list * Xsimple(args)			run command and wait * Xreturn				kill thread * Xsubshell{... Xexit}			execute {} in a subshell and wait * Xtrue{...}				execute {} if true * Xunlocal				delete local variable * Xword[string]			push string * Xwrite(file)[fd]			open file to write */voidXappend(void){	char *file;	int f;	switch(count(runq->argv->words)){	default:		Xerror1(">> requires singleton");		return;	case 0:		Xerror1(">> requires file");		return;	case 1:		break;	}	file = runq->argv->words->word;	if((f = open(file, 1))<0 && (f = Creat(file))<0){		pfmt(err, "%s: ", file);		Xerror("can't open");		return;	}	Seek(f, 0L, 2);	pushredir(ROPEN, f, runq->code[runq->pc].i);	runq->pc++;	poplist();}voidXsettrue(void){	setstatus("");}voidXbang(void){	setstatus(truestatus()?"false":"");}voidXclose(void){	pushredir(RCLOSE, runq->code[runq->pc].i, 0);	runq->pc++;}voidXdup(void){	pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);	runq->pc+=2;}voidXeflag(void){	if(eflagok && !truestatus()) Xexit();}voidXexit(void){	struct var *trapreq;	struct word *starval;	static int beenhere = 0;	if(getpid()==mypid && !beenhere){		trapreq = vlook("sigexit");		if(trapreq->fn){			beenhere = 1;			--runq->pc;			starval = vlook("*")->val;			start(trapreq->fn, trapreq->pc, (struct var *)0);			runq->local = newvar(strdup("*"), runq->local);			runq->local->val = copywords(starval, (struct word *)0);			runq->local->changed = 1;			runq->redir = runq->startredir = 0;			return;		}	}	Exit(getstatus());}voidXfalse(void){	if(truestatus()) runq->pc = runq->code[runq->pc].i;	else runq->pc++;}int ifnot;		/* dynamic if not flag */voidXifnot(void){	if(ifnot)		runq->pc++;	else		runq->pc = runq->code[runq->pc].i;}voidXjump(void){	runq->pc = runq->code[runq->pc].i;}voidXmark(void){	pushlist();}voidXpopm(void){	poplist();}voidXread(void){	char *file;	int f;	switch(count(runq->argv->words)){	default:		Xerror1("< requires singleton\n");		return;	case 0:		Xerror1("< requires file\n");		return;	case 1:		break;	}	file = runq->argv->words->word;	if((f = open(file, 0))<0){		pfmt(err, "%s: ", file);		Xerror("can't open");		return;	}	pushredir(ROPEN, f, runq->code[runq->pc].i);	runq->pc++;	poplist();}voidXrdwr(void){	char *file;	int f;	switch(count(runq->argv->words)){	default:		Xerror1("<> requires singleton\n");		return;	case 0:		Xerror1("<> requires file\n");		return;	case 1:		break;	}	file = runq->argv->words->word;	if((f = open(file, ORDWR))<0){		pfmt(err, "%s: ", file);		Xerror("can't open");		return;	}	pushredir(ROPEN, f, runq->code[runq->pc].i);	runq->pc++;	poplist();}voidturfredir(void){	while(runq->redir!=runq->startredir)		Xpopredir();}voidXpopredir(void){	struct redir *rp = runq->redir;	if(rp==0)		panic("turfredir null!", 0);	runq->redir = rp->next;	if(rp->type==ROPEN)		close(rp->from);	efree((char *)rp);}voidXreturn(void){	struct thread *p = runq;	turfredir();	while(p->argv) poplist();	codefree(p->code);	runq = p->ret;	efree((char *)p);	if(runq==0)		Exit(getstatus());}voidXtrue(void){	if(truestatus()) runq->pc++;	else runq->pc = runq->code[runq->pc].i;}voidXif(void){	ifnot = 1;	if(truestatus()) runq->pc++;	else runq->pc = runq->code[runq->pc].i;}voidXwastrue(void){	ifnot = 0;}voidXword(void){	pushword(runq->code[runq->pc++].s);}voidXwrite(void){	char *file;	int f;	switch(count(runq->argv->words)){	default:		Xerror1("> requires singleton\n");		return;	case 0:		Xerror1("> requires file\n");		return;	case 1:		break;	}	file = runq->argv->words->word;	if((f = Creat(file))<0){		pfmt(err, "%s: ", file);

⌨️ 快捷键说明

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