module System.Posix.Env (
getEnv
, getEnvDefault
, getEnvironmentPrim
, getEnvironment
, putEnv
, setEnv
, unsetEnv
) where
import Foreign.C.Error ( throwErrnoIfMinus1_ )
import Foreign.C.Types ( CInt )
import Foreign.C.String
import Foreign.Marshal.Array
import Foreign.Ptr
import Foreign.Storable
import Control.Monad ( liftM )
import Data.Maybe ( fromMaybe )
getEnv :: String -> IO (Maybe String)
getEnv name = do
litstring <- withCString name c_getenv
if litstring /= nullPtr
then liftM Just $ peekCString litstring
else return Nothing
getEnvDefault :: String -> String -> IO String
getEnvDefault name fallback = liftM (fromMaybe fallback) (getEnv name)
foreign import ccall unsafe "getenv"
c_getenv :: CString -> IO CString
getEnvironmentPrim :: IO [String]
getEnvironmentPrim = do
c_environ <- peek c_environ_p
arr <- peekArray0 nullPtr c_environ
mapM peekCString arr
foreign import ccall unsafe "&environ"
c_environ_p :: Ptr (Ptr CString)
getEnvironment :: IO [(String,String)]
getEnvironment = do
env <- getEnvironmentPrim
return $ map (dropEq.(break ((==) '='))) env
where
dropEq (x,'=':ys) = (x,ys)
dropEq (x,_) = error $ "getEnvironment: insane variable " ++ x
unsetEnv :: String -> IO ()
unsetEnv name = withCString name c_unsetenv
foreign import ccall unsafe "unsetenv"
c_unsetenv :: CString -> IO ()
putEnv :: String -> IO ()
putEnv keyvalue = withCString keyvalue $ \s ->
throwErrnoIfMinus1_ "putenv" (c_putenv s)
foreign import ccall unsafe "stdlib.h putenv"
c_putenv :: CString -> IO CInt
setEnv :: String -> String -> Bool -> IO ()
setEnv key value ovrwrt = do
withCString key $ \ keyP ->
withCString value $ \ valueP ->
throwErrnoIfMinus1_ "setenv" $
c_setenv keyP valueP (fromIntegral (fromEnum ovrwrt))
foreign import ccall unsafe "setenv"
c_setenv :: CString -> CString -> CInt -> IO CInt