packages feed

hpath-directory 0.13.0 → 0.13.1

raw patch · 8 files changed

+10/−422 lines, 8 filesdep +hpath-posixPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: hpath-posix

API changes (from Hackage documentation)

- System.Posix.FD: openFd :: RawFilePath -> OpenMode -> [Flags] -> Maybe FileMode -> IO Fd
- System.Posix.Foreign: DirType :: Int -> DirType
- System.Posix.Foreign: Flags :: Int -> Flags
- System.Posix.Foreign: UnsupportedFlag :: String -> Flags
- System.Posix.Foreign: data Flags
- System.Posix.Foreign: dtBlk :: DirType
- System.Posix.Foreign: dtChr :: DirType
- System.Posix.Foreign: dtDir :: DirType
- System.Posix.Foreign: dtFifo :: DirType
- System.Posix.Foreign: dtLnk :: DirType
- System.Posix.Foreign: dtReg :: DirType
- System.Posix.Foreign: dtSock :: DirType
- System.Posix.Foreign: dtUnknown :: DirType
- System.Posix.Foreign: instance GHC.Classes.Eq System.Posix.Foreign.DirType
- System.Posix.Foreign: instance GHC.Classes.Eq System.Posix.Foreign.Flags
- System.Posix.Foreign: instance GHC.Show.Show System.Posix.Foreign.DirType
- System.Posix.Foreign: instance GHC.Show.Show System.Posix.Foreign.Flags
- System.Posix.Foreign: isSupported :: Flags -> Bool
- System.Posix.Foreign: newtype DirType
- System.Posix.Foreign: oAppend :: Flags
- System.Posix.Foreign: oAsync :: Flags
- System.Posix.Foreign: oCloexec :: Flags
- System.Posix.Foreign: oCreat :: Flags
- System.Posix.Foreign: oDirectory :: Flags
- System.Posix.Foreign: oExcl :: Flags
- System.Posix.Foreign: oNoctty :: Flags
- System.Posix.Foreign: oNofollow :: Flags
- System.Posix.Foreign: oNonblock :: Flags
- System.Posix.Foreign: oRdonly :: Flags
- System.Posix.Foreign: oRdwr :: Flags
- System.Posix.Foreign: oSync :: Flags
- System.Posix.Foreign: oTrunc :: Flags
- System.Posix.Foreign: oWronly :: Flags
- System.Posix.Foreign: pathMax :: Int
- System.Posix.Foreign: unFlags :: Flags -> Int
- System.Posix.Foreign: unionFlags :: [Flags] -> CInt
- System.Posix.RawFilePath.Directory.Traversals: allDirectoryContents :: RawFilePath -> IO [RawFilePath]
- System.Posix.RawFilePath.Directory.Traversals: allDirectoryContents' :: RawFilePath -> IO [RawFilePath]
- System.Posix.RawFilePath.Directory.Traversals: fdOpendir :: Fd -> IO DirStream
- System.Posix.RawFilePath.Directory.Traversals: getDirectoryContents :: RawFilePath -> IO [(DirType, RawFilePath)]
- System.Posix.RawFilePath.Directory.Traversals: getDirectoryContents' :: Fd -> IO [(DirType, RawFilePath)]
- System.Posix.RawFilePath.Directory.Traversals: packDirStream :: Ptr CDir -> DirStream
- System.Posix.RawFilePath.Directory.Traversals: readDirEnt :: DirStream -> IO (DirType, RawFilePath)
- System.Posix.RawFilePath.Directory.Traversals: realpath :: RawFilePath -> IO RawFilePath
- System.Posix.RawFilePath.Directory.Traversals: traverseDirectory :: (s -> RawFilePath -> IO s) -> s -> RawFilePath -> IO s
- System.Posix.RawFilePath.Directory.Traversals: unpackDirStream :: DirStream -> Ptr CDir

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for hpath-directory +## 0.13.1 -- 2020-01-29++* Split some functionality out into 'hpath-posix'+ ## 0.1.0.0 -- 2020-01-26  * First version. Released on an unsuspecting world.
− cbits/dirutils.c
@@ -1,7 +0,0 @@-#include "dirutils.h"-unsigned int-    __posixdir_d_type(struct dirent* d)-    {-      return(d -> d_type);-    }-
− cbits/dirutils.h
@@ -1,13 +0,0 @@-#ifndef POSIXPATHS_CBITS_DIRUTILS_H-#define POSIXPATHS_CBITS_DIRUTILS_H--#include <stdlib.h>-#include <dirent.h>-#include <sys/types.h>-#include <sys/stat.h>-#include <fcntl.h>--extern unsigned int-    __posixdir_d_type(struct dirent* d)-    ;-#endif
hpath-directory.cabal view
@@ -1,7 +1,7 @@ cabal-version:       >=1.10  name:                hpath-directory-version:             0.13.0+version:             0.13.1 synopsis:            Alternative to 'directory' package with ByteString based filepaths description:         This provides a safer alternative to the 'directory'                      package. FilePaths are ByteString based, so this@@ -20,7 +20,6 @@ category:            Filesystem build-type:          Simple extra-source-files:  CHANGELOG.md-                     cbits/dirutils.h tested-with:         GHC==7.10.3                    , GHC==8.0.2                    , GHC==8.2.2@@ -34,20 +33,17 @@     buildable: False   exposed-modules:     System.Posix.RawFilePath.Directory                        System.Posix.RawFilePath.Directory.Errors-                       System.Posix.RawFilePath.Directory.Traversals-                       System.Posix.Foreign,-                       System.Posix.FD   -- other-modules:   -- other-extensions:-  c-sources:           cbits/dirutils.c   build-depends:         base                >= 4.8  && <5                        , IfElse                        , bytestring          >= 0.10                        , exceptions          >= 0.10                        , hpath-filepath      >= 0.10.3+                       , hpath-posix         >= 0.13                        , safe-exceptions     >= 0.1                        , streamly            >= 0.7-                       , streamly-bytestring >= 0.1+                       , streamly-bytestring >= 0.1.0.1                        , time                >= 1.8                        , unix                >= 2.5                        , unix-bytestring     >= 0.3@@ -104,6 +100,7 @@                       , bytestring >= 0.10.0.0                       , hpath-directory                       , hpath-filepath >= 0.10+                      , hpath-posix    >= 0.13                       , hspec >= 1.3                       , process                       , time >= 1.8
− src/System/Posix/FD.hs
@@ -1,75 +0,0 @@--- |--- Module      :  System.Posix.FD--- Copyright   :  © 2016 Julian Ospald--- License     :  BSD3------ Maintainer  :  Julian Ospald <hasufell@posteo.de>--- Stability   :  experimental--- Portability :  portable------ Provides an alternative for `System.Posix.IO.ByteString.openFd`--- which gives us more control on what status flags to pass to the--- low-level @open(2)@ call, in contrast to the unix package.---{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TupleSections #-}--{-# OPTIONS_GHC -Wall #-}---module System.Posix.FD (-    openFd-) where---import Foreign.C.String-import Foreign.C.Types-import System.Posix.Foreign-import qualified System.Posix as Posix-import System.Posix.ByteString.FilePath---foreign import ccall unsafe "open"-   c_open :: CString -> CInt -> Posix.CMode -> IO CInt---open_  :: CString-       -> Posix.OpenMode-       -> [Flags]-       -> Maybe Posix.FileMode-       -> IO Posix.Fd-open_ str how optional_flags maybe_mode = do-    fd <- c_open str all_flags mode_w-    return (Posix.Fd fd)-  where-    all_flags  = unionFlags $ optional_flags ++ [open_mode] ++ creat---    (creat, mode_w) = case maybe_mode of-                        Nothing -> ([],0)-                        Just x  -> ([oCreat], x)--    open_mode = case how of-                   Posix.ReadOnly  -> oRdonly-                   Posix.WriteOnly -> oWronly-                   Posix.ReadWrite -> oRdwr----- |Open and optionally create this file. See 'System.Posix.Files'--- for information on how to use the 'FileMode' type.------ Note that passing @Just x@ as the 4th argument triggers the--- `oCreat` status flag, which must be set when you pass in `oExcl`--- to the status flags. Also see the manpage for @open(2)@.-openFd :: RawFilePath-       -> Posix.OpenMode-       -> [Flags]               -- ^ status flags of @open(2)@-       -> Maybe Posix.FileMode  -- ^ @Just x@ => creates the file with the given modes, Nothing => the file must exist.-       -> IO Posix.Fd-openFd name how optional_flags maybe_mode =-   withFilePath name $ \str ->-     throwErrnoPathIfMinus1Retry "openFd" name $-       open_ str how optional_flags maybe_mode-
− src/System/Posix/Foreign.hsc
@@ -1,55 +0,0 @@-module System.Posix.Foreign where--import Data.Bits-import Data.List (foldl')-import Foreign.C.Types--#include <limits.h>-#include <stdlib.h>-#include <dirent.h>-#include <sys/types.h>-#include <sys/stat.h>-#include <fcntl.h>--newtype DirType = DirType Int deriving (Eq, Show)-data Flags = Flags Int | UnsupportedFlag String deriving (Eq, Show)--unFlags :: Flags -> Int-unFlags (Flags i) = i-unFlags (UnsupportedFlag name) = error (name ++ " is not supported on this platform")---- |Returns @True@ if posix-paths was compiled with support for the provided--- flag. (As of this writing, the only flag for which this check may be--- necessary is 'oCloexec'; all other flags will always yield @True@.)-isSupported :: Flags -> Bool-isSupported (Flags _) = True-isSupported _ = False---- |@O_CLOEXEC@ is not supported on every POSIX platform. Use--- @'isSupported' oCloexec@ to determine if support for @O_CLOEXEC@ was--- compiled into your version of posix-paths. (If not, using @oCloexec@ will--- throw an exception.)-oCloexec :: Flags-#ifdef O_CLOEXEC-oCloexec = Flags #{const O_CLOEXEC}-#else-{-# WARNING oCloexec-    "This version of posix-paths was compiled without @O_CLOEXEC@ support." #-}-oCloexec = UnsupportedFlag "O_CLOEXEC"-#endif------ If these enum declarations occur earlier in the file, haddock--- gets royally confused about the above doc comments.--- Probably http://trac.haskell.org/haddock/ticket/138--#{enum DirType, DirType, DT_BLK, DT_CHR, DT_DIR, DT_FIFO, DT_LNK, DT_REG, DT_SOCK, DT_UNKNOWN}--#{enum Flags, Flags, O_APPEND, O_ASYNC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_RDONLY, O_WRONLY, O_RDWR, O_SYNC, O_TRUNC}--pathMax :: Int-pathMax = #{const PATH_MAX}--unionFlags :: [Flags] -> CInt-unionFlags = fromIntegral . foldl' ((. unFlags) . (.|.)) 0
src/System/Posix/RawFilePath/Directory.hs view
@@ -891,7 +891,7 @@   --- | Open the given file as a filestream. Once the filestream+-- | Open the given file as a filestream. Once the filestream is -- exits, the filehandle is cleaned up. -- -- Throws:@@ -905,7 +905,7 @@   fd     <- openFd fp SPI.ReadOnly [] Nothing   handle <- SPI.fdToHandle fd   let stream =-        fmap fromArray (S.unfold (SU.finally (\h -> putStrLn "lol" >> SIO.hClose h) FH.readChunks) handle)+        fmap fromArray (S.unfold (SU.finally SIO.hClose FH.readChunks) handle)   pure stream  
− src/System/Posix/RawFilePath/Directory/Traversals.hs
@@ -1,263 +0,0 @@--- |--- Module      :  System.Posix.RawFilePath.Directory.Traversals--- Copyright   :  © 2016 Julian Ospald--- License     :  BSD3------ Maintainer  :  Julian Ospald <hasufell@posteo.de>--- Stability   :  experimental--- Portability :  portable------ Traversal and read operations on directories.---{-# LANGUAGE CPP #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE ViewPatterns #-}--{-# OPTIONS_GHC -Wall #-}---module System.Posix.RawFilePath.Directory.Traversals (--  getDirectoryContents-, getDirectoryContents'--, allDirectoryContents-, allDirectoryContents'-, traverseDirectory---- lower-level stuff-, readDirEnt-, packDirStream-, unpackDirStream-, fdOpendir--, realpath-) where---#if __GLASGOW_HASKELL__ < 710-import Control.Applicative ((<$>))-#endif-import Control.Monad-import System.Posix.FilePath ((</>))-import System.Posix.Foreign--import qualified System.Posix as Posix-import System.IO.Error-import Control.Exception-import qualified Data.ByteString.Char8 as BS-import System.Posix.ByteString.FilePath-import System.Posix.Directory.ByteString as PosixBS-import System.Posix.Files.ByteString--import System.IO.Unsafe-import "unix" System.Posix.IO.ByteString (closeFd)-import Unsafe.Coerce (unsafeCoerce)-import Foreign.C.Error-import Foreign.C.String-import Foreign.C.Types-import Foreign.Marshal.Alloc (alloca,allocaBytes)-import Foreign.Ptr-import Foreign.Storable------------------------------------------------------------------- | Get all files from a directory and its subdirectories.------ Upon entering a directory, 'allDirectoryContents' will get all entries--- strictly.  However the returned list is lazy in that directories will only--- be accessed on demand.------ Follows symbolic links for the input dir.-allDirectoryContents :: RawFilePath -> IO [RawFilePath]-allDirectoryContents topdir = do-    namesAndTypes <- getDirectoryContents topdir-    let properNames = filter ((`notElem` [".", ".."]) . snd) namesAndTypes-    paths <- forM properNames $ \(typ,name) -> unsafeInterleaveIO $ do-        let path = topdir </> name-        case () of-            () | typ == dtDir -> allDirectoryContents path-               | typ == dtUnknown -> do-                    isDir <- isDirectory <$> getFileStatus path-                    if isDir-                        then allDirectoryContents path-                        else return [path]-               | otherwise -> return [path]-    return (topdir : concat paths)---- | Get all files from a directory and its subdirectories strictly.------ Follows symbolic links for the input dir.-allDirectoryContents' :: RawFilePath -> IO [RawFilePath]-allDirectoryContents' = fmap reverse . traverseDirectory (\acc fp -> return (fp:acc)) []--- this uses traverseDirectory because it's more efficient than forcing the--- lazy version.---- | Recursively apply the 'action' to the parent directory and all--- files/subdirectories.------ This function allows for memory-efficient traversals.------ Follows symbolic links for the input dir.-traverseDirectory :: (s -> RawFilePath -> IO s) -> s -> RawFilePath -> IO s-traverseDirectory act s0 topdir = toploop-  where-    toploop = do-        isDir <- isDirectory <$> getFileStatus topdir-        s' <- act s0 topdir-        if isDir then actOnDirContents topdir s' loop-                 else return s'-    loop typ path acc = do-        isDir <- case () of-            () | typ == dtDir     -> return True-               | typ == dtUnknown -> isDirectory <$> getFileStatus path-               | otherwise        -> return False-        if isDir-          then act acc path >>= \acc' -> actOnDirContents path acc' loop-          else act acc path--actOnDirContents :: RawFilePath-                 -> b-                 -> (DirType -> RawFilePath -> b -> IO b)-                 -> IO b-actOnDirContents pathRelToTop b f =-  modifyIOError ((`ioeSetFileName` (BS.unpack pathRelToTop)) .-                 (`ioeSetLocation` "findBSTypRel")) $-    bracket-      (openDirStream pathRelToTop)-      Posix.closeDirStream-      (\dirp -> loop dirp b)- where-  loop dirp b' = do-    (typ,e) <- readDirEnt dirp-    if (e == "")-      then return b'-      else-          if (e == "." || e == "..")-              then loop dirp b'-              else f typ (pathRelToTop </> e) b' >>= loop dirp---------------------------------------------------------------- dodgy stuff--type CDir = ()-type CDirent = ()---- Posix doesn't export DirStream, so to re-use that type we need to use--- unsafeCoerce.  It's just a newtype, so this is a legitimate usage.--- ugly trick.-unpackDirStream :: DirStream -> Ptr CDir-unpackDirStream = unsafeCoerce--packDirStream :: Ptr CDir -> DirStream-packDirStream = unsafeCoerce---- the __hscore_* functions are defined in the unix package.  We can import them and let--- the linker figure it out.-foreign import ccall unsafe "__hscore_readdir"-  c_readdir  :: Ptr CDir -> Ptr (Ptr CDirent) -> IO CInt--foreign import ccall unsafe "__hscore_free_dirent"-  c_freeDirEnt  :: Ptr CDirent -> IO ()--foreign import ccall unsafe "__hscore_d_name"-  c_name :: Ptr CDirent -> IO CString--foreign import ccall unsafe "__posixdir_d_type"-  c_type :: Ptr CDirent -> IO DirType--foreign import ccall "realpath"-  c_realpath :: CString -> CString -> IO CString--foreign import ccall unsafe "fdopendir"-  c_fdopendir :: Posix.Fd -> IO (Ptr ())--------------------------------------------------------------- less dodgy but still lower-level---readDirEnt :: DirStream -> IO (DirType, RawFilePath)-readDirEnt (unpackDirStream -> dirp) =-  alloca $ \ptr_dEnt  -> loop ptr_dEnt- where-  loop ptr_dEnt = do-    resetErrno-    r <- c_readdir dirp ptr_dEnt-    if (r == 0)-       then do-         dEnt <- peek ptr_dEnt-         if (dEnt == nullPtr)-            then return (dtUnknown,BS.empty)-            else do-                 dName <- c_name dEnt >>= peekFilePath-                 dType <- c_type dEnt-                 c_freeDirEnt dEnt-                 return (dType, dName)-       else do-         errno <- getErrno-         if (errno == eINTR)-            then loop ptr_dEnt-            else do-                 let (Errno eo) = errno-                 if (eo == 0)-                    then return (dtUnknown,BS.empty)-                    else throwErrno "readDirEnt"----- |Gets all directory contents (not recursively).-getDirectoryContents :: RawFilePath -> IO [(DirType, RawFilePath)]-getDirectoryContents path =-  modifyIOError ((`ioeSetFileName` (BS.unpack path)) .-                 (`ioeSetLocation` "System.Posix.RawFilePath.Directory.Traversals.getDirectoryContents")) $-    bracket-      (PosixBS.openDirStream path)-      PosixBS.closeDirStream-      _dirloop----- |Binding to @fdopendir(3)@.-fdOpendir :: Posix.Fd -> IO DirStream-fdOpendir fd =-    packDirStream <$> throwErrnoIfNull "fdOpendir" (c_fdopendir fd)----- |Like `getDirectoryContents` except for a file descriptor.------ To avoid complicated error checks, the file descriptor is--- __always__ closed, even if `fdOpendir` fails. Usually, this--- only happens on successful `fdOpendir` and after the directory--- stream is closed. Also see the manpage of @fdopendir(3)@ for--- more details.-getDirectoryContents' :: Posix.Fd -> IO [(DirType, RawFilePath)]-getDirectoryContents' fd = do-  dirstream <- fdOpendir fd `catchIOError` \e -> do-    closeFd fd-    ioError e-  -- closeDirStream closes the filedescriptor-  finally (_dirloop dirstream) (PosixBS.closeDirStream dirstream)---_dirloop :: DirStream -> IO [(DirType, RawFilePath)]-{-# INLINE _dirloop #-}-_dirloop dirp = do-   t@(_typ,e) <- readDirEnt dirp-   if BS.null e then return [] else do-     es <- _dirloop dirp-     return (t:es)----- | return the canonicalized absolute pathname------ like canonicalizePath, but uses @realpath(3)@-realpath :: RawFilePath -> IO RawFilePath-realpath inp =-    allocaBytes pathMax $ \tmp -> do-        void $ BS.useAsCString inp $ \cstr -> throwErrnoIfNull "realpath" $ c_realpath cstr tmp-        BS.packCString tmp