{-# LANGUAGE CPP, ScopedTypeVariables #-} -- | Module for system like things in base/directory/etc, or could plausibly be added. module General.System(module General.System, module X) where import System.Process as X import System.Directory as X import System.Environment as X import System.Exit as X import System.IO as X import System.Mem as X (performGC) import General.Base import qualified Control.Exception as E #if __GLASGOW_HASKELL__ >= 612 import GHC.IO.Handle(hDuplicate,hDuplicateTo) #endif #ifndef mingw32_HOST_OS import System.Posix(setFileCreationMask) #else setFileCreationMask :: Int -> IO Int setFileCreationMask _ = return 0 #endif isWindows :: Bool #ifdef mingw32_HOST_OS isWindows = True #else isWindows = False #endif removeFile_ x = removeFile x `E.catch` \(_ :: E.SomeException) -> return () withDirectory dir cmd = E.bracket (do x <- getCurrentDirectory; setCurrentDirectory dir; return x) setCurrentDirectory (const cmd) withModeGlobalRead :: IO () -> IO () withModeGlobalRead act = E.bracket (setFileCreationMask 0o022) (\x -> setFileCreationMask x >> return ()) (const act) -- FIXME: This could use a lot more bracket calls! captureOutput :: IO () -> IO (Maybe String) #if __GLASGOW_HASKELL__ < 612 captureOutput act = return Nothing #else captureOutput act = do tmp <- getTemporaryDirectory (f,h) <- openTempFile tmp "hoogle" sto <- hDuplicate stdout ste <- hDuplicate stderr hDuplicateTo h stdout hDuplicateTo h stderr hClose h act hDuplicateTo sto stdout hDuplicateTo ste stderr res <- readFile' f removeFile f return $ Just res #endif system_ :: String -> IO () system_ x = do res <- system x when (res /= ExitSuccess) $ error $ "System command failed: " ++ x exitMessage :: [String] -> IO a exitMessage msg = putStr (unlines msg) >> exitFailure getEnvVar :: String -> IO (Maybe String) getEnvVar x = E.catch (fmap Just $ getEnv x) (\(x :: E.SomeException) -> return Nothing)