system-linux-proc 0.1.0.0 → 0.1.0.1
raw patch · 6 files changed
+129/−37 lines, 6 filesdep +directory
Dependencies added: directory
Files
- System/Linux/Proc/Errors.hs +28/−0
- System/Linux/Proc/File.hs +0/−29
- System/Linux/Proc/IO.hs +35/−0
- System/Linux/Proc/MemInfo.hs +31/−5
- System/Linux/Proc/Process.hs +29/−0
- system-linux-proc.cabal +6/−3
+ System/Linux/Proc/Errors.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}++module System.Linux.Proc.Errors+ ( ProcError (..)+ , renderProcError+ ) where++import Data.Text (Text)+import qualified Data.Text as T+++data ProcError+ = ProcReadError !FilePath !Text+ | ProcParseError !FilePath !Text+ | ProcMemInfoKeyError !Text+ deriving (Eq, Show)++renderProcError :: ProcError -> Text+renderProcError = \case+ ProcReadError fp msg -> T.concat+ [ "Error reading '", T.pack fp, "': ", msg ]+ ProcParseError fp msg -> T.concat+ [ "Parser error on file '", T.pack fp, ": ", msg ]+ ProcMemInfoKeyError key -> T.concat+ [ "MemInfo: Key not found: '", key, "'" ]++
− System/Linux/Proc/File.hs
@@ -1,29 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module System.Linux.Proc.File- ( readProcFile- ) where--import Control.Error (ExceptT, handleExceptT)--import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS--import Data.Text (Text)-import qualified Data.Text as T--import System.IO (IOMode (..), withFile)--import System.Linux.Proc.Errors---readProcFile :: FilePath -> ExceptT ProcError IO ByteString-readProcFile fpath =- handleExceptT (ProcReadError fpath . ioErrorToText) $- -- BS.readFile won't work here because it tries to get the file- -- length before reading the file and files in the /proc filesystem- -- are reported as having zero length.- withFile fpath ReadMode BS.hGetContents--ioErrorToText :: IOError -> Text-ioErrorToText = T.pack . show
+ System/Linux/Proc/IO.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE OverloadedStrings #-}++module System.Linux.Proc.IO+ ( listProcDirectory+ , readProcFile+ ) where++import Control.Error (ExceptT, handleExceptT)++import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as BS++import Data.Text (Text)+import qualified Data.Text as T++import System.IO (IOMode (..), withFile)++import System.Directory (listDirectory)+import System.Linux.Proc.Errors+++readProcFile :: FilePath -> ExceptT ProcError IO ByteString+readProcFile fpath =+ handleExceptT (ProcReadError fpath . ioErrorToText) $+ -- BS.readFile won't work here because it tries to get the file+ -- length before reading the file and files in the /proc filesystem+ -- are reported as having zero length.+ withFile fpath ReadMode BS.hGetContents++listProcDirectory :: FilePath -> ExceptT ProcError IO [FilePath]+listProcDirectory fpath =+ handleExceptT (ProcReadError fpath . ioErrorToText) $ listDirectory fpath++ioErrorToText :: IOError -> Text+ioErrorToText = T.pack . show
System/Linux/Proc/MemInfo.hs view
@@ -3,10 +3,11 @@ module System.Linux.Proc.MemInfo ( MemInfo (..) , readProcMemInfo+ , readProcMemInfoKey , readProcMemUsage ) where -import Control.Error (fromMaybe, runExceptT, throwE)+import Control.Error (ExceptT (..), fromMaybe, runExceptT, throwE) import Data.Attoparsec.ByteString.Char8 (Parser) import qualified Data.Attoparsec.ByteString.Char8 as A@@ -15,10 +16,11 @@ import qualified Data.List as DL import qualified Data.Map.Strict as DM+import Data.Maybe (mapMaybe) import qualified Data.Text as T import Data.Word (Word64) -import System.Linux.Proc.File+import System.Linux.Proc.IO import System.Linux.Proc.Errors -- | A struct to contain information parsed from the `/proc/meminfo` file@@ -69,15 +71,39 @@ convert :: (Word64, Word64) -> Double convert (avail, total) = fromIntegral avail / fromIntegral total - fromEither :: a -> Either e a -> a- fromEither a (Left _) = a- fromEither _ (Right a) = a+-- | Read the value for the given key from `/proc/meminfo`.+-- Although this is in `IO` all exceptions and errors should be caught and+-- returned as a `ProcError`.+readProcMemInfoKey :: ByteString -> IO (Either ProcError Word64)+readProcMemInfoKey target =+ runExceptT $ do+ xs <- BS.lines <$> readProcFile fpMemInfo+ hoistEither . headEither keyError $ mapMaybe findValue xs+ where+ findValue :: ByteString -> Maybe Word64+ findValue bs =+ let (key, rest) = BS.break (== ':') bs in+ if key /= target + then Nothing+ else either (const Nothing) Just $ A.parseOnly pValue rest+ keyError :: ProcError+ keyError = ProcMemInfoKeyError $ T.pack (BS.unpack target) -- ----------------------------------------------------------------------------- -- Internals. fpMemInfo :: FilePath fpMemInfo = "/proc/meminfo"++fromEither :: a -> Either e a -> a+fromEither a = either (const a) id++headEither :: e -> [a] -> Either e a+headEither e [] = Left e+headEither _ (x:_) = Right x++hoistEither :: Monad m => Either e a -> ExceptT e m a+hoistEither = ExceptT . pure construct :: [(ByteString, Word64)] -> MemInfo construct xs =
+ System/Linux/Proc/Process.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE OverloadedStrings #-}++module System.Linux.Proc.Process+ ( ProcessId (..)+ , getProcProcessIds+ ) where++import Control.Error (runExceptT)++import Data.Maybe (mapMaybe)++import System.Linux.Proc.IO+import System.Linux.Proc.Errors++newtype ProcessId+ = ProcessId { unProcessId :: Int }+ deriving (Eq, Show)++-- | Get the current list of `ProcessId`s.+getProcProcessIds :: IO (Either ProcError [ProcessId])+getProcProcessIds =+ runExceptT $+ mapMaybe maybeProcessId <$> listProcDirectory "/proc"+ where+ maybeProcessId :: String -> Maybe ProcessId+ maybeProcessId str =+ case reads str of+ [(i, "")] -> Just $ ProcessId i+ _ -> Nothing
system-linux-proc.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: system-linux-proc-version: 0.1.0.0+version: 0.1.0.1 synopsis: A library for accessing the /proc filesystem in Linux -- description: homepage: https://github.com/erikd/system-linux-proc@@ -22,13 +22,16 @@ ghc-options: -Wall -fwarn-tabs hs-source-dirs: . - exposed-modules: System.Linux.Proc.MemInfo- , System.Linux.Proc.File+ exposed-modules: System.Linux.Proc.Errors+ , System.Linux.Proc.IO+ , System.Linux.Proc.MemInfo+ , System.Linux.Proc.Process build-depends: base >= 4.8 && < 5.0 , attoparsec == 0.13.* , bytestring == 0.10.* , containers == 0.5.*+ , directory == 1.3.* , errors == 2.2.* , text == 1.2.*