packages feed

hinotify 0.3.9 → 0.3.10

raw patch · 9 files changed

+115/−81 lines, 9 filesdep +bytestringdep ~asyncPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: bytestring

Dependency ranges changed: async

API changes (from Hackage documentation)

- System.INotify: Accessed :: Bool -> Maybe FilePath -> Event
+ System.INotify: Accessed :: Bool -> Maybe RawFilePath -> Event
- System.INotify: Attributes :: Bool -> Maybe FilePath -> Event
+ System.INotify: Attributes :: Bool -> Maybe RawFilePath -> Event
- System.INotify: Closed :: Bool -> Maybe FilePath -> Bool -> Event
+ System.INotify: Closed :: Bool -> Maybe RawFilePath -> Bool -> Event
- System.INotify: Created :: Bool -> FilePath -> Event
+ System.INotify: Created :: Bool -> RawFilePath -> Event
- System.INotify: Deleted :: Bool -> FilePath -> Event
+ System.INotify: Deleted :: Bool -> RawFilePath -> Event
- System.INotify: Modified :: Bool -> Maybe FilePath -> Event
+ System.INotify: Modified :: Bool -> Maybe RawFilePath -> Event
- System.INotify: MovedIn :: Bool -> FilePath -> Cookie -> Event
+ System.INotify: MovedIn :: Bool -> RawFilePath -> Cookie -> Event
- System.INotify: MovedOut :: Bool -> FilePath -> Cookie -> Event
+ System.INotify: MovedOut :: Bool -> RawFilePath -> Cookie -> Event
- System.INotify: Opened :: Bool -> Maybe FilePath -> Event
+ System.INotify: Opened :: Bool -> Maybe RawFilePath -> Event
- System.INotify: [filePath] :: Event -> FilePath
+ System.INotify: [filePath] :: Event -> RawFilePath
- System.INotify: [maybeFilePath] :: Event -> Maybe FilePath
+ System.INotify: [maybeFilePath] :: Event -> Maybe RawFilePath
- System.INotify: addWatch :: INotify -> [EventVariety] -> FilePath -> (Event -> IO ()) -> IO WatchDescriptor
+ System.INotify: addWatch :: INotify -> [EventVariety] -> RawFilePath -> (Event -> IO ()) -> IO WatchDescriptor

Files

