plan 9 kernel history: overview | file list | diff list

2001/0510/port/devenv.c (diff list | history)

port/devenv.c on 1990/0227
1990/0227    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0227    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1990/0227    
 
 
1992/0623    
enum 
1990/0227    
{ 
1992/0623    
	Maxenvsize = 16300, 
1990/0227    
}; 
 
1997/0327    
static int 
1995/0804    
envgen(Chan *c, Dirtab*, int, int s, Dir *dp) 
1990/0227    
{ 
1991/0705    
	Egrp *eg; 
1992/0623    
	Evalue *e; 
1990/0227    
 
1999/1230    
	if(s == DEVDOTDOT){ 
		devdir(c, c->qid, "#e", 0, eve, 0775, dp); 
		return 1; 
	} 
 
1993/0501    
	eg = up->egrp; 
1992/0623    
	qlock(eg); 
 
	for(e = eg->entries; e && s; e = e->link) 
		s--; 
 
	if(e == 0) { 
		qunlock(eg); 
		return -1; 
1990/0227    
	} 
1992/0623    
 
1999/0122    
	devdir(c, e->qid, e->name, e->len, eve, 0666, dp); 
1992/0623    
	qunlock(eg); 
	return 1; 
1990/0227    
} 
 
1999/0122    
static Evalue* 
envlookup(Egrp *eg, char *name, ulong qidpath) 
{ 
	Evalue *e; 
	for(e = eg->entries; e; e = e->link) 
		if(e->qid.path == qidpath || (name && strcmp(e->name, name) == 0)) 
			return e; 
	return nil; 
} 
 
1997/0327    
static Chan* 
1990/0227    
envattach(char *spec) 
{ 
	return devattach('e', spec); 
} 
 
1997/0327    
static int 
1990/0227    
envwalk(Chan *c, char *name) 
{ 
2001/0510    
	Evalue *e; 
	Egrp *eg; 
	int rv; 
 
	if(c->qid.path == CHDIR && name[0] != '.'){ 
		rv = 0; 
		eg = up->egrp; 
		qlock(eg); 
		for(e = eg->entries; e; e = e->link) 
			if(strcmp(e->name, name) == 0){ 
				rv = 1; 
				c->qid = e->qid; 
			} 
		qunlock(eg); 
		return rv; 
	} else 
		return devwalk(c, name, 0, 0, envgen); 
1990/0227    
} 
 
1997/0327    
static void 
1990/0227    
envstat(Chan *c, char *db) 
{ 
1999/0122    
	if(c->qid.path & CHDIR) 
		c->qid.vers = up->egrp->vers; 
1990/0227    
	devstat(c, db, 0, 0, envgen); 
} 
 
1997/0327    
static Chan* 
1990/0227    
envopen(Chan *c, int omode) 
{ 
1991/0705    
	Egrp *eg; 
1992/0623    
	Evalue *e; 
1998/0512    
 
1993/0501    
	eg = up->egrp; 
1992/0625    
	if(c->qid.path & CHDIR) { 
1991/1018    
		if(omode != OREAD) 
1990/11211    
			error(Eperm); 
1992/0623    
	} 
	else { 
		qlock(eg); 
1999/0122    
		e = envlookup(eg, nil, c->qid.path); 
1992/0623    
		if(e == 0) { 
			qunlock(eg); 
1991/1018    
			error(Enonexist); 
1990/0227    
		} 
1999/0122    
		if((omode & OTRUNC) && e->value) { 
			e->qid.vers++; 
1992/0623    
			free(e->value); 
			e->value = 0; 
			e->len = 0; 
1990/0227    
		} 
1992/0623    
		qunlock(eg); 
1990/0227    
	} 
1992/0623    
	c->mode = openmode(omode); 
1990/0227    
	c->flag |= COPEN; 
	c->offset = 0; 
	return c; 
} 
 
1997/0327    
static void 
1995/0726    
envcreate(Chan *c, char *name, int omode, ulong) 
1990/0227    
{ 
1991/0705    
	Egrp *eg; 
1992/0623    
	Evalue *e; 
1990/0227    
 
1990/11211    
	if(c->qid.path != CHDIR) 
		error(Eperm); 
1992/0623    
 
1991/1018    
	omode = openmode(omode); 
1993/0501    
	eg = up->egrp; 
1992/0623    
 
	qlock(eg); 
	if(waserror()) { 
		qunlock(eg); 
		nexterror(); 
1990/0227    
	} 
1992/0623    
 
1999/0122    
	if(envlookup(eg, name, -1)) 
		error(Eexist); 
1992/0623    
 
	e = smalloc(sizeof(Evalue)); 
	e->name = smalloc(strlen(name)+1); 
	strcpy(e->name, name); 
 
1999/0122    
	e->qid.path = ++eg->path; 
	e->qid.vers = 0; 
	eg->vers++; 
1992/0623    
	e->link = eg->entries; 
	eg->entries = e; 
1999/0122    
	c->qid = e->qid; 
1998/0512    
 
1992/0623    
	qunlock(eg); 
	poperror(); 
 
1990/0227    
	c->offset = 0; 
1991/1018    
	c->mode = omode; 
1990/0227    
	c->flag |= COPEN; 
} 
 
