With the recent unification of server and cmdline processing, `IO.Process` tests that previously broke the server because they directly wrote to stdout are now flaky on the cmdline because elaboration and reporting are happening in separate threads. By removing direct writes to stdout, the race condition is removed and the file can actually be edited in the language server as well again.
66 lines
2 KiB
Text
66 lines
2 KiB
Text
--
|
||
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
|
||
let child ← spawn { cmd := "true", stdin := Stdio.piped };
|
||
discard $ child.wait;
|
||
child.stdin.putStrLn "ha!";
|
||
child.stdin.flush <|> IO.println "flush of broken pipe failed"
|
||
|
||
#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
|