static void envremove(Chan *c) { int i; Egrp *eg; Evalue *e; if(c->qid.type & QTDIR || !envwriteable(c)) error(Eperm); eg = envgrp(c); wlock(eg); e = nil; 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); if(e == nil) error(Enonexist); free(e->name); free(e->value); free(e); }
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; }
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; }
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; }
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); }