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

📄 compiling.on.unix

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 UNIX
📖 第 1 页 / 共 3 页
字号:
From geoff@collyer.net Fri Dec 19 01:21:40 EST 2003Received: from plan9.cs.bell-labs.com ([135.104.9.2]) by plan9; Fri Dec 19 01:21:39 EST 2003Received: from collyer.net ([63.192.14.226]) by plan9; Fri Dec 19 01:21:35 EST 2003Message-ID: <c790d8b1e06b3918ad2c7848a3ae0ec7@collyer.net>subject: rc on unix, part 1From: Geoff Collyer <geoff@collyer.net>Date: Thu, 18 Dec 2003 22:21:33 -0800To: presotto@plan9.bell-labs.com, rsc@plan9.bell-labs.com, geoff@collyer.netMIME-Version: 1.0Content-Type: text/plain; charset="US-ASCII"Content-Transfer-Encoding: 7bitI got /sys/src/cmd/rc to compile under APE (in preparation for moving itto Unixes) with the following changed files.  I cadged some include filesfrom rsc but had to edit lib9.h slightly.  I'll send the include filesseparately.  I can't tell if it works yet, but it does complain about/usr/lib/rcmain being absent when I start it.  Oh, and I haven't yetsimulated the effect of the OCEXEC bit.# To unbundle, run this fileecho mkfilesed 's/^X//' >mkfile <<'!'X</$objtype/mkfileTARG=rcCOMMONOFILES=\X	code.$O\X	exec.$O\X	getflags.$O\X	glob.$O\X	here.$O\X	io.$O\X	lex.$O\X	pcmd.$O\X	pfnc.$O\X	simple.$O\X	subr.$O\X	trap.$O\X	tree.$O\X	var.$O\X	havefork.$O\PLAN9OFILES=plan9.$O\UNIXOFILES=unix.$O\OFILES=$COMMONOFILES $UNIXOFILES y.tab.$OHFILES=rc.h\X	x.tab.h\X	io.h\X	exec.h\X	fns.h\YFILES=syn.yBIN=/$objtype/binUPDATE=\X	mkfile\X	$HFILES\X	${COMMONOFILES:%.$O=%.c}\X	${UNIXOFILES:%.$O=%.c}\X	${PLAN9OFILES:%.$O=%.c}\X	$YFILES\X	${TARG:%=/386/bin/%}\CC=pcc -c -B -I../includeLD=pccX</sys/src/cmd/mkonex.tab.h: y.tab.hX	cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.hclean:V:X	rm -f [$OS].out *.[$OS] [xy].tab.? y.debug $TARGregress: $O.outX	cd testX	mkunregress:V:X	for(test in test/*.test) rc $test >$test.outlisting:X	pr mkfile $HFILES $FILES $FILES9 $FILESUNIX $YFILES|lp -du!echo simple.csed 's/^X//' >simple.c <<'!'X/*X * Maybe `simple' is a misnomer.X */X#include "rc.h"X#include "getflags.h"X#include "exec.h"X#include "io.h"X#include "fns.h"X/*X * Search through the following code to see if we're just going to exit.X */exitnext(void){X	union code *c=&runq->code[runq->pc];X	while(c->f==Xpopredir) c++;X	return c->f==Xexit;X}voidXXsimple(void)X{X	word *a;X	thread *p = runq;X	var *v;X	struct builtin *bp;X	int pid;X	globlist();X	a = runq->argv->words;X	if(a==0){X		Xerror1("empty argument list");X		return;X	}X	if(flag['x'])X		pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */X	v = gvlook(a->word);X	if(v->fn)X		execfunc(v);X	else{X		if(strcmp(a->word, "builtin")==0){X			if(count(a)==1){X				pfmt(err, "builtin: empty argument list\n");X				setstatus("empty arg list");X				poplist();X				return;X			}X			a = a->next;X			popword();X		}X		for(bp = Builtin;bp->name;bp++)X			if(strcmp(a->word, bp->name)==0){X				(*bp->fnc)();X				return;X			}X		if(exitnext()){X			/* fork and wait is redundant */X			pushword("exec");X			execexec();X			Xexit();X		}X		else{X			flush(err);X			Updenv();	/* necessary so changes don't go out again */X			if((pid = execforkexec()) < 0){X				Xerror("try again");X				return;X			}X			/* interrupts don't get us out */X			poplist();X			while(Waitfor(pid, 1) < 0)X				;X		}X	}X}struct word nullpath = { "", 0};voiddoredir(redir *rp)X{X	if(rp){X		doredir(rp->next);X		switch(rp->type){X		case ROPEN:X			if(rp->from!=rp->to){X				Dup(rp->from, rp->to);X				close(rp->from);X			}X			break;X		case RDUP:X			Dup(rp->from, rp->to);X			break;X		case RCLOSE:X			close(rp->from);X			break;X		}X	}X}word*searchpath(char *w)X{X	word *path;X	if(strncmp(w, "/", 1)==0X	|| strncmp(w, "#", 1)==0X	|| strncmp(w, "./", 2)==0X	|| strncmp(w, "../", 3)==0X	|| (path = vlook("path")->val)==0)X		path=&nullpath;X	return path;X}voidexecexec(void)X{X	popword();	/* "exec" */X	if(runq->argv->words==0){X		Xerror1("empty argument list");X		return;X	}X	doredir(runq->redir);X	Execute(runq->argv->words, searchpath(runq->argv->words->word));X	poplist();X}voidexecfunc(var *func)X{X	word *starval;X	popword();X	starval = runq->argv->words;X	runq->argv->words = 0;X	poplist();X	start(func->fn, func->pc, (struct var *)0);X	runq->local = newvar(strdup("*"), runq->local);X	runq->local->val = starval;X	runq->local->changed = 1;X}intdochdir(char *word)X{X	/* report to /dev/wdir if it exists and we're interactive */X	static int wdirfd = -2;X	if(chdir(word)<0) return -1;X	if(flag['i']!=0){X		if(wdirfd==-2)	/* try only once */X			/* TODO: arrange close-on-exec on Unix */X			wdirfd = open("/dev/wdir", OWRITE|OCEXEC);X		if(wdirfd>=0)X			write(wdirfd, word, strlen(word));X	}X	return 1;X}voidexeccd(void)X{X	word *a = runq->argv->words;X	word *cdpath;X	char dir[512];X	setstatus("can't cd");X	cdpath = vlook("cdpath")->val;X	switch(count(a)){X	default:X		pfmt(err, "Usage: cd [directory]\n");X		break;X	case 2:X		if(a->next->word[0]=='/' || cdpath==0)X			cdpath=&nullpath;X		for(;cdpath;cdpath = cdpath->next){X			strcpy(dir, cdpath->word);X			if(dir[0])X				strcat(dir, "/");X			strcat(dir, a->next->word);X			if(dochdir(dir)>=0){X				if(strlen(cdpath->word)X				&& strcmp(cdpath->word, ".")!=0)X					pfmt(err, "%s\n", dir);X				setstatus("");X				break;X			}X		}X		if(cdpath==0)X			pfmt(err, "Can't cd %s: %r\n", a->next->word);X		break;X	case 1:X		a = vlook("home")->val;X		if(count(a)>=1){X			if(dochdir(a->word)>=0)X				setstatus("");X			elseX				pfmt(err, "Can't cd %s: %r\n", a->word);X		}X		elseX			pfmt(err, "Can't cd -- $home empty\n");X		break;X	}X	poplist();X}voidexecexit(void)X{X	switch(count(runq->argv->words)){X	default:X		pfmt(err, "Usage: exit [status]\nExiting anyway\n");X	case 2:X		setstatus(runq->argv->words->next->word);X	case 1:	Xexit();X	}X}voidexecshift(void)X{X	int n;X	word *a;X	var *star;X	switch(count(runq->argv->words)){X	default:X		pfmt(err, "Usage: shift [n]\n");X		setstatus("shift usage");X		poplist();X		return;X	case 2:X		n = atoi(runq->argv->words->next->word);X		break;X	case 1:X		n = 1;X		break;X	}X	star = vlook("*");X	for(;n && star->val;--n){X		a = star->val->next;X		efree(star->val->word);X		efree((char *)star->val);X		star->val = a;X		star->changed = 1;X	}X	setstatus("");X	poplist();X}intoctal(char *s)X{X	int n = 0;X	while(*s==' ' || *s=='\t' || *s=='\n') s++;X	while('0'<=*s && *s<='7') n = n*8+*s++-'0';X	return n;X}intmapfd(int fd)X{X	redir *rp;X	for(rp = runq->redir;rp;rp = rp->next){X		switch(rp->type){X		case RCLOSE:X			if(rp->from==fd)X				fd=-1;X			break;X		case RDUP:X		case ROPEN:X			if(rp->to==fd)X				fd = rp->from;X			break;X		}X	}X	return fd;X}union code rdcmds[4];voidexeccmds(io *f)X{X	static int first = 1;X	if(first){X		rdcmds[0].i = 1;X		rdcmds[1].f = Xrdcmds;X		rdcmds[2].f = Xreturn;X		first = 0;X	}X	start(rdcmds, 1, runq->local);X	runq->cmdfd = f;X	runq->iflast = 0;X}voidexeceval(void)X{X	char *cmdline, *s, *t;X	int len = 0;X	word *ap;X	if(count(runq->argv->words)<=1){X		Xerror1("Usage: eval cmd ...");X		return;X	}X	eflagok = 1;X	for(ap = runq->argv->words->next;ap;ap = ap->next)X		len+=1+strlen(ap->word);X	cmdline = emalloc(len);X	s = cmdline;X	for(ap = runq->argv->words->next;ap;ap = ap->next){X		for(t = ap->word;*t;) *s++=*t++;X		*s++=' ';X	}X	s[-1]='\n';X	poplist();X	execcmds(opencore(cmdline, len));X	efree(cmdline);X}union code dotcmds[14];voidexecdot(void)X{X	int iflag = 0;X	int fd;X	list *av;X	thread *p = runq;X	char *zero;X	static int first = 1;X	char file[512];X	word *path;X	if(first){X		dotcmds[0].i = 1;X		dotcmds[1].f = Xmark;X		dotcmds[2].f = Xword;X		dotcmds[3].s="0";X		dotcmds[4].f = Xlocal;X		dotcmds[5].f = Xmark;X		dotcmds[6].f = Xword;X		dotcmds[7].s="*";X		dotcmds[8].f = Xlocal;X		dotcmds[9].f = Xrdcmds;X		dotcmds[10].f = Xunlocal;X		dotcmds[11].f = Xunlocal;X		dotcmds[12].f = Xreturn;X		first = 0;X	}X	elseX		eflagok = 1;X	popword();X	if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){X		iflag = 1;X		popword();X	}X	/* get input file */X	if(p->argv->words==0){X		Xerror1("Usage: . [-i] file [arg ...]");X		return;X	}X	zero = strdup(p->argv->words->word);X	popword();X	fd=-1;X	for(path = searchpath(zero);path;path = path->next){X		strcpy(file, path->word);X		if(file[0])X			strcat(file, "/");X		strcat(file, zero);X		if((fd = open(file, 0))>=0) break;X		if(strcmp(file, "/dev/stdin")==0){	/* for sun & ucb */X			fd = Dup1(0);X			if(fd>=0)X				break;X		}X	}X	if(fd<0){X		pfmt(err, "%s: ", zero);X		setstatus("can't open");X		Xerror(".: can't open");X		return;X	}X	/* set up for a new command loop */X	start(dotcmds, 1, (struct var *)0);X	pushredir(RCLOSE, fd, 0);X	runq->cmdfile = zero;X	runq->cmdfd = openfd(fd);X	runq->iflag = iflag;X	runq->iflast = 0;X	/* push $* value */X	pushlist();X	runq->argv->words = p->argv->words;X	/* free caller's copy of $* */X	av = p->argv;X	p->argv = av->next;X	efree((char *)av);X	/* push $0 value */X	pushlist();X	pushword(zero);X	ndot++;X}voidexecflag(void)X{X	char *letter, *val;X	switch(count(runq->argv->words)){X	case 2:X		setstatus(flag[runq->argv->words->next->word[0]]?"":"flag not set");X		break;X	case 3:X		letter = runq->argv->words->next->word;X		val = runq->argv->words->next->next->word;X		if(strlen(letter)==1){X			if(strcmp(val, "+")==0){X				flag[letter[0]] = flagset;X				break;X			}X			if(strcmp(val, "-")==0){X				flag[letter[0]] = 0;X				break;X			}X		}X	default:X		Xerror1("Usage: flag [letter] [+-]");X		return;X	}X	poplist();X}voidexecwhatis(void){	/* mildly wrong -- should fork before writing */X	word *a, *b, *path;X	var *v;X	struct builtin *bp;X	char file[512];X	struct io out[1];X	int found, sep;X	a = runq->argv->words->next;X	if(a==0){X		Xerror1("Usage: whatis name ...");X		return;X	}X	setstatus("");X	out->fd = mapfd(1);X	out->bufp = out->buf;X	out->ebuf = &out->buf[NBUF];X	out->strp = 0;X	for(;a;a = a->next){X		v = vlook(a->word);X		if(v->val){X			pfmt(out, "%s=", a->word);X			if(v->val->next==0)X				pfmt(out, "%q\n", v->val->word);X			else{X				sep='(';X				for(b = v->val;b && b->word;b = b->next){X					pfmt(out, "%c%q", sep, b->word);X					sep=' ';X				}X				pfmt(out, ")\n");X			}X			found = 1;X		}X		elseX			found = 0;X		v = gvlook(a->word);X		if(v->fn)X			pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);X		else{X			for(bp = Builtin;bp->name;bp++)X				if(strcmp(a->word, bp->name)==0){X					pfmt(out, "builtin %s\n", a->word);X					break;X				}X			if(!bp->name){X				for(path = searchpath(a->word);path;path = path->next){X					strcpy(file, path->word);X					if(file[0])X						strcat(file, "/");X					strcat(file, a->word);X					if(Executable(file)){X						pfmt(out, "%s\n", file);X						break;X					}X				}X				if(!path && !found){X					pfmt(err, "%s: not found\n", a->word);X					setstatus("not found");X				}X			}X		}X	}X	poplist();X	flush(err);X}voidexecwait(void)X{X	switch(count(runq->argv->words)){X	default:X		Xerror1("Usage: wait [pid]");X		return;X	case 2:X		Waitfor(atoi(runq->argv->words->next->word), 0);X		break;X	case 1:X		Waitfor(-1, 0);X		break;X	}X	poplist();X}!echo havefork.csed 's/^X//' >havefork.c <<'!'X#include "rc.h"X#include "getflags.h"X#include "exec.h"X#include "io.h"X#include "fns.h"int havefork = 1;voidXXasync(void)X{X	int null = open("/dev/null", 0);X	int pid;X	char npid[10];X	if(null<0){X		Xerror("Can't open /dev/null\n");X		return;X	}X#ifdef UnixX	pid = fork();X#elseX	pid = rfork(RFFDG|RFPROC|RFNOTEG);X#endifX	switch(pid){X	case -1:

⌨️ 快捷键说明

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