From 98363cb27276b29ff3795d1ef93e4ea2e82e106f Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 22 Nov 2015 02:39:57 +0100 Subject: 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. --- sys/src/9/port/devenv.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'sys/src') 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); -- cgit v1.2.3