diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -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}"
+ ```
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/System/SysInfo.hsc b/src/System/SysInfo.hsc
new file mode 100644
--- /dev/null
+++ b/src/System/SysInfo.hsc
@@ -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
diff --git a/sysinfo.cabal b/sysinfo.cabal
new file mode 100644
--- /dev/null
+++ b/sysinfo.cabal
@@ -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
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -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)
+
