module Z.IO.Environment
(
getArgs
, getAllEnv
, getEnv, getEnv'
, setEnv, unsetEnv
, getCWD, chDir, getHomeDir, getTempDir
, getRandom, getRandomT
, getResUsage, ResUsage(..), TimeVal(..)
, getResidentSetMemory
, getUpTime
, getHighResolutionTime
, PID(..)
, getPID, getPPID
, getHostname
, getOSName, OSName(..)
, getPassWD, PassWD(..), UID, GID
, getCPUInfo, CPUInfo(..)
, getLoadAvg
, getFreeMem, getTotalMem, getConstrainedMem
) where
import Control.Monad
import Data.Word
import Z.Data.Vector.Base as V
import Z.Data.CBytes
import Z.Foreign
import Z.IO.Exception
import Z.IO.UV.Errno
import Z.IO.UV.Manager
import Foreign.Storable
import Z.IO.UV.FFI
getArgs :: IO [CBytes]
getArgs = do
(argc :: CInt, (p_argv :: Ptr CString, _)) <- allocPrimUnsafe $ \ p_argc -> do
allocPrimUnsafe $ \ p_p_argv -> do
getProgArgv p_argc p_p_argv
forM [0..fromIntegral (argc-1)] $ \ i -> do
fromCString =<< peekElemOff p_argv i
getAllEnv :: HasCallStack => IO [(CBytes, CBytes)]
getAllEnv = bracket
(do (p_env :: Ptr CString, (envc :: CInt, _)) <- allocPrimUnsafe $ \ p_p_env -> do
allocPrimUnsafe $ \ p_envc ->
throwUVIfMinus_ (uv_os_environ p_p_env p_envc)
return (p_env, envc))
(\ (p_env, envc) -> uv_os_free_environ p_env envc)
(\ (p_env, envc) -> do
forM [0..fromIntegral (envc-1)] $ \ i -> do
k <- fromCString =<< peekElemOff p_env (i*2)
v <- fromCString =<< peekElemOff p_env (i*2+1)
return (k, v))
getEnv :: HasCallStack => CBytes -> IO (Maybe CBytes)
getEnv k = go 512
where
go siz = do
(siz', (v, r))<- withPrimUnsafe siz $ \ p_siz ->
withCBytesUnsafe k $ \ p_k ->
allocCBytesUnsafe siz $ \ p_v ->
uv_os_getenv p_k p_v p_siz
case r of
UV_ENOBUFS -> go siz'
UV_ENOENT -> return Nothing
_ -> do
throwUVIfMinus_ (return r)
return (Just v)
getEnv' :: HasCallStack => CBytes -> IO CBytes
getEnv' k = getEnv k >>= \ mv -> case mv of
Just v -> return v
_ -> throwUVError UV_ENOENT (IOEInfo "ENOENT" "no such environment variable" callStack)
setEnv :: HasCallStack => CBytes -> CBytes -> IO ()
setEnv k v = withCBytesUnsafe k $ \ p_k ->
withCBytesUnsafe v $ \ p_v ->
throwUVIfMinus_ (uv_os_setenv p_k p_v)
unsetEnv :: HasCallStack => CBytes -> IO ()
unsetEnv k = void . withCBytesUnsafe k $ \ p -> throwUVIfMinus_ (uv_os_unsetenv p)
getResidentSetMemory :: HasCallStack => IO CSize
getResidentSetMemory = do
(size, r) <- allocPrimUnsafe uv_resident_set_memory
throwUVIfMinus_ (return r)
return size
getUpTime :: HasCallStack => IO Double
getUpTime = do
(size, r) <- allocPrimUnsafe uv_uptime
throwUVIfMinus_ (return r)
return size
getHighResolutionTime :: IO Word64
getHighResolutionTime = uv_hrtime
getResUsage :: HasCallStack => IO ResUsage
getResUsage = do
(MutableByteArray mba#) <- newByteArray sizeOfResUsage
throwUVIfMinus_ (uv_getrusage mba#)
peekResUsage mba#
getPID :: IO PID
getPID = uv_os_getpid
getPPID :: IO PID
getPPID = uv_os_getppid
getHostname :: HasCallStack => IO CBytes
getHostname = do
(n, _) <- allocCBytesUnsafe (fromIntegral UV_MAXHOSTNAMESIZE) $ \ p_n ->
withPrimUnsafe UV_MAXHOSTNAMESIZE $ \ p_siz ->
throwUVIfMinus_ (uv_os_gethostname p_n p_siz)
return n
getRandom :: Int -> IO V.Bytes
getRandom siz = do
(v, _) <- allocPrimVectorUnsafe siz $ \ mba# ->
throwUVIfMinus_ (hs_uv_random mba# (fromIntegral siz) 0)
return v
getRandomT :: Int -> IO V.Bytes
getRandomT siz = do
(v, _) <- allocPrimVectorSafe siz $ \ p -> do
uvm <- getUVManager
withUVRequest_ uvm (hs_uv_random_threaded p (fromIntegral siz) 0)
return v
getCWD :: HasCallStack => IO CBytes
getCWD = go 512
where
go siz = do
(siz', (v, r))<- withPrimUnsafe siz $ \ p_siz ->
allocCBytesUnsafe siz $ \ p_v ->
uv_cwd p_v p_siz
case r of
UV_ENOBUFS -> go siz'
_ -> do
throwUVIfMinus_ (return r)
return v
chDir :: HasCallStack => CBytes -> IO ()
chDir p = throwUVIfMinus_ (withCBytesUnsafe p $ \ pp -> uv_chdir pp)
getHomeDir :: HasCallStack => IO CBytes
getHomeDir = go 512
where
go siz = do
(siz', (v, r))<- withPrimUnsafe siz $ \ p_siz ->
allocCBytesUnsafe siz $ \ p_v ->
uv_os_homedir p_v p_siz
case r of
UV_ENOBUFS -> go siz'
_ -> do
throwUVIfMinus_ (return r)
return v
getTempDir :: HasCallStack => IO CBytes
getTempDir = go 512
where
go siz = do
(siz', (v, r))<- withPrimUnsafe siz $ \ p_siz ->
allocCBytesUnsafe siz $ \ p_v ->
uv_os_tmpdir p_v p_siz
case r of
UV_ENOBUFS -> go siz'
_ -> do
throwUVIfMinus_ (return r)
return v
getFreeMem :: IO Word64
getFreeMem = uv_get_free_memory
getTotalMem :: IO Word64
getTotalMem = uv_get_total_memory
getConstrainedMem :: IO Word64
getConstrainedMem = uv_get_constrained_memory
foreign import ccall unsafe getProgArgv :: MBA# CInt -> MBA# (Ptr CString) -> IO ()