Handle garbage collection yields wrong exit code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Main where

import Control.Concurrent (threadDelay)
import System.Process
import System.IO
import System.Exit


run :: FilePath -> [String] -> IO (Handle, Handle, Handle, ProcessHandle)
run cmd args = do
  r@(i, o, e, p) <- runInteractiveProcess cmd args Nothing Nothing
  getProcessExitCode p >>= \me -> case me of
    Just (ExitFailure 127) -> error $ "command not found: " ++ show cmd
    _                      -> do
      mapM_ (flip hSetBuffering LineBuffering) [i, o, e]
      return r


main = do
  (i, o, e, p) <- run "./test" []

  putStrLn "spawned"
  threadDelay 1100000
  putStrLn "waited"

  print =<< getProcessExitCode p

  -- If you comment these away, the above always returns Just ExitSuccess
  -- print =<< hGetContents o
  -- print =<< hGetContents e


{- test.c:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
  sleep (1);
  printf ("some stdout\n");
  fprintf (stderr, "some stderr\n");
  fflush (stdout);
  fflush (stderr);
  return 2;
}

-}
15:13: Warning: Use section
Found:
(flip hSetBuffering LineBuffering)
Why not:
(`hSetBuffering` LineBuffering)