| 1 | -- | Pipe processes together. Two StdStream's must be supplied: for pipeline's |
|---|
| 2 | -- stdin and stdout. Stderr's of all processes are as set in the process creation |
|---|
| 3 | -- descriptors. List of process handles is returned as well as handles for pipe ends. |
|---|
| 4 | -- To wait on all processes in the pipe: mapM_ waitForProcess ps where ps is the list |
|---|
| 5 | -- of process handles returned by this function. To supply some text to the beginning |
|---|
| 6 | -- of the pipeline, provide CreatePipe as the first argument, then preferrably in a |
|---|
| 7 | -- forked thread, hPutStrLn this text into the returned handle. |
|---|
| 8 | |
|---|
| 9 | runPipe :: StdStream -- stdin |
|---|
| 10 | -> StdStream -- stdout |
|---|
| 11 | -> [CreateProcess] -- processes (start at left, end at right) |
|---|
| 12 | -> IO (Maybe Handle -- pipe in |
|---|
| 13 | ,Maybe Handle -- pipe out |
|---|
| 14 | ,[ProcessHandle]) -- same order as in the input list of descriptors |
|---|
| 15 | |
|---|
| 16 | runPipe ins outs [] = return (Nothing, Nothing, []) |
|---|
| 17 | |
|---|
| 18 | runPipe ins outs [p] = do |
|---|
| 19 | let p' = p {std_in = ins, std_out = outs} |
|---|
| 20 | (pin, pout, _, ph) <- createProcess p' |
|---|
| 21 | return (pin, pout, [ph]) |
|---|
| 22 | |
|---|
| 23 | runPipe ins outs (pstart:ps) = do |
|---|
| 24 | let pstart' = pstart {std_in = ins} |
|---|
| 25 | prev@(pend:rps) = reverse (pstart':ps) |
|---|
| 26 | pend' = pend {std_out = outs} |
|---|
| 27 | piper (pend':rps) [] Nothing Nothing |
|---|
| 28 | |
|---|
| 29 | -- This function is not exported. |
|---|
| 30 | |
|---|
| 31 | piper :: [CreateProcess] |
|---|
| 32 | -> [ProcessHandle] |
|---|
| 33 | -> Maybe Handle |
|---|
| 34 | -> Maybe Handle |
|---|
| 35 | -> IO (Maybe Handle, Maybe Handle, [ProcessHandle]) |
|---|
| 36 | |
|---|
| 37 | piper [] phs pin pend = return (pin, pend, phs) |
|---|
| 38 | |
|---|
| 39 | piper (p:ps) [] Nothing Nothing = do |
|---|
| 40 | let p' = p {std_in = CreatePipe} |
|---|
| 41 | (pin, pend, _, ph) <- createProcess p' |
|---|
| 42 | piper ps [ph] pin pend |
|---|
| 43 | |
|---|
| 44 | piper (p:ps) phs pin pend = do |
|---|
| 45 | let p' = p {std_in = CreatePipe, std_out = UseHandle (fromJust pin)} |
|---|
| 46 | (pin', _, _, ph) <- createProcess p' |
|---|
| 47 | piper ps (ph:phs) pin' pend |
|---|
| 48 | |
|---|