-- open IO.Process def usingIO {α} (x : IO α) : IO α := x #eval usingIO do let child ← spawn { cmd := "sh", args := #["-c", "exit 1"] }; child.wait #eval usingIO do let child ← spawn { cmd := "sh", args := #["-c", "echo ho!"], stdout := Stdio.piped }; child.wait >>= IO.println; child.stdout.readToEnd #eval usingIO do let child ← spawn { cmd := "head", args := #["-n1"], stdin := Stdio.piped, stdout := Stdio.piped }; child.stdin.putStrLn "hu!"; child.stdin.flush; discard $ child.wait; child.stdout.readToEnd #eval usingIO do -- produce enough output to fill both pipes on all platforms let out ← output { cmd := "sh", args := #["-c", "printf '%100000s' >& 2; printf '%100001s'"] }; IO.println out.stdout.length; IO.println out.stderr.length #eval usingIO do -- With a non-empty stdin, cat would wait on input forever let child ← spawn { cmd := "sh", args := #["-c", "cat"], stdin := Stdio.null }; child.wait #eval usingIO do let child ← spawn { cmd := "sh", args := #["-c", "echo nullStdout"], stdout := Stdio.null }; child.wait #eval usingIO do let child ← spawn { cmd := "sh", args := #["-c", "echo nullStderr >& 2"], stderr := Stdio.null }; child.wait #eval usingIO do let lean ← IO.Process.spawn { cmd := "lean", args := #["--stdin"] stdin := IO.Process.Stdio.piped stdout := IO.Process.Stdio.piped } let (stdin, lean) ← lean.takeStdin stdin.putStr "#exit\n" let _ ← lean.wait lean.stdout.readToEnd #eval usingIO do let child ← spawn { cmd := "sh", args := #["-c", "cat"], stdin := .piped, stdout := .piped } IO.println (← child.tryWait) -- We take stdin in here such that it is closed automatically by dropping the object right away. -- This will kill the `cat` process. let (stdin, child) ← child.takeStdin IO.sleep 1000 child.tryWait