예제 #1
0
파일: devenv.c 프로젝트: srk-cmu/9problems
static int
envgen(Chan *c, char *name, Dirtab*, int, 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);
	if(name != nil)
		e = envlookup(eg, name, -1);
	else if(s < eg->nent)
		e = &eg->ent[s];
	else
		e = nil;
	if(e == nil || name != nil && (strlen(e->name) >= sizeof(up->genbuf))) {
		runlock(eg);
		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);
	return 1;
}
예제 #2
0
파일: devenv.c 프로젝트: Requaos/harvey
static int
envgen(Chan *c, char *name, Dirtab* dir, int i, int s, Dir *dp)
{
	Proc *up = externup();
	Egrp *eg;
	Evalue *e;

	if(s == DEVDOTDOT){
		devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp);
		return 1;
	}

	eg = envgrp(c);
	rlock(&eg->rwl);
	e = 0;
	if(name)
		e = envlookup(eg, name, -1);
	else if(s < eg->nent)
		e = eg->ent[s];

	if(e == 0) {
		runlock(&eg->rwl);
		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->rwl);
	return 1;
}
예제 #3
0
파일: devenv.c 프로젝트: Requaos/harvey
static int32_t
envread(Chan *c, void *a, int32_t n, int64_t off)
{
	Egrp *eg;
	Evalue *e;
	int32_t offset;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, 0, 0, envgen);

	eg = envgrp(c);
	rlock(&eg->rwl);
	e = envlookup(eg, nil, c->qid.path);
	if(e == 0) {
		runlock(&eg->rwl);
		error(Enonexist);
	}

	offset = off;
	if(offset > e->len)	/* protects against overflow converting int64_t to long */
		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->rwl);
	return n;
}
예제 #4
0
파일: devenv.c 프로젝트: srk-cmu/9problems
static long
envread(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);
	if(waserror()){
		runlock(eg);
		nexterror();
	}

	e = envlookup(eg, nil, c->qid.path);
	if(e == nil)
		error(Enonexist);
	if(offset >= e->len || e->value == nil)
		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);
	poperror();
	return n;
}
예제 #5
0
파일: devenv.c 프로젝트: Nurb432/plan9front
static Chan*
envcreate(Chan *c, char *name, int omode, ulong)
{
	Egrp *eg;
	Evalue *e;
	Evalue **ent;

	if(c->qid.type != QTDIR || !envwriteable(c))
		error(Eperm);

	if(strlen(name) >= sizeof(up->genbuf))
		error(Etoolong);

	omode = openmode(omode);
	eg = envgrp(c);

	wlock(eg);
	if(waserror()) {
		wunlock(eg);
		nexterror();
	}

	if(envlookup(eg, name, -1) != nil)
		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);
	poperror();

	c->offset = 0;
	c->mode = omode;
	c->flag |= COPEN;
	return c;
}
예제 #6
0
파일: devenv.c 프로젝트: srk-cmu/9problems
static Chan*
envcreate(Chan *c, char *name, int omode, ulong)
{
	Egrp *eg;
	Evalue *e;

	if(c->qid.type != QTDIR || !envwriteable(c))
		error(Eperm);

	if(strlen(name) >= sizeof(up->genbuf))
		error(Etoolong);

	omode = openmode(omode);
	eg = envgrp(c);
	wlock(eg);
	if(waserror()) {
		wunlock(eg);
		nexterror();
	}

	if(envlookup(eg, name, -1) != nil)
		error(Eexist);

	if(eg->nent == eg->ment){
		Evalue *tmp;

		eg->ment += DELTAENV;
		if((tmp = realloc(eg->ent, sizeof(eg->ent[0])*eg->ment)) == nil){
			eg->ment -= DELTAENV;
			error(Enomem);
		}
		eg->ent = tmp;
	}
	eg->vers++;
	e = &eg->ent[eg->nent++];
	e->value = nil;
	e->len = 0;
	e->name = smalloc(strlen(name)+1);
	strcpy(e->name, name);
	mkqid(&e->qid, ++eg->path, 0, QTFILE);
	c->qid = e->qid;

	wunlock(eg);
	poperror();

	c->offset = 0;
	c->mode = omode;
	c->flag |= COPEN;
	return c;
}
예제 #7
0
파일: devenv.c 프로젝트: Requaos/harvey
static void
envcreate(Chan *c, char *name, int omode, int i)
{
	Proc *up = externup();
	Egrp *eg;
	Evalue *e;
	Evalue **ent;

	if(c->qid.type != QTDIR)
		error(Eperm);

	omode = openmode(omode);
	eg = envgrp(c);

	wlock(&eg->rwl);
	if(waserror()) {
		wunlock(&eg->rwl);
		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->rwl);
	poperror();

	c->offset = 0;
	c->mode = omode;
	c->flag |= COPEN;
}
예제 #8
0
파일: devenv.c 프로젝트: Requaos/harvey
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->rwl);
		else
			rlock(&eg->rwl);
		e = envlookup(eg, nil, c->qid.path);
		if(e == 0) {
			if(trunc)
				wunlock(&eg->rwl);
			else
				runlock(&eg->rwl);
			error(Enonexist);
		}
		if(trunc && e->value) {
			e->qid.vers++;
			free(e->value);
			e->value = 0;
			e->len = 0;
		}
		if(trunc)
			wunlock(&eg->rwl);
		else
			runlock(&eg->rwl);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
예제 #9
0
파일: devenv.c 프로젝트: srk-cmu/9problems
static long
envwrite(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);
	if(waserror()){
		wunlock(eg);
		nexterror();
	}

	e = envlookup(eg, nil, c->qid.path);
	if(e == nil)
		error(Enonexist);

	len = offset+n;
	if(len > e->len) {
		s = realloc(e->value, len);
		if(s == nil)
			error(Enomem);
		memset(s+offset, 0, n);
		e->value = s;
		e->len = len;
	}
	memmove(e->value+offset, a, n);
	e->qid.vers++;
	eg->vers++;

	wunlock(eg);
	poperror();
	return n;
}
예제 #10
0
파일: devenv.c 프로젝트: srk-cmu/9problems
static void
envremove(Chan *c)
{
	Egrp *eg;
	Evalue *e;

	if(c->qid.type & QTDIR || !envwriteable(c))
		error(Eperm);

	eg = envgrp(c);
	wlock(eg);
	e = envlookup(eg, nil, c->qid.path);
	if(e == nil){
		wunlock(eg);
		error(Enonexist);
	}
	free(e->name);
	free(e->value);
	*e = eg->ent[--eg->nent];
	eg->vers++;
	wunlock(eg);
}
예제 #11
0
파일: devenv.c 프로젝트: Requaos/harvey
static int32_t
envwrite(Chan *c, void *a, int32_t n, int64_t off)
{
	char *s;
	Egrp *eg;
	Evalue *e;
	int32_t len, offset;

	if(n <= 0)
		return 0;
	offset = off;
	if(offset > Maxenvsize || n > (Maxenvsize - offset))
		error(Etoobig);

	eg = envgrp(c);
	wlock(&eg->rwl);
	e = envlookup(eg, nil, c->qid.path);
	if(e == 0) {
		wunlock(&eg->rwl);
		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->rwl);
	return n;
}