summaryrefslogtreecommitdiff
path: root/lib/ProcessUtils.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2016-04-24 18:43:00 -0400
committerjoe <joe@jerkface.net>2016-04-24 18:43:00 -0400
commitfbf425fbef1c1e60fcdddfbd9b25976162725f97 (patch)
treeb3877b56401f22efed0486ae10950af3a5ebadf8 /lib/ProcessUtils.hs
parent7d8798f60b11973fd17d85caf3da2e8473842d2a (diff)
Refactored build of executable and library.
Diffstat (limited to 'lib/ProcessUtils.hs')
-rw-r--r--lib/ProcessUtils.hs45
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/ProcessUtils.hs b/lib/ProcessUtils.hs
new file mode 100644
index 0000000..4e3ac38
--- /dev/null
+++ b/lib/ProcessUtils.hs
@@ -0,0 +1,45 @@
1module ProcessUtils
2 ( ExitCode(ExitFailure,ExitSuccess)
3 , systemEnv
4 ) where
5
6import GHC.IO.Exception ( ioException, IOErrorType(..) )
7import System.Process
8import System.Posix.Signals
9import System.Process.Internals (runGenProcess_,defaultSignal)
10import System.Environment
11import Data.Maybe ( isNothing )
12import System.IO.Error ( mkIOError, ioeSetErrorString )
13import System.Exit ( ExitCode(..) )
14
15
16-- | systemEnv
17-- This is like System.Process.system except that it lets you set
18-- some environment variables.
19systemEnv :: [(String, String)] -> String -> IO ExitCode
20systemEnv _ "" =
21 ioException (ioeSetErrorString (mkIOError InvalidArgument "system" Nothing Nothing) "null command")
22systemEnv vars cmd = do
23 env0 <- getEnvironment
24 let env1 = filter (isNothing . flip lookup vars . fst) env0
25 env = vars ++ env1
26 syncProcess "system" $ (shell cmd) {env=Just env}
27 where
28 -- This is a non-exported function from System.Process
29 syncProcess fun c = do
30 -- The POSIX version of system needs to do some manipulation of signal
31 -- handlers. Since we're going to be synchronously waiting for the child,
32 -- we want to ignore ^C in the parent, but handle it the default way
33 -- in the child (using SIG_DFL isn't really correct, it should be the
34 -- original signal handler, but the GHC RTS will have already set up
35 -- its own handler and we don't want to use that).
36 old_int <- installHandler sigINT Ignore Nothing
37 old_quit <- installHandler sigQUIT Ignore Nothing
38 (_,_,_,p) <- runGenProcess_ fun c
39 (Just defaultSignal) (Just defaultSignal)
40 r <- waitForProcess p
41 _ <- installHandler sigINT old_int Nothing
42 _ <- installHandler sigQUIT old_quit Nothing
43 return r
44
45