packages feed

sysinfo (empty) → 0.1.0.0

raw patch · 6 files changed

+241/−0 lines, 6 filesdep +basedep +hspecdep +hspec-expectationssetup-changed

Dependencies added: base, hspec, hspec-expectations, sysinfo

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Sibi Prabakaran (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Sibi Prabakaran nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,18 @@+# sysinfo++[![Build Status](https://travis-ci.org/psibi/sysinfo.svg?branch=master)](https://travis-ci.org/psibi/sysinfo)++Haskell interface for the `sysinfo` Linux system call. This can be used+to get system statistics like uptime, free memory, system load etc.++Note that the package works *only* on Linux system with kernel+version >= 2.3.23 and uses FFI calls.++## Usage++``` haskell+λ> 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}"+ ```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/System/SysInfo.hsc view
@@ -0,0 +1,122 @@+{-#LANGUAGE ForeignFunctionInterface#-}+{-#LANGUAGE ScopedTypeVariables#-}+{-#LANGUAGE RecordWildCards#-}++module System.SysInfo+  ( ++   -- * Usage+   -- $usage++    sysInfo+  , SysInfo(..)+  , Loads(..)+  ) where++#include <sys/sysinfo.h>++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]++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
+ sysinfo.cabal view
@@ -0,0 +1,38 @@+name:                sysinfo+version:             0.1.0.0+synopsis:            Haskell Interface for getting overall system statistics+description:         This package can be used to get system statistics like+                     uptime, free memory, system load etc. Note that+                     the package works *only* on Linux system with+                     kernel version >= 2.3.23 and uses FFI calls.+homepage:            https://github.com/psibi/sysinfo#readme+license:             BSD3+license-file:        LICENSE+author:              Sibi Prabakaran+maintainer:          sibi@psibi.in+copyright:           Copyright: (c) 2017 Sibi+category:            FFI, Linux, System+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     System.SysInfo+  build-depends:       base >= 4.7 && < 5+  default-language:    Haskell2010++test-suite sysinfo-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , sysinfo+                     , hspec+                     , hspec-expectations+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/psibi/sysinfo
+ test/Spec.hs view
@@ -0,0 +1,31 @@+{-#LANGUAGE CPP#-}++import Test.Hspec+import Test.Hspec.Expectations.Contrib (isRight)+import System.SysInfo+import Foreign.C.Error+#if __GLASGOW_HASKELL__ <= 784+import Control.Applicative ((<$>))+#endif++instance Show Errno where+    show (Errno val) = show val++getRight :: (Show a, Show b) => Either a b -> b+getRight (Right b) = b+getRight x@(Left a) = error $ "Invalid value " ++ show x++main :: IO ()+main =+  hspec $+  do describe "sysInfo function" $+       do it "retuns valid data" $+            do val <- sysInfo+               val `shouldSatisfy` isRight+          it "uptime > 0" $+            do val <- getRight <$> sysInfo+               (uptime val) `shouldSatisfy` (> 0)+          it "freeram > 0" $+            do val <- getRight <$> sysInfo+               (freeram val) `shouldSatisfy` (> 0)+