| 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 | } | |