{-# LINE 1 "libraries/unix/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))
import qualified System.Posix.Env.Internal as Internal
getEnv ::
ByteString ->
IO (Maybe ByteString)
getEnv :: ByteString -> IO (Maybe ByteString)
getEnv ByteString
name = do
litstring <- ByteString -> (CString -> IO CString) -> IO CString
forall a. ByteString -> (CString -> IO a) -> IO a
B.useAsCString ByteString
name CString -> IO CString
c_getenv
if litstring /= nullPtr
then Just <$> B.packCString litstring
else return Nothing
getEnvDefault ::
ByteString ->
ByteString ->
IO ByteString
getEnvDefault :: ByteString -> ByteString -> IO ByteString
getEnvDefault ByteString
name ByteString
fallback = ByteString -> Maybe ByteString -> ByteString
forall a. a -> Maybe a -> a
fromMaybe ByteString
fallback (Maybe ByteString -> ByteString)
-> IO (Maybe ByteString) -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> IO (Maybe ByteString)
getEnv ByteString
name
foreign import ccall unsafe "getenv"
c_getenv :: CString -> IO CString
getEnvironmentPrim :: IO [ByteString]
getEnvironmentPrim :: IO [ByteString]
getEnvironmentPrim = IO [CString]
Internal.getEnvironmentPrim IO [CString] -> ([CString] -> IO [ByteString]) -> IO [ByteString]
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 ByteString) -> [CString] -> IO [ByteString]
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 ByteString
B.packCString
getEnvironment :: IO [(ByteString,ByteString)]
getEnvironment :: IO [(ByteString, ByteString)]
getEnvironment = do
env <- IO [ByteString]
getEnvironmentPrim
return $ map (dropEq.(BC.break ((==) '='))) env
where
dropEq :: (ByteString, ByteString) -> (ByteString, ByteString)
dropEq (ByteString
x,ByteString
y)
| ByteString -> Char
BC.head ByteString
y Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=' = (ByteString
x,HasCallStack => ByteString -> ByteString
ByteString -> ByteString
B.tail ByteString
y)
| Bool
otherwise = [Char] -> (ByteString, ByteString)
forall a. HasCallStack => [Char] -> a
error ([Char] -> (ByteString, ByteString))
-> [Char] -> (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ [Char]
"getEnvironment: insane variable " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
BC.unpack ByteString
x
setEnvironment ::
[(ByteString,ByteString)] ->
IO ()
setEnvironment :: [(ByteString, ByteString)] -> IO ()
setEnvironment [(ByteString, ByteString)]
env = do
IO ()
clearEnv
[(ByteString, ByteString)]
-> ((ByteString, ByteString) -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(ByteString, ByteString)]
env (((ByteString, ByteString) -> IO ()) -> IO ())
-> ((ByteString, ByteString) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(ByteString
key,ByteString
value) ->
ByteString -> ByteString -> Bool -> IO ()
setEnv ByteString
key ByteString
value Bool
True
unsetEnv :: ByteString -> IO ()
{-# LINE 105 "libraries/unix/System/Posix/Env/ByteString.hsc" #-}
unsetEnv :: ByteString -> IO ()
{-# LINE 106 "libraries/unix/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 119 "libraries/unix/System/Posix/Env/ByteString.hsc" #-}
{-# LINE 122 "libraries/unix/System/Posix/Env/ByteString.hsc" #-}
putEnv :: ByteString -> IO ()
putEnv :: ByteString -> IO ()
putEnv (PS ForeignPtr Word8
fp Int
o Int
l) = ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
buf <- Int -> IO (Ptr (ZonkAny 0))
forall a. Int -> IO (Ptr a)
mallocBytes (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
copyBytes 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 156 "libraries/unix/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 172 "libraries/unix/System/Posix/Env/ByteString.hsc" #-}
getArgs :: IO [ByteString]
getArgs :: IO [ByteString]
getArgs =
(Ptr CInt -> IO [ByteString]) -> IO [ByteString]
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO [ByteString]) -> IO [ByteString])
-> (Ptr CInt -> IO [ByteString]) -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ \ Ptr CInt
p_argc ->
(Ptr (Ptr CString) -> IO [ByteString]) -> IO [ByteString]
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CString) -> IO [ByteString]) -> IO [ByteString])
-> (Ptr (Ptr CString) -> IO [ByteString]) -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ \ Ptr (Ptr CString)
p_argv -> do
Ptr CInt -> Ptr (Ptr CString) -> IO ()
getProgArgv Ptr CInt
p_argc Ptr (Ptr CString)
p_argv
p <- CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
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 ()