{-# LINE 1 "System/Posix/Env/ByteString.hsc" #-}
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE Trustworthy #-}
module System.Posix.Env.ByteString (
getEnv
, getEnvDefault
, getEnvironmentPrim
, getEnvironment
, setEnvironment
, putEnv
, setEnv
, unsetEnv
, clearEnv
, getArgs
) where
import Control.Monad
import Foreign
import Foreign.C
import Data.Maybe ( fromMaybe )
import System.Posix.Env ( clearEnv )
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.ByteString (ByteString)
import Data.ByteString.Internal (ByteString (PS), memcpy)
getEnv ::
ByteString ->
IO (Maybe ByteString)
getEnv name = do
litstring <- B.useAsCString name c_getenv
if litstring /= nullPtr
then liftM Just $ B.packCString litstring
else return Nothing
getEnvDefault ::
ByteString ->
ByteString ->
IO ByteString
getEnvDefault name fallback = liftM (fromMaybe fallback) (getEnv name)
foreign import ccall unsafe "getenv"
c_getenv :: CString -> IO CString
getEnvironmentPrim :: IO [ByteString]
getEnvironmentPrim = do
c_environ <- getCEnviron
arr <- peekArray0 nullPtr c_environ
mapM B.packCString arr
getCEnviron :: IO (Ptr CString)
{-# LINE 86 "System/Posix/Env/ByteString.hsc" #-}
getCEnviron = peek c_environ_p
foreign import ccall unsafe "&environ"
c_environ_p :: Ptr (Ptr CString)
{-# LINE 91 "System/Posix/Env/ByteString.hsc" #-}
getEnvironment :: IO [(ByteString,ByteString)]
getEnvironment = do
env <- getEnvironmentPrim
return $ map (dropEq.(BC.break ((==) '='))) env
where
dropEq (x,y)
| BC.head y == '=' = (x,B.tail y)
| otherwise = error $ "getEnvironment: insane variable " ++ BC.unpack x
setEnvironment ::
[(ByteString,ByteString)] ->
IO ()
setEnvironment env = do
clearEnv
forM_ env $ \(key,value) ->
setEnv key value True
unsetEnv :: ByteString -> IO ()
{-# LINE 121 "System/Posix/Env/ByteString.hsc" #-}
{-# LINE 122 "System/Posix/Env/ByteString.hsc" #-}
unsetEnv name = B.useAsCString name $ \ s ->
throwErrnoIfMinus1_ "unsetenv" (c_unsetenv s)
foreign import capi unsafe "HsUnix.h unsetenv"
c_unsetenv :: CString -> IO CInt
{-# LINE 135 "System/Posix/Env/ByteString.hsc" #-}
{-# LINE 138 "System/Posix/Env/ByteString.hsc" #-}
putEnv :: ByteString -> IO ()
putEnv (PS fp o l) = withForeignPtr fp $ \p -> do
buf <- mallocBytes (l+1)
memcpy buf (p `plusPtr` o) l
pokeByteOff buf l (0::Word8)
throwErrnoIfMinus1_ "putenv" (c_putenv (castPtr buf))
foreign import ccall unsafe "putenv"
c_putenv :: CString -> IO CInt
setEnv ::
ByteString ->
ByteString ->
Bool ->
IO ()
{-# LINE 172 "System/Posix/Env/ByteString.hsc" #-}
setEnv key value ovrwrt = do
B.useAsCString key $ \ keyP ->
B.useAsCString value $ \ valueP ->
throwErrnoIfMinus1_ "setenv" $
c_setenv keyP valueP (fromIntegral (fromEnum ovrwrt))
foreign import ccall unsafe "setenv"
c_setenv :: CString -> CString -> CInt -> IO CInt
{-# LINE 188 "System/Posix/Env/ByteString.hsc" #-}
getArgs :: IO [ByteString]
getArgs =
alloca $ \ p_argc ->
alloca $ \ p_argv -> do
getProgArgv p_argc p_argv
p <- fromIntegral `liftM` peek p_argc
argv <- peek p_argv
peekArray (p - 1) (advancePtr argv 1) >>= mapM B.packCString
foreign import ccall unsafe "getProgArgv"
getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()