Skip to content

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 -
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information