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