1{-# LANGUAGE CPP #-}
2-- | Unlifted "System.Process".
3--
4-- @since 0.2.5.0
5
6module UnliftIO.Process (
7  -- * Running sub-processes
8  CreateProcess(..), CmdSpec(..), StdStream(..), ProcessHandle, createProcess
9
10#if MIN_VERSION_process(1,2,1)
11  , createProcess_
12#endif
13
14  , P.shell, P.proc
15
16  -- ** Simpler functions for common tasks
17  , callProcess, callCommand, spawnProcess, spawnCommand
18
19#if MIN_VERSION_process(1,2,3)
20  , readCreateProcess
21#endif
22
23  , readProcess
24
25#if MIN_VERSION_process(1,2,3)
26  , readCreateProcessWithExitCode
27#endif
28
29  , readProcessWithExitCode
30
31#if MIN_VERSION_process(1,4,3)
32  , withCreateProcess
33#endif
34
35  -- ** Related utilities
36  , P.showCommandForUser
37
38  -- * Process completion
39  , waitForProcess, getProcessExitCode, terminateProcess, interruptProcessGroupOf
40
41#if MIN_VERSION_process(1,2,1)
42  -- * Interprocess communication
43  , createPipe
44#endif
45
46#if MIN_VERSION_process(1,4,2)
47  , createPipeFd
48#endif
49  ) where
50
51import Control.Monad.IO.Unlift
52import System.Exit
53import System.IO
54import System.Posix.Internals
55import System.Process
56  ( CmdSpec(..)
57  , CreateProcess(..)
58  , ProcessHandle
59  , StdStream(..)
60  )
61import qualified System.Process as P
62
63-- | Lifted 'P.createProcess'.
64--
65-- @since 0.2.5.0
66{-# INLINE createProcess #-}
67createProcess ::
68     MonadIO m
69  => CreateProcess
70  -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
71createProcess = liftIO . P.createProcess
72
73#if MIN_VERSION_process(1,2,1)
74-- | Lifted 'P.createProcess_'.
75--
76-- @since 0.2.5.0
77{-# INLINE createProcess_ #-}
78createProcess_ ::
79     MonadIO m
80  => String
81  -> CreateProcess
82  -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
83createProcess_ msg proc_ = liftIO (P.createProcess_ msg proc_)
84#endif
85
86-- | Lifted 'P.callProcess'.
87--
88-- @since 0.2.5.0
89{-# INLINE callProcess #-}
90callProcess :: MonadIO m => FilePath -> [String] -> m ()
91callProcess cmd args = liftIO (P.callProcess cmd args)
92
93-- | Lifted 'P.callCommand'.
94--
95-- @since 0.2.5.0
96{-# INLINE callCommand #-}
97callCommand :: MonadIO m => String -> m ()
98callCommand = liftIO . P.callCommand
99
100-- | Lifted 'P.spawnProcess'.
101--
102-- @since 0.2.5.0
103{-# INLINE spawnProcess #-}
104spawnProcess :: MonadIO m => FilePath -> [String] -> m ProcessHandle
105spawnProcess cmd args = liftIO (P.spawnProcess cmd args)
106
107-- | Lifted 'P.spawnCommand'.
108--
109-- @since 0.2.5.0
110{-# INLINE spawnCommand #-}
111spawnCommand :: MonadIO m => String -> m ProcessHandle
112spawnCommand = liftIO . P.spawnCommand
113
114#if MIN_VERSION_process(1,2,3)
115-- | Lifted 'P.readCreateProcess'.
116--
117-- @since 0.2.5.0
118{-# INLINE readCreateProcess #-}
119readCreateProcess :: MonadIO m => CreateProcess -> String -> m String
120readCreateProcess cp input = liftIO (P.readCreateProcess cp input)
121#endif
122
123-- | Lifted 'P.readProcess'.
124--
125-- @since 0.2.5.0
126{-# INLINE readProcess #-}
127readProcess :: MonadIO m => FilePath -> [String] -> String -> m String
128readProcess cmd args input = liftIO (P.readProcess cmd args input)
129
130#if MIN_VERSION_process(1,2,3)
131-- | Lifted 'P.readCreateProcessWithExitCode'.
132--
133-- @since 0.2.5.0
134{-# INLINE readCreateProcessWithExitCode #-}
135readCreateProcessWithExitCode ::
136     MonadIO m => CreateProcess -> String -> m (ExitCode, String, String)
137readCreateProcessWithExitCode cp input =
138  liftIO (P.readCreateProcessWithExitCode cp input)
139#endif
140
141-- | Lifted 'P.readProcessWithExitCode'.
142--
143-- @since 0.2.5.0
144{-# INLINE readProcessWithExitCode #-}
145readProcessWithExitCode ::
146     MonadIO m => FilePath -> [String] -> String -> m (ExitCode, String, String)
147readProcessWithExitCode cmd args input =
148  liftIO (P.readProcessWithExitCode cmd args input)
149
150#if MIN_VERSION_process(1,4,3)
151-- | Unlifted 'P.withCreateProcess'.
152--
153-- @since 0.2.5.0
154{-# INLINE withCreateProcess #-}
155withCreateProcess ::
156     MonadUnliftIO m
157  => CreateProcess
158  -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> m a)
159  -> m a
160withCreateProcess c action =
161  withRunInIO
162    (\u ->
163       P.withCreateProcess
164         c
165         (\stdin_h stdout_h stderr_h proc_h ->
166            u (action stdin_h stdout_h stderr_h proc_h)))
167#endif
168
169-- | Lifted 'P.waitForProcess'.
170--
171-- @since 0.2.5.0
172{-# INLINE waitForProcess #-}
173waitForProcess :: MonadIO m => ProcessHandle -> m ExitCode
174waitForProcess = liftIO . P.waitForProcess
175
176-- | Lifted 'P.getProcessExitCode'.
177--
178-- @since 0.2.5.0
179{-# INLINE getProcessExitCode #-}
180getProcessExitCode :: MonadIO m => ProcessHandle -> m (Maybe ExitCode)
181getProcessExitCode = liftIO . P.getProcessExitCode
182
183-- | Lifted 'P.terminateProcess'.
184--
185-- @since 0.2.5.0
186{-# INLINE terminateProcess #-}
187terminateProcess :: MonadIO m => ProcessHandle -> m ()
188terminateProcess = liftIO . P.terminateProcess
189
190-- | Lifted 'P.interruptProcessGroupOf'.
191--
192-- @since 0.2.5.0
193{-# INLINE interruptProcessGroupOf #-}
194interruptProcessGroupOf :: MonadIO m => ProcessHandle -> m ()
195interruptProcessGroupOf = liftIO . P.interruptProcessGroupOf
196
197#if MIN_VERSION_process(1,2,1)
198-- | Lifted 'P.createPipe'.
199--
200-- @since 0.2.5.0
201{-# INLINE createPipe #-}
202createPipe :: MonadIO m => m (Handle, Handle)
203createPipe = liftIO P.createPipe
204#endif
205
206#if MIN_VERSION_process(1,4,2)
207-- | Lifted 'P.createPipeFd'.
208--
209-- @since 0.2.5.0
210{-# INLINE createPipeFd #-}
211createPipeFd :: MonadIO m => m (FD, FD)
212createPipeFd = liftIO P.createPipeFd
213#endif
214