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

📄 plan9.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"mk.h"char 	*shell =	"/bin/rc";char 	*shellname =	"rc";static	Word	*encodenulls(char*, int);voidreadenv(void){	char *p;	int envf, f;	Dir *e;	char nam[1024];	int i, n, len;	Word *w;	rfork(RFENVG);	/*  use copy of the current environment variables */	envf = open("/env", OREAD);	if(envf < 0)		return;	while((n = dirread(envf, &e)) > 0){		for(i = 0; i < n; i++){			len = e[i].length;				/* don't import funny names, NULL values,				 * or internal mk variables				 */			if(len <= 0 || *shname(e[i].name) != '\0')				continue;			if (symlook(e[i].name, S_INTERNAL, 0))				continue;			sprint(nam, "/env/%s", e[i].name);			f = open(nam, OREAD);			if(f < 0)				continue;			p = Malloc(len+1);			if(read(f, p, len) != len){				perror(nam);				close(f);				continue;			}			close(f);			if (p[len-1] == 0)				len--;			else				p[len] = 0;			w = encodenulls(p, len);			free(p);			p = strdup(e[i].name);			setvar(p, (void *) w);			symlook(p, S_EXPORTED, (void*)"")->u.ptr = "";		}		free(e);	}	close(envf);}/* break string of values into words at 01's or nulls*/static Word *encodenulls(char *s, int n){	Word *w, *head;	char *cp;	head = w = 0;	while (n-- > 0) {		for (cp = s; *cp && *cp != '\0'; cp++)				n--;		*cp = 0;		if (w) {			w->next = newword(s);			w = w->next;		} else			head = w = newword(s);		s = cp+1;	}	if (!head)		head = newword("");	return head;}/* as well as 01's, change blanks to nulls, so that rc will * treat the words as separate arguments */voidexportenv(Envy *e){	int f, n, hasvalue, first;	Word *w;	Symtab *sy;	char nam[256];	for(;e->name; e++){		sy = symlook(e->name, S_VAR, 0);		if (e->values == 0 || e->values->s == 0 || e->values->s[0] == 0)			hasvalue = 0;		else			hasvalue = 1;		if(sy == 0 && !hasvalue)	/* non-existant null symbol */			continue;		sprint(nam, "/env/%s", e->name);		if (sy != 0 && !hasvalue) {	/* Remove from environment */				/* we could remove it from the symbol table				 * too, but we're in the child copy, and it				 * would still remain in the parent's table.				 */			remove(nam);			delword(e->values);			e->values = 0;		/* memory leak */			continue;		}			f = create(nam, OWRITE, 0666L);		if(f < 0) {			fprint(2, "can't create %s, f=%d\n", nam, f);			perror(nam);			continue;		}		first = 1;		for (w = e->values; w; w = w->next) {			n = strlen(w->s);			if (n) {				if(first)					first = 0;				else{					if (write (f, "\0", 1) != 1)						perror(nam);				}				if (write(f, w->s, n) != n)					perror(nam);			}		}		close(f);	}}intwaitfor(char *msg){	Waitmsg *w;	int pid;	if((w=wait()) == nil)		return -1;	strecpy(msg, msg+ERRMAX, w->msg);	pid = w->pid;	free(w);	return pid;}voidexpunge(int pid, char *msg){	postnote(PNPROC, pid, msg);}intexecsh(char *args, char *cmd, Bufblock *buf, Envy *e){	char *p;	int tot, n, pid, in[2], out[2];	if(buf && pipe(out) < 0){		perror("pipe");		Exit();	}	pid = rfork(RFPROC|RFFDG|RFENVG);	if(pid < 0){		perror("mk rfork");		Exit();	}	if(pid == 0){		if(buf)			close(out[0]);		if(pipe(in) < 0){			perror("pipe");			Exit();		}		pid = fork();		if(pid < 0){			perror("mk fork");			Exit();		}		if(pid != 0){			dup(in[0], 0);			if(buf){				dup(out[1], 1);				close(out[1]);			}			close(in[0]);			close(in[1]);			if (e)				exportenv(e);			if(shflags)				execl(shell, shellname, shflags, args, nil);			else				execl(shell, shellname, args, nil);			perror(shell);			_exits("exec");		}		close(out[1]);		close(in[0]);		p = cmd+strlen(cmd);		while(cmd < p){			n = write(in[1], cmd, p-cmd);			if(n < 0)				break;			cmd += n;		}		close(in[1]);		_exits(0);	}	if(buf){		close(out[1]);		tot = 0;		for(;;){			if (buf->current >= buf->end)				growbuf(buf);			n = read(out[0], buf->current, buf->end-buf->current);			if(n <= 0)				break;			buf->current += n;			tot += n;		}		if (tot && buf->current[-1] == '\n')			buf->current--;		close(out[0]);	}	return pid;}intpipecmd(char *cmd, Envy *e, int *fd){	int pid, pfd[2];	if(DEBUG(D_EXEC))		fprint(1, "pipecmd='%s'\n", cmd);/**/	if(fd && pipe(pfd) < 0){		perror("pipe");		Exit();	}	pid = rfork(RFPROC|RFFDG|RFENVG);	if(pid < 0){		perror("mk fork");		Exit();	}	if(pid == 0){		if(fd){			close(pfd[0]);			dup(pfd[1], 1);			close(pfd[1]);		}		if(e)			exportenv(e);		if(shflags)			execl(shell, shellname, shflags, "-c", cmd, nil);		else			execl(shell, shellname, "-c", cmd, nil);		perror(shell);		_exits("exec");	}	if(fd){		close(pfd[1]);		*fd = pfd[0];	}	return pid;}voidExit(void){	while(waitpid() >= 0)		;	exits("error");}intnotifyf(void *a, char *msg){	static int nnote;	USED(a);	if(++nnote > 100){	/* until andrew fixes his program */		fprint(2, "mk: too many notes\n");		notify(0);		abort();	}	if(strcmp(msg, "interrupt")!=0 && strcmp(msg, "hangup")!=0)		return 0;	killchildren(msg);	return -1;}voidcatchnotes(){	atnotify(notifyf, 1);}char*maketmp(void){	static char temp[] = "/tmp/mkargXXXXXX";	mktemp(temp);	return temp;}intchgtime(char *name){	Dir sbuf;	if(access(name, AEXIST) >= 0) {		nulldir(&sbuf);		sbuf.mtime = time((long *)0);		return dirwstat(name, &sbuf);	}	return close(create(name, OWRITE, 0666));}voidrcopy(char **to, Resub *match, int n){	int c;	char *p;	*to = match->sp;		/* stem0 matches complete target */	for(to++, match++; --n > 0; to++, match++){		if(match->sp && match->ep){			p = match->ep;			c = *p;			*p = 0;			*to = strdup(match->sp);			*p = c;		}		else			*to = 0;	}}voiddirtime(char *dir, char *path){	int i, fd, n;	Dir *d;	char buf[4096];	fd = open(dir, OREAD);	if(fd >= 0){		while((n = dirread(fd, &d)) > 0){			for(i=0; i<n; i++){				if(d[i].mtime == 0)	/* yeah, this is likely */					continue;				sprint(buf, "%s%s", path, d[i].name);				if(symlook(buf, S_TIME, 0))					continue;				symlook(strdup(buf), S_TIME, (void*)d[i].mtime)->u.value = d[i].mtime;			}			free(d);		}		close(fd);	}}voidbulkmtime(char *dir){	char buf[4096];	char *ss, *s, *sym;	if(dir){		sym = dir;		s = dir;		if(strcmp(dir, "/") == 0)			strcpy(buf, dir);		else			sprint(buf, "%s/", dir);	}else{		s = ".";		sym = "";		buf[0] = 0;	}	if(symlook(sym, S_BULKED, 0))		return;	ss = strdup(sym);	symlook(ss, S_BULKED, (void*)ss);	dirtime(s, buf);}ulongmkmtime(char *name, int force){	Dir *d;	char *s, *ss, carry;	ulong t;	Symtab *sym;	char buf[4096];	strcpy(buf, name);	cleanname(buf);	name = buf;	s = utfrrune(name, '/');	if(s == name)		s++;	if(s){		ss = name;		carry = *s;		*s = 0;	}else{		ss = 0;		carry = 0;	}	bulkmtime(ss);	if(carry)		*s = carry;	if(!force){		sym = symlook(name, S_TIME, 0);		if(sym)			return sym->u.value;		return 0;	}	if((d = dirstat(name)) == nil)		return 0;	t = d->mtime;	free(d);	return t;}

⌨️ 快捷键说明

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