runInteractiveProcess and closed stdin.
Hello,
The System.Process.runInteractiveProcess function
doesn't seem to provide the child process with a stdin
handle when the parent's stdin is closed. Below is a
small example:
import System.Process
import Control.Concurrent
import System.IO
main = do
hClose stdin -- everything works as expected if the
handle isn't closed.
putStrLn "Running cat ..."
(inp, out, err, pid) <- runInteractiveProcess "cat"
[] Nothing Nothing
forkIO (hPutStrLn inp "foo" >> hClose inp)
forkIO (putStrLn =<< hGetContents out)
forkIO (putStrLn =<< hGetContents err)
-- Don't want to deal with waitForProcess and
-threaded right now.
threadDelay 1000000
return ()
Running this example produces the error
% ghc Run.hs -o run
% ./run
Running cat ...
cat: -: Bad file descriptor
cat: closing standard input: Bad file descriptor
I think the bug is in
fptools/libraries/base/cbits/runProcess.c:
//...
pipe(fdStdInput);
//...
dup2 (fdStdInput[0], STDIN_FILENO);
/...
close(fdStdInput[0]);
//...
pipe(...) will assign the lowest available file
descriptors, i.e. 0 if stdin is closed. The dup2 won't
do anything, since src and dest fds are identical, so
close(...) will close the child's stdin immediately.
% uname -a
Linux mthomas 2.6.12 #2 Thu Jul 21 07:51:44 EDT 2005
i686 GNU/Linux
% ghc --version
The Glorious Glasgow Haskell Compilation System,
version 6.5.20050728
Thanks,
-- Thomas Jäger
Edited by Ian Lynagh -