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.
@@ -10,6 +10,8 @@ pkg std =
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 run = {cmd
;;
}
-
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 @@ const spork = {cmd
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 @@ const spork = {cmd
-> `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 @@ const espork = {cmd
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 @@ const filterfd = {fd, cmd
-> `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 filterfd = {fd, cmd
;;
}
-const sporkfd = {cmd, infds, outfds, errfds
+const sporkfd = {cmd, dir, infds, outfds, errfds
var pid
pid = fork()
@@ -181,6 +190,9 @@ const sporkfd = {cmd, infds, outfds, errfds
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()
