git: 9front

Download patch

ref: cb9ba93026a294607139f6edd19a33ef8182e406
parent: af492155d39f1ea88afc7da47e754ab7a116bb16
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Aug 20 19:56:15 EDT 2013

rc: flush environment variables (update /env) before fork

on races... normal forks will all share the /env environment but
not the in memory variables of rc. so when we would normally fork
whoever does an exec (flush) first will override what the values of the
/env variables are, *independent* of the variables that where
actually modified *in* the process.

when we flush *before* fork, then at least both processes start out
with marked clean in memory variables and the processes will flush
only the things they actually change.

--- a/sys/src/cmd/rc/havefork.c
+++ b/sys/src/cmd/rc/havefork.c
@@ -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");
--