x=foo; @{x=bar}; echo `{cat /env/x} yields "foo" but
x=foo; echo; @{x=bar}; echo `{cat /env/x} yields "bar" the problem is that the environment variables are only flushed to /env on exec, but not on fork. in the first example, after executing the subshell, x is still marked as "modified" by us and the cat/echo will cause the old value to be flushed and the changed value from the subshell be overridden. havntfork.c does flush the variables on fork tho. i think it would be more consistent todo this for havefork.c as well. is there a good reason not to? the following patch seems to work fine: diff -r 5a4a76cd3657 sys/src/cmd/rc/havefork.c --- a/sys/src/cmd/rc/havefork.c Mon Aug 19 16:07:07 2013 +0200 +++ b/sys/src/cmd/rc/havefork.c Mon Aug 19 21:31:06 2013 +0200 @@ -12,10 +12,12 @@ int null = open("/dev/null", 0); int pid; char npid[10]; + if(null<0){ Xerror("Can't open /dev/null\n"); return; } + Updenv(); switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){ case -1: close(null); @@ -45,10 +47,12 @@ int lfd = p->code[pc++].i; int rfd = p->code[pc++].i; int pfd[2]; + if(pipe(pfd)<0){ Xerror("can't get pipe"); return; } + Updenv(); switch(forkid = fork()){ case -1: Xerror("try again"); @@ -91,6 +95,7 @@ Xerror("can't make pipe"); return; } + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); @@ -152,6 +157,7 @@ char name[40]; int pfd[2]; int sidefd, mainfd; + if(pipe(pfd)<0){ Xerror("can't get pipe"); return; @@ -164,6 +170,7 @@ sidefd = pfd[PRD]; mainfd = pfd[PWR]; } + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); @@ -191,6 +198,8 @@ Xsubshell(void) { int pid; + + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); -- cinap