ref: 1779c6b7aedf6bb7665b8f650f37958340f3177c
parent: c8397e67b2c1f2a994c4399e0654fe145b97629a
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 23 18:36:57 EDT 2018
Add sporkdir variants. This allows running a command in a directory without modifying the global state of the program. This is useful in multithreaded programs that launch subcommands.
--- a/lib/std/spork.myr
+++ b/lib/std/spork.myr
@@ -10,6 +10,8 @@
const run : (cmd : byte[:][:] -> waitstatus)
const spork : (cmd : byte[:][:] -> result((pid, fd, fd), errno))
const espork : (cmd : byte[:][:] -> result((pid, fd, fd, fd), errno))
+ const sporkdir : (cmd : byte[:][:], dir : byte[:] -> result((pid, fd, fd), errno))
+ const esporkdir : (cmd : byte[:][:], dir : byte[:] -> result((pid, fd, fd, fd), errno))
const filterfd : (fd : fd, cmd : byte[:][:] -> result(pid, errno))
;;
@@ -28,8 +30,15 @@
;;
}
-
const spork = {cmd
+ -> sporkdir(cmd, "")
+}
+
+const espork = {cmd
+ -> esporkdir(cmd, "")
+}
+
+const sporkdir = {cmd, dir
var infds : fd[2], outfds : fd[2]
var err
@@ -46,7 +55,7 @@
goto sporkerr
;;
- match sporkfd(cmd, infds, outfds, [-1, 2])
+ match sporkfd(cmd, dir, infds, outfds, [-1, 2])
| `Ok pid:
/* close unused fd ends */
close(infds[0]);
@@ -64,7 +73,7 @@
-> `Err err
}
-const espork = {cmd
+const esporkdir = {cmd, dir
var infds : fd[2], outfds : fd[2], errfds : fd[2]
var err
@@ -86,7 +95,7 @@
goto sporkerr
;;
- match sporkfd(cmd, infds, outfds, errfds)
+ match sporkfd(cmd, dir, infds, outfds, errfds)
| `Ok pid:
/* close unused fd ends */
close(infds[0]);
@@ -117,7 +126,7 @@
-> `Err err
;;
- match sporkfd(cmd, [fd, -1], outfds, [-1, 2])
+ match sporkfd(cmd, "", [fd, -1], outfds, [-1, 2])
| `Ok pid:
dup2(outfds[0], fd)
close(outfds[0]);
@@ -128,7 +137,7 @@
;;
}
-const sporkfd = {cmd, infds, outfds, errfds
+const sporkfd = {cmd, dir, infds, outfds, errfds
var pid
pid = fork()
@@ -181,6 +190,9 @@
close(outfds[0])
close(errfds[0])
+ if dir.len != 0 && !chdir(dir)
+ std.die("could not chdir")
+ ;;
execvp(cmd[0], cmd)
/* if fork succeeds, we never return */
suicide()