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

📄 compiling.on.unix

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 UNIX
📖 第 1 页 / 共 3 页
字号:
X		close(null);X		Xerror("try again");X		break;X	case 0:X		pushredir(ROPEN, null, 0);X		start(runq->code, runq->pc+1, runq->local);X		runq->ret = 0;X		break;X	default:X		close(null);X		runq->pc = runq->code[runq->pc].i;X		inttoascii(npid, pid);X		setvar("apid", newword(npid, (word *)0));X		break;X	}X}voidXXpipe(void)X{X	struct thread *p = runq;X	int pc = p->pc, forkid;X	int lfd = p->code[pc++].i;X	int rfd = p->code[pc++].i;X	int pfd[2];X	if(pipe(pfd)<0){X		Xerror("can't get pipe");X		return;X	}X	switch(forkid = fork()){X	case -1:X		Xerror("try again");X		break;X	case 0:X		start(p->code, pc+2, runq->local);X		runq->ret = 0;X		close(pfd[PRD]);X		pushredir(ROPEN, pfd[PWR], lfd);X		break;X	default:X		start(p->code, p->code[pc].i, runq->local);X		close(pfd[PWR]);X		pushredir(ROPEN, pfd[PRD], rfd);X		p->pc = p->code[pc+1].i;X		p->pid = forkid;X		break;X	}X}X/*X * Who should wait for the exit from the fork?X */voidXXbackq(void)X{X	char wd[8193];X	int c;X	char *s, *ewd=&wd[8192], *stop;X	struct io *f;X	var *ifs = vlook("ifs");X	word *v, *nextv;X	int pfd[2];X	int pid;X	stop = ifs->val?ifs->val->word:"";X	if(pipe(pfd)<0){X		Xerror("can't make pipe");X		return;X	}X	switch(pid = fork()){X	case -1:X		Xerror("try again");X		close(pfd[PRD]);X		close(pfd[PWR]);X		return;X	case 0:X		close(pfd[PRD]);X		start(runq->code, runq->pc+1, runq->local);X		pushredir(ROPEN, pfd[PWR], 1);X		return;X	default:X		close(pfd[PWR]);X		f = openfd(pfd[PRD]);X		s = wd;X		v = 0;X		while((c = rchr(f))!=EOF){X			if(strchr(stop, c) || s==ewd){X				if(s!=wd){X					*s='\0';X					v = newword(wd, v);X					s = wd;X				}X			}X			else *s++=c;X		}X		if(s!=wd){X			*s='\0';X			v = newword(wd, v);X		}X		closeio(f);X		Waitfor(pid, 0);X		/* v points to reversed arglist -- reverse it onto argv */X		while(v){X			nextv = v->next;X			v->next = runq->argv->words;X			runq->argv->words = v;X			v = nextv;X		}X		runq->pc = runq->code[runq->pc].i;X		return;X	}X}voidXXpipefd(void)X{X	struct thread *p = runq;X	int pc = p->pc;X	char name[40];X	int pfd[2];X	int sidefd, mainfd;X	if(pipe(pfd)<0){X		Xerror("can't get pipe");X		return;X	}X	if(p->code[pc].i==READ){X		sidefd = pfd[PWR];X		mainfd = pfd[PRD];X	}X	else{X		sidefd = pfd[PRD];X		mainfd = pfd[PWR];X	}X	switch(fork()){X	case -1:X		Xerror("try again");X		break;X	case 0:X		start(p->code, pc+2, runq->local);X		close(mainfd);X		pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);X		runq->ret = 0;X		break;X	default:X		close(sidefd);X		pushredir(ROPEN, mainfd, mainfd);	/* isn't this a noop? */X		strcpy(name, Fdprefix);X		inttoascii(name+strlen(name), mainfd);X		pushword(name);X		p->pc = p->code[pc+1].i;X		break;X	}X}voidXXsubshell(void)X{X	int pid;X	switch(pid = fork()){X	case -1:X		Xerror("try again");X		break;X	case 0:X		start(runq->code, runq->pc+1, runq->local);X		runq->ret = 0;X		break;X	default:X		Waitfor(pid, 1);X		runq->pc = runq->code[runq->pc].i;X		break;X	}X}intexecforkexec(void)X{X	int pid;X	int n;X	char buf[ERRMAX];X	switch(pid = fork()){X	case -1:X		return -1;X	case 0:X		pushword("exec");X		execexec();X		strcpy(buf, "can't exec: ");X		n = strlen(buf);X		errstr(buf+n, ERRMAX-n);X		Exit(buf);X	}X	return pid;X}!echo rc.hsed 's/^X//' >rc.h <<'!'X/*X * Plan9 is defined for plan 9X * V9 is defined for 9th editionX * Sun is defined for sun-osX * Please don't litter the code with ifdefs.  The three below should be enough.X */X#define UnixX#ifdef	Plan9X#include <u.h>X#include <libc.h>X#define	NSIG	32X#define	SIGINT	2X#define	SIGQUIT	3X#endifX#ifdef UnixX#define _POSIX_SOURCEX#define _BSD_EXTENSIONX#include <stdlib.h>X#include <stdarg.h>X#include <string.h>X#include <unistd.h>X#include <fcntl.h>X#include <lib9.h>X#include <signal.h>X#endifX#ifndef ERRMAXX#define ERRMAX 128X#endifX#define	YYMAXDEPTH	500X#ifndef PARENX#include "x.tab.h"X#endiftypedef struct tree tree;typedef struct word word;typedef struct io io;typedef union code code;typedef struct var var;typedef struct list list;typedef struct redir redir;typedef struct thread thread;typedef struct builtin builtin;struct tree{X	int type;X	int rtype, fd0, fd1;		/* details of REDIR PIPE DUP tokens */X	char *str;X	int quoted;X	int iskw;X	tree *child[3];X	tree *next;X};tree *newtree(void);tree *token(char*, int), *klook(char*), *tree1(int, tree*);tree *tree2(int, tree*, tree*), *tree3(int, tree*, tree*, tree*);tree *mung1(tree*, tree*), *mung2(tree*, tree*, tree*);tree *mung3(tree*, tree*, tree*, tree*), *epimung(tree*, tree*);tree *simplemung(tree*), *heredoc(tree*);void freetree(tree*);tree *cmdtree;X/*X * The first word of any code vector is a reference count.X * Always create a new reference to a code vector by calling codecopy(.).X * Always call codefree(.) when deleting a reference.X */union code{X	void (*f)(void);X	int i;X	char *s;X};char *promptstr;int doprompt;X#define	NTOK	8192char tok[NTOK];X#define	APPEND	1X#define	WRITE	2X#define	READ	3X#define	HERE	4X#define	DUPFD	5X#define	CLOSE	6struct var{X	char *name;		/* ascii name */X	word *val;	/* value */X	int changed;X	code *fn;		/* pointer to function's code vector */X	int fnchanged;X	int pc;			/* pc of start of function */X	var *next;	/* next on hash or local list */X};var *vlook(char*), *gvlook(char*), *newvar(char*, var*);X#define	NVAR	521var *gvar[NVAR];				/* hash for globals */X#define	new(type)	((type *)emalloc(sizeof(type)))char *emalloc(long);void *Malloc(ulong);void efree(char*);X#define	NOFILE	128		/* should come from <param.h> */struct here{X	tree *tag;X	char *name;X	struct here *next;X};int mypid;X/*X * Glob character escape in strings:X *	In a string, GLOB must be followed by *?[ or GLOB.X *	GLOB* matches any stringX *	GLOB? matches any single characterX *	GLOB[...] matches anything in the bracketsX *	GLOBGLOB matches GLOBX */X#define	GLOB	((char)0x01)X/*X * onebyte(c), twobyte(c), threebyte(c)X * Is c the first character of a one- two- or three-byte utf sequence?X */X#define	onebyte(c)	((c&0x80)==0x00)X#define	twobyte(c)	((c&0xe0)==0xc0)X#define	threebyte(c)	((c&0xf0)==0xe0)char **argp;char **args;int nerror;		/* number of errors encountered during compilation */int doprompt;		/* is it time for a prompt? */X/*X * Which fds are the reading/writing end of a pipe?X * Unfortunately, this can vary from system to system.X * 9th edition Unix doesn't care, the following definesX * work on plan 9.X */X#define	PRD	0X#define	PWR	1char Rcmain[], Fdprefix[];X#define	registerX/*X * How many dot commands have we executed?X * Used to ensure that -v flag doesn't print rcmain.X */int ndot;char *getstatus(void);int lastc;int lastword;!echo unix.csed 's/^X//' >unix.c <<'!'X/*X * Unix versions of system-specific functionsX *	By convention, exported routines herein have names beginning with anX *	upper case letter.X */X#include "rc.h"X#include "io.h"X#include "exec.h"X#include "getflags.h"X#include <errno.h>char Rcmain[]="/usr/lib/rcmain";char Fdprefix[]="/dev/fd/";void execfinit(void);struct builtin Builtin[] = {X	"cd",		execcd,X	"whatis",	execwhatis,X	"eval",		execeval,X	"exec",		execexec,	/* but with popword first */X	"exit",		execexit,X	"shift",	execshift,X	"wait",		execwait,X	"umask",	execumask,X	".",		execdot,X	"finit",	execfinit,X	"flag",		execflag,X	0X};X#define	SEP	'\1'char **environp;struct word*enval(s)register char *s;X{X	char *t, c;X	struct word *v;X	for(t = s;*t && *t!=SEP;t++);X	c=*t;X	*t='\0';X	v = newword(s, c=='\0'?(struct word *)0:enval(t+1));X	*t = c;X	return v;X}voidVinit(void)X{X	extern char **environ;X	char *s;X	char **env = environ;X	environp = env;X	for(;*env;env++){X		for(s=*env;*s && *s!='(' && *s!='=';s++);X		switch(*s){X		case '\0':X			pfmt(err, "environment %q?\n", *env);X			break;X		case '=':X			*s='\0';X			setvar(*env, enval(s+1));X			*s='=';X			break;X		case '(':	/* ignore functions for now */X			break;X		}X	}X}char **envp;voidXXrdfn(void)X{X	char *s;X	int len;X	for(;*envp;envp++){X		for(s=*envp;*s && *s!='(' && *s!='=';s++);X		switch(*s){X		case '\0':X			pfmt(err, "environment %q?\n", *envp);X			break;X		case '=':	/* ignore variables */X			break;X		case '(':		/* Bourne again */X			s=*envp+3;X			envp++;X			len = strlen(s);X			s[len]='\n';X			execcmds(opencore(s, len+1));X			s[len]='\0';X			return;X		}X	}X	Xreturn();X}union code rdfns[4];voidexecfinit(void)X{X	static int first = 1;X	if(first){X		rdfns[0].i = 1;X		rdfns[1].f = Xrdfn;X		rdfns[2].f = Xjump;X		rdfns[3].i = 1;X		first = 0;X	}X	Xpopm();X	envp = environp;X	start(rdfns, 1, runq->local);X}intcmpenv(const void *aa, const void *ab)X{X	char **a = aa, **b = ab;X	return strcmp(*a, *b);X}char **mkenv(void)X{X	char **env, **ep, *p, *q;X	struct var **h, *v;X	struct word *a;X	int nvar = 0, nchr = 0, sep;X	/*X	 * Slightly kludgy loops look at locals then globals.X	 * locals no longer exist - geoffX	 */X	for(h = gvar-1; h != &gvar[NVAR]; h++)X	for(v = h >= gvar? *h: runq->local; v ;v = v->next){X		if((v==vlook(v->name)) && v->val){X			nvar++;X			nchr+=strlen(v->name)+1;X			for(a = v->val;a;a = a->next)X				nchr+=strlen(a->word)+1;X		}X		if(v->fn){X			nvar++;X			nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;X		}X	}X	env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr);X	ep = env;X	p = (char *)&env[nvar+1];X	for(h = gvar-1; h != &gvar[NVAR]; h++)X	for(v = h >= gvar? *h: runq->local;v;v = v->next){X		if((v==vlook(v->name)) && v->val){X			*ep++=p;X			q = v->name;X			while(*q) *p++=*q++;X			sep='=';X			for(a = v->val;a;a = a->next){X				*p++=sep;X				sep = SEP;X				q = a->word;X				while(*q) *p++=*q++;X			}X			*p++='\0';X		}X		if(v->fn){X			*ep++=p;X			*p++='#'; *p++='('; *p++=')';	/* to fool Bourne */X			*p++='f'; *p++='n'; *p++=' ';X			q = v->name;X			while(*q) *p++=*q++;X			*p++=' ';X			q = v->fn[v->pc-1].s;X			while(*q) *p++=*q++;X			*p++='\0';X		}X	}X	*ep = 0;X	qsort((void *)env, nvar, sizeof ep[0], cmpenv);X	return env;	X}char *sigmsg[] = {X/*  0 normal  */ 0,X/*  1 SIGHUP  */ "Hangup",X/*  2 SIGINT  */ 0,X/*  3 SIGQUIT */ "Quit",X/*  4 SIGILL  */ "Illegal instruction",X/*  5 SIGTRAP */ "Trace/BPT trap",X/*  6 SIGIOT  */ "abort",X/*  7 SIGEMT  */ "EMT trap",X/*  8 SIGFPE  */ "Floating exception",X/*  9 SIGKILL */ "Killed",X/* 10 SIGBUS  */ "Bus error",X/* 11 SIGSEGV */ "Memory fault",X/* 12 SIGSYS  */ "Bad system call",X/* 13 SIGPIPE */ 0,X/* 14 SIGALRM */ "Alarm call",X/* 15 SIGTERM */ "Terminated",X/* 16 unused  */ "signal 16",X/* 17 SIGSTOP */ "Process stopped",X/* 18 unused  */ "signal 18",X/* 19 SIGCONT */ "Process continued",X/* 20 SIGCHLD */ "Child death",X};voidWaitfor(int pid, int persist)X{X	int wpid, sig;X	struct thread *p;X	int wstat;X	char wstatstr[12];X	for(;;){X		errno = 0;X		wpid = wait(&wstat);X		if(errno==EINTR && persist)X			continue;X		if(wpid==-1)X			break;X		sig = wstat&0177;X		if(sig==0177){X			pfmt(err, "trace: ");X			sig = (wstat>>8)&0177;X		}X		if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){X			if(pid!=wpid)X				pfmt(err, "%d: ", wpid);X			if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))X				pfmt(err, "%s", sigmsg[sig]);X			else if(sig==0177) pfmt(err, "stopped by ptrace");X			else pfmt(err, "signal %d", sig);X			if(wstat&0200)pfmt(err, " -- core dumped");X			pfmt(err, "\n");X		}X		wstat = sig?sig+1000:(wstat>>8)&0xFF;X		if(wpid==pid){X			inttoascii(wstatstr, wstat);X			setstatus(wstatstr);X			break;X		}X		else{X			for(p = runq->ret;p;p = p->ret)X				if(p->pid==wpid){X					p->pid=-1;X					inttoascii(p->status, wstat);X					break;X				}X		}X	}X}char **mkargv(a)register struct word *a;X{X	char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));X	char **argp = argv+1;	/* leave one at front for runcoms */X	for(;a;a = a->next)X		*argp++=a->word;X	*argp = 0;X	return argv;X}voidUpdenv(void)X{X}voidExecute(struct word *args, struct word *path)X{X	char *msg="not found";X#ifdef ETXTBSYX	int txtbusy = 0;X#endif

⌨️ 快捷键说明

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