Stephan Tobies wrote:
> [...] So what I want to do is, to start a subprocess which receives
> some input from its stdin which is piped into by the main process.
> 
> The problem: There is no fdToHandle, is there???

It's in the Posix library.  But when you are forking another process,
you should be carefule closing the right file descriptors.  Otherwise
EOF ist not seen on the other end of a pipe, because both processes
write on the *same* pipe.  To make this a little clearer, here's my
helper function for connecting a Haskell program to another program
via a pipe (we use this for interfacing Haskell to the graph layout
program daVinci):

import IO(stderr,Handle,BufferMode(..),hSetBuffering,hGetLine,hPutStrLn)
import Posix(forkProcess,executeFile,Fd,createPipe,dupTo,fdClose,
             intToFd,fdToHandle,handleToFd)
import PosixUtil(ProcessID)
import Directory(setCurrentDirectory)

runPiped :: FilePath                        -- Command
         -> [String]                        -- Arguments
         -> Maybe [(String, String)]        -- Environment
         -> Maybe FilePath                  -- Working directory    
         -> IO (ProcessID,Handle,Handle)    -- (pid, fromChild, toChild)
runPiped path args env dir = 
   do (rd1,wd1) <- createPipe
      (rd2,wd2) <- createPipe
      maybePid <- forkProcess
      case maybePid of
         -- child
         Nothing   -> do case dir of
                            Nothing -> return ()
                            Just x  -> setCurrentDirectory x
                         dupTo rd1 (intToFd 0)
                         dupTo wd2 (intToFd 1)
                         fdClose rd1
                         fdClose wd1
                         fdClose rd2
                         fdClose wd2
                         executeFile path True args env
                         fail (userError "runPiped")
         -- parent
         Just pid  -> do fdClose rd1
                         fdClose wd2
                         fromChild <- fdToHandle rd2
                         toChild   <- fdToHandle wd1
                         hSetBuffering fromChild LineBuffering
                         hSetBuffering toChild   LineBuffering
                         return (pid, fromChild, toChild)

-- Strange: hClose does *not* really close a file from fdToHandle!!
-- No idea why. So we have to use this function...
reallyClose :: Handle -> IO ()
reallyClose handle = do fd <- handleToFd handle
                        fdClose fd

-- 
Sven Panne                                        Tel.: +49/89/2178-2235
LMU, Institut fuer Informatik                     FAX : +49/89/2178-2211
LFE Programmier- und Modellierungssprachen              Oettingenstr. 67
mailto:[EMAIL PROTECTED]            D-80538 Muenchen
http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne

Reply via email to