ref: 3699a6c3daf7648653b3e4936f39bc6061331446
dir: /libstd/spork.myr/
use "die.use" use "execvp.use" use "fmt.use" use "result.use" use "syswrap.use" pkg std = const spork : (cmd : byte[:][:] -> result((pid, fd, fd), int)) const sporkfd : (cmd : byte[:][:], infd : fd, outfd : fd -> result(pid, int)) ;; const spork = {cmd var infds :fd[2], outfds : fd[2] var err /* open up pipes */ err = pipe(&infds) if err != 0 -> `Fail (-err castto(int)) ;; err = pipe(&outfds) if err != 0 -> `Fail (-err castto(int)) ;; match sporkfd(cmd, infds[0] castto(fd), outfds[1] castto(fd)) | `Ok pid: /* close unused fd ends */ close(infds[0]); close(outfds[1]); -> `Ok (pid, infds[1], outfds[0]) | `Fail m: -> `Fail m ;; } const sporkfd = {cmd, infd, outfd var pid pid = fork() /* error */ if pid == -1 -> `Fail -1 /* child */ elif pid == 0 /* stdin/stdout for our communication. */ if dup2(infd castto(fd), 0) != 0 fatal("unable to set stdin\n") ;; if dup2(outfd castto(fd), 1) != 1 fatal("unable to set stdout\n") ;; close(infd) close(outfd) execvp(cmd[0], cmd) < 0 fatal("failed to exec {}\n", cmd[0]) /* parent */ else -> `Ok pid ;; }