shithub: mc

Download patch

ref: 937e5e744d303c722c7782209f94c706b8f4c22a
parent: ff614fa9710df61b6607ec9c38d6d909f5aa2d35
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Dec 16 18:01:34 EST 2016

Implement filterfd().

	We can push a filter onto an fd.

--- a/lib/std/spork.myr
+++ b/lib/std/spork.myr
@@ -8,6 +8,7 @@
 pkg std =
 	const spork	: (cmd : byte[:][:]	-> result((pid, fd, fd), errno))
 	const espork	: (cmd : byte[:][:]	-> result((pid, fd, fd, fd), errno))
+	const filterfd	: (fd : fd, cmd  : byte[:][:] -> result(pid, errno))
 ;;
 
 const spork = {cmd
@@ -65,6 +66,26 @@
 	;;
 }
 
+const filterfd = {fd, cmd
+	var outfds : fd[2]
+	var err
+
+	err = pipe(&outfds)
+	if err != Enone
+		-> `Err err
+	;;
+
+	match sporkfd(cmd, [fd, -1], outfds, [-1, 2])
+	| `Ok pid:
+		dup2(outfds[0], fd)
+		close(outfds[0]);
+		close(outfds[1]);
+		-> `Ok pid
+	| `Err e:
+		-> `Err e
+	;;
+}
+
 const sporkfd = {cmd, infds, outfds, errfds
 	var pid, err
 
@@ -71,6 +92,13 @@
 	pid = fork()
 	/* error  */
 	if pid < 0
+		/* we don't want to leak the pipe fds on error */
+		close(infds[0]);
+		close(infds[1]);
+		close(outfds[0]);
+		close(outfds[1]);
+		close(errfds[0]);
+		close(errfds[1]);
 		-> `Err (pid : errno)
 	/* child */
 	elif pid == 0