udev-0.0.0.0: src/System/UDev/Enumerate.hs
-- |
-- Copyright : (c) Sam Truzjan 2013
-- License : BSD3
-- Maintainer : pxqr.sta@gmail.com
-- Stability : stable
-- Portability : portable
--
-- Lookup devices in the sys filesystem, filter devices by
-- properties, and return a sorted list of devices.
--
{-# LANGUAGE ForeignFunctionInterface #-}
module System.UDev.Enumerate
( Enumerate
, newEnumerate
-- * Match
, Subsystem
, addMatchSubsystem
, addNoMatchSubsystem
, SysAttr
, SysValue
, addMatchSysattr
, addNoMatchSysattr
, addMatchProperty
, addMatchTag
, addMatchParent
, addMatchIsInitialized
, addMatchSysname
, addSyspath
-- * Scan
, scanDevices
, scanSubsystems
-- * Query
, getListEntry
) where
import Data.ByteString as BS
import Foreign
import Foreign.C.Error
import Foreign.C.String
import Foreign.C.Types
import System.UDev.Context
import System.UDev.Device
import System.UDev.List
import System.UDev.Types
foreign import ccall unsafe "udev_enumerate_new"
c_new :: UDev -> IO Enumerate
-- | Create an enumeration context to scan /sys.
newEnumerate :: UDev -> IO Enumerate
newEnumerate = c_new
{-# INLINE newEnumerate #-}
{-----------------------------------------------------------------------
-- Match
-----------------------------------------------------------------------}
foreign import ccall unsafe "udev_enumerate_add_match_subsystem"
c_addMatchSubsystem :: Enumerate -> CString -> IO CInt
-- | Kernel subsystem string.
type Subsystem = ByteString
-- | Match only devices belonging to a certain kernel subsystem.
addMatchSubsystem :: Enumerate -- ^ context
-> Subsystem -- ^ filter for a subsystem of the
-- device to include in the list
-> IO () -- ^ can throw exception
addMatchSubsystem enumerate subsystem = do
throwErrnoIfMinus1_ "addMatchSubsystem" $ do
useAsCString subsystem $
c_addMatchSubsystem enumerate
foreign import ccall unsafe "udev_enumerate_add_nomatch_subsystem"
c_addNoMatchSubsystem :: Enumerate -> CString -> IO CInt
-- | Match only devices not belonging to a certain kernel subsystem.
addNoMatchSubsystem :: Enumerate -- ^ context
-> Subsystem -- ^ filter for a subsystem of the
-- device to exclude from the list
-> IO () -- ^ can throw exception
addNoMatchSubsystem enumerate subsystem = do
throwErrnoIfMinus1_ "addNoMatchSubsystem" $ do
useAsCString subsystem $
c_addNoMatchSubsystem enumerate
-- | \/sys attribute string.
type SysAttr = ByteString
-- | Attribute specific \/sys value string. Can be an int or
-- identifier depending on attribute.
type SysValue = ByteString
foreign import ccall unsafe "udev_enumerate_add_match_sysattr"
c_addMatchSysattr :: Enumerate -> CString -> CString -> IO CInt
-- | Match only devices with a certain \/sys device attribute.
addMatchSysattr :: Enumerate -- ^ context
-> SysAttr -- ^ filter for a sys attribute at
-- the device to include in the list
-> Maybe SysValue -- ^ optional value of the sys attribute
-> IO () -- ^ can throw exception
addMatchSysattr enumerate sysattr mvalue = do
throwErrnoIf_ (< 0) "addMatchSysattr" $ do
useAsCString sysattr $ \ c_sysattr -> do
case mvalue of
Nothing -> c_addMatchSysattr enumerate c_sysattr nullPtr
Just value -> do
useAsCString value $ \ c_value -> do
c_addMatchSysattr enumerate c_sysattr c_value
foreign import ccall unsafe "udev_enumerate_add_nomatch_sysattr"
c_addNoMatchSysattr :: Enumerate -> CString -> CString -> IO CInt
-- | Match only devices not having a certain /sys device attribute.
addNoMatchSysattr :: Enumerate -- ^ context
-> ByteString -- ^ filter for a sys attribute at the
-- device to exclude from the list
-> Maybe ByteString -- ^ optional value of the sys
-- attribute
-> IO ()
addNoMatchSysattr enumerate sysattr mvalue = do
throwErrnoIf_ (< 0) "addNoMatchSysattr" $ do
useAsCString sysattr $ \ c_sysattr -> do
case mvalue of
Nothing -> c_addNoMatchSysattr enumerate c_sysattr nullPtr
Just value -> do
useAsCString value $ \ c_value -> do
c_addNoMatchSysattr enumerate c_sysattr c_value
foreign import ccall unsafe "udev_enumerate_add_match_property"
c_addMatchProperty :: Enumerate -> CString -> CString -> IO CInt
-- | Match only devices with a certain property.
addMatchProperty :: Enumerate -- ^ context
-> ByteString -- ^ filter for a property of the
-- device to include in the list
-> ByteString -- ^ value of the property
-> IO ()
addMatchProperty enumerate prop value = do
throwErrnoIf_ (< 0) "addMatchProperty" $ do
useAsCString prop $ \ c_prop -> do
useAsCString value $ \ c_value -> do
c_addMatchProperty enumerate c_prop c_value
foreign import ccall unsafe "udev_enumerate_add_match_tag"
c_addMatchTag :: Enumerate -> CString -> IO CInt
-- | Match only devices with a certain tag.
addMatchTag :: Enumerate -- ^ context
-> ByteString -- ^ filter for a tag of the device to
-- include in the list
-> IO ()
addMatchTag enumerate tag = do
throwErrnoIf_ (< 0) "addMatchTag" $ do
useAsCString tag $ \ c_tag -> do
c_addMatchTag enumerate c_tag
foreign import ccall unsafe "udev_enumerate_add_match_parent"
c_addMatchParent :: Enumerate -> Device -> IO CInt
-- | Return the devices on the subtree of one given device. The parent
-- itself is included in the list.
--
-- A reference for the device is held until the udev_enumerate context
-- is cleaned up.
--
addMatchParent :: Enumerate -- ^ context
-> Device -- ^ parent device where to start searching
-> IO () -- ^ can throw exception
addMatchParent enumerate dev = do
throwErrnoIf_ (< 0) "addMatchParent" $ do
c_addMatchParent enumerate dev
foreign import ccall unsafe "udev_enumerate_add_match_is_initialized"
c_addMatchIsInitialized :: Enumerate -> IO CInt
-- | Match only devices which udev has set up already.
addMatchIsInitialized :: Enumerate -> IO ()
addMatchIsInitialized enumerate = do
throwErrnoIfMinus1_ "addMatchIsInitialized" $ do
c_addMatchIsInitialized enumerate
foreign import ccall unsafe "udev_enumerate_add_match_sysname"
c_addMatchSysname :: Enumerate -> CString -> IO CInt
-- | Match only devices with a given \/sys device name.
addMatchSysname :: Enumerate -- ^ context
-> ByteString -- ^ filter for the name of the device
-- to include in the list
-> IO () -- ^ can throw exception
addMatchSysname enumerate sysName = do
throwErrnoIfMinus1_ "addMatchSysname" $ do
useAsCString sysName $
c_addMatchSysname enumerate
foreign import ccall unsafe "udev_enumerate_add_syspath"
c_addSyspath :: Enumerate -> CString -> IO CInt
-- | Add a device to the list of devices, to retrieve it back sorted
-- in dependency order.
--
addSyspath :: Enumerate -- ^ context
-> ByteString -- ^ path of a device
-> IO () -- ^ can throw exception
addSyspath enumerate syspath = do
throwErrnoIf_ (< 0) "addSyspath" $ do
useAsCString syspath $ \ c_syspath -> do
c_addSyspath enumerate c_syspath
{-----------------------------------------------------------------------
-- Scan
-----------------------------------------------------------------------}
foreign import ccall unsafe "udev_enumerate_scan_devices"
c_scanDevices :: Enumerate -> IO CInt
-- | Scan \/sys for all devices which match the given filters.
scanDevices :: Enumerate -> IO ()
scanDevices = throwErrnoIfMinus1_ "scanDevices" . c_scanDevices
foreign import ccall unsafe "udev_enumerate_scan_subsystems"
c_scanSubsystems :: Enumerate -> IO CInt
-- | Scan \/sys for all devices which match the given filters.
scanSubsystems :: Enumerate -> IO ()
scanSubsystems = throwErrnoIfMinus1_ "scanSubsystems" . c_scanSubsystems
{-----------------------------------------------------------------------
-- Query
-----------------------------------------------------------------------}
foreign import ccall unsafe "udev_enumerate_get_list_entry"
c_getListEntry :: Enumerate -> IO List
-- | Get the first entry of the sorted list of device paths.
getListEntry :: Enumerate -> IO List
getListEntry = c_getListEntry
{-# INLINE getListEntry #-}