{-# LINE 1 "System/Posix/Env.hsc" #-}
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE Safe #-}
module System.Posix.Env (
getEnv
, getEnvDefault
, getEnvironmentPrim
, getEnvironment
, setEnvironment
, putEnv
, setEnv
, unsetEnv
, clearEnv
) where
import Foreign hiding (void)
import Foreign.C.Error (throwErrnoIfMinus1_)
import Foreign.C.Types
import Foreign.C.String
import Control.Monad
import Data.Maybe (fromMaybe)
import System.Posix.Internals
import qualified System.Posix.Env.Internal as Internal
getEnv ::
String ->
IO (Maybe String)
getEnv :: String -> IO (Maybe String)
getEnv String
name = do
CString
litstring <- String -> (CString -> IO CString) -> IO CString
forall a. String -> (CString -> IO a) -> IO a
withFilePath String
name CString -> IO CString
c_getenv
if CString
litstring CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
/= CString
forall a. Ptr a
nullPtr
then String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> IO String -> IO (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CString -> IO String
peekFilePath CString
litstring
else Maybe String -> IO (Maybe String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
getEnvDefault ::
String ->
String ->
IO String
getEnvDefault :: String -> String -> IO String
getEnvDefault String
name String
fallback = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
fallback (Maybe String -> String) -> IO (Maybe String) -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
getEnv String
name
foreign import ccall unsafe "getenv"
c_getenv :: CString -> IO CString
getEnvironmentPrim :: IO [String]
getEnvironmentPrim :: IO [String]
getEnvironmentPrim = IO [CString]
Internal.getEnvironmentPrim IO [CString] -> ([CString] -> IO [String]) -> IO [String]
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CString -> IO String) -> [CString] -> IO [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM CString -> IO String
peekFilePath
getEnvironment :: IO [(String,String)]
getEnvironment :: IO [(String, String)]
getEnvironment = do
[String]
env <- IO [String]
getEnvironmentPrim
[(String, String)] -> IO [(String, String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(String, String)] -> IO [(String, String)])
-> [(String, String)] -> IO [(String, String)]
forall a b. (a -> b) -> a -> b
$ (String -> (String, String)) -> [String] -> [(String, String)]
forall a b. (a -> b) -> [a] -> [b]
map ((String, String) -> (String, String)
dropEq((String, String) -> (String, String))
-> (String -> (String, String)) -> String -> (String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
(==) Char
'='))) [String]
env
where
dropEq :: (String, String) -> (String, String)
dropEq (String
x,Char
'=':String
ys) = (String
x,String
ys)
dropEq (String
x,String
_) = String -> (String, String)
forall a. HasCallStack => String -> a
error (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ String
"getEnvironment: insane variable " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x
setEnvironment ::
[(String,String)] ->
IO ()
setEnvironment :: [(String, String)] -> IO ()
setEnvironment [(String, String)]
env = do
IO ()
clearEnv
[(String, String)] -> ((String, String) -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(String, String)]
env (((String, String) -> IO ()) -> IO ())
-> ((String, String) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(String
key,String
value) ->
String -> String -> Bool -> IO ()
setEnv String
key String
value Bool
True
unsetEnv :: String -> IO ()
{-# LINE 95 "System/Posix/Env.hsc" #-}
unsetEnv :: String -> IO ()
{-# LINE 96 "System/Posix/Env.hsc" #-}
unsetEnv name = withFilePath name $ \ s ->
throwErrnoIfMinus1_ "unsetenv" (c_unsetenv s)
foreign import capi unsafe "HsUnix.h unsetenv"
c_unsetenv :: CString -> IO CInt
{-# LINE 109 "System/Posix/Env.hsc" #-}
{-# LINE 112 "System/Posix/Env.hsc" #-}
putEnv :: String -> IO ()
putEnv :: String -> IO ()
putEnv String
keyvalue = do CString
s <- String -> IO CString
newFilePath String
keyvalue
String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"putenv" (CString -> IO CInt
c_putenv CString
s)
foreign import ccall unsafe "putenv"
c_putenv :: CString -> IO CInt
setEnv ::
String ->
String ->
Bool ->
IO ()
{-# LINE 139 "System/Posix/Env.hsc" #-}
setEnv key value ovrwrt = do
withFilePath key $ \ keyP ->
withFilePath value $ \ valueP ->
throwErrnoIfMinus1_ "setenv" $
c_setenv keyP valueP (fromIntegral (fromEnum ovrwrt))
foreign import ccall unsafe "setenv"
c_setenv :: CString -> CString -> CInt -> IO CInt
{-# LINE 155 "System/Posix/Env.hsc" #-}
clearEnv :: IO ()
clearEnv :: IO ()
{-# LINE 159 "System/Posix/Env.hsc" #-}
clearEnv = void c_clearenv
foreign import ccall unsafe "clearenv"
c_clearenv :: IO Int
{-# LINE 170 "System/Posix/Env.hsc" #-}