1997/0327    
static void 
1990/0227    
envremove(Chan *c) 
{ 
1991/0705    
	Egrp *eg; 
1992/0623    
	Evalue *e, **l; 
1990/0227    
 
1990/11211    
	if(c->qid.path & CHDIR) 
		error(Eperm); 
1992/0623    
 
1993/0501    
	eg = up->egrp; 
1992/0623    
	qlock(eg); 
	l = &eg->entries; 
	for(e = *l; e; e = e->link) { 
1999/0122    
		if(e->qid.path == c->qid.path) 
1992/0623    
			break; 
		l = &e->link; 
	} 
 
	if(e == 0) { 
		qunlock(eg); 
1990/11211    
		error(Enonexist); 
1990/0227    
	} 
1992/0623    
 
	*l = e->link; 
1999/0122    
	eg->vers++; 
1992/0623    
	qunlock(eg); 
	free(e->name); 
	if(e->value) 
		free(e->value); 
	free(e); 
1990/0227    
} 
 
1997/0327    
static void 
1999/0122    
envclose(Chan *c) 
1990/0227    
{ 
1999/0122    
	/* 
	 * close can't fail, so errors from remove will be ignored anyway. 
	 * since permissions aren't checked, 
	 * envremove can't not remove it if its there. 
	 */ 
	if(c->flag & CRCLOSE) 
		envremove(c); 
1991/1018    
} 
1990/0227    
 
1997/0327    
static long 
1998/0319    
envread(Chan *c, void *a, long n, vlong off) 
1990/0227    
{ 
1991/1018    
	Egrp *eg; 
1992/0623    
	Evalue *e; 
1998/0319    
	ulong offset = off; 
1990/0227    
 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/0227    
		return devdirread(c, a, n, 0, 0, envgen); 
1992/0623    
 
1993/0501    
	eg = up->egrp; 
1992/0623    
	qlock(eg); 
1999/0122    
	e = envlookup(eg, nil, c->qid.path); 
1992/0623    
	if(e == 0) { 
		qunlock(eg); 
1991/1018    
		error(Enonexist); 
1990/0227    
	} 
1992/0623    
 
	if(offset + n > e->len) 
		n = e->len - offset; 
1990/0227    
	if(n <= 0) 
		n = 0; 
	else 
1992/0623    
		memmove(a, e->value+offset, n); 
	qunlock(eg); 
1990/0227    
	return n; 
} 
 
1997/0327    
static long 
1998/0319    
envwrite(Chan *c, void *a, long n, vlong off) 
1990/0227    
{ 
1992/0623    
	char *s; 
	int vend; 
1991/1018    
	Egrp *eg; 
1992/0623    
	Evalue *e; 
1998/0319    
	ulong offset = off; 
1990/0227    
 
	if(n <= 0) 
		return 0; 
1992/0623    
 
	vend = offset+n; 
	if(vend > Maxenvsize) 
1991/1018    
		error(Etoobig); 
1992/0623    
 
1993/0501    
	eg = up->egrp; 
1992/0623    
	qlock(eg); 
1999/0122    
	e = envlookup(eg, nil, c->qid.path); 
1992/0623    
	if(e == 0) { 
		qunlock(eg); 
1991/1018    
		error(Enonexist); 
1990/0227    
	} 
 
1992/0623    
	if(vend > e->len) { 
		s = smalloc(offset+n); 
2000/0121    
		if(e->value){ 
			memmove(s, e->value, e->len); 
1992/0623    
			free(e->value); 
2000/0121    
		} 
1992/0623    
		e->value = s; 
		e->len = vend; 
1991/1018    
	} 
1992/0623    
	memmove(e->value+offset, a, n); 
1999/0122    
	e->qid.vers++; 
	eg->vers++; 
1992/0623    
	qunlock(eg); 
	return n; 
1995/0108    
} 
 
1997/0327    
Dev envdevtab = { 
1997/0408    
	'e', 
	"env", 
 
1997/0327    
	devreset, 
	devinit, 
	envattach, 
	devclone, 
	envwalk, 
	envstat, 
	envopen, 
	envcreate, 
	envclose, 
	envread, 
	devbread, 
	envwrite, 
	devbwrite, 
	envremove, 
	devwstat, 
}; 
1992/0625    
 
void 
envcpy(Egrp *to, Egrp *from) 
{ 
	Evalue **l, *ne, *e; 
 
	l = &to->entries; 
	qlock(from); 
	for(e = from->entries; e; e = e->link) { 
		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; 
		} 
1999/0122    
		ne->qid.path = ++to->path; 
1992/0625    
		*l = ne; 
		l = &ne->link; 
	} 
	qunlock(from); 
} 
 
void 
closeegrp(Egrp *eg) 
{ 
	Evalue *e, *next; 
 
	if(decref(eg) == 0) { 
		for(e = eg->entries; e; e = next) { 
			next = e->link; 
			free(e->name); 
			if(e->value) 
				free(e->value); 
			free(e); 
		} 
		free(eg); 
	} 
1991/1022    
} 
 
1991/0927    
/* 
 *  to let the kernel set environment variables 
 */ 
void 
ksetenv(char *ename, char *eval) 
{ 
	Chan *c; 
	char buf[2*NAMELEN]; 
 
	sprint(buf, "#e/%s", ename); 
	c = namec(buf, Acreate, OWRITE, 0600); 
1997/0327    
	devtab[c->type]->write(c, eval, strlen(eval), 0); 
	cclose(c); 
1991/1102    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)