----------------------------------------------------------------------------- -- | -- Module : StatFS -- Copyright : (c) Jose A Ortega Ruiz -- License : BSD-style (see LICENSE) -- -- Maintainer : Jose A Ortega Ruiz -- Stability : unstable -- Portability : unportable -- -- A binding to C's statvfs(2) -- ----------------------------------------------------------------------------- {-# LANGUAGE CPP, ForeignFunctionInterface, EmptyDataDecls #-} module Xmobar.System.StatFS ( FileSystemStats(..), getFileSystemStats ) where import Foreign import Foreign.C.Types import Foreign.C.String import Data.ByteString (useAsCString) import Data.ByteString.Char8 (pack) #if defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__APPLE__) || defined (__DragonFly__) #define IS_BSD_SYSTEM #endif #ifdef IS_BSD_SYSTEM # include # include #else # include #endif data FileSystemStats = FileSystemStats { fsStatBlockSize :: Integer -- ^ Optimal transfer block size. , fsStatBlockCount :: Integer -- ^ Total data blocks in file system. , fsStatByteCount :: Integer -- ^ Total bytes in file system. , fsStatBytesFree :: Integer -- ^ Free bytes in file system. , fsStatBytesAvailable :: Integer -- ^ Free bytes available to non-superusers. , fsStatBytesUsed :: Integer -- ^ Bytes used. } deriving (Show, Eq) data CStatfs #ifdef IS_BSD_SYSTEM foreign import ccall unsafe "sys/mount.h statfs" #else foreign import ccall unsafe "sys/vfs.h statvfs" #endif c_statfs :: CString -> Ptr CStatfs -> IO CInt toI :: CULong -> Integer toI = toInteger getFileSystemStats :: String -> IO (Maybe FileSystemStats) getFileSystemStats path = allocaBytes (#size struct statfs) $ \vfs -> useAsCString (pack path) $ \cpath -> do res <- c_statfs cpath vfs if res /= 0 then return Nothing else do bsize <- (#peek struct statfs, f_bsize) vfs bcount <- (#peek struct statfs, f_blocks) vfs bfree <- (#peek struct statfs, f_bfree) vfs bavail <- (#peek struct statfs, f_bavail) vfs let bpb = toI bsize return $ Just FileSystemStats { fsStatBlockSize = bpb , fsStatBlockCount = toI bcount , fsStatByteCount = toI bcount * bpb , fsStatBytesFree = toI bfree * bpb , fsStatBytesAvailable = toI bavail * bpb , fsStatBytesUsed = toI (bcount - bfree) * bpb }