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 +30/−0
- README.md +18/−0
- Setup.hs +2/−0
- src/System/SysInfo.hsc +122/−0
- sysinfo.cabal +38/−0
- test/Spec.hs +31/−0
+ 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++[](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)+