## diffname port/devenv.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/devenv.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "errno.h"
#include "devtab.h"
/*
* An environment value is kept in some number of contiguous
* Envvals, with the Env's val pointing at the first.
* Envvals are allocated from the end of a fixed arena, which
* is compacted when the arena end is reached.
* A `piece' (number of contiguous Envvals) is free to be
* reclaimed if its e pointer is 0.
*
* Locking: an env's val can change by compaction, so lock
* an env before using its value. A pgrp env[] slot can go
* to 0 and the corresponding env freed (by envremove()), so
* lock the pgrp around the use of a value retrieved from a slot.
* Lock in order: pgrp, envalloc, env (but ok to skip envalloc
* lock if there is no possibility of blocking).
*/
struct Envval
{
ulong n; /* number of Envval's (including this) in this piece */
ulong len; /* how much of dat[] is valid */
Env *e; /* the Env whose val points here */
char dat[4]; /* possibly extends into further envvals after this */
};
/* number of contiguous Envvals needed to hold n characters */
#define EVNEEDED(n) ((n)<4? 1 : 1+((n)+(sizeof(Envval))-1-4)/(sizeof(Envval)))
struct
{
Lock;
Envval *arena;
Envval *vfree;
Envval *end;
Env *efree;
Env *earena;
}envalloc;
void compactenv(Env *, ulong);
void
envreset(void)
{
int i, n;
n = EVNEEDED(conf.nenvchar);
envalloc.arena = ialloc(n*sizeof(Envval), 0);
envalloc.vfree = envalloc.arena;
envalloc.end = envalloc.arena+n;
envalloc.earena = ialloc(conf.nenv*sizeof(Env), 0);
envalloc.efree = envalloc.earena;
for(i=0; i<conf.nenv-1; i++)
envalloc.earena[i].next = &envalloc.earena[i+1];
envalloc.earena[conf.nenv-1].next = 0;
}
void
envinit(void)
{
}
/*
* Make sure e->val points at a value big enough to hold nchars chars.
* The caller should fix e->val->len.
* envalloc and e should be locked
*/
void
growenval(Env *e, ulong nchars)
{
Envval *p;
ulong n, nfree;
n = EVNEEDED(nchars);
if(p = e->val){ /* assign = */
if(p->n < n){
if(p+p->n == envalloc.vfree){
compactenv(e, n - p->n);
p = e->val;
envalloc.vfree += n - p->n;
}else{
compactenv(e, n);
p = envalloc.vfree;
envalloc.vfree += n;
memcpy(p, e->val, e->val->n*sizeof(Envval));
p->e = e;
e->val->e = 0;
e->val = p;
}
p->n = n;
}
}else{
compactenv(e, n);
p = envalloc.vfree;
envalloc.vfree += n;
p->n = n;
p->e = e;
e->val = p;
}
}
/*
* Make sure there is room for n Envval's at the end of envalloc.vfree.
* Call this with envalloc and e locked.
*/
void
compactenv(Env *e, ulong n)
{
Envval *p1, *p2;
Env *p2e;
if(envalloc.end-envalloc.vfree >= n)
return;
p1 = envalloc.arena; /* dest */
p2 = envalloc.arena; /* source */
while(p2 < envalloc.vfree){
p2e = p2->e;
if(p2e == 0){
Free:
p2 += p2->n;
continue;
}
if(p2e<envalloc.earena || p2e>=envalloc.earena+conf.nenv){
print("%lux not an env\n", p2e);
panic("compactenv");
}
if(p1 != p2){
if(p2e != e)
lock(p2e);
if(p2->e != p2e){ /* freed very recently */
print("compactenv p2e moved\n");
if(p2->e)
panic("compactenv p2->e %lux\n", p2->e);
unlock(p2e);
goto Free;
}
if(p2+p2->n > envalloc.end)
panic("compactpte copying too much");
memcpy(p1, p2, p2->n*sizeof(Envval));
p2e->val = p1;
if(p2e != e)
unlock(p2e);
}
p2 += p1->n;
p1 += p1->n;
}
envalloc.vfree = p1;
if(envalloc.end-envalloc.vfree < n){
print("env compact failed\n");
error(0, Enoenv);
}
}
/*
* Return an env with a copy of e's value.
* envalloc and e should be locked,
* and the value returned will be locked too.
*/
Env *
copyenv(Env *e, int trunc)
{
Env *ne;
int n;
ne = envalloc.efree;
if(!ne){
print("out of envs\n");
error(0, Enoenv);
}
envalloc.efree = ne->next;
lock(ne);
if(waserror()){
unlock(ne);
nexterror();
}
ne->next = 0;
ne->pgref = 1;
strncpy(ne->name, e->name, NAMELEN);
if(e->val && !trunc){
n = e->val->len;
/*
* growenval can't hold the lock on another env
* because compactenv assumes only one is held
*/
unlock(e);
growenval(ne, n);
lock(e);
if(n != e->val->len){
print("e changed in copyenv\n");
if(n > ne->val->len)
n = ne->val->len;
}
if((char*)(ne->val+ne->val->n) < ne->val->dat+n)
panic("copyenv corrupt");
memcpy(ne->val->dat, e->val->dat, n);
ne->val->len = n;
}
poperror();
return ne;
}
int
envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
{
Env *e;
Pgrp *pg;
int ans;
pg = u->p->pgrp;
lock(pg);
if(s >= pg->nenv)
ans = -1;
else{
e = pg->etab[s].env;
if(e == 0)
ans = 0;
else{
lock(e);
devdir(c, s+1, e->name, e->val? e->val->len : 0, 0666, dp);
unlock(e);
ans = 1;
}
}
unlock(pg);
return ans;
}
Chan*
envattach(char *spec)
{
return devattach('e', spec);
}
Chan*
envclone(Chan *c, Chan *nc)
{
Pgrp *pg;
if(!(c->qid&CHDIR)){
pg = u->p->pgrp;
lock(pg);
pg->etab[c->qid-1].chref++;
unlock(pg);
}
return devclone(c, nc);
}
int
envwalk(Chan *c, char *name)
{
Pgrp *pg;
if(devwalk(c, name, 0, 0, envgen)){
if(!(c->qid&CHDIR)){
pg = u->p->pgrp;
lock(pg);
pg->etab[c->qid-1].chref++;
unlock(pg);
return 1;
}
}
return 0;
}
void
envstat(Chan *c, char *db)
{
devstat(c, db, 0, 0, envgen);
}
Chan *
envopen(Chan *c, int omode)
{
Env *e, *ne;
Envp *ep;
Pgrp *pg;
if(omode & (OWRITE|OTRUNC)){
if(c->qid & CHDIR)
error(0, Eperm);
pg = u->p->pgrp;
lock(pg);
ep = &pg->etab[c->qid-1];
e = ep->env;
if(!e){
unlock(pg);
error(0, Egreg);
}
lock(&envalloc);
lock(e);
if(waserror()){
unlock(e);
unlock(&envalloc);
nexterror();
}
if(e->pgref == 0)
panic("envopen");
if(e->pgref == 1){
if((omode&OTRUNC) && e->val){
e->val->e = 0;
e->val = 0;
}
}else{
ne = copyenv(e, omode&OTRUNC);
e->pgref--; /* it will still be positive */
ep->env = ne;
unlock(ne);
}
poperror();
unlock(e);
unlock(&envalloc);
unlock(pg);
}
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
return c;
}
void
envcreate(Chan *c, char *name, int omode, ulong perm)
{
Env *e;
Pgrp *pg;
int i;
if(c->qid != CHDIR)
error(0, Eperm);
pg = u->p->pgrp;
lock(pg);
lock(&envalloc);
if(waserror()){
unlock(&envalloc);
unlock(pg);
nexterror();
}
e = envalloc.efree;
if(e == 0){
print("out of envs\n");
error(0,Enoenv);
}
envalloc.efree = e->next;
e->next = 0;
e->pgref = 1;
strncpy(e->name, name, NAMELEN);
if(pg->nenv == conf.npgenv){
for(i = 0; i<pg->nenv; i++)
if(pg->etab[i].chref == 0)
break;
if(i == pg->nenv){
print("out of pgroup envs\n");
error(0, Enoenv);
}
}else
i = pg->nenv++;
c->qid = i+1;
pg->etab[i].env = e;
pg->etab[i].chref = 1;
unlock(&envalloc);
unlock(pg);
c->offset = 0;
c->mode = openmode(omode);
poperror();
c->flag |= COPEN;
}
void
envremove(Chan *c)
{
Env *e;
Envp *ep;
Pgrp *pg;
if(c->qid & CHDIR)
error(0, Eperm);
pg = u->p->pgrp;
lock(pg);
ep = &pg->etab[c->qid-1];
e = ep->env;
if(!e){
unlock(pg);
error(0, Enonexist);
}
ep->env = 0;
ep->chref--;
envpgclose(e);
unlock(pg);
}
void
envwstat(Chan *c, char *db)
{ int dumpenv(void);
dumpenv(); /*DEBUG*/
print("envwstat\n");
error(0, Egreg);
}
void
envclose(Chan * c)
{
Pgrp *pg;
if(c->qid & CHDIR)
return;
pg = u->p->pgrp;
lock(pg);
pg->etab[c->qid-1].chref--;
unlock(pg);
}
void
envpgclose(Env *e)
{
lock(&envalloc);
lock(e);
if(--e->pgref <= 0){
if(e->val){
e->val->e = 0;
e->val = 0;
}
e->next = envalloc.efree;
envalloc.efree = e;
}
unlock(e);
unlock(&envalloc);
}
long
envread(Chan *c, void *va, long n)
{
Env *e;
Envval *ev;
char *p;
long vn;
Pgrp *pg;
char *a = va;
if(c->qid & CHDIR)
return devdirread(c, a, n, 0, 0, envgen);
pg = u->p->pgrp;
lock(pg);
e = pg->etab[c->qid-1].env;
if(!e){
unlock(pg);
error(0, Eio);
}
lock(e);
ev = e->val;
vn = ev? e->val->len : 0;
if(c->offset+n > vn)
n = vn - c->offset;
if(n <= 0)
n = 0;
else
memcpy(a, ev->dat+c->offset, n);
unlock(e);
unlock(pg);
return n;
}
long
envwrite(Chan *c, void *va, long n)
{
Env *e;
char *p;
Envval *ev;
long vn;
Pgrp *pg;
char *a = va;
if(n <= 0)
return 0;
pg = u->p->pgrp;
lock(pg);
e = pg->etab[c->qid-1].env; /* caller checks for CHDIR */
if(!e){
unlock(pg);
error(0, Eio);
}
lock(&envalloc);
lock(e);
if(waserror()){
unlock(e);
unlock(&envalloc);
unlock(pg);
nexterror();
}
if(e->pgref>1)
panic("envwrite to non-duped env");
growenval(e, c->offset+n);
ev = e->val;
vn = ev? ev->len : 0;
if(c->offset > vn)
error(0, Egreg); /* perhaps should zero fill */
memcpy(ev->dat+c->offset, a, n);
e->val->len = c->offset+n;
poperror();
unlock(e);
unlock(&envalloc);
unlock(pg);
return n;
}
void
dumpenv(void)
{
Env *e;
Envp *ep;
Envval *ev;
Pgrp *pg;
int i;
char hold;
pg = u->p->pgrp;
for(ep=pg->etab, i=0; i<pg->nenv; i++, ep++)
print("P%d(%lux %d)",i, ep->env, ep->chref);
for(e=envalloc.earena; e<&envalloc.earena[conf.nenv]; e++)
if(e->pgref){
print("E{%lux %d '%s'}[", e, e->pgref, e->name);
if(e->val){
hold = e->val->dat[e->val->len];
e->val->dat[e->val->len] = 0;
print("%s", e->val->dat);
e->val->dat[e->val->len] = hold;
}
print("]");
}else if(e->val)
print("whoops, free env %lux has val=%lux\n",e,e->val);
for(i=0, e=envalloc.efree; e; e=e->next)
i++;
print("\n%d free envs", i);
for(i=0, ev=envalloc.arena; ev<envalloc.vfree; ev+=ev->n)
if(!ev->e)
i += ev->n*sizeof(Envval);
print(" %d free enval chars\n", i+((char *)envalloc.end-(char*)envalloc.vfree));
}
void
envuserstr(Error *e, char *buf)
{
consuserstr(e, buf);
}
void
enverrstr(Error *e, char *buf)
{
rooterrstr(e, buf);
}
.
## diffname port/devenv.c 1990/03042
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devenv.c /n/bootesdump/1990/03042/sys/src/9/mips/devenv.c
301a
unlock(pg);
.
## diffname port/devenv.c 1990/0802
## diff -e /n/bootesdump/1990/03042/sys/src/9/mips/devenv.c /n/bootesdump/1990/0802/sys/src/9/mips/devenv.c
146c
panic("compactenv copying too much");
.
## diffname port/devenv.c 1990/11211
## diff -e /n/bootesdump/1990/0802/sys/src/9/mips/devenv.c /n/bootesdump/1990/11211/sys/src/9/mips/devenv.c
546,558d
503c
error(Egreg); /* perhaps should zero fill */
.
487c
error(Eio);
.
484c
e = pg->etab[c->qid.path-1].env; /* caller checks for CHDIR */
.
454c
error(Eio);
.
451c
e = pg->etab[c->qid.path-1].env;
.
447c
if(c->qid.path & CHDIR)
.
416c
pg->etab[c->qid.path-1].chref--;
.
412c
if(c->qid.path & CHDIR)
.
404c
error(Egreg);
.
391c
error(Enonexist);
.
387c
ep = &pg->etab[c->qid.path-1];
.
383,384c
if(c->qid.path & CHDIR)
error(Eperm);
.
365c
c->qid.path = i+1;
.
361c
error(Enoenv);
.
349c
error(Enoenv);
.
336,337c
if(c->qid.path != CHDIR)
error(Eperm);
.
295c
error(Egreg);
.
291c
ep = &pg->etab[c->qid.path-1];
.
287,288c
if(c->qid.path & CHDIR)
error(Eperm);
.
265c
pg->etab[c->qid.path-1].chref++;
.
262c
if(!(c->qid.path&CHDIR)){
.
250c
pg->etab[c->qid.path-1].chref++;
.
247c
if(!(c->qid.path&CHDIR)){
.
227c
devdir(c, (Qid){s+1,0}, e->name, e->val? e->val->len : 0, 0666, dp);
.
176c
error(Enoenv);
.
158c
error(Enoenv);
.
## diffname port/devenv.c 1991/0318
## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/devenv.c /n/bootesdump/1991/0318/sys/src/9/port/devenv.c
504c
memmove(ev->dat+c->offset, a, n);
.
464c
memmove(a, ev->dat+c->offset, n);
.
203c
memmove(ne->val->dat, e->val->dat, n);
.
147c
memmove(p1, p2, p2->n*sizeof(Envval));
.
93c
memmove(p, e->val, e->val->n*sizeof(Envval));
.
## diffname port/devenv.c 1991/0411
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/devenv.c /n/bootesdump/1991/0411/sys/src/9/port/devenv.c
504,505c
memmove(ev->dat+offset, a, n);
e->val->len = offset+n;
.
502c
if(offset > vn)
.
499c
growenval(e, offset+n);
.
471c
envwrite(Chan *c, void *va, long n, ulong offset)
.
464c
memmove(a, ev->dat+offset, n);
.
459,460c
if(offset+n > vn)
n = vn - offset;
.
438c
envread(Chan *c, void *va, long n, ulong offset)
.
## diffname port/devenv.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/port/devenv.c /n/bootesdump/1991/0419/sys/src/9/port/devenv.c
272a
Chan*
envclwalk(Chan *c, char *name)
{
return devclwalk(c, name);
}
.
## diffname port/devenv.c 1991/0427
## diff -e /n/bootesdump/1991/0419/sys/src/9/port/devenv.c /n/bootesdump/1991/0427/sys/src/9/port/devenv.c
273,278d
## diffname port/devenv.c 1991/0705
## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devenv.c /n/bootesdump/1991/0705/sys/src/9/port/devenv.c
523,524c
eg = u->p->egrp;
for(ep=eg->etab, i=0; i<eg->nenv; i++, ep++)
.
519c
Egrp *eg;
.
509c
unlock(eg);
.
494c
unlock(eg);
.
486c
unlock(eg);
.
482,484c
eg = u->p->egrp;
lock(eg);
e = eg->etab[c->qid.path-1].env; /* caller checks for CHDIR */
.
477c
Egrp *eg;
.
466c
unlock(eg);
.
453c
unlock(eg);
.
449,451c
eg = u->p->egrp;
lock(eg);
e = eg->etab[c->qid.path-1].env;
.
444c
Egrp *eg;
.
414,417c
eg = u->p->egrp;
lock(eg);
eg->etab[c->qid.path-1].chref--;
unlock(eg);
.
410c
Egrp *eg;
.
396c
unlock(eg);
.
390c
unlock(eg);
.
385,387c
eg = u->p->egrp;
lock(eg);
ep = &eg->etab[c->qid.path-1];
.
381c
Egrp *eg;
.
369c
unlock(eg);
.
366,367c
eg->etab[i].env = e;
eg->etab[i].chref = 1;
.
364c
i = eg->nenv++;
.
359,360c
if(i == eg->nenv){
print("out of egroup envs\n");
.
355,357c
if(eg->nenv == conf.npgenv){
for(i = 0; i<eg->nenv; i++)
if(eg->etab[i].chref == 0)
.
343c
unlock(eg);
.
338,339c
eg = u->p->egrp;
lock(eg);
.
333c
Egrp *eg;
.
321c
unlock(eg);
.
302c
unlock(eg);
.
294c
unlock(eg);
.
289,291c
eg = u->p->egrp;
lock(eg);
ep = &eg->etab[c->qid.path-1];
.
284c
Egrp *eg;
.
263,266c
eg = u->p->egrp;
lock(eg);
eg->etab[c->qid.path-1].chref++;
unlock(eg);
.
259c
Egrp *eg;
.
248,251c
eg = u->p->egrp;
lock(eg);
eg->etab[c->qid.path-1].chref++;
unlock(eg);
.
245c
Egrp *eg;
.
232c
unlock(eg);
.
222c
e = eg->etab[s].env;
.
217,219c
eg = u->p->egrp;
lock(eg);
if(s >= eg->nenv)
.
214c
Egrp *eg;
.
## diffname port/devenv.c 1991/0927
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/devenv.c /n/bootesdump/1991/0927/sys/src/9/port/devenv.c
545a
/*
* 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);
(*devtab[c->type].write)(c, eval, strlen(eval), 0);
close(c);
}
.
## diffname port/devenv.c 1991/1018
## diff -e /n/bootesdump/1991/0927/sys/src/9/port/devenv.c /n/bootesdump/1991/1018/sys/src/9/port/devenv.c
523,544c
h = 0;
for(t = (uchar*)s; t - (uchar*)s < n; t++)
h = (h << 1) ^ *t;
h &= EVHASH - 1;
for(ev = evhash[h].next; ev; ev = ev->next)
if(ev->len == n && memcmp(ev->val, s, n) == 0){
ev->ref++;
return ev;
}
ev = evalloc(n);
ev->len = n;
memmove(ev->val, s, n);
if(ev->next = evhash[h].next)
ev->next->prev = ev;
evhash[h].next = ev;
ev->prev = &evhash[h];
return ev;
}
/*
* called only from newev
*/
Envval *
evalloc(ulong n)
{
Envval *ev, **p;
char *b, *lim;
ulong size;
n = (n - 1) / ALIGN;
size = (n + 1) * ALIGN;
p = &envalloc.free[n < EVFREE ? n : EVFREE];
for(ev = *p; ev; ev = *p){
if(ev->len == size){
*p = ev->next;
ev->ref = 1;
return ev;
}
p = &ev->next;
}
/*
* make sure we have enough space to allocate the buffer.
* if not, use the remaining space for the smallest buffers
*/
if(size > MAXENV)
panic("evalloc");
b = envalloc.block;
lim = envalloc.lim;
if(!b || lim < b + size + sizeof *ev){
p = &envalloc.free[0];
while(lim >= b + ALIGN + sizeof *ev){
ev = (Envval*)b;
ev->len = ALIGN;
ev->val = b + sizeof *ev;
ev->next = *p;
*p = ev;
b += ALIGN + sizeof *ev;
}
b = (char*)VA(kmap(newpage(0, 0, 0)));
envalloc.lim = b + BY2PG;
}
ev = (Envval*)b;
ev->val = b + sizeof *ev;
ev->ref = 1;
envalloc.block = b + size + sizeof *ev;
return ev;
}
/*
* called with evlock qlocked
*/
void
evfree(Envval *ev)
{
int n;
if(--ev->ref > 0)
return;
if(ev->prev)
ev->prev->next = ev->next;
if(ev->next)
ev->next->prev = ev->prev;
n = (ev->len + ALIGN - 1) & ~(ALIGN - 1);
ev->len = n;
n = (n - 1) / ALIGN;
if(n > EVFREE)
n = EVFREE;
ev->next = envalloc.free[n];
envalloc.free[n] = ev;
.
519,521c
uchar *t;
int h;
.
516,517d
513,514c
/*
* called with evlock qlocked
*/
Envval *
newev(char *s, ulong n)
.
501,509c
olen = ev ? ev->len : 0;
qlock(&evlock);
if(offset == 0 && n >= olen)
e->val = newev(a, n);
else{
if(olen > offset)
olen = offset;
if(ev)
memmove(evscratch, ev->val, olen);
if(olen < offset)
memset(evscratch + olen, '\0', offset - olen);
memmove(evscratch + offset, a, n);
e->val = newev(evscratch, offset + n);
}
if(ev)
evfree(ev);
qunlock(&evlock);
qunlock(&eg->ev);
.
489,499d
483,487c
qlock(&eg->ev);
e = &eg->etab[c->qid.path-1];
if(!e->name){
qunlock(&eg->ev);
error(Enonexist);
.
481a
if(offset + n > MAXENV)
error(Etoobig);
.
476,478c
ulong olen;
.
474d
472a
Egrp *eg;
.
471c
envwrite(Chan *c, void *a, long n, ulong offset)
.
464,466c
memmove(a, ev->val + offset, n);
qunlock(&eg->ev);
.
458,459c
vn = ev ? ev->len : 0;
if(offset + n > vn)
.
456d
450,454c
qlock(&eg->ev);
e = &eg->etab[c->qid.path-1];
if(!e->name){
qunlock(&eg->ev);
error(Enonexist);
.
444,445d
442d
439a
Egrp *eg;
.
438c
envread(Chan *c, void *a, long n, ulong offset)
.
423,434c
qlock(&evlock);
if(e->name)
evfree(e->name);
if(e->val)
evfree(e->val);
e->name = e->val = 0;
qunlock(&evlock);
.
412,417c
void
envpgcopy(Env *t, Env *f)
{
qlock(&evlock);
if(t->name = f->name)
t->name->ref++;
if(t->val = f->val)
t->val->ref++;
qunlock(&evlock);
.
410c
}
.
401,404c
{
error(Eperm);
.
396c
qunlock(&eg->ev);
.
393,394d
386,390c
qlock(&eg->ev);
e = &eg->etab[c->qid.path-1];
if(!e->name){
qunlock(&eg->ev);
.
381a
Env *e;
.
379,380d
371,372c
c->mode = omode;
.
351,369c
i = e - eg->etab + 1;
e->val = 0;
qlock(&evlock);
e->name = newev(name, strlen(name)+1);
qunlock(&evlock);
if(i > eg->nenv)
eg->nenv = i;
qunlock(&eg->ev);
c->qid = (Qid){i, 0};
.
339,348c
qlock(&eg->ev);
e = eg->etab;
ne = 0;
for(i = 0; i < eg->nenv; i++, e++)
if(e->name == 0)
ne = e;
else if(strcmp(e->name->val, name) == 0){
qunlock(&eg->ev);
error(Einuse);
}
if(ne)
e = ne;
else if(eg->nenv == conf.npgenv){
print("out of egroup envs\n");
qunlock(&eg->ev);
.
337a
omode = openmode(omode);
.
333a
Env *e, *ne;
.
332d
323c
c->mode = mode;
.
305,321c
qunlock(&eg->ev);
.
297,303c
if(omode == (OWRITE|OTRUNC) && e->val){
qlock(&evlock);
evfree(e->val);
qunlock(&evlock);
e->val = 0;
.
290,295c
qlock(&eg->ev);
e = &eg->etab[c->qid.path-1];
if(!e->name){
qunlock(&eg->ev);
error(Enonexist);
.
288a
}else{
.
286,287c
mode = openmode(omode);
if(c->qid.path & CHDIR){
if(omode != OREAD)
.
284a
Env *e;
int mode;
.
282,283d
261,270c
return devwalk(c, name, 0, 0, envgen);
.
259d
245,252d
232c
qunlock(&eg->ev);
.
226,228c
devdir(c, (Qid){s+1, (ulong)e->val}, e->name->val, e->val? e->val->len : 0, 0666, dp);
.
222,223c
e = &eg->etab[s];
if(!e->name)
.
218c
qlock(&eg->ev);
.
214a
Env *e;
.
213d
71,209d
52,63c
evscratch = ialloc(BY2PG, 0);
.
48a
Envval *newev(char*, ulong);
Envval *evalloc(ulong);
void evfree(Envval*);
.
47c
QLock evlock;
Envval evhash[EVHASH];
char *evscratch; /* for constructing the contents of a file */
.
39,44c
Envval *free[EVFREE+1];
char *block; /* the free page we are allocating from */
char *lim; /* end of block */
.
34,35c
enum{
MAXENV = (BY2PG - sizeof(Envval)),
EVHASH = 64,
EVFREE = 16,
ALIGN = 16,
};
.
28,31c
Envval *next; /* for hashing & easy deletion from hash list */
Envval *prev;
ulong len; /* length of val that is valid */
int ref;
char *val;
.
10,25d
## diffname port/devenv.c 1991/1022
## diff -e /n/bootesdump/1991/1018/sys/src/9/port/devenv.c /n/bootesdump/1991/1022/sys/src/9/port/devenv.c
400a
}
void
envdump(void)
{
Envval *ev;
int i, j;
qlock(&evlock);
print("pages allocated: %d\n", envalloc.npage);
print("bytes left in page: %d\n", envalloc.lim - envalloc.block);
for(i = 0; i < EVFREE + 1; i++){
j = 0;
if(i == EVFREE)
print("big blocks:\n");
else
print("%d byte blocks:\n", (i + 1) * ALIGN);
for(ev = envalloc.free[i]; ev; ev = ev->next){
if(j++ == 1000){
print("circular\n");
break;
}
if(j < 10)
print("\tenv %d %lux n%lux p%lux r%d\n",
ev->len, ev, ev->next, ev->prev, ev->ref);
}
}
for(i = 0; i < EVHASH; i++){
j = 0;
for(ev = evhash[i].next; ev; ev = ev->next){
if(j++ == 1000){
print("hash bucket %d circular\n", i);
break;
}
}
}
qunlock(&evlock);
.
371c
.
368a
envalloc.npage++;
.
30a
int npage; /* total pages gotten from newpage() */
.
## diffname port/devenv.c 1991/1024
## diff -e /n/bootesdump/1991/1022/sys/src/9/port/devenv.c /n/bootesdump/1991/1024/sys/src/9/port/devenv.c
401a
ev->prev = 0;
.
393a
else
panic("evfree");
.
## diffname port/devenv.c 1991/1030
## diff -e /n/bootesdump/1991/1024/sys/src/9/port/devenv.c /n/bootesdump/1991/1030/sys/src/9/port/devenv.c
435a
uchar *t, *s;
int h, n;
s = (uchar*)ev->val;
n = ev->len;
h = 0;
for(t = s; t - s < n; t++)
h = (h << 1) ^ *t;
h &= EVHASH - 1;
if(h != i)
print("hash conflict: %d %d\n", i, h);
.
## diffname port/devenv.c 1991/1102
## diff -e /n/bootesdump/1991/1030/sys/src/9/port/devenv.c /n/bootesdump/1991/1102/sys/src/9/port/devenv.c
469a
void
ksetterm(char *f)
{
char buf[2*NAMELEN];
sprint(buf, f, conffile);
ksetenv("terminal", buf);
}
.
## diffname port/devenv.c 1991/1105
## diff -e /n/bootesdump/1991/1102/sys/src/9/port/devenv.c /n/bootesdump/1991/1105/sys/src/9/port/devenv.c
160a
print("out of egroup envs\n");
.
159d
## diffname port/devenv.c 1991/1108
## diff -e /n/bootesdump/1991/1105/sys/src/9/port/devenv.c /n/bootesdump/1991/1108/sys/src/9/port/devenv.c
408,455d
## diffname port/devenv.c 1991/1109
## diff -e /n/bootesdump/1991/1108/sys/src/9/port/devenv.c /n/bootesdump/1991/1109/sys/src/9/port/devenv.c
69c
devdir(c, (Qid){s+1, (ulong)e->val}, e->name->val, e->val? e->val->len : 0, eve, 0666, dp);
.
## diffname port/devenv.c 1991/1115
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/devenv.c /n/bootesdump/1991/1115/sys/src/9/port/devenv.c
204a
USED(c);
.
198a
USED(c, db);
.
## diffname port/devenv.c 1991/1121
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devenv.c /n/bootesdump/1991/1121/sys/src/9/port/devenv.c
341,342c
size = (n + ALIGN - 1) & ~(ALIGN - 1);
n = (size - 1) / ALIGN;
.
271c
olen = (offset + n + ALIGN - 1) & ~(ALIGN - 1);
if(olen > MAXENV)
.
## diffname port/devenv.c 1992/0111
## diff -e /n/bootesdump/1991/1121/sys/src/9/port/devenv.c /n/bootesdump/1992/0111/sys/src/9/port/devenv.c
6c
#include "../port/error.h"
.
## diffname port/devenv.c 1992/0321
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devenv.c /n/bootesdump/1992/0321/sys/src/9/port/devenv.c
2c
#include "../port/lib.h"
.
## diffname port/devenv.c 1992/0331
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devenv.c /n/bootesdump/1992/0331/sys/src/9/port/devenv.c
69c
devdir(c, (Qid){s+1, (ulong)e->name}, e->name->val, e->val? e->val->len : 0, eve, 0666, dp);
.
## diffname port/devenv.c 1992/0622
## diff -e /n/bootesdump/1992/0331/sys/src/9/port/devenv.c /n/bootesdump/1992/0622/sys/src/9/port/devenv.c
45c
evscratch = xalloc(BY2PG);
.
## diffname port/devenv.c 1992/0623
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/devenv.c /n/bootesdump/1992/0623/sys/src/9/port/devenv.c
353,408c
memmove(e->value+offset, a, n);
qunlock(eg);
return n;
.
303,351c
if(vend > e->len) {
s = smalloc(offset+n);
memmove(s, e->value, e->len);
if(e->value)
free(e->value);
e->value = s;
e->len = vend;
.
281,301d
275,278c
qlock(eg);
for(e = eg->entries; e; e = e->link)
if(e->path == c->qid.path)
break;
if(e == 0) {
qunlock(eg);
.
273a
.
271,272c
vend = offset+n;
if(vend > Maxenvsize)
.
265,267c
Evalue *e;
.
263a
char *s;
int vend;
.
256,257c
memmove(a, e->value+offset, n);
qunlock(eg);
.
249,252c
if(offset + n > e->len)
n = e->len - offset;
.
243,246c
qlock(eg);
for(e = eg->entries; e; e = e->link)
if(e->path == c->qid.path)
break;
if(e == 0) {
qunlock(eg);
.
241a
.
236,238c
Evalue *e;
.
209,231d
192,193c
*l = e->link;
qunlock(eg);
free(e->name);
if(e->value)
free(e->value);
free(e);
.
186,189c
qlock(eg);
l = &eg->entries;
for(e = *l; e; e = e->link) {
if(e->path == c->qid.path)
break;
l = &e->link;
}
if(e == 0) {
qunlock(eg);
.
184a
.
181c
Evalue *e, **l;
.
163,171c
for(e = eg->entries; e; e = e->link)
if(strcmp(e->name, name) == 0)
error(Einuse);
e = smalloc(sizeof(Evalue));
e->name = smalloc(strlen(name)+1);
strcpy(e->name, name);
e->path = ++eg->path;
e->link = eg->entries;
eg->entries = e;
c->qid = (Qid){e->path, 0};
qunlock(eg);
poperror();
.
146,161c
qlock(eg);
if(waserror()) {
qunlock(eg);
nexterror();
.
143a
.
139,140c
Evalue *e;
.
129c
c->mode = openmode(omode);
.
127c
qunlock(eg);
.
121,125c
if(omode == (OWRITE|OTRUNC) && e->value) {
free(e->value);
e->value = 0;
e->len = 0;
.
113,118c
}
else {
qlock(eg);
for(e = eg->entries; e; e = e->link)
if(e->path == c->qid.path)
break;
if(e == 0) {
qunlock(eg);
.
106,109c
Evalue *e;
eg = u->p->egrp;
.
73,74c
devdir(c, (Qid){e->path, 0}, e->name, e->len, eve, 0666, dp);
qunlock(eg);
return 1;
.
61,71c
qlock(eg);
for(e = eg->entries; e && s; e = e->link)
s--;
if(e == 0) {
qunlock(eg);
return -1;
.
57,58c
Evalue *e;
.
45d
19,41d
12,16c
Maxenvsize = 16300,
.
10c
enum
.
## diffname port/devenv.c 1992/0625
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devenv.c /n/bootesdump/1992/0625/sys/src/9/port/devenv.c
256a
}
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;
}
ne->path = ++to->path;
*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);
}
.
79c
if(c->qid.path & CHDIR) {
.
## diffname port/devenv.c 1992/0711
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/devenv.c /n/bootesdump/1992/0711/sys/src/9/port/devenv.c
111a
USED(perm);
.
30a
USED(tab);
USED(ntab);
.
## diffname port/devenv.c 1992/1107
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devenv.c /n/bootesdump/1992/1107/sys/src/9/port/devenv.c
270a
if(e->name == 0) panic("e->name == 0");
for(p = e->name; *p; p++) if(p - e->name >= NAMELEN) panic("e->name %.*s", NAMELEN, e->name);
.
266a
char *p;
.
## diffname port/devenv.c 1993/0123
## diff -e /n/bootesdump/1992/1107/sys/src/9/port/devenv.c /n/bootesdump/1993/0123/sys/src/9/port/devenv.c
272,273d
267d
## diffname port/devenv.c 1993/0501
## diff -e /n/bootesdump/1993/0123/sys/src/9/port/devenv.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devenv.c
316,324d
239c
eg = up->egrp;
.
203c
eg = up->egrp;
.
158c
eg = up->egrp;
.
120c
eg = up->egrp;
.
81c
eg = up->egrp;
.
65d
34c
eg = up->egrp;
.
## diffname port/devenv.c 1995/0108
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devenv.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devenv.c
259a
}
long
envbwrite(Chan *c, Block *bp, ulong offset)
{
return devbwrite(c, bp, offset);
.
222a
Block*
envbread(Chan *c, long n, ulong offset)
{
return devbread(c, n, offset);
}
.
## diffname port/devenv.c 1995/0726
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devenv.c /n/fornaxdump/1995/0726/sys/src/brazil/port/devenv.c
114d
109c
envcreate(Chan *c, char *name, int omode, ulong)
.
## diffname port/devenv.c 1995/0804
## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/port/devenv.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devenv.c
189d
187c
envclose(Chan*)
.
182d
180c
envwstat(Chan*, char*)
.
31,33d
26c
envgen(Chan *c, Dirtab*, int, int s, Dir *dp)
.
## diffname port/devenv.c 1996/0223
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devenv.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devenv.c
8d
## diffname port/devenv.c 1997/0327
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devenv.c /n/emeliedump/1997/0327/sys/src/brazil/port/devenv.c
318,319c
devtab[c->type]->write(c, eval, strlen(eval), 0);
cclose(c);
.
261,265c
Dev envdevtab = {
devreset,
devinit,
envattach,
devclone,
envwalk,
envstat,
envopen,
envcreate,
envclose,
envread,
devbread,
envwrite,
devbwrite,
envremove,
devwstat,
};
.
216,222c
static long
.
186c
static long
.
175,181c
static void
.
143c
static void
.
104c
static void
.
70c
static Chan*
.
64c
static void
.
52,58c
static int
.
46c
static Chan*
.
14,24c
static int
.
## diffname port/devenv.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devenv.c /n/emeliedump/1997/0408/sys/src/brazil/port/devenv.c
233a
'e',
"env",
.
## diffname port/devenv.c 1998/0319
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devenv.c /n/emeliedump/1998/0319/sys/src/brazil/port/devenv.c
200a
ulong offset = off;
.
195c
envwrite(Chan *c, void *a, long n, vlong off)
.
168a
ulong offset = off;
.
165c
envread(Chan *c, void *a, long n, vlong off)
.
## diffname port/devenv.c 1998/0512
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devenv.c /n/emeliedump/1998/0512/sys/src/brazil/port/devenv.c
118c
.
59c
.
## diffname port/devenv.c 1999/0122
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/devenv.c /n/emeliedump/1999/0122/sys/src/brazil/port/devenv.c
272c
ne->qid.path = ++to->path;
.
230a
e->qid.vers++;
eg->vers++;
.
213,216c
e = envlookup(eg, nil, c->qid.path);
.
176,179c
e = envlookup(eg, nil, c->qid.path);
.
161a
/*
* 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);
.
160c
envclose(Chan *c)
.
151a
eg->vers++;
.
141c
if(e->qid.path == c->qid.path)
.
138d
117c
c->qid = e->qid;
.
114c
e->qid.path = ++eg->path;
e->qid.vers = 0;
eg->vers++;
.
106,108c
if(envlookup(eg, name, -1))
error(Eexist);
.
75c
if((omode & OTRUNC) && e->value) {
e->qid.vers++;
.
67,70c
e = envlookup(eg, nil, c->qid.path);
.
50a
if(c->qid.path & CHDIR)
c->qid.vers = up->egrp->vers;
.
35a
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;
}
.
31c
devdir(c, e->qid, e->name, e->len, eve, 0666, dp);
.
## diffname port/devenv.c 1999/1230
## diff -e /n/emeliedump/1999/0122/sys/src/brazil/port/devenv.c /n/emeliedump/1999/1230/sys/src/9/port/devenv.c
19a
if(s == DEVDOTDOT){
devdir(c, c->qid, "#e", 0, eve, 0775, dp);
return 1;
}
.
## diffname port/devenv.c 2000/0121
## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devenv.c /n/emeliedump/2000/0121/sys/src/9/port/devenv.c
243a
}
.
241,242c
if(e->value){
memmove(s, e->value, e->len);
.
## diffname port/devenv.c 2001/0510
## diff -e /n/emeliedump/2000/0121/sys/src/9/port/devenv.c /n/emeliedump/2001/0510/sys/src/9/port/devenv.c
60c
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);
.
## diffname port/devenv.c 2001/0527
## diff -e /n/emeliedump/2001/0510/sys/src/9/port/devenv.c /n/emeliedump/2001/0527/sys/src/9/port/devenv.c
339c
char buf[2*KNAMELEN];
.
278d
210c
if(c->qid.type & QTDIR)
.
165c
if(c->qid.type & QTDIR)
.
125c
if(c->qid.type != QTDIR)
.
94c
if(c->qid.type & QTDIR) {
.
84c
return devstat(c, db, n, 0, 0, envgen);
.
82c
if(c->qid.type & QTDIR)
.
79,80c
static int
envstat(Chan *c, uchar *db, int n)
.
60,76c
return devwalk(c, nc, name, nname, 0, 0, envgen);
.
57,58c
static Walkqid*
envwalk(Chan *c, Chan *nc, char **name, int nname)
.
36c
/* 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);
.
21c
devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp);
.
15c
envgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
.
## diffname port/devenv.c 2001/1204
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devenv.c /n/emeliedump/2001/1204/sys/src/9/port/devenv.c
181c
* cclose can't fail, so errors from remove will be ignored.
.
## diffname port/devenv.c 2002/0109
## diff -e /n/emeliedump/2001/1204/sys/src/9/port/devenv.c /n/emeliedump/2002/0109/sys/src/9/port/devenv.c
329a
}
/*
* 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 n;
qlock(eg);
if(waserror()) {
qunlock(eg);
nexterror();
}
/* determine size */
n = 0;
for(e=eg->entries; e; e=e->link)
n += strlen(e->name) + e->len + 2;
p = malloc(n + 1);
if(p == nil)
error(Enomem);
q = p;
for(e=eg->entries; e; e=e->link) {
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();
qunlock(eg);
return p;
.
325,326c
snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename);
.
321c
ksetenv(char *ename, char *eval, int conf)
.
316a
static Egrp*
envgrp(Chan *c)
{
if(c->aux == nil)
return up->egrp;
return c->aux;
}
static int
envwriteable(Chan *c)
{
return iseve() || c->aux == nil;
}
.
262a
devshutdown,
.
233c
eg = envgrp(c);
.
199c
eg = envgrp(c);
.
154c
eg = envgrp(c);
.
115c
eg = envgrp(c);
.
84a
if(omode != OREAD && !envwriteable(c))
error(Eperm);
.
79c
eg = envgrp(c);
.
69c
c->qid.vers = envgrp(c)->vers;
.
56c
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;
.
25c
eg = envgrp(c);
.
13a
static Egrp *envgrp(Chan *c);
static int envwriteable(Chan *c);
static Egrp confegrp; /* global environment group containing the kernel configuration */
.
8d
## diffname port/devenv.c 2002/0405
## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devenv.c /n/emeliedump/2002/0405/sys/src/9/port/devenv.c
403c
runlock(eg);
.
380c
runlock(eg);
.
378c
rlock(eg);
.
316c
runlock(from);
.
302c
rlock(from);
.
271c
wunlock(eg);
.
255c
wunlock(eg);
.
252c
wlock(eg);
.
231c
runlock(eg);
.
221c
rlock(eg);
.
218c
rlock(eg);
.
188c
wunlock(eg);
.
182c
wunlock(eg);
.
173c
wlock(eg);
.
155c
wunlock(eg);
.
137c
wunlock(eg);
.
135c
wlock(eg);
.
115c
runlock(eg);
.
106c
runlock(eg);
.
103c
rlock(eg);
.
43c
runlock(eg);
.
36c
runlock(eg);
.
30,31c
rlock(eg);
.
## diffname port/devenv.c 2002/0407
## diff -e /n/emeliedump/2002/0405/sys/src/9/port/devenv.c /n/emeliedump/2002/0407/sys/src/9/port/devenv.c
114c
if(trunc)
wunlock(eg);
else
runlock(eg);
.
108c
if(trunc && e->value) {
.
105c
if(trunc)
wunlock(eg);
else
runlock(eg);
.
102c
if(trunc)
wlock(eg);
else
rlock(eg);
.
99a
trunc = omode & OTRUNC;
.
92a
int trunc;
.
## diffname port/devenv.c 2002/0409
## diff -e /n/emeliedump/2002/0407/sys/src/9/port/devenv.c /n/emeliedump/2002/0409/sys/src/9/port/devenv.c
235c
if(offset > e->len) /* protects against overflow converting vlong to ulong */
n = 0;
else if(offset + n > e->len)
.
## diffname port/devenv.c 2002/0426
## diff -e /n/emeliedump/2002/0409/sys/src/9/port/devenv.c /n/emeliedump/2002/0426/sys/src/9/port/devenv.c
231c
runlock(eg);
.
## diffname port/devenv.c 2003/0325
## diff -e /n/emeliedump/2002/0426/sys/src/9/port/devenv.c /n/emeliedump/2003/0325/sys/src/9/port/devenv.c
404c
for(i=0; i<eg->nent; i++){
e = eg->ent[i];
.
399a
}
.
398c
for(i=0; i<eg->nent; i++){
e = eg->ent[i];
.
388c
int i, n;
.
343a
free(eg->ent);
.
336,338c
if(decref(eg) == 0){
for(i=0; i<eg->nent; i++){
e = eg->ent[i];
.
334c
int i;
Evalue *e;
.
327a
to->nent = from->nent;
.
325,326c
to->ent[i] = ne;
.
319c
if(e->value){
.
315c
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];
.
313d
311c
int i;
Evalue *ne, *e;
.
198a
if(e == 0)
error(Enonexist);
.
190,197d
188c
}
.
184,186c
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++;
.
177c
Evalue *e;
.
175a
int i;
.
161,162c
eg->ent[eg->nent++] = e;
.
157a
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;
}
.
137a
Evalue **ent;
.
46,55d
31,32c
e = 0;
if(name)
e = envlookup(eg, name, -1);
else if(s < eg->nent)
e = eg->ent[s];
.
19c
envgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
.
17a
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;
}
.
|