Ticket #4192: pipe.hs

File pipe.hs, 1.8 KB (added by golubovsky, 3 years ago)

Source code of the process piping function

Line 
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
9runPipe :: 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
16runPipe ins outs [] = return (Nothing, Nothing, [])
17
18runPipe 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
23runPipe 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
31piper :: [CreateProcess] 
32      -> [ProcessHandle] 
33      -> Maybe Handle
34      -> Maybe Handle
35      -> IO (Maybe Handle, Maybe Handle, [ProcessHandle])
36
37piper [] phs pin pend = return (pin, pend, phs)
38
39piper (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
44piper (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