sysinfo-0.1.1: src/System/SysInfo.hsc
{-#LANGUAGE CPP#-}
{-#LANGUAGE ForeignFunctionInterface#-}
{-#LANGUAGE ScopedTypeVariables#-}
{-#LANGUAGE RecordWildCards#-}
module System.SysInfo
(
-- * Usage
-- $usage
sysInfo
, SysInfo(..)
, Loads(..)
) where
#ifndef NO_SYSINFO
#include <sys/sysinfo.h>
#endif
import Foreign.C
import Foreign.Ptr
import Foreign.C.Error
import Foreign.Storable
import Foreign.Marshal.Alloc
-- $usage
--
-- @
-- λ> import System.SysInfo
-- λ> val <- sysInfo
-- λ> either (\_ -> "sysinfo failed") show val
-- "SysInfo {uptime = 121149, loads = Loads {sloads = [91200,80736,82592]}, totalram = 12286611456, freeram = 967655424, sharedram = 63033344, bufferram = 838983680, totalswap = 8261726208, freeswap = 8259276800, procs = 418, totalhigh = 0, freehigh = 0, memUnit = 1}"
-- @
#if __GLASGOW_HASKELL__ < 800
#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
#endif
-- | Data type representing system informating
data SysInfo = SysInfo
{ uptime :: CLong -- ^ Seconds since boot
, loads :: Loads -- ^ 1, 5, and 15 minute load averages
, totalram :: CULong -- ^ Total usable main memory size
, freeram :: CULong -- ^ Available memory size
, sharedram :: CULong -- ^ Amount of shared memory
, bufferram :: CULong -- ^ Memory used by buffers
, totalswap :: CULong -- ^ Total swap space size
, freeswap :: CULong -- ^ swap space still available
, procs :: CUShort -- ^ Number of current processes
, totalhigh :: CULong -- ^ Total high memory size
, freehigh :: CULong -- ^ Available high memory size
, memUnit :: CUInt -- ^ Memory unit size in bytes
} deriving (Show, Eq, Ord)
newtype Loads = Loads
{ sloads :: [CULong]
} deriving (Show, Eq, Ord)
instance Storable Loads where
sizeOf _ = (sizeOf (undefined :: CULong)) * 3
alignment _ = alignment (undefined :: CULong)
peek ptr = do
(vals :: [CULong]) <- mapM (peekElemOff ptr') index
return $ Loads vals
where
ptr' = castPtr ptr
index = [0, 1, 2]
poke ptr (Loads val) = mapM_ (\(v, i) -> pokeElemOff ptr' i v) (zip val index)
where
(ptr' :: Ptr CULong) = castPtr ptr
index = [0, 1, 2]
#ifndef NO_SYSINFO
instance Storable SysInfo where
sizeOf _ = (#size struct sysinfo)
alignment _ = (#alignment struct sysinfo)
peek ptr = do
uptime <- (#peek struct sysinfo, uptime) ptr
loads <- (#peek struct sysinfo, loads) ptr
totalram <- (#peek struct sysinfo, totalram) ptr
freeram <- (#peek struct sysinfo, freeram) ptr
sharedram <- (#peek struct sysinfo, sharedram) ptr
bufferram <- (#peek struct sysinfo, bufferram) ptr
totalswap <- (#peek struct sysinfo, totalswap) ptr
freeswap <- (#peek struct sysinfo, freeswap) ptr
procs <- (#peek struct sysinfo, procs) ptr
totalhigh <- (#peek struct sysinfo, totalhigh) ptr
freehigh <- (#peek struct sysinfo, freehigh) ptr
memUnit <- (#peek struct sysinfo, mem_unit) ptr
return $
SysInfo
{ ..
}
poke ptr (SysInfo {..}) = do
(#poke struct sysinfo, uptime) ptr uptime
(#poke struct sysinfo, loads) ptr loads
(#poke struct sysinfo, totalram) ptr totalram
(#poke struct sysinfo, freeram) ptr freeram
(#poke struct sysinfo, sharedram) ptr sharedram
(#poke struct sysinfo, bufferram) ptr bufferram
(#poke struct sysinfo, totalswap) ptr totalswap
(#poke struct sysinfo, freeswap) ptr freeswap
(#poke struct sysinfo, procs) ptr procs
(#poke struct sysinfo, totalhigh) ptr totalhigh
(#poke struct sysinfo, freehigh) ptr freehigh
(#poke struct sysinfo, mem_unit) ptr memUnit
foreign import ccall safe "sysinfo" c_sysinfo ::
Ptr SysInfo -> IO CInt
-- | Function for getting system information. Internally it uses the
-- Linux system call sysinfo to get the system statistics.
sysInfo :: IO (Either Errno SysInfo)
sysInfo = do
(sptr :: Ptr SysInfo) <- malloc
res <- c_sysinfo sptr
if (res == 0)
then do
val <- peek sptr
free sptr
return $ Right val
else do
free sptr
err <- getErrno
return $ Left err
#else
-- | Functor for getting system information. On non-Linux sytems always fails
-- with @E_NODATA@.
sysInfo :: IO (Either Errno SysInfo)
sysInfo = return (Left eNODATA)
#endif