shithub: p9-stm32-example-os

ref: f801657f77f3923ec2388c25bdcb036c8019ba89
dir: /port/env.c/

View raw version
/*
 *	devenv - environment
 */
#include	<u.h>
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"libkern/kern.h"
#include	"port/error.h"

enum
{
	Maxenvname = 32,
	Maxenvsize = 64,
};

/*
 * kernel interface to environment variables
 */
Egrp*
newegrp(void)
{
	Egrp	*e;

	e = smalloc(sizeof(Egrp));
	e->ref = 1;
	return e;
}

void
closeegrp(Egrp *e)
{
	Evalue *el, *nl;

	if(e == nil || decref(e) != 0)
		return;
	for (el = e->entries; el != nil; el = nl) {
		free(el->var);
		if (el->val)
			free(el->val);
		nl = el->next;
		free(el);
	}
	free(e);
}

void
egrpcpy(Egrp *to, Egrp *from)
{
	Evalue *e, *ne, **last;

	if(from == nil)
		return;
	last = &to->entries;
	qlock(from);
	for (e = from->entries; e != nil; e = e->next) {
		ne = smalloc(sizeof(Evalue));
		ne->var = smalloc(strlen(e->var)+1);
		strcpy(ne->var, e->var);
		if (e->val) {
			ne->val = smalloc(e->len);
			memmove(ne->val, e->val, e->len);
			ne->len = e->len;
		}
//		ne->qid.path = ++to->path;
		*last = ne;
		last = &ne->next;
	}
	qunlock(from);
}

int
kenvcreate(Egrp *eg, char *name)
{
	Evalue *e, **le;

	if(eg == nil)
		return 0;

	if(strlen(name) >= Maxenvname)
		error("name too long");

	qlock(eg);

	if(waserror()){
		qunlock(eg);
		nexterror();
	}

	for(le = &eg->entries; (e = *le) != nil; le = &e->next)
		if(strcmp(e->var, name) == 0)
			return 0;

	e = smalloc(sizeof(Evalue));
	e->var = smalloc(strlen(name)+1);
	strcpy(e->var, name);
	e->val = 0;
	e->len = 0;
	e->next = nil;

	*le = e;

	eg->vers++;

	poperror();
	qunlock(eg);

	return 1;
}

int
kwriteenv(Egrp *eg, char *name, char *val)
{
	Evalue *e;
	ulong vlen = strlen(val);

	if(eg == nil)
		return 0;

	if(vlen > Maxenvsize)
		return 0;

	qlock(eg);
	if(waserror()){
		qunlock(eg);
		nexterror();
	}
	for(e = eg->entries; e != nil; e = e->next)
		if(strcmp(e->var, name) == 0)
			break;
	if(e == nil)
		return 0;
	if(e->val)
		free(e->val);
	e->val = smalloc(vlen);
	memcpy(e->val, val, vlen);

	poperror();
	qunlock(eg);
	return 1;
}

int
ksetenv(Egrp *eg, char *name, char *val)
{
	kenvcreate(eg, name);
	return kwriteenv(eg, name, val);
}

int
kgetenv(Egrp *eg, char *name, void* a)
{
	Evalue *e;

	qlock(eg);
	if(waserror()){
		qunlock(eg);
		nexterror();
	}
	for(e = eg->entries; e != nil; e = e->next) {
		if(strcmp(e->var, name) == 0)
			break;
	}
	if(e == nil)
		return 0;

	print("kgetenv: %s\n", e->val);
	memcpy(a, e->val, strlen(e->val));
	poperror();
	qunlock(eg);
	return 1;
}

int
kdelenv(Egrp *eg, char *name)
{
	Evalue *e, **l;

	if(eg == nil)
		return 0;

	qlock(eg);
	for(l = &eg->entries; (e = *l) != nil; l = &e->next)
		if(!strcmp(e->var, name))
			break;
	if(e == nil) {
		qunlock(eg);
		return 0;
	}
	*l = e->next;
	eg->vers++;
	qunlock(eg);
	free(e->var);
	if(e->val != nil)
		free(e->val);
	free(e);
}