summaryrefslogtreecommitdiff
path: root/sys/src/9
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-11-22 02:39:57 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-11-22 02:39:57 +0100
commit98363cb27276b29ff3795d1ef93e4ea2e82e106f (patch)
treedf142a47c3c630e8f9915c15df2a893a37462877 /sys/src/9
parent38e1e5272fc9c66a00d702246813135452819ffe (diff)
devenv: fix ORCLOSE handling
when opening a /env file ORCLOSE, and the process exits, envgrp() would return nil can crash in envremove() because procexit will have set up->egrp to nil before calling closefgrp(). the solution is to capture the environment on open, keeping a reference in Chan.aux, so it doesnt matter on what process the close happens and a env chan will always refer to its original environment group.
Diffstat (limited to 'sys/src/9')
-rw-r--r--sys/src/9/port/devenv.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/sys/src/9/port/devenv.c b/sys/src/9/port/devenv.c
index 728df1f47..4e12ad514 100644
--- a/sys/src/9/port/devenv.c
+++ b/sys/src/9/port/devenv.c
@@ -132,8 +132,10 @@ envopen(Chan *c, int omode)
runlock(eg);
}
c->mode = openmode(omode);
- c->flag |= COPEN;
+ incref(eg);
+ c->aux = eg;
c->offset = 0;
+ c->flag |= COPEN;
return c;
}
@@ -181,7 +183,8 @@ envcreate(Chan *c, char *name, int omode, ulong)
wunlock(eg);
poperror();
-
+ incref(eg);
+ c->aux = eg;
c->offset = 0;
c->mode = omode;
c->flag |= COPEN;
@@ -214,13 +217,19 @@ envremove(Chan *c)
static void
envclose(Chan *c)
{
- /*
- * cclose can't fail, so errors from remove will be ignored.
- * since permissions aren't checked,
- * envremove can't not remove it if its there.
- */
- if(c->flag & CRCLOSE)
- envremove(c);
+ if(c->flag & COPEN){
+ /*
+ * cclose can't fail, so errors from remove will be ignored.
+ * since permissions aren't checked,
+ * envremove can't not remove it if its there.
+ */
+ if(c->flag & CRCLOSE && !waserror()){
+ envremove(c);
+ poperror();
+ }
+ closeegrp((Egrp*)c->aux);
+ c->aux = nil;
+ }
}
static long
@@ -350,7 +359,7 @@ closeegrp(Egrp *eg)
{
Evalue *e, *ee;
- if(decref(eg) == 0){
+ if(decref(eg) == 0 && eg != &confegrp){
e = eg->ent;
for(ee = e + eg->nent; e < ee; e++){
free(e->name);