CHANGELOG.md view
@@ -1,6 +1,15 @@ hinotify ====== +hinotify-0.3.10+---------------++- Allow async-2.2.+- Use `RawFilePath` (`ByteString`) for filenames, from `unix` package.++  Changes the `Event` type and `addWatch` function.++ hinotify-0.3.9 -------------- 
hinotify.cabal view
@@ -1,5 +1,5 @@ name:               hinotify-version:            0.3.9+version:            0.3.10 build-type:         Simple synopsis:           Haskell binding to inotify description:@@ -21,8 +21,8 @@  library     default-language: Haskell2010-    build-depends:  base >= 4.5.0.0 && < 5, containers, directory, unix,-                    async >= 1.0 && < 2.2+    build-depends:  base >= 4.5.0.0 && < 5, bytestring, containers, unix,+                    async >= 1.0 && < 2.3      exposed-modules:         System.INotify@@ -36,7 +36,7 @@ test-suite test001     type: exitcode-stdio-1.0     default-language: Haskell2010-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     hs-source-dirs: src tests     main-is: test001-list-dir-contents.hs     other-modules: Utils@@ -45,7 +45,7 @@ test-suite test002     type: exitcode-stdio-1.0     default-language: Haskell2010-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     hs-source-dirs: src tests     main-is: test002-writefile.hs     other-modules: Utils@@ -54,7 +54,7 @@ test-suite test003     type: exitcode-stdio-1.0     default-language: Haskell2010-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     hs-source-dirs: src tests     main-is: test003-removefile.hs     other-modules: Utils@@ -63,7 +63,7 @@ test-suite test004     type: exitcode-stdio-1.0     default-language: Haskell2010-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     hs-source-dirs: src tests     main-is: test004-modify-file.hs     other-modules: Utils@@ -71,7 +71,7 @@  test-suite test005     type: exitcode-stdio-1.0-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     default-language: Haskell2010     hs-source-dirs: src tests     main-is: test005-move-file.hs@@ -80,7 +80,7 @@  test-suite test006     type: exitcode-stdio-1.0-    build-depends: base, directory, hinotify+    build-depends: base, bytestring, directory, hinotify, unix     default-language: Haskell2010     hs-source-dirs: src tests     main-is: test006-callbackHang.hs
src/System/INotify.hsc view
@@ -15,7 +15,7 @@ -- Use 'initINotify' to get a 'INotify', then use 'addWatch' to -- add a watch on a file or directory. Select which events you're interested -- in with 'EventVariety', which corresponds to the 'Event' events.--- +-- -- Use 'removeWatch' once you don't want to watch a file any more. -- -----------------------------------------------------------------------------@@ -43,18 +43,19 @@ import Data.Maybe import Data.Map (Map) import qualified Data.Map as Map-import Foreign.C hiding (withCString, peekCString)+import Foreign.C import Foreign.Marshal hiding (void) import Foreign.Ptr import Foreign.Storable import System.IO import System.IO.Error++import System.Posix.ByteString.FilePath+import System.Posix.Files.ByteString+ import GHC.IO.FD as FD (mkFD) import GHC.IO.Handle.FD (mkHandleFromFD) import GHC.IO.Device (IODeviceType(Stream))-import System.Posix.Files-import GHC.IO.Encoding (getFileSystemEncoding)-import GHC.Foreign (withCString, peekCString)  import System.INotify.Masks @@ -73,45 +74,45 @@  newtype Cookie = Cookie CUInt deriving (Eq,Ord) -data FDEvent = FDEvent WD Masks CUInt{-Cookie-} (Maybe String) deriving (Eq, Show)+data FDEvent = FDEvent WD Masks CUInt{-Cookie-} (Maybe RawFilePath) deriving (Eq, Show)  data Event =     -- | A file was accessed. @Accessed isDirectory file@       Accessed         { isDirectory :: Bool-        , maybeFilePath :: Maybe FilePath+        , maybeFilePath :: Maybe RawFilePath         }     -- | A file was modified. @Modified isDirectory file@     | Modified         { isDirectory :: Bool-        , maybeFilePath :: Maybe FilePath+        , maybeFilePath :: Maybe RawFilePath         }     -- | A files attributes where changed. @Attributes isDirectory file@     | Attributes         { isDirectory :: Bool-        , maybeFilePath :: Maybe FilePath+        , maybeFilePath :: Maybe RawFilePath         }     -- | A file was closed. @Closed isDirectory file wasWriteable@     | Closed         { isDirectory :: Bool-        , maybeFilePath :: Maybe FilePath+        , maybeFilePath :: Maybe RawFilePath         , wasWriteable :: Bool         }     -- | A file was opened. @Opened isDirectory maybeFilePath@     | Opened         { isDirectory :: Bool-        , maybeFilePath :: Maybe FilePath+        , maybeFilePath :: Maybe RawFilePath         }     -- | A file was moved away from the watched dir. @MovedFrom isDirectory from cookie@     | MovedOut         { isDirectory :: Bool-        , filePath :: FilePath+        , filePath :: RawFilePath         , moveCookie :: Cookie         }     -- | A file was moved into the watched dir. @MovedTo isDirectory to cookie@     | MovedIn         { isDirectory :: Bool-        , filePath :: FilePath+        , filePath :: RawFilePath         , moveCookie :: Cookie         }     -- | The watched file was moved. @MovedSelf isDirectory@@@ -121,12 +122,12 @@     -- | A file was created. @Created isDirectory file@     | Created         { isDirectory :: Bool-        , filePath :: FilePath+        , filePath :: RawFilePath         }     -- | A file was deleted. @Deleted isDirectory file@     | Deleted         { isDirectory :: Bool-        , filePath :: FilePath+        , filePath :: RawFilePath         }     -- | The file watched was deleted.     | DeletedSelf@@ -162,7 +163,7 @@  instance Show INotify where     show (INotify _ fd _ _ _) =-        showString "<inotify fd=" . +        showString "<inotify fd=" .         shows fd $ ">"  instance Show WatchDescriptor where@@ -187,7 +188,7 @@     (tid1, tid2) <- inotify_start_thread h em     return (INotify h fdint em tid1 tid2) -addWatch :: INotify -> [EventVariety] -> FilePath -> (Event -> IO ()) -> IO WatchDescriptor+addWatch :: INotify -> [EventVariety] -> RawFilePath -> (Event -> IO ()) -> IO WatchDescriptor addWatch inotify@(INotify _ fd em _ _) masks fp cb = do     catch_IO (void $               (if (NoSymlink `elem` masks) then getSymbolicLinkStatus else getFileStatus)@@ -195,10 +196,9 @@         ioError $ mkIOError doesNotExistErrorType              "can't watch what isn't there!"              Nothing-             (Just fp)+             (Just (show fp))     let mask = joinMasks (map eventVarietyToMask masks)-    enc <- getFileSystemEncoding-    wd <- withCString enc fp $ \fp_c ->+    wd <- withFilePath fp $ \fp_c ->             throwErrnoIfMinus1 "addWatch" $               c_inotify_add_watch (fromIntegral fd) fp_c mask     let event = \e -> ignore_failure $ do@@ -241,7 +241,11 @@       where       ignore :: SomeException -> IO ()       ignore e+##if MIN_VERSION_async(2,2,1)+        | Just AsyncCancelled <- fromException e = throwIO e+##else         | Just ThreadKilled{} <- fromException e = throwIO e+##endif         | otherwise = return ()  removeWatch :: WatchDescriptor -> IO ()@@ -255,7 +259,7 @@     modifyMVar_ em (return . Map.delete wd)  read_events :: Handle -> IO [WDEvent]-read_events h = +read_events h =     let maxRead = 16385 in     allocaBytes maxRead $ \buffer -> do         _ <- hWaitForInput h (-1)  -- wait forever@@ -272,13 +276,12 @@         nameM  <- if len == 0                     then return Nothing                     else do-                        enc <- getFileSystemEncoding-                        fmap Just $ peekCString enc ((#ptr struct inotify_event, name) ptr)-        let event_size = (#size struct inotify_event) + (fromIntegral len) +                        fmap Just $ peekFilePath ((#ptr struct inotify_event, name) ptr)+        let event_size = (#size struct inotify_event) + (fromIntegral len)             event = cEvent2Haskell (FDEvent wd mask cookie nameM)         rest <- read_events' (ptr `plusPtr` event_size) (r - event_size)         return (event:rest)-    cEvent2Haskell :: FDEvent +    cEvent2Haskell :: FDEvent                -> WDEvent     cEvent2Haskell fdevent@(FDEvent wd mask cookie nameM)         = (wd, event)@@ -324,7 +327,7 @@     runHandler (_,  e@QOverflow) = do -- send overflows to all handlers         handlers <- readMVar em         mapM_ ($ e) (Map.elems handlers)-    runHandler (wd, event) = do +    runHandler (wd, event) = do         handlers <- readMVar em         let handlerM = Map.lookup wd handlers         case handlerM of@@ -333,7 +336,11 @@      logFailure name io = io `E.catch` \e ->        case e of+##if MIN_VERSION_async(2,2,1)+         _ | Just AsyncCancelled <- fromException e -> return ()+##else          _ | Just ThreadKilled{} <- fromException e -> return ()+##endif            | otherwise -> hPutStrLn stderr (name ++ " dying: " ++ show e)  killINotify :: INotify -> IO ()
tests/Utils.hs view
@@ -1,41 +1,50 @@+{-# LANGUAGE OverloadedStrings #-} module Utils where  import Control.Concurrent.Chan import Control.Exception -import System.Directory+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as BC8+import Data.String++import System.Directory ( removeDirectoryRecursive ) import System.Environment import System.Exit  import System.INotify -testName :: IO String+import System.Posix.ByteString.FilePath+import System.Posix.Directory.ByteString+import System.Posix.Files.ByteString++testName :: IO RawFilePath testName = do     n <- getProgName-    return (n ++ "-playground")+    return (fromString n `B.append` "-playground") -withTempDir :: (String -> IO a) -> IO a+withTempDir :: (RawFilePath -> IO a) -> IO a withTempDir f = do     path <- testName     bracket-        ( createDirectory path >> return path )-        ( removeDirectoryRecursive )-        ( f )+        ( createDirectory path ownerModes >> return path )+        ( removeDirectoryRecursive . fromString . BC8.unpack )+        f -withWatch :: INotify -> [EventVariety] -> FilePath -> (Event -> IO ()) -> IO a -> IO a+withWatch :: INotify -> [EventVariety] -> RawFilePath -> (Event -> IO ()) -> IO a -> IO a withWatch inot events path action f =     bracket         ( addWatch inot events path action )         removeWatch         ( const f ) -inTestEnviron :: [EventVariety] -> (String -> IO a) -> ([Event] -> IO b) -> IO b-inTestEnviron events action f = do+inTestEnviron :: [EventVariety] -> (FilePath -> IO a) -> ([Event] -> IO b) -> IO b+inTestEnviron events action f =     withTempDir $ \testPath -> do         inot <- initINotify         chan <- newChan         withWatch inot events testPath (writeChan chan) $ do-            _ <- action testPath+            _ <- action (fromString . BC8.unpack $ testPath)             events' <- getChanContents chan             f events' @@ -56,5 +65,5 @@  testFailure, testSuccess :: IO a testFailure = exitFailure -testSuccess = exitWith ExitSuccess+testSuccess = exitSuccess 
tests/test002-writefile.hs view
@@ -1,14 +1,17 @@+{-# LANGUAGE OverloadedStrings #-} module Main where  import Control.Monad +import qualified Data.ByteString as B+ import System.INotify as INotify  import Utils -write :: String -> IO ()-write path = do-    writeFile (path ++ "/hello") ""+write :: FilePath -> IO ()+write path =+    B.writeFile (path ++ "/hello") ""     -- actually writing any contents gives me two Modified      main :: IO ()
tests/test003-removefile.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} module Main where  import Control.Monad@@ -12,11 +13,11 @@ file = "hello"  write :: String -> IO ()-write path = do+write path =     writeFile (path ++ '/':file) ""  remove :: String -> IO ()-remove path = do+remove path =     removeFile (path ++ '/':file)  action :: String -> IO ()@@ -34,9 +35,9 @@  expected :: [Event] expected =-    [ Created   False file-    , Opened    False (Just file)-    , Modified  False (Just file)-    , Closed    False (Just file) True-    , Deleted   False file+    [ Created   False "hello"+    , Opened    False (Just "hello")+    , Modified  False (Just "hello")+    , Closed    False (Just "hello") True+    , Deleted   False "hello"     ]
tests/test004-modify-file.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} module Main where  import Control.Exception@@ -14,18 +15,18 @@ file = "hello"  write :: String -> IO ()-write path = do+write path =     writeFile (path ++ '/':file) ""  modify :: String -> IO ()-modify path = do+modify path =     bracket         (openFile (path ++ '/':file) AppendMode)-        (hClose)+        hClose         (\h -> hPutStr h "yarr!")  remove :: String -> IO ()-remove path = do+remove path =     removeFile (path ++ '/':file)  action :: String -> IO ()@@ -44,12 +45,12 @@  expected :: [Event] expected =-    [ Created   False file-    , Opened    False (Just file)-    , Modified  False (Just file)-    , Closed    False (Just file) True-    , Opened    False (Just file)-    , Modified  False (Just file)-    , Closed    False (Just file) True-    , Deleted   False file+    [ Created   False "hello"+    , Opened    False (Just "hello")+    , Modified  False (Just "hello")+    , Closed    False (Just "hello") True+    , Opened    False (Just "hello")+    , Modified  False (Just "hello")+    , Closed    False (Just "hello") True+    , Deleted   False "hello"     ]
tests/test005-move-file.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE OverloadedStrings #-} module Main where  import Control.Monad+ import System.Directory  import System.INotify as INotify@@ -9,18 +11,18 @@  file, file2 :: String file = "hello"-file2 = file ++ "2"+file2 = "hello2"  write :: String -> IO ()-write path = do+write path =     writeFile (path ++ '/':file) ""  move :: String -> IO ()-move path = do+move path =     renameFile (path ++ '/':file) (path ++ '/':file2)  remove :: String -> IO ()-remove path = do+remove path =     removeFile (path ++ '/':file2)  action :: String -> IO ()@@ -40,11 +42,11 @@  expected :: Cookie -> [Event] expected cookie =-    [ Created   False file-    , Opened    False (Just file)-    , Modified  False (Just file)-    , Closed    False (Just file) True-    , MovedOut  False file  cookie-    , MovedIn   False file2 cookie-    , Deleted   False file2+    [ Created   False "hello"+    , Opened    False (Just "hello")+    , Modified  False (Just "hello")+    , Closed    False (Just "hello") True+    , MovedOut  False "hello"  cookie+    , MovedIn   False "hello2" cookie+    , Deleted   False "hello2"     ]
tests/test006-callbackHang.hs view
@@ -1,5 +1,7 @@+{-# LANGUAGE OverloadedStrings #-} module Main where +import qualified Data.ByteString.Char8 as BC8 import Control.Concurrent import Control.Exception @@ -30,5 +32,5 @@             _ <- addWatch inot [AllEvents] testPath $ \_event -> do                 putMVar mvar1 ()                 takeMVar mvar2 -- hangs here-            write testPath+            write (BC8.unpack testPath)             takeMVar mvar1