git: 9front

Download patch

ref: da6bd0c1e2a342db9ff9616390a1fc982ca1711f
parent: b8d5b5ebfd8b340dddd7e120a0ef9fd3675d40da
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri Oct 4 12:08:19 EDT 2013

mothra: run page in own note group, close unneeded filedescriptors after forking

running page in own note group avoids killing it when we
exit mothra.

copypaste dupfds() function from page and use it to close
unneeded file descriptors.

--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -748,14 +748,12 @@
 }
 
 void filter(char *cmd, int fd){
-	switch(rfork(RFFDG|RFPROC|RFMEM|RFNOWAIT)){
+	switch(rfork(RFFDG|RFPROC|RFMEM|RFNOWAIT|RFNOTEG)){
 	case -1:
 		message("Can't fork!");
 		break;
 	case 0:
-		close(0);
-		dup(fd, 0);
-		close(fd);
+		dupfds(fd, 1, 2, -1);
 		execl("/bin/rc", "rc", "-c", cmd, 0);
 		_exits(0);
 	}
@@ -796,6 +794,32 @@
 	plrtfree(tt);
 }
 
+void
+dupfds(int fd, ...)
+{
+	int mfd, n, i;
+	va_list arg;
+	Dir *dir;
+
+	va_start(arg, fd);
+	for(mfd = 0; fd >= 0; fd = va_arg(arg, int), mfd++)
+		if(fd != mfd)
+			if(dup(fd, mfd) < 0)
+				sysfatal("dup: %r");
+	va_end(arg);
+	if((fd = open("/fd", OREAD)) < 0)
+		sysfatal("open: %r");
+	n = dirreadall(fd, &dir);
+	for(i=0; i<n; i++){
+		if(strstr(dir[i].name, "ctl"))
+			continue;
+		fd = atoi(dir[i].name);
+		if(fd >= mfd)
+			close(fd);
+	}
+	free(dir);
+}
+
 int pipeline(char *cmd, int fd)
 {
 	int pfd[2];
@@ -806,22 +830,19 @@
 		werrstr("pipeline for %s failed: %r", cmd);
 		return -1;
 	}
-	switch(fork()){
+	switch(rfork(RFFDG|RFPROC|RFMEM|RFNOWAIT)){
 	case -1:
 		close(pfd[0]);
 		close(pfd[1]);
 		goto Err;
 	case 0:
-		dup(fd, 0);
-		dup(pfd[0], 1);
-		close(pfd[0]);
-		close(pfd[1]);
+		dupfds(fd, pfd[1], 2, -1);
 		execl("/bin/rc", "rc", "-c", cmd, 0);
 		_exits(0);
 	}
-	close(pfd[0]);
 	close(fd);
-	return pfd[1];
+	close(pfd[1]);
+	return pfd[0];
 }
 
 char*
--- a/sys/src/cmd/mothra/mothra.h
+++ b/sys/src/cmd/mothra/mothra.h
@@ -87,6 +87,7 @@
 void getpix(Rtext *, Www *);
 ulong countpix(void *p);
 void freepix(void *p);
+void dupfds(int fd, ...);
 int pipeline(char *, int);
 void getfonts(void);
 void *emalloc(int);
--