linux-inotify 0.1.0.1 → 0.2.0.0
raw patch · 2 files changed
+42/−18 lines, 2 filesdep +hashabledep ~bytestring
Dependencies added: hashable
Dependency ranges changed: bytestring
Files
- linux-inotify.cabal +6/−3
- src/System/Linux/Inotify.hsc +36/−15
linux-inotify.cabal view
@@ -1,5 +1,5 @@ name: linux-inotify-version: 0.1.0.1+version: 0.2.0.0 synopsis: Thinner binding to the Linux Kernel's inotify interface description: This is a binding for GHC 7 to the Linux Kernel's inotify interface,@@ -45,7 +45,10 @@ library hs-source-dirs: src exposed-modules: System.Linux.Inotify- build-depends: base >= 4 && < 5, unix, bytestring+ build-depends: base >= 4 && < 5,+ bytestring >= 0.9,+ hashable >= 1.1.2,+ unix ghc-options: -Wall @@ -56,4 +59,4 @@ source-repository this type: git location: http://github.com/lpsmith/linux-inotify- tag: v0.1.0.1+ tag: v0.2.0.0
src/System/Linux/Inotify.hsc view
@@ -3,6 +3,8 @@ {-# LANGUAGE BangPatterns, DoAndIfThenElse #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+ ----------------------------------------------------------------------------- -- | -- Module : System.Linux.Inotify@@ -11,8 +13,8 @@ -- -- Maintainer : leon@melding-monads.com ----- Note that you will probably find inotify's manual page useful in--- conjunction with this documentation:+-- Although this module copies portions of inotify's manual page, it may+-- be useful to consult the original in conjunction with this documentation: -- -- <http://man7.org/linux/man-pages/man7/inotify.7.html> --@@ -80,6 +82,7 @@ import Data.Monoid import Data.Typeable import Data.Function ( on )+import Data.Word import Control.Concurrent ( threadWaitRead ) import GHC.Conc ( closeFdWith ) #if __GLASGOW_HASKELL__ < 706@@ -93,6 +96,8 @@ import qualified Foreign.Concurrent as FC import System.Posix.ByteString.FilePath (RawFilePath) +import Data.Hashable+ -- | 'Inotify' represents an inotify descriptor, to which watches can be added -- and events can be read from. Internally, it also includes a buffer -- of events that have been delivered to the application from the kernel@@ -138,6 +143,9 @@ newtype Watch = Watch CInt deriving (Eq, Ord, Show, Typeable) +instance Hashable Watch where+ hashWithSalt salt (Watch (CInt x)) = hashWithSalt salt x+ -- | Represents the mask, which in inotify terminology is a union -- of bit flags representing various event types and watch options. --@@ -146,7 +154,7 @@ -- when receiving an event. ('EventFlag') Polymorphic -- parameters mean that the flag may appear in either context. -newtype Mask a = Mask CUInt deriving (Eq, Show, Typeable)+newtype Mask a = Mask Word32 deriving (Eq, Show, Typeable) -- | Computes the union of two 'Mask's. instance Monoid (Mask a) where@@ -293,17 +301,30 @@ in_UNMOUNT :: Mask EventFlag in_UNMOUNT = Mask (#const IN_UNMOUNT) +-- | A newtype wrapper for the 'cookie' field of the 'Event'. -newtype Cookie = Cookie CUInt deriving (Eq, Ord, Show, Typeable)+newtype Cookie = Cookie Word32 deriving (Eq, Ord, Show, Typeable, Hashable) data Event = Event { wd :: {-# UNPACK #-} !Watch+ -- ^ Identifies the watch for which this event occurs. It is one of the+ -- watch descriptors returned by a previous call to 'addWatch' or+ -- 'addWatch_'. , mask :: {-# UNPACK #-} !(Mask EventFlag)+ -- ^ contains bits that describe the event that occurred , cookie :: {-# UNPACK #-} !Cookie+ -- ^ A unique integer that connects related events. Currently this is+ -- only used for rename events, and allows the resulting pair of+ -- 'in_MOVE_FROM' and 'in_MOVE_TO' events to be connected by the+ -- application. , name :: {-# UNPACK #-} !B.ByteString- -- ^ The proper interpretation of this seems to be to use- -- 'GHC.IO.getForeignEncoding' and then unpack it to a String- -- or decode it using the text package.+ -- ^ The name field is only present when an event is returned for a file+ -- inside a watched directory; it identifies the file pathname relative+ -- to the watched directory.+ --+ -- The proper Haskell interpretation of this seems to be to use+ -- 'GHC.IO.getForeignEncoding' and then unpack it to a 'String'+ -- or decode it using the text package. } deriving (Eq, Show, Typeable) #if __GLASGOW_HASKELL__ < 706@@ -448,8 +469,8 @@ -- | Returns an inotify event, blocking until one is available. ----- If this returns an event, then the next read from the inotify--- descriptor will return the same event and the second read will not+-- After this returns an event, the next read from the inotify+-- descriptor will return the same event. This read will not -- result in a system call. -- -- It is not safe to call this function from multiple threads at the same@@ -511,9 +532,9 @@ start <- readIORef startRef let ptr = ptr0 `plusPtr` start wd <- Watch <$> ((#peek struct inotify_event, wd ) ptr :: IO CInt)- mask <- Mask <$> ((#peek struct inotify_event, mask ) ptr :: IO CUInt)- cookie <- Cookie <$> ((#peek struct inotify_event, cookie) ptr :: IO CUInt)- len <- ((#peek struct inotify_event, len ) ptr :: IO CUInt)+ mask <- Mask <$> ((#peek struct inotify_event, mask ) ptr :: IO Word32)+ cookie <- Cookie <$> ((#peek struct inotify_event, cookie) ptr :: IO Word32)+ len <- ((#peek struct inotify_event, len ) ptr :: IO Word32) name <- if len == 0 then return B.empty else B.packCString ((#ptr struct inotify_event, name) ptr)@@ -525,7 +546,7 @@ start <- readIORef startRef len <- withForeignPtr buffer $ \ptr0 -> do let ptr = ptr0 `plusPtr` start- (#peek struct inotify_event, len ) ptr :: IO CUInt+ (#peek struct inotify_event, len ) ptr :: IO Word32 writeIORef startRef $! start + (#size struct inotify_event) + fromIntegral len {-# INLINE consumeMessage #-} @@ -549,7 +570,7 @@ -- | Returns an inotify event only if one is immediately available. -- -- If this returns an event, then the next read from the inotify--- descriptor will return the same event and the second read will+-- descriptor will return the same event, and this read will -- not result in a system call. -- -- One possible downside of the current implementation is that@@ -583,7 +604,7 @@ -- buffer. This won't ever make a system call. -- -- If this returns an event, then the next read from the inotify--- descriptor will return the same event and the second read will not+-- descriptor will return the same event, and this read will not -- result in a system call. peekEventFromBuffer :: Inotify -> IO (Maybe Event)