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

📄 devenv.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
字号:
#include	"u.h"#include	"lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"error.h"enum{	Maxenvsize = 16300,};static Egrp	*envgrp(Chan *c);static int	envwriteable(Chan *c);static Egrp	confegrp;	/* global environment group containing the kernel configuration */static Evalue*envlookup(Egrp *eg, char *name, ulong qidpath){	Evalue *e;	int i;	for(i=0; i<eg->nent; i++){		e = eg->ent[i];		if(e->qid.path == qidpath || (name && e->name[0]==name[0] && strcmp(e->name, name) == 0))			return e;	}	return nil;}static intenvgen(Chan *c, char *name, Dirtab *dt, int i, int s, Dir *dp){	Egrp *eg;	Evalue *e;	if(s == DEVDOTDOT){		devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp);		return 1;	}	eg = envgrp(c);	rlock(&eg->lk);	e = 0;	if(name)		e = envlookup(eg, name, -1);	else if(s < eg->nent)		e = eg->ent[s];	if(e == 0) {		runlock(&eg->lk);		return -1;	}	/* make sure name string continues to exist after we release lock */	kstrcpy(up->genbuf, e->name, sizeof up->genbuf);	devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp);	runlock(&eg->lk);	return 1;}static Chan*envattach(char *spec){	Chan *c;	Egrp *egrp = nil;	if(spec && *spec) {		if(strcmp(spec, "c") == 0)			egrp = &confegrp;		if(egrp == nil)			error(Ebadarg);	}	c = devattach('e', spec);	c->aux = egrp;	return c;}static Walkqid*envwalk(Chan *c, Chan *nc, char **name, int nname){	return devwalk(c, nc, name, nname, 0, 0, envgen);}static intenvstat(Chan *c, uchar *db, int n){	if(c->qid.type & QTDIR)		c->qid.vers = envgrp(c)->vers;	return devstat(c, db, n, 0, 0, envgen);}static Chan*envopen(Chan *c, int omode){	Egrp *eg;	Evalue *e;	int trunc;	eg = envgrp(c);	if(c->qid.type & QTDIR) {		if(omode != OREAD)			error(Eperm);	}	else {		trunc = omode & OTRUNC;		if(omode != OREAD && !envwriteable(c))			error(Eperm);		if(trunc)			wlock(&eg->lk);		else			rlock(&eg->lk);		e = envlookup(eg, nil, c->qid.path);		if(e == 0) {			if(trunc)				wunlock(&eg->lk);			else				runlock(&eg->lk);			error(Enonexist);		}		if(trunc && e->value) {			e->qid.vers++;			free(e->value);			e->value = 0;			e->len = 0;		}		if(trunc)			wunlock(&eg->lk);		else			runlock(&eg->lk);	}	c->mode = openmode(omode);	c->flag |= COPEN;	c->offset = 0;	return c;}static voidenvcreate(Chan *c, char *name, int omode, ulong perm){	Egrp *eg;	Evalue *e;	Evalue **ent;	if(c->qid.type != QTDIR)		error(Eperm);	omode = openmode(omode);	eg = envgrp(c);	wlock(&eg->lk);	if(waserror()) {		wunlock(&eg->lk);		nexterror();	}	if(envlookup(eg, name, -1))		error(Eexist);	e = smalloc(sizeof(Evalue));	e->name = smalloc(strlen(name)+1);	strcpy(e->name, name);	if(eg->nent == eg->ment){		eg->ment += 32;		ent = smalloc(sizeof(eg->ent[0])*eg->ment);		if(eg->nent)			memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent);		free(eg->ent);		eg->ent = ent;	}	e->qid.path = ++eg->path;	e->qid.vers = 0;	eg->vers++;	eg->ent[eg->nent++] = e;	c->qid = e->qid;	wunlock(&eg->lk);	poperror();	c->offset = 0;	c->mode = omode;	c->flag |= COPEN;}static voidenvremove(Chan *c){	int i;	Egrp *eg;	Evalue *e;	if(c->qid.type & QTDIR)		error(Eperm);	eg = envgrp(c);	wlock(&eg->lk);	e = 0;	for(i=0; i<eg->nent; i++){		if(eg->ent[i]->qid.path == c->qid.path){			e = eg->ent[i];			eg->nent--;			eg->ent[i] = eg->ent[eg->nent];			eg->vers++;			break;		}	}	wunlock(&eg->lk);	if(e == 0)		error(Enonexist);	free(e->name);	if(e->value)		free(e->value);	free(e);}static voidenvclose(Chan *c){	/*	 * cclose can't fail, so errors from remove will be ignored.	 * since permissions aren't checked,	 * envremove can't not remove it if its there.	 */	if(c->flag & CRCLOSE)		envremove(c);}static longenvread(Chan *c, void *a, long n, vlong off){	Egrp *eg;	Evalue *e;	ulong offset = off;	if(c->qid.type & QTDIR)		return devdirread(c, a, n, 0, 0, envgen);	eg = envgrp(c);	rlock(&eg->lk);	e = envlookup(eg, nil, c->qid.path);	if(e == 0) {		runlock(&eg->lk);		error(Enonexist);	}	if(offset > e->len)	/* protects against overflow converting vlong to ulong */		n = 0;	else if(offset + n > e->len)		n = e->len - offset;	if(n <= 0)		n = 0;	else		memmove(a, e->value+offset, n);	runlock(&eg->lk);	return n;}static longenvwrite(Chan *c, void *a, long n, vlong off){	char *s;	ulong len;	Egrp *eg;	Evalue *e;	ulong offset = off;	if(n <= 0)		return 0;	if(offset > Maxenvsize || n > (Maxenvsize - offset))		error(Etoobig);	eg = envgrp(c);	wlock(&eg->lk);	e = envlookup(eg, nil, c->qid.path);	if(e == 0) {		wunlock(&eg->lk);		error(Enonexist);	}	len = offset+n;	if(len > e->len) {		s = smalloc(len);		if(e->value){			memmove(s, e->value, e->len);			free(e->value);		}		e->value = s;		e->len = len;	}	memmove(e->value+offset, a, n);	e->qid.vers++;	eg->vers++;	wunlock(&eg->lk);	return n;}Dev envdevtab = {	'e',	"env",	devreset,	devinit,	devshutdown,	envattach,	envwalk,	envstat,	envopen,	envcreate,	envclose,	envread,	devbread,	envwrite,	devbwrite,	envremove,	devwstat,};voidenvcpy(Egrp *to, Egrp *from){	int i;	Evalue *ne, *e;	rlock(&from->lk);	to->ment = (from->nent+31)&~31;	to->ent = smalloc(to->ment*sizeof(to->ent[0]));	for(i=0; i<from->nent; i++){		e = from->ent[i];		ne = smalloc(sizeof(Evalue));		ne->name = smalloc(strlen(e->name)+1);		strcpy(ne->name, e->name);		if(e->value){			ne->value = smalloc(e->len);			memmove(ne->value, e->value, e->len);			ne->len = e->len;		}		ne->qid.path = ++to->path;		to->ent[i] = ne;	}	to->nent = from->nent;	runlock(&from->lk);}voidcloseegrp(Egrp *eg){	int i;	Evalue *e;	if(decref(&eg->ref) == 0){		for(i=0; i<eg->nent; i++){			e = eg->ent[i];			free(e->name);			if(e->value)				free(e->value);			free(e);		}		free(eg->ent);		free(eg);	}}static Egrp*envgrp(Chan *c){	if(c->aux == nil)		return up->egrp;	return c->aux;}static intenvwriteable(Chan *c){	return iseve() || c->aux == nil;}/* *  to let the kernel set environment variables */voidksetenv(char *ename, char *eval, int conf){	Chan *c;	char buf[2*KNAMELEN];		snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename);	c = namec(buf, Acreate, OWRITE, 0600);	devtab[c->type]->write(c, eval, strlen(eval), 0);	cclose(c);}/* * Return a copy of configuration environment as a sequence of strings. * The strings alternate between name and value.  A zero length name string * indicates the end of the list */char *getconfenv(void){	Egrp *eg = &confegrp;	Evalue *e;	char *p, *q;	int i, n;	rlock(&eg->lk);	if(waserror()) {		runlock(&eg->lk);		nexterror();	}		/* determine size */	n = 0;	for(i=0; i<eg->nent; i++){		e = eg->ent[i];		n += strlen(e->name) + e->len + 2;	}	p = malloc(n + 1);	if(p == nil)		error(Enomem);	q = p;	for(i=0; i<eg->nent; i++){		e = eg->ent[i];		strcpy(q, e->name);		q += strlen(q) + 1;		memmove(q, e->value, e->len);		q[e->len] = 0;		/* move up to the first null */		q += strlen(q) + 1;	}	*q = 0;		poperror();	runlock(&eg->lk);	return p;}

⌨️ 快捷键说明

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