diff --git a/HPath-IO-Errors.html b/HPath-IO-Errors.html index 8a99629..99dc52b 100644 --- a/HPath-IO-Errors.html +++ b/HPath-IO-Errors.html @@ -1,22 +1,22 @@ -HPath.IO.Errors

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath.IO.Errors

Contents

Description

Provides error handling.

Synopsis

Types

Exception identifiers

Path based functions

throwSameFile :: Path Abs -> Path Abs -> IO () Source #

Uses isSameFile and throws SameFile if it returns True.

sameFile :: Path Abs -> Path Abs -> IO Bool Source #

Check if the files are the same by examining device and file id. - This follows symbolic links.

throwDestinationInSource Source #

Arguments

:: Path Abs

source dir

-> Path Abs

full destination, dirname dest - must exist

-> IO () 

Checks whether the destination directory is contained +

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath.IO.Errors

Description

Provides error handling.

Synopsis

Types

Exception identifiers

Path based functions

throwSameFile :: Path Abs -> Path Abs -> IO () Source

Uses isSameFile and throws SameFile if it returns True.

sameFile :: Path Abs -> Path Abs -> IO Bool Source

Check if the files are the same by examining device and file id. + This follows symbolic links.

throwDestinationInSource Source

Arguments

:: Path Abs

source dir

-> Path Abs

full destination, dirname dest + must exist

-> IO () 

Checks whether the destination directory is contained within the source directory by comparing the device+file ID of the source directory with all device+file IDs of the parent directories - of the destination.

doesFileExist :: Path Abs -> IO Bool Source #

Checks if the given file exists and is not a directory. - Does not follow symlinks.

doesDirectoryExist :: Path Abs -> IO Bool Source #

Checks if the given file exists and is a directory. - Does not follow symlinks.

isWritable :: Path Abs -> IO Bool Source #

Checks whether a file or folder is writable.

canOpenDirectory :: Path Abs -> IO Bool Source #

Checks whether the directory at the given path exists and can be - opened. This invokes openDirStream which follows symlinks.

throwCantOpenDirectory :: Path Abs -> IO () Source #

Throws a Can'tOpenDirectory HPathIOException if the directory at the given - path cannot be opened.

Error handling functions

catchErrno Source #

Arguments

:: [Errno]

errno to catch

-> IO a

action to try, which can raise an IOException

-> IO a

action to carry out in case of an IOException and - if errno matches

-> IO a 

Carries out an action, then checks if there is an IOException and + of the destination.

doesFileExist :: Path Abs -> IO Bool Source

Checks if the given file exists and is not a directory. + Does not follow symlinks.

doesDirectoryExist :: Path Abs -> IO Bool Source

Checks if the given file exists and is a directory. + Does not follow symlinks.

isWritable :: Path Abs -> IO Bool Source

Checks whether a file or folder is writable.

canOpenDirectory :: Path Abs -> IO Bool Source

Checks whether the directory at the given path exists and can be + opened. This invokes openDirStream which follows symlinks.

throwCantOpenDirectory :: Path Abs -> IO () Source

Throws a Can'tOpenDirectory HPathIOException if the directory at the given + path cannot be opened.

Error handling functions

catchErrno Source

Arguments

:: [Errno]

errno to catch

-> IO a

action to try, which can raise an IOException

-> IO a

action to carry out in case of an IOException and + if errno matches

-> IO a 

Carries out an action, then checks if there is an IOException and a specific errno. If so, then it carries out another action, otherwise - it rethrows the error.

rethrowErrnoAs Source #

Arguments

:: Exception e 
=> [Errno]

errno to catch

-> e

rethrow as if errno matches

-> IO a

action to try

-> IO a 

Execute the given action and retrow IO exceptions as a new Exception + it rethrows the error.

rethrowErrnoAs Source

Arguments

:: Exception e 
=> [Errno]

errno to catch

-> e

rethrow as if errno matches

-> IO a

action to try

-> IO a 

Execute the given action and retrow IO exceptions as a new Exception that have the given errno. If errno does not match the exception is rethrown - as is.

handleIOError :: (IOError -> IO a) -> IO a -> IO a Source #

Like catchIOError, with arguments swapped.

bracketeer Source #

Arguments

:: IO a

computation to run first

-> (a -> IO b)

computation to run last, when - no exception was raised

-> (a -> IO b)

computation to run last, - when an exception was raised

-> (a -> IO c)

computation to run in-between

-> IO c 

Like bracket, but allows to have different clean-up + as is.

handleIOError :: (IOError -> IO a) -> IO a -> IO a Source

Like catchIOError, with arguments swapped.

bracketeer Source

Arguments

:: IO a

computation to run first

-> (a -> IO b)

computation to run last, when + no exception was raised

-> (a -> IO b)

computation to run last, + when an exception was raised

-> (a -> IO c)

computation to run in-between

-> IO c 

Like bracket, but allows to have different clean-up actions depending on whether the in-between computation - has raised an exception or not.

reactOnError Source #

Arguments

:: IO a 
-> [(IOErrorType, IO a)]

reaction on IO errors

-> [(HPathIOException, IO a)]

reaction on HPathIOException

-> IO a 
\ No newline at end of file + has raised an exception or not.

reactOnError Source

Arguments

:: IO a 
-> [(IOErrorType, IO a)]

reaction on IO errors

-> [(HPathIOException, IO a)]

reaction on HPathIOException

-> IO a 
\ No newline at end of file diff --git a/HPath-IO-Utils.html b/HPath-IO-Utils.html index cb433f6..9e2ee59 100644 --- a/HPath-IO-Utils.html +++ b/HPath-IO-Utils.html @@ -1,6 +1,6 @@ -HPath.IO.Utils

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath.IO.Utils

Description

Random and general IO/monad utilities.

Synopsis

Documentation

whenM :: Monad m => m Bool -> m () -> m () Source #

If the value of the first argument is True, then execute the action - provided in the second argument, otherwise do nothing.

unlessM :: Monad m => m Bool -> m () -> m () Source #

If the value of the first argument is False, then execute the action - provided in the second argument, otherwise do nothing.

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath.IO.Utils

Description

Random and general IO/monad utilities.

Synopsis

Documentation

whenM :: Monad m => m Bool -> m () -> m () Source

If the value of the first argument is True, then execute the action + provided in the second argument, otherwise do nothing.

unlessM :: Monad m => m Bool -> m () -> m () Source

If the value of the first argument is False, then execute the action + provided in the second argument, otherwise do nothing.

\ No newline at end of file diff --git a/HPath-IO.html b/HPath-IO.html index 212d11e..6feb5f5 100644 --- a/HPath-IO.html +++ b/HPath-IO.html @@ -1,4 +1,4 @@ -HPath.IO

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

HPath.IO

Contents

Description

This module provides high-level IO related file operations like @@ -16,55 +16,55 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath-IO.html");}; exception handling is kept.

Note: BlockDevice, CharacterDevice, NamedPipe and Socket are ignored by some of the more high-level functions (like easyCopy). For other functions (like copyFile), the behavior on these file types is - unreliable/unsafe. Check the documentation of those functions for details.

Synopsis

Types

data RecursiveMode Source #

The mode for any recursive operation.

On FailEarly the whole operation fails immediately if any of the + unreliable/unsafe. Check the documentation of those functions for details.

Types

data RecursiveErrorMode Source

The error mode for any recursive operation.

On FailEarly the whole operation fails immediately if any of the recursive sub-operations fail, which is sort of the default for IO operations.

On CollectFailures skips errors in the recursion and keeps on recursing. However all errors are collected in the RecursiveFailure error type, - which is raised finally if there was any error.

Constructors

FailEarly 
CollectFailures 

data CopyMode Source #

The mode for copy and file moves. + which is raised finally if there was any error.

Constructors

FailEarly 
CollectFailures 

data CopyMode Source

The mode for copy and file moves. Overwrite mode is usually not very well defined, but is a convenience - shortcut.

Constructors

Strict

fail if any target exists

Overwrite

overwrite targets

File copying

copyDirRecursive Source #

Arguments

:: Path Abs

source dir

-> Path Abs

full destination

-> CopyMode 
-> RecursiveMode 
-> IO () 

Copies a directory recursively to the given destination. + shortcut.

Constructors

Strict

fail if any target exists

Overwrite

overwrite targets

File copying

copyDirRecursive Source

Arguments

:: Path Abs

source dir

-> Path Abs

full destination

-> CopyMode 
-> RecursiveErrorMode 
-> IO () 

Copies a directory recursively to the given destination. Does not follow symbolic links.

For directory contents, this will ignore any file type that is not - RegularFile, SymbolicLink or Directory.

For Overwrite mode this does not prune destination directory contents, + RegularFile, SymbolicLink or Directory.

For Overwrite copy mode this does not prune destination directory contents, so the destination might contain more files than the source after the operation has completed.

Note that there is no guaranteed ordering of the exceptions - contained within RecursiveFailure in CollectFailures RecursiveMode.

Safety/reliability concerns:

  • not atomic
  • examines filetypes explicitly
  • an explicit check throwDestinationInSource is carried out for the + contained within RecursiveFailure in CollectFailures RecursiveErrorMode.

    Safety/reliability concerns:

    • not atomic
    • examines filetypes explicitly
    • an explicit check throwDestinationInSource is carried out for the top directory for basic sanity, because otherwise we might end up with an infinite copy loop... however, this operation is not carried out recursively (because it's slow)

    Throws:

    Throws in FailEarly RecursiveMode only:

    • PermissionDenied if output directory is not writable
    • InvalidArgument if source directory is wrong type (symlink)
    • InappropriateType if source directory is wrong type (regular file)

    Throws in CollectFailures RecursiveMode only:

    Throws in Strict CopyMode only:

    • AlreadyExists if destination already exists

recreateSymlink Source #

Arguments

:: Path Abs

the old symlink file

-> Path Abs

destination file

-> CopyMode 
-> IO () 

Recreate a symlink.

In Overwrite mode only files and empty directories are deleted.

Safety/reliability concerns:

Throws:

  • InvalidArgument if source file is wrong type (not a symlink)
  • PermissionDenied if output directory cannot be written to
  • PermissionDenied if source directory cannot be opened
  • SameFile if source and destination are the same file - (HPathIOException)

Throws in Strict mode only:

  • AlreadyExists if destination file already exists

Throws in Overwrite mode only:

  • UnsatisfiedConstraints if destination file is non-empty directory

Note: calls symlink

copyFile Source #

Arguments

:: Path Abs

source file

-> Path Abs

destination file

-> CopyMode 
-> IO () 

Copies the given regular file to the given destination. + (HPathIOException)

Throws in FailEarly RecursiveErrorMode only:

  • PermissionDenied if output directory is not writable
  • InvalidArgument if source directory is wrong type (symlink)
  • InappropriateType if source directory is wrong type (regular file)

Throws in CollectFailures RecursiveErrorMode only:

Throws in Strict CopyMode only:

  • AlreadyExists if destination already exists

recreateSymlink Source

Arguments

:: Path Abs

the old symlink file

-> Path Abs

destination file

-> CopyMode 
-> IO () 

Recreate a symlink.

In Overwrite copy mode only files and empty directories are deleted.

Safety/reliability concerns:

Throws:

  • InvalidArgument if source file is wrong type (not a symlink)
  • PermissionDenied if output directory cannot be written to
  • PermissionDenied if source directory cannot be opened
  • SameFile if source and destination are the same file + (HPathIOException)

Throws in Strict mode only:

  • AlreadyExists if destination file already exists

Throws in Overwrite mode only:

  • UnsatisfiedConstraints if destination file is non-empty directory

Note: calls symlink

copyFile Source

Arguments

:: Path Abs

source file

-> Path Abs

destination file

-> CopyMode 
-> IO () 

Copies the given regular file to the given destination. Neither follows symbolic links, nor accepts them. For "copying" symbolic links, use recreateSymlink instead.

Note that this is still sort of a low-level function and doesn't examine file types. For a more high-level version, use easyCopy - instead.

In Overwrite mode only overwrites actual files, not directories.

Safety/reliability concerns:

  • Overwrite mode is not atomic
  • when used on CharacterDevice, reads the "contents" and copies + instead.

    In Overwrite copy mode only overwrites actual files, not directories.

    Safety/reliability concerns:

    • Overwrite mode is not atomic
    • when used on CharacterDevice, reads the "contents" and copies them to a regular file, which might take indefinitely
    • when used on BlockDevice, may either read the "contents" and copy them to a regular file (potentially hanging indefinitely) or may create a regular empty destination file
    • when used on NamedPipe, will hang indefinitely

    Throws:

    • NoSuchThing if source file does not exist
    • NoSuchThing if source file is a a Socket
    • PermissionDenied if output directory is not writable
    • PermissionDenied if source directory can't be opened
    • InvalidArgument if source file is wrong type (symlink or directory)
    • SameFile if source and destination are the same file - (HPathIOException)

    Throws in Strict mode only:

    • AlreadyExists if destination already exists

    Note: calls sendfile and possibly read/write as fallback

easyCopy :: Path Abs -> Path Abs -> CopyMode -> RecursiveMode -> IO () Source #

Copies a regular file, directory or symbolic link. In case of a + (HPathIOException)

Throws in Strict mode only:

  • AlreadyExists if destination already exists

Note: calls sendfile and possibly read/write as fallback

easyCopy :: Path Abs -> Path Abs -> CopyMode -> RecursiveErrorMode -> IO () Source

Copies a regular file, directory or symbolic link. In case of a symbolic link it is just recreated, even if it points to a directory. - Any other file type is ignored.

Safety/reliability concerns:

File deletion

deleteFile :: Path Abs -> IO () Source #

Deletes the given file. Raises eISDIR - if run on a directory. Does not follow symbolic links.

Throws:

  • InappropriateType for wrong file type (directory)
  • NoSuchThing if the file does not exist
  • PermissionDenied if the directory cannot be read

deleteDir :: Path Abs -> IO () Source #

Deletes the given directory, which must be empty, never symlinks.

Throws:

  • InappropriateType for wrong file type (symlink to directory)
  • InappropriateType for wrong file type (regular file)
  • NoSuchThing if directory does not exist
  • UnsatisfiedConstraints if directory is not empty
  • PermissionDenied if we can't open or write to parent directory

Notes: calls rmdir

deleteDirRecursive :: Path Abs -> IO () Source #

Deletes the given directory recursively. Does not follow symbolic + Any other file type is ignored.

Safety/reliability concerns:

File deletion

deleteFile :: Path Abs -> IO () Source

Deletes the given file. Raises eISDIR + if run on a directory. Does not follow symbolic links.

Throws:

  • InappropriateType for wrong file type (directory)
  • NoSuchThing if the file does not exist
  • PermissionDenied if the directory cannot be read

deleteDir :: Path Abs -> IO () Source

Deletes the given directory, which must be empty, never symlinks.

Throws:

  • InappropriateType for wrong file type (symlink to directory)
  • InappropriateType for wrong file type (regular file)
  • NoSuchThing if directory does not exist
  • UnsatisfiedConstraints if directory is not empty
  • PermissionDenied if we can't open or write to parent directory

Notes: calls rmdir

deleteDirRecursive :: Path Abs -> IO () Source

Deletes the given directory recursively. Does not follow symbolic links. Tries deleteDir first before attemtping a recursive deletion.

On directory contents this behaves like easyDelete and thus will ignore any file type that is not RegularFile, - SymbolicLink or Directory.

Safety/reliability concerns:

  • not atomic
  • examines filetypes explicitly

Throws:

  • InappropriateType for wrong file type (symlink to directory)
  • InappropriateType for wrong file type (regular file)
  • NoSuchThing if directory does not exist
  • PermissionDenied if we can't open or write to parent directory

easyDelete :: Path Abs -> IO () Source #

Deletes a file, directory or symlink. + SymbolicLink or Directory.

Safety/reliability concerns:

  • not atomic
  • examines filetypes explicitly

Throws:

  • InappropriateType for wrong file type (symlink to directory)
  • InappropriateType for wrong file type (regular file)
  • NoSuchThing if directory does not exist
  • PermissionDenied if we can't open or write to parent directory

easyDelete :: Path Abs -> IO () Source

Deletes a file, directory or symlink. In case of directory, performs recursive deletion. In case of a symlink, the symlink file is deleted. - Any other file type is ignored.

Safety/reliability concerns:

File opening

openFile :: Path Abs -> IO ProcessID Source #

Opens a file appropriately by invoking xdg-open. The file type - is not checked. This forks a process.

executeFile Source #

Arguments

:: Path Abs

program

-> [ByteString]

arguments

-> IO ProcessID 

Executes a program with the given arguments. This forks a process.

File creation

createRegularFile :: Path Abs -> IO () Source #

Create an empty regular file at the given directory with the given - filename.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination file already exists

createDir :: Path Abs -> IO () Source #

Create an empty directory at the given directory with the given filename.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination directory already exists

createSymlink Source #

Arguments

:: Path Abs

destination file

-> ByteString

path the symlink points to

-> IO () 

Create a symlink.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination file already exists

Note: calls symlink

File renaming/moving

renameFile :: Path Abs -> Path Abs -> IO () Source #

Rename a given file with the provided filename. Destination and source - must be on the same device, otherwise eXDEV will be raised.

Does not follow symbolic links, but renames the symbolic link file.

Safety/reliability concerns:

  • has a separate set of exception handling, apart from the syscall

Throws:

  • NoSuchThing if source file does not exist
  • PermissionDenied if output directory cannot be written to
  • PermissionDenied if source directory cannot be opened
  • UnsupportedOperation if source and destination are on different + Any other file type is ignored.

    Safety/reliability concerns:

File opening

openFile :: Path Abs -> IO ProcessID Source

Opens a file appropriately by invoking xdg-open. The file type + is not checked. This forks a process.

executeFile Source

Arguments

:: Path Abs

program

-> [ByteString]

arguments

-> IO ProcessID 

Executes a program with the given arguments. This forks a process.

File creation

createRegularFile :: Path Abs -> IO () Source

Create an empty regular file at the given directory with the given + filename.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination file already exists

createDir :: Path Abs -> IO () Source

Create an empty directory at the given directory with the given filename.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination directory already exists

createSymlink Source

Arguments

:: Path Abs

destination file

-> ByteString

path the symlink points to

-> IO () 

Create a symlink.

Throws:

  • PermissionDenied if output directory cannot be written to
  • AlreadyExists if destination file already exists

Note: calls symlink

File renaming/moving

renameFile :: Path Abs -> Path Abs -> IO () Source

Rename a given file with the provided filename. Destination and source + must be on the same device, otherwise eXDEV will be raised.

Does not follow symbolic links, but renames the symbolic link file.

Safety/reliability concerns:

  • has a separate set of exception handling, apart from the syscall

Throws:

  • NoSuchThing if source file does not exist
  • PermissionDenied if output directory cannot be written to
  • PermissionDenied if source directory cannot be opened
  • UnsupportedOperation if source and destination are on different devices
  • FileDoesExist if destination file already exists (HPathIOException)
  • DirDoesExist if destination directory already exists (HPathIOException)
  • SameFile if destination and source are the same file - (HPathIOException)

Note: calls rename (but does not allow to rename over existing files)

moveFile Source #

Arguments

:: Path Abs

file to move

-> Path Abs

destination

-> CopyMode 
-> IO () 

Move a file. This also works across devices by copy-delete fallback. + (HPathIOException)

Note: calls rename (but does not allow to rename over existing files)

moveFile Source

Arguments

:: Path Abs

file to move

-> Path Abs

destination

-> CopyMode 
-> IO () 

Move a file. This also works across devices by copy-delete fallback. And also works on directories.

Does not follow symbolic links, but renames the symbolic link file.

Safety/reliability concerns:

Throws:

  • NoSuchThing if source file does not exist
  • PermissionDenied if output directory cannot be written to
  • PermissionDenied if source directory cannot be opened
  • SameFile if destination and source are the same file (HPathIOException)

Throws in Strict mode only:

Note: calls rename (but does not allow to rename over existing files)

File permissions

newFilePerms :: FileMode Source #

Default permissions for a new file.

newDirPerms :: FileMode Source #

Default permissions for a new directory.

Directory reading

getDirsFiles Source #

Arguments

:: Path Abs

dir to read

-> IO [Path Abs] 

Gets all filenames of the given directory. This excludes "." and "..". - This version does not follow symbolic links.

The contents are not sorted and there is no guarantee on the ordering.

Throws:

  • NoSuchThing if directory does not exist
  • InappropriateType if file type is wrong (file)
  • InappropriateType if file type is wrong (symlink to file)
  • InappropriateType if file type is wrong (symlink to dir)
  • PermissionDenied if directory cannot be opened

Filetype operations

getFileType :: Path Abs -> IO FileType Source #

Get the file type of the file located at the given path. Does - not follow symbolic links.

Throws:

  • NoSuchThing if the file does not exist
  • PermissionDenied if any part of the path is not accessible

Others

canonicalizePath :: Path Abs -> IO (Path Abs) Source #

Applies realpath on the given absolute path.

Throws:

  • NoSuchThing if the file at the given path does not exist
  • NoSuchThing if the symlink is broken
\ No newline at end of file + (HPathIOException)

Note: calls rename (but does not allow to rename over existing files)

File permissions

newFilePerms :: FileMode Source

Default permissions for a new file.

newDirPerms :: FileMode Source

Default permissions for a new directory.

Directory reading

getDirsFiles Source

Arguments

:: Path Abs

dir to read

-> IO [Path Abs] 

Gets all filenames of the given directory. This excludes "." and "..". + This version does not follow symbolic links.

The contents are not sorted and there is no guarantee on the ordering.

Throws:

Filetype operations

getFileType :: Path Abs -> IO FileType Source

Get the file type of the file located at the given path. Does + not follow symbolic links.

Throws:

Others

canonicalizePath :: Path Abs -> IO (Path Abs) Source

Applies realpath on the given absolute path.

Throws:

\ No newline at end of file diff --git a/HPath.html b/HPath.html index 9b1575c..82ad6f9 100644 --- a/HPath.html +++ b/HPath.html @@ -1,8 +1,8 @@ -HPath

hpath-0.7.5: Support for well-typed paths

Copyright© 2015–2016 FP Complete, 2016 Julian Ospald
LicenseBSD 3 clause
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath

Contents

Description

Support for well-typed paths.

Synopsis

Types

data Abs Source #

An absolute path.

data Path b Source #

Path of some base and type.

Internally is a ByteString. The ByteString can be of two formats only:

  1. without trailing path separator: file.txt, foo/bar.txt, /foo/bar.txt
  2. with trailing path separator: foo/, /foo/bar/

There are no duplicate - path separators //, no .., no ./, no ~/, etc.

Instances

Eq (Path b) Source #

ByteString equality.

The following property holds:

show x == show y ≡ x == y

Methods

(==) :: Path b -> Path b -> Bool #

(/=) :: Path b -> Path b -> Bool #

Ord (Path b) Source #

ByteString ordering.

The following property holds:

show x `compare` show y ≡ x `compare` y

Methods

compare :: Path b -> Path b -> Ordering #

(<) :: Path b -> Path b -> Bool #

(<=) :: Path b -> Path b -> Bool #

(>) :: Path b -> Path b -> Bool #

(>=) :: Path b -> Path b -> Bool #

max :: Path b -> Path b -> Path b #

min :: Path b -> Path b -> Path b #

Show (Path b) Source #

Same as toFilePath.

The following property holds:

x == y ≡ show x == show y

Methods

showsPrec :: Int -> Path b -> ShowS #

show :: Path b -> String #

showList :: [Path b] -> ShowS #

NFData (Path b) Source # 

Methods

rnf :: Path b -> () #

data Rel Source #

A relative path; one without a root.

Instances

data Fn Source #

A filename, without any /.

Instances

class RelC m Source #

Instances

PatternSynonyms/ViewPatterns

pattern Path :: forall a. ByteString -> Path a Source #

Path Parsing

parseAbs :: MonadThrow m => ByteString -> m (Path Abs) Source #

Get a location for an absolute path. Produces a normalised path.

Throws: PathParseException

>>> parseAbs "/abc"          :: Maybe (Path Abs)
+

hpath-0.7.5: Support for well-typed paths

Copyright© 2015–2016 FP Complete, 2016 Julian Ospald
LicenseBSD 3 clause
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

HPath

Description

Support for well-typed paths.

Synopsis

Types

data Abs Source

An absolute path.

data Path b Source

Path of some base and type.

Internally is a ByteString. The ByteString can be of two formats only:

  1. without trailing path separator: file.txt, foo/bar.txt, /foo/bar.txt
  2. with trailing path separator: foo/, /foo/bar/

There are no duplicate + path separators //, no .., no ./, no ~/, etc.

Instances

Eq (Path b) Source

ByteString equality.

The following property holds:

show x == show y ≡ x == y
Ord (Path b) Source

ByteString ordering.

The following property holds:

show x `compare` show y ≡ x `compare` y
Show (Path b) Source

Same as toFilePath.

The following property holds:

x == y ≡ show x == show y
NFData (Path b) Source 

data Rel Source

A relative path; one without a root.

Instances

data Fn Source

A filename, without any /.

Instances

data PathParseException Source

Exception when parsing a location.

class RelC m Source

Instances

PatternSynonyms/ViewPatterns

pattern Path :: ByteString -> Path a Source

Path Parsing

parseAbs :: MonadThrow m => ByteString -> m (Path Abs) Source

Get a location for an absolute path. Produces a normalised path.

Throws: PathParseException

>>> parseAbs "/abc"          :: Maybe (Path Abs)
 Just "/abc"
 >>> parseAbs "/"             :: Maybe (Path Abs)
 Just "/"
@@ -16,8 +16,8 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 Nothing
 >>> parseAbs "/abc/../foo"   :: Maybe (Path Abs)
 Nothing
-

parseFn :: MonadThrow m => ByteString -> m (Path Fn) Source #

Parses a filename. Filenames must not contain slashes. - Excludes . and '..'.

Throws: PathParseException

>>> parseFn "abc"        :: Maybe (Path Fn)
+

parseFn :: MonadThrow m => ByteString -> m (Path Fn) Source

Parses a filename. Filenames must not contain slashes. + Excludes . and '..'.

Throws: PathParseException

>>> parseFn "abc"        :: Maybe (Path Fn)
 Just "abc"
 >>> parseFn "..."        :: Maybe (Path Fn)
 Just "..."
@@ -37,7 +37,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 Nothing
 >>> parseFn ".."         :: Maybe (Path Fn)
 Nothing
-

parseRel :: MonadThrow m => ByteString -> m (Path Rel) Source #

Get a location for a relative path. Produces a normalised +

parseRel :: MonadThrow m => ByteString -> m (Path Rel) Source

Get a location for a relative path. Produces a normalised path.

Note that filepath may contain any number of ./ but may not consist solely of ./. It also may not contain a single .. anywhere.

Throws: PathParseException

>>> parseRel "abc"        :: Maybe (Path Rel)
 Just "abc"
@@ -57,7 +57,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 Nothing
 >>> parseRel ".."         :: Maybe (Path Rel)
 Nothing
-

Path Conversion

fromAbs :: Path Abs -> ByteString Source #

Convert an absolute Path to a ByteString type.

fromRel :: RelC r => Path r -> ByteString Source #

Convert a relative Path to a ByteString type.

toFilePath :: Path b -> ByteString Source #

Convert any Path to a ByteString type.

Path Operations

(</>) :: RelC r => Path b -> Path r -> Path b Source #

Append two paths.

The second argument must always be a relative path, which ensures +

Path Conversion

fromAbs :: Path Abs -> ByteString Source

Convert an absolute Path to a ByteString type.

fromRel :: RelC r => Path r -> ByteString Source

Convert a relative Path to a ByteString type.

toFilePath :: Path b -> ByteString Source

Convert any Path to a ByteString type.

Path Operations

(</>) :: RelC r => Path b -> Path r -> Path b Source

Append two paths.

The second argument must always be a relative path, which ensures that undefinable things like `"abc" <> "/def"` cannot happen.

Technically, the first argument can be a path that points to a non-directory, because this library is IO-agnostic and makes no assumptions about file types.

>>> (MkPath "/")        </> (MkPath "file"     :: Path Rel)
@@ -68,15 +68,15 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 "/file/lal"
 >>> (MkPath "/")        </> (MkPath "file/"    :: Path Rel)
 "/file/"
-

basename :: MonadThrow m => Path b -> m (Path Fn) Source #

Extract the file part of a path.

The following properties hold:

basename (p </> a) == basename a

Throws: PathException if given the root path "/"

>>> basename (MkPath "/abc/def/dod") :: Maybe (Path Fn)
+

basename :: MonadThrow m => Path b -> m (Path Fn) Source

Extract the file part of a path.

The following properties hold:

basename (p </> a) == basename a

Throws: PathException if given the root path "/"

>>> basename (MkPath "/abc/def/dod") :: Maybe (Path Fn)
 Just "dod"
 >>> basename (MkPath "/")            :: Maybe (Path Fn)
 Nothing
-

dirname :: Path Abs -> Path Abs Source #

Extract the directory name of a path.

The following properties hold:

dirname (p </> a) == dirname p
>>> dirname (MkPath "/abc/def/dod")
+

dirname :: Path Abs -> Path Abs Source

Extract the directory name of a path.

The following properties hold:

dirname (p </> a) == dirname p
>>> dirname (MkPath "/abc/def/dod")
 "/abc/def"
 >>> dirname (MkPath "/")
 "/"
-

isParentOf :: Path b -> Path b -> Bool Source #

Is p a parent of the given location? Implemented in terms of +

isParentOf :: Path b -> Path b -> Bool Source

Is p a parent of the given location? Implemented in terms of stripDir. The bases must match.

>>> (MkPath "/lal/lad")     `isParentOf` (MkPath "/lal/lad/fad")
 True
 >>> (MkPath "lal/lad")      `isParentOf` (MkPath "lal/lad/fad")
@@ -87,11 +87,11 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 False
 >>> (MkPath "fad")          `isParentOf` (MkPath "fad")
 False
-

getAllParents :: Path Abs -> [Path Abs] Source #

Get all parents of a path.

>>> getAllParents (MkPath "/abs/def/dod")
+

getAllParents :: Path Abs -> [Path Abs] Source

Get all parents of a path.

>>> getAllParents (MkPath "/abs/def/dod")
 ["/abs/def","/abs","/"]
 >>> getAllParents (MkPath "/")
 []
-

stripDir :: MonadThrow m => Path b -> Path b -> m (Path Rel) Source #

Strip directory from path, making it relative to that directory. +

stripDir :: MonadThrow m => Path b -> Path b -> m (Path Rel) Source

Strip directory from path, making it relative to that directory. Throws Couldn'tStripPrefixDir if directory is not a parent of the path.

The bases must match.

>>> (MkPath "/lal/lad")     `stripDir` (MkPath "/lal/lad/fad") :: Maybe (Path Rel)
 Just "fad"
 >>> (MkPath "lal/lad")      `stripDir` (MkPath "lal/lad/fad")  :: Maybe (Path Rel)
@@ -102,4 +102,4 @@ window.onload = function () {pageLoad();setSynopsis("mini_HPath.html");};
 Nothing
 >>> (MkPath "fad")          `stripDir` (MkPath "fad")          :: Maybe (Path Rel)
 Nothing
-

Path IO helpers

withFnPath :: Path Fn -> (ByteString -> IO a) -> IO a Source #

\ No newline at end of file +

Path IO helpers

withFnPath :: Path Fn -> (ByteString -> IO a) -> IO a Source

\ No newline at end of file diff --git a/System-Posix-Directory-Foreign.html b/System-Posix-Directory-Foreign.html index e90f461..9900155 100644 --- a/System-Posix-Directory-Foreign.html +++ b/System-Posix-Directory-Foreign.html @@ -1,9 +1,9 @@ -System.Posix.Directory.Foreign

hpath-0.7.5: Support for well-typed paths

Safe HaskellSafe
LanguageHaskell2010

System.Posix.Directory.Foreign

Documentation

newtype DirType Source #

Constructors

DirType Int 

data Flags Source #

Instances

Eq Flags Source # 

Methods

(==) :: Flags -> Flags -> Bool #

(/=) :: Flags -> Flags -> Bool #

Show Flags Source # 

Methods

showsPrec :: Int -> Flags -> ShowS #

show :: Flags -> String #

showList :: [Flags] -> ShowS #

isSupported :: Flags -> Bool Source #

Returns True if posix-paths was compiled with support for the provided +

hpath-0.7.5: Support for well-typed paths

Safe HaskellSafe
LanguageHaskell2010

System.Posix.Directory.Foreign

Documentation

newtype DirType Source

Constructors

DirType Int 

isSupported :: Flags -> Bool Source

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.)

oCloexec :: Flags Source #

O_CLOEXEC is not supported on every POSIX platform. Use + necessary is oCloexec; all other flags will always yield True.)

oCloexec :: Flags Source

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.)

\ No newline at end of file + throw an exception.)

\ No newline at end of file diff --git a/System-Posix-Directory-Traversals.html b/System-Posix-Directory-Traversals.html index 984140a..b6836ad 100644 --- a/System-Posix-Directory-Traversals.html +++ b/System-Posix-Directory-Traversals.html @@ -1,11 +1,11 @@ -System.Posix.Directory.Traversals

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

System.Posix.Directory.Traversals

Description

Traversal and read operations on directories.

Documentation

getDirectoryContents :: RawFilePath -> IO [(DirType, RawFilePath)] Source #

Gets all directory contents (not recursively).

getDirectoryContents' :: Fd -> IO [(DirType, RawFilePath)] Source #

Like getDirectoryContents except for a file descriptor.

To avoid complicated error checks, the file descriptor is +

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

System.Posix.Directory.Traversals

Description

Traversal and read operations on directories.

Documentation

getDirectoryContents :: RawFilePath -> IO [(DirType, RawFilePath)] Source

Gets all directory contents (not recursively).

getDirectoryContents' :: Fd -> IO [(DirType, RawFilePath)] Source

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.

allDirectoryContents :: RawFilePath -> IO [RawFilePath] Source #

Get all files from a directory and its subdirectories.

Upon entering a directory, allDirectoryContents will get all entries + more details.

allDirectoryContents :: RawFilePath -> IO [RawFilePath] Source

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] Source #

Get all files from a directory and its subdirectories strictly.

Follows symbolic links for the input dir.

traverseDirectory :: (s -> RawFilePath -> IO s) -> s -> RawFilePath -> IO s Source #

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.

fdOpendir :: Fd -> IO DirStream Source #

Binding to fdopendir(3).

realpath :: RawFilePath -> IO RawFilePath Source #

return the canonicalized absolute pathname

like canonicalizePath, but uses realpath(3)

\ No newline at end of file + be accessed on demand.

Follows symbolic links for the input dir.

allDirectoryContents' :: RawFilePath -> IO [RawFilePath] Source

Get all files from a directory and its subdirectories strictly.

Follows symbolic links for the input dir.

traverseDirectory :: (s -> RawFilePath -> IO s) -> s -> RawFilePath -> IO s Source

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.

fdOpendir :: Fd -> IO DirStream Source

Binding to fdopendir(3).

realpath :: RawFilePath -> IO RawFilePath Source

return the canonicalized absolute pathname

like canonicalizePath, but uses realpath(3)

\ No newline at end of file diff --git a/System-Posix-FD.html b/System-Posix-FD.html index 4a95367..a15c865 100644 --- a/System-Posix-FD.html +++ b/System-Posix-FD.html @@ -1,9 +1,9 @@ -System.Posix.FD

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

System.Posix.FD

Description

Provides an alternative for openFd +

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

System.Posix.FD

Description

Provides an alternative for 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.

Synopsis

Documentation

openFd Source #

Arguments

:: RawFilePath 
-> OpenMode 
-> [Flags]

status flags of open(2)

-> Maybe FileMode

Just x => creates the file with the given modes, Nothing => the file must exist.

-> IO Fd 

Open and optionally create this file. See Files + low-level open(2) call, in contrast to the unix package.

Synopsis

Documentation

openFd Source

Arguments

:: RawFilePath 
-> OpenMode 
-> [Flags]

status flags of open(2)

-> Maybe FileMode

Just x => creates the file with the given modes, Nothing => the file must exist.

-> IO Fd 

Open and optionally create this file. See 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).

\ No newline at end of file + to the status flags. Also see the manpage for open(2).

\ No newline at end of file diff --git a/System-Posix-FilePath.html b/System-Posix-FilePath.html index b291afc..4fd098a 100644 --- a/System-Posix-FilePath.html +++ b/System-Posix-FilePath.html @@ -1,7 +1,7 @@ -System.Posix.FilePath

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

System.Posix.FilePath

Description

The equivalent of System.FilePath on raw (byte string) file paths.

Not all functions of System.FilePath are implemented yet. Feel free to contribute!

Synopsis

Separator predicates

pathSeparator :: Word8 Source #

Path separator character

isPathSeparator :: Word8 -> Bool Source #

Check if a character is the path separator

\n ->  (_chr n == '/') == isPathSeparator n

searchPathSeparator :: Word8 Source #

Search path separator

isSearchPathSeparator :: Word8 -> Bool Source #

Check if a character is the search path separator

\n -> (_chr n == ':') == isSearchPathSeparator n

extSeparator :: Word8 Source #

File extension separator

isExtSeparator :: Word8 -> Bool Source #

Check if a character is the file extension separator

\n -> (_chr n == '.') == isExtSeparator n

$PATH methods

splitSearchPath :: ByteString -> [RawFilePath] Source #

Take a ByteString, split it on the searchPathSeparator. +

hpath-0.7.5: Support for well-typed paths

Copyright© 2016 Julian Ospald
LicenseBSD3
MaintainerJulian Ospald <hasufell@posteo.de>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

System.Posix.FilePath

Description

The equivalent of System.FilePath on raw (byte string) file paths.

Not all functions of System.FilePath are implemented yet. Feel free to contribute!

Synopsis

Separator predicates

pathSeparator :: Word8 Source

Path separator character

isPathSeparator :: Word8 -> Bool Source

Check if a character is the path separator

\n ->  (_chr n == '/') == isPathSeparator n

searchPathSeparator :: Word8 Source

Search path separator

isSearchPathSeparator :: Word8 -> Bool Source

Check if a character is the search path separator

\n -> (_chr n == ':') == isSearchPathSeparator n

extSeparator :: Word8 Source

File extension separator

isExtSeparator :: Word8 -> Bool Source

Check if a character is the file extension separator

\n -> (_chr n == '.') == isExtSeparator n

$PATH methods

splitSearchPath :: ByteString -> [RawFilePath] Source

Take a ByteString, split it on the searchPathSeparator. Blank items are converted to ..

Follows the recommendations in http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html

>>> splitSearchPath "File1:File2:File3"
 ["File1","File2","File3"]
@@ -9,45 +9,45 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 ["File1",".","File2","File3"]
 >>> splitSearchPath ""
 ["."]
-

getSearchPath :: IO [RawFilePath] Source #

Get a list of RawFilePaths in the $PATH variable.

Extension functions

splitExtension :: RawFilePath -> (RawFilePath, ByteString) Source #

Split a RawFilePath into a path+filename and extension

>>> splitExtension "file.exe"
+

getSearchPath :: IO [RawFilePath] Source

Get a list of RawFilePaths in the $PATH variable.

Extension functions

splitExtension :: RawFilePath -> (RawFilePath, ByteString) Source

Split a RawFilePath into a path+filename and extension

>>> splitExtension "file.exe"
 ("file",".exe")
 >>> splitExtension "file"
 ("file","")
 >>> splitExtension "/path/file.tar.gz"
 ("/path/file.tar",".gz")
-
\path -> uncurry (BS.append) (splitExtension path) == path

takeExtension :: RawFilePath -> ByteString Source #

Get the final extension from a RawFilePath

>>> takeExtension "file.exe"
+
\path -> uncurry (BS.append) (splitExtension path) == path

takeExtension :: RawFilePath -> ByteString Source

Get the final extension from a RawFilePath

>>> takeExtension "file.exe"
 ".exe"
 >>> takeExtension "file"
 ""
 >>> takeExtension "/path/file.tar.gz"
 ".gz"
-

replaceExtension :: RawFilePath -> ByteString -> RawFilePath Source #

Change a file's extension

\path -> let ext = takeExtension path in replaceExtension path ext == path

dropExtension :: RawFilePath -> RawFilePath Source #

Drop the final extension from a RawFilePath

>>> dropExtension "file.exe"
+

replaceExtension :: RawFilePath -> ByteString -> RawFilePath Source

Change a file's extension

\path -> let ext = takeExtension path in replaceExtension path ext == path

dropExtension :: RawFilePath -> RawFilePath Source

Drop the final extension from a RawFilePath

>>> dropExtension "file.exe"
 "file"
 >>> dropExtension "file"
 "file"
 >>> dropExtension "/path/file.tar.gz"
 "/path/file.tar"
-

addExtension :: RawFilePath -> ByteString -> RawFilePath Source #

Add an extension to a RawFilePath

>>> addExtension "file" ".exe"
+

addExtension :: RawFilePath -> ByteString -> RawFilePath Source

Add an extension to a RawFilePath

>>> addExtension "file" ".exe"
 "file.exe"
 >>> addExtension "file.tar" ".gz"
 "file.tar.gz"
 >>> addExtension "/path/" ".ext"
 "/path/.ext"
-

hasExtension :: RawFilePath -> Bool Source #

Check if a RawFilePath has an extension

>>> hasExtension "file"
+

hasExtension :: RawFilePath -> Bool Source

Check if a RawFilePath has an extension

>>> hasExtension "file"
 False
 >>> hasExtension "file.tar"
 True
 >>> hasExtension "/path.part1/"
 False
-

splitExtensions :: RawFilePath -> (RawFilePath, ByteString) Source #

Split a RawFilePath on the first extension.

>>> splitExtensions "/path/file.tar.gz"
+

splitExtensions :: RawFilePath -> (RawFilePath, ByteString) Source

Split a RawFilePath on the first extension.

>>> splitExtensions "/path/file.tar.gz"
 ("/path/file",".tar.gz")
-
\path -> uncurry addExtension (splitExtensions path) == path

dropExtensions :: RawFilePath -> RawFilePath Source #

Remove all extensions from a RawFilePath

>>> dropExtensions "/path/file.tar.gz"
+
\path -> uncurry addExtension (splitExtensions path) == path

dropExtensions :: RawFilePath -> RawFilePath Source

Remove all extensions from a RawFilePath

>>> dropExtensions "/path/file.tar.gz"
 "/path/file"
-

takeExtensions :: RawFilePath -> ByteString Source #

Take all extensions from a RawFilePath

>>> takeExtensions "/path/file.tar.gz"
+

takeExtensions :: RawFilePath -> ByteString Source

Take all extensions from a RawFilePath

>>> takeExtensions "/path/file.tar.gz"
 ".tar.gz"
-

stripExtension :: ByteString -> RawFilePath -> Maybe RawFilePath Source #

Drop the given extension from a FilePath, and the "." preceding it. - Returns Nothing if the FilePath does not have the given extension, or - Just and the part before the extension if it does.

This function can be more predictable than dropExtensions, +

stripExtension :: ByteString -> RawFilePath -> Maybe RawFilePath Source

Drop the given extension from a FilePath, and the "." preceding it. + Returns Nothing if the FilePath does not have the given extension, or + Just and the part before the extension if it does.

This function can be more predictable than dropExtensions, especially if the filename might itself contain . characters.

>>> stripExtension "hs.o" "foo.x.hs.o"
 Just "foo.x"
 >>> stripExtension "hi.o" "foo.x.hs.o"
@@ -60,27 +60,27 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 Nothing
 >>> stripExtension "bar"  "foobar"
 Nothing
-
\path -> stripExtension "" path == Just path
\path -> dropExtension path  == fromJust (stripExtension (takeExtension path) path)
\path -> dropExtensions path == fromJust (stripExtension (takeExtensions path) path)

Filename/directory functions

splitFileName :: RawFilePath -> (RawFilePath, RawFilePath) Source #

Split a RawFilePath into (path,file). combine is the inverse

>>> splitFileName "path/file.txt"
+
\path -> stripExtension "" path == Just path
\path -> dropExtension path  == fromJust (stripExtension (takeExtension path) path)
\path -> dropExtensions path == fromJust (stripExtension (takeExtensions path) path)

Filename/directory functions

splitFileName :: RawFilePath -> (RawFilePath, RawFilePath) Source

Split a RawFilePath into (path,file). combine is the inverse

>>> splitFileName "path/file.txt"
 ("path/","file.txt")
 >>> splitFileName "path/"
 ("path/","")
 >>> splitFileName "file.txt"
 ("./","file.txt")
-
\path -> uncurry combine (splitFileName path) == path || fst (splitFileName path) == "./"

takeFileName :: RawFilePath -> RawFilePath Source #

Get the file name

>>> takeFileName "path/file.txt"
+
\path -> uncurry combine (splitFileName path) == path || fst (splitFileName path) == "./"

takeFileName :: RawFilePath -> RawFilePath Source

Get the file name

>>> takeFileName "path/file.txt"
 "file.txt"
 >>> takeFileName "path/"
 ""
-

replaceFileName :: RawFilePath -> ByteString -> RawFilePath Source #

Change the file name

\path -> replaceFileName path (takeFileName path) == path

dropFileName :: RawFilePath -> RawFilePath Source #

Drop the file name

>>> dropFileName "path/file.txt"
+

replaceFileName :: RawFilePath -> ByteString -> RawFilePath Source

Change the file name

\path -> replaceFileName path (takeFileName path) == path

dropFileName :: RawFilePath -> RawFilePath Source

Drop the file name

>>> dropFileName "path/file.txt"
 "path/"
 >>> dropFileName "file.txt"
 "./"
-

takeBaseName :: RawFilePath -> ByteString Source #

Get the file name, without a trailing extension

>>> takeBaseName "path/file.tar.gz"
+

takeBaseName :: RawFilePath -> ByteString Source

Get the file name, without a trailing extension

>>> takeBaseName "path/file.tar.gz"
 "file.tar"
 >>> takeBaseName ""
 ""
-

replaceBaseName :: RawFilePath -> ByteString -> RawFilePath Source #

Change the base name

>>> replaceBaseName "path/file.tar.gz" "bob"
+

replaceBaseName :: RawFilePath -> ByteString -> RawFilePath Source

Change the base name

>>> replaceBaseName "path/file.tar.gz" "bob"
 "path/bob.gz"
-
\path -> replaceBaseName path (takeBaseName path) == path

takeDirectory :: RawFilePath -> RawFilePath Source #

Get the directory, moving up one level if it's already a directory

>>> takeDirectory "path/file.txt"
+
\path -> replaceBaseName path (takeBaseName path) == path

takeDirectory :: RawFilePath -> RawFilePath Source

Get the directory, moving up one level if it's already a directory

>>> takeDirectory "path/file.txt"
 "path"
 >>> takeDirectory "file"
 "."
@@ -88,33 +88,33 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 "/path/to"
 >>> takeDirectory "/path/to"
 "/path"
-

replaceDirectory :: RawFilePath -> ByteString -> RawFilePath Source #

Change the directory component of a RawFilePath

\path -> replaceDirectory path (takeDirectory path) `equalFilePath` path || takeDirectory path == "."

combine :: RawFilePath -> RawFilePath -> RawFilePath Source #

Join two paths together

>>> combine "/" "file"
+

replaceDirectory :: RawFilePath -> ByteString -> RawFilePath Source

Change the directory component of a RawFilePath

\path -> replaceDirectory path (takeDirectory path) `equalFilePath` path || takeDirectory path == "."

combine :: RawFilePath -> RawFilePath -> RawFilePath Source

Join two paths together

>>> combine "/" "file"
 "/file"
 >>> combine "/path/to" "file"
 "/path/to/file"
 >>> combine "file" "/absolute/path"
 "/absolute/path"
-

(</>) :: RawFilePath -> RawFilePath -> RawFilePath Source #

Operator version of combine

splitPath :: RawFilePath -> [RawFilePath] Source #

Split a path into a list of components:

>>> splitPath "/path/to/file.txt"
+

(</>) :: RawFilePath -> RawFilePath -> RawFilePath Source

Operator version of combine

splitPath :: RawFilePath -> [RawFilePath] Source

Split a path into a list of components:

>>> splitPath "/path/to/file.txt"
 ["/","path/","to/","file.txt"]
-
\path -> BS.concat (splitPath path) == path

joinPath :: [RawFilePath] -> RawFilePath Source #

Join a split path back together

\path -> joinPath (splitPath path) == path
>>> joinPath ["path","to","file.txt"]
+
\path -> BS.concat (splitPath path) == path

joinPath :: [RawFilePath] -> RawFilePath Source

Join a split path back together

\path -> joinPath (splitPath path) == path
>>> joinPath ["path","to","file.txt"]
 "path/to/file.txt"
-

splitDirectories :: RawFilePath -> [RawFilePath] Source #

Like splitPath, but without trailing slashes

>>> splitDirectories "/path/to/file.txt"
+

splitDirectories :: RawFilePath -> [RawFilePath] Source

Like splitPath, but without trailing slashes

>>> splitDirectories "/path/to/file.txt"
 ["/","path","to","file.txt"]
 >>> splitDirectories ""
 []
-

Trailing slash functions

hasTrailingPathSeparator :: RawFilePath -> Bool Source #

Check if the last character of a RawFilePath is /.

>>> hasTrailingPathSeparator "/path/"
+

Trailing slash functions

hasTrailingPathSeparator :: RawFilePath -> Bool Source

Check if the last character of a RawFilePath is /.

>>> hasTrailingPathSeparator "/path/"
 True
 >>> hasTrailingPathSeparator "/"
 True
 >>> hasTrailingPathSeparator "/path"
 False
-

addTrailingPathSeparator :: RawFilePath -> RawFilePath Source #

Add a trailing path separator.

>>> addTrailingPathSeparator "/path"
+

addTrailingPathSeparator :: RawFilePath -> RawFilePath Source

Add a trailing path separator.

>>> addTrailingPathSeparator "/path"
 "/path/"
 >>> addTrailingPathSeparator "/path/"
 "/path/"
 >>> addTrailingPathSeparator "/"
 "/"
-

dropTrailingPathSeparator :: RawFilePath -> RawFilePath Source #

Remove a trailing path separator

>>> dropTrailingPathSeparator "/path/"
+

dropTrailingPathSeparator :: RawFilePath -> RawFilePath Source

Remove a trailing path separator

>>> dropTrailingPathSeparator "/path/"
 "/path"
 >>> dropTrailingPathSeparator "/path////"
 "/path"
@@ -122,7 +122,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 "/"
 >>> dropTrailingPathSeparator "//"
 "/"
-

File name manipulations

normalise :: RawFilePath -> RawFilePath Source #

Normalise a file.

>>> normalise "/file/\\test////"
+

File name manipulations

normalise :: RawFilePath -> RawFilePath Source

Normalise a file.

>>> normalise "/file/\\test////"
 "/file/\\test/"
 >>> normalise "/file/./test"
 "/file/test"
@@ -148,7 +148,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 "bob/fred/"
 >>> normalise "//home"
 "/home"
-

makeRelative :: RawFilePath -> RawFilePath -> RawFilePath Source #

Contract a filename, based on a relative path. Note that the resulting +

makeRelative :: RawFilePath -> RawFilePath -> RawFilePath Source

Contract a filename, based on a relative path. Note that the resulting path will never introduce .. paths, as the presence of symlinks means ../b may not reach a/b if it starts from a/c. For a worked example see @@ -166,7 +166,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath. "fred/" >>> makeRelative "some/path" "some/path/a/b/c" "a/b/c" -

\p -> makeRelative p p == "."
\p -> makeRelative (takeDirectory p) p `equalFilePath` takeFileName p

prop x y -> equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y / makeRelative y x) x

equalFilePath :: RawFilePath -> RawFilePath -> Bool Source #

Equality of two filepaths. The filepaths are normalised +

\p -> makeRelative p p == "."
\p -> makeRelative (takeDirectory p) p `equalFilePath` takeFileName p

prop x y -> equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y / makeRelative y x) x

equalFilePath :: RawFilePath -> RawFilePath -> Bool Source

Equality of two filepaths. The filepaths are normalised and trailing path separators are dropped.

>>> equalFilePath "foo" "foo"
 True
 >>> equalFilePath "foo" "foo/"
@@ -181,23 +181,23 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 False
 >>> equalFilePath "foo" "../foo"
 False
-
\p -> equalFilePath p p

isRelative :: RawFilePath -> Bool Source #

Check if a path is relative

\path -> isRelative path /= isAbsolute path

isAbsolute :: RawFilePath -> Bool Source #

Check if a path is absolute

>>> isAbsolute "/path"
+
\p -> equalFilePath p p

isRelative :: RawFilePath -> Bool Source

Check if a path is relative

\path -> isRelative path /= isAbsolute path

isAbsolute :: RawFilePath -> Bool Source

Check if a path is absolute

>>> isAbsolute "/path"
 True
 >>> isAbsolute "path"
 False
 >>> isAbsolute ""
 False
-

isValid :: RawFilePath -> Bool Source #

Is a FilePath valid, i.e. could you create a file like it?

>>> isValid ""
+

isValid :: RawFilePath -> Bool Source

Is a FilePath valid, i.e. could you create a file like it?

>>> isValid ""
 False
 >>> isValid "\0"
 False
 >>> isValid "/random_ path:*"
 True
-

makeValid :: RawFilePath -> RawFilePath Source #

Take a FilePath and make it valid; does not change already valid FilePaths.

>>> makeValid ""
+

makeValid :: RawFilePath -> RawFilePath Source

Take a FilePath and make it valid; does not change already valid FilePaths.

>>> makeValid ""
 "_"
 >>> makeValid "file\0name"
 "file_name"
-
\p -> if isValid p then makeValid p == p else makeValid p /= p
\p -> isValid (makeValid p)

isFileName :: RawFilePath -> Bool Source #

Is the given path a valid filename? This includes +

\p -> if isValid p then makeValid p == p else makeValid p /= p
\p -> isValid (makeValid p)

isFileName :: RawFilePath -> Bool Source

Is the given path a valid filename? This includes "." and "..".

>>> isFileName "lal"
 True
 >>> isFileName "."
@@ -210,7 +210,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 False
 >>> isFileName "/random_ path:*"
 False
-

hasParentDir :: RawFilePath -> Bool Source #

Check if the filepath has any parent directories in it.

>>> hasParentDir "/.."
+

hasParentDir :: RawFilePath -> Bool Source

Check if the filepath has any parent directories in it.

>>> hasParentDir "/.."
 True
 >>> hasParentDir "foo/bar/.."
 True
@@ -224,7 +224,7 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 False
 >>> hasParentDir ".."
 False
-

hiddenFile :: RawFilePath -> Bool Source #

Whether the file is a hidden file.

>>> hiddenFile ".foo"
+

hiddenFile :: RawFilePath -> Bool Source

Whether the file is a hidden file.

>>> hiddenFile ".foo"
 True
 >>> hiddenFile "..foo.bar"
 True
@@ -240,4 +240,4 @@ window.onload = function () {pageLoad();setSynopsis("mini_System-Posix-FilePath.
 False
 >>> hiddenFile ""
 False
-
\ No newline at end of file +
\ No newline at end of file diff --git a/doc-index-60.html b/doc-index-60.html index fcbb148..5a012a3 100644 --- a/doc-index-60.html +++ b/doc-index-60.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - <)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-A.html b/doc-index-A.html index dcfed87..376e07c 100644 --- a/doc-index-A.html +++ b/doc-index-A.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - A)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-All.html b/doc-index-All.html index 873232c..7500c32 100644 --- a/doc-index-All.html +++ b/doc-index-All.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index)

hpath-0.7.5: Support for well-typed paths

Index

<.>System.Posix.FilePath
</> 
1 (Function)System.Posix.FilePath
2 (Function)HPath
AbsHPath
addExtensionSystem.Posix.FilePath
addTrailingPathSeparatorSystem.Posix.FilePath
allDirectoryContentsSystem.Posix.Directory.Traversals
allDirectoryContents'System.Posix.Directory.Traversals
basenameHPath
BlockDeviceHPath.IO
bracketeerHPath.IO.Errors
Can'tOpenDirectoryHPath.IO.Errors
canonicalizePathHPath.IO
canOpenDirectoryHPath.IO.Errors
catchErrnoHPath.IO.Errors
CharacterDeviceHPath.IO
CollectFailuresHPath.IO
combineSystem.Posix.FilePath
copyDirRecursiveHPath.IO
CopyFailedHPath.IO.Errors
copyFileHPath.IO
CopyModeHPath.IO
createDirHPath.IO
createRegularFileHPath.IO
createSymlinkHPath.IO
deleteDirHPath.IO
deleteDirRecursiveHPath.IO
deleteFileHPath.IO
DestinationInSourceHPath.IO.Errors
DirDoesExistHPath.IO.Errors
DirDoesNotExistHPath.IO.Errors
DirectoryHPath.IO
dirnameHPath
DirType 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
doesDirectoryExistHPath.IO.Errors
doesFileExistHPath.IO.Errors
dropExtensionSystem.Posix.FilePath
dropExtensionsSystem.Posix.FilePath
dropFileNameSystem.Posix.FilePath
dropTrailingPathSeparatorSystem.Posix.FilePath
dtBlkSystem.Posix.Directory.Foreign
dtChrSystem.Posix.Directory.Foreign
dtDirSystem.Posix.Directory.Foreign
dtFifoSystem.Posix.Directory.Foreign
dtLnkSystem.Posix.Directory.Foreign
dtRegSystem.Posix.Directory.Foreign
dtSockSystem.Posix.Directory.Foreign
dtUnknownSystem.Posix.Directory.Foreign
easyCopyHPath.IO
easyDeleteHPath.IO
equalFilePathSystem.Posix.FilePath
executeFileHPath.IO
extSeparatorSystem.Posix.FilePath
FailEarlyHPath.IO
fdOpendirSystem.Posix.Directory.Traversals
FileDoesExistHPath.IO.Errors
FileDoesNotExistHPath.IO.Errors
FileTypeHPath.IO
Flags 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
FnHPath
fromAbsHPath
fromRelHPath
getAllParentsHPath
getDirectoryContentsSystem.Posix.Directory.Traversals
getDirectoryContents'System.Posix.Directory.Traversals
getDirsFilesHPath.IO
getFileTypeHPath.IO
getSearchPathSystem.Posix.FilePath
handleIOErrorHPath.IO.Errors
hasExtensionSystem.Posix.FilePath
hasParentDirSystem.Posix.FilePath
hasTrailingPathSeparatorSystem.Posix.FilePath
hiddenFileSystem.Posix.FilePath
HPathIOExceptionHPath.IO.Errors
InvalidOperationHPath.IO.Errors
isAbsoluteSystem.Posix.FilePath
isCan'tOpenDirectoryHPath.IO.Errors
isCopyFailedHPath.IO.Errors
isDestinationInSourceHPath.IO.Errors
isDirDoesExistHPath.IO.Errors
isDirDoesNotExistHPath.IO.Errors
isExtSeparatorSystem.Posix.FilePath
isFileDoesExistHPath.IO.Errors
isFileDoesNotExistHPath.IO.Errors
isFileNameSystem.Posix.FilePath
isInvalidOperationHPath.IO.Errors
isParentOfHPath
isPathSeparatorSystem.Posix.FilePath
isRecursiveFailureHPath.IO.Errors
isRelativeSystem.Posix.FilePath
isSameFileHPath.IO.Errors
isSearchPathSeparatorSystem.Posix.FilePath
isSupportedSystem.Posix.Directory.Foreign
isValidSystem.Posix.FilePath
isWritableHPath.IO.Errors
joinPathSystem.Posix.FilePath
makeRelativeSystem.Posix.FilePath
makeValidSystem.Posix.FilePath
moveFileHPath.IO
NamedPipeHPath.IO
newDirPermsHPath.IO
newFilePermsHPath.IO
normaliseSystem.Posix.FilePath
oAppendSystem.Posix.Directory.Foreign
oAsyncSystem.Posix.Directory.Foreign
oCloexecSystem.Posix.Directory.Foreign
oCreatSystem.Posix.Directory.Foreign
oDirectorySystem.Posix.Directory.Foreign
oExclSystem.Posix.Directory.Foreign
oNocttySystem.Posix.Directory.Foreign
oNofollowSystem.Posix.Directory.Foreign
oNonblockSystem.Posix.Directory.Foreign
openFdSystem.Posix.FD
openFileHPath.IO
oRdonlySystem.Posix.Directory.Foreign
oRdwrSystem.Posix.Directory.Foreign
oSyncSystem.Posix.Directory.Foreign
oTruncSystem.Posix.Directory.Foreign
OverwriteHPath.IO
oWronlySystem.Posix.Directory.Foreign
packDirStreamSystem.Posix.Directory.Traversals
parseAbsHPath
parseFnHPath
parseRelHPath
Path 
1 (Type/Class)HPath
2 (Data Constructor)HPath
PathExceptionHPath
pathMaxSystem.Posix.Directory.Foreign
PathParseExceptionHPath
pathSeparatorSystem.Posix.FilePath
peekFilePathSystem.Posix.FilePath
peekFilePathLenSystem.Posix.FilePath
RawFilePathSystem.Posix.FilePath
reactOnErrorHPath.IO.Errors
readDirEntSystem.Posix.Directory.Traversals
realpathSystem.Posix.Directory.Traversals
recreateSymlinkHPath.IO
RecursiveFailureHPath.IO.Errors
RecursiveModeHPath.IO
RegularFileHPath.IO
RelHPath
RelCHPath
renameFileHPath.IO
replaceBaseNameSystem.Posix.FilePath
replaceDirectorySystem.Posix.FilePath
replaceExtensionSystem.Posix.FilePath
replaceFileNameSystem.Posix.FilePath
rethrowErrnoAsHPath.IO.Errors
SameFileHPath.IO.Errors
sameFileHPath.IO.Errors
searchPathSeparatorSystem.Posix.FilePath
SocketHPath.IO
splitDirectoriesSystem.Posix.FilePath
splitExtensionSystem.Posix.FilePath
splitExtensionsSystem.Posix.FilePath
splitFileNameSystem.Posix.FilePath
splitPathSystem.Posix.FilePath
splitSearchPathSystem.Posix.FilePath
StrictHPath.IO
stripDirHPath
stripExtensionSystem.Posix.FilePath
SymbolicLinkHPath.IO
takeBaseNameSystem.Posix.FilePath
takeDirectorySystem.Posix.FilePath
takeExtensionSystem.Posix.FilePath
takeExtensionsSystem.Posix.FilePath
takeFileNameSystem.Posix.FilePath
throwCantOpenDirectoryHPath.IO.Errors
throwDestinationInSourceHPath.IO.Errors
throwDirDoesExistHPath.IO.Errors
throwDirDoesNotExistHPath.IO.Errors
throwErrnoPathSystem.Posix.FilePath
throwErrnoPathIfSystem.Posix.FilePath
throwErrnoPathIfMinus1System.Posix.FilePath
throwErrnoPathIfMinus1RetrySystem.Posix.FilePath
throwErrnoPathIfMinus1Retry_System.Posix.FilePath
throwErrnoPathIfMinus1_System.Posix.FilePath
throwErrnoPathIfNullSystem.Posix.FilePath
throwErrnoPathIfNullRetrySystem.Posix.FilePath
throwErrnoPathIfRetrySystem.Posix.FilePath
throwErrnoPathIf_System.Posix.FilePath
throwFileDoesExistHPath.IO.Errors
throwFileDoesNotExistHPath.IO.Errors
throwSameFileHPath.IO.Errors
toFilePathHPath
traverseDirectorySystem.Posix.Directory.Traversals
unFlagsSystem.Posix.Directory.Foreign
unionFlagsSystem.Posix.Directory.Foreign
unlessMHPath.IO.Utils
unpackDirStreamSystem.Posix.Directory.Traversals
UnsupportedFlagSystem.Posix.Directory.Foreign
whenMHPath.IO.Utils
withAbsPathHPath
withFilePathSystem.Posix.FilePath
withFnPathHPath
withRelPathHPath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index

<.>System.Posix.FilePath
</> 
1 (Function)System.Posix.FilePath
2 (Function)HPath
AbsHPath
addExtensionSystem.Posix.FilePath
addTrailingPathSeparatorSystem.Posix.FilePath
allDirectoryContentsSystem.Posix.Directory.Traversals
allDirectoryContents'System.Posix.Directory.Traversals
basenameHPath
BlockDeviceHPath.IO
bracketeerHPath.IO.Errors
Can'tOpenDirectoryHPath.IO.Errors
canonicalizePathHPath.IO
canOpenDirectoryHPath.IO.Errors
catchErrnoHPath.IO.Errors
CharacterDeviceHPath.IO
CollectFailuresHPath.IO
combineSystem.Posix.FilePath
copyDirRecursiveHPath.IO
CopyFailedHPath.IO.Errors
copyFileHPath.IO
CopyModeHPath.IO
createDirHPath.IO
createRegularFileHPath.IO
createSymlinkHPath.IO
deleteDirHPath.IO
deleteDirRecursiveHPath.IO
deleteFileHPath.IO
DestinationInSourceHPath.IO.Errors
DirDoesExistHPath.IO.Errors
DirDoesNotExistHPath.IO.Errors
DirectoryHPath.IO
dirnameHPath
DirType 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
doesDirectoryExistHPath.IO.Errors
doesFileExistHPath.IO.Errors
dropExtensionSystem.Posix.FilePath
dropExtensionsSystem.Posix.FilePath
dropFileNameSystem.Posix.FilePath
dropTrailingPathSeparatorSystem.Posix.FilePath
dtBlkSystem.Posix.Directory.Foreign
dtChrSystem.Posix.Directory.Foreign
dtDirSystem.Posix.Directory.Foreign
dtFifoSystem.Posix.Directory.Foreign
dtLnkSystem.Posix.Directory.Foreign
dtRegSystem.Posix.Directory.Foreign
dtSockSystem.Posix.Directory.Foreign
dtUnknownSystem.Posix.Directory.Foreign
easyCopyHPath.IO
easyDeleteHPath.IO
equalFilePathSystem.Posix.FilePath
executeFileHPath.IO
extSeparatorSystem.Posix.FilePath
FailEarlyHPath.IO
fdOpendirSystem.Posix.Directory.Traversals
FileDoesExistHPath.IO.Errors
FileDoesNotExistHPath.IO.Errors
FileTypeHPath.IO
Flags 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
FnHPath
fromAbsHPath
fromRelHPath
getAllParentsHPath
getDirectoryContentsSystem.Posix.Directory.Traversals
getDirectoryContents'System.Posix.Directory.Traversals
getDirsFilesHPath.IO
getFileTypeHPath.IO
getSearchPathSystem.Posix.FilePath
handleIOErrorHPath.IO.Errors
hasExtensionSystem.Posix.FilePath
hasParentDirSystem.Posix.FilePath
hasTrailingPathSeparatorSystem.Posix.FilePath
hiddenFileSystem.Posix.FilePath
HPathIOExceptionHPath.IO.Errors
InvalidOperationHPath.IO.Errors
isAbsoluteSystem.Posix.FilePath
isCan'tOpenDirectoryHPath.IO.Errors
isCopyFailedHPath.IO.Errors
isDestinationInSourceHPath.IO.Errors
isDirDoesExistHPath.IO.Errors
isDirDoesNotExistHPath.IO.Errors
isExtSeparatorSystem.Posix.FilePath
isFileDoesExistHPath.IO.Errors
isFileDoesNotExistHPath.IO.Errors
isFileNameSystem.Posix.FilePath
isInvalidOperationHPath.IO.Errors
isParentOfHPath
isPathSeparatorSystem.Posix.FilePath
isRecursiveFailureHPath.IO.Errors
isRelativeSystem.Posix.FilePath
isSameFileHPath.IO.Errors
isSearchPathSeparatorSystem.Posix.FilePath
isSupportedSystem.Posix.Directory.Foreign
isValidSystem.Posix.FilePath
isWritableHPath.IO.Errors
joinPathSystem.Posix.FilePath
makeRelativeSystem.Posix.FilePath
makeValidSystem.Posix.FilePath
moveFileHPath.IO
NamedPipeHPath.IO
newDirPermsHPath.IO
newFilePermsHPath.IO
normaliseSystem.Posix.FilePath
oAppendSystem.Posix.Directory.Foreign
oAsyncSystem.Posix.Directory.Foreign
oCloexecSystem.Posix.Directory.Foreign
oCreatSystem.Posix.Directory.Foreign
oDirectorySystem.Posix.Directory.Foreign
oExclSystem.Posix.Directory.Foreign
oNocttySystem.Posix.Directory.Foreign
oNofollowSystem.Posix.Directory.Foreign
oNonblockSystem.Posix.Directory.Foreign
openFdSystem.Posix.FD
openFileHPath.IO
oRdonlySystem.Posix.Directory.Foreign
oRdwrSystem.Posix.Directory.Foreign
oSyncSystem.Posix.Directory.Foreign
oTruncSystem.Posix.Directory.Foreign
OverwriteHPath.IO
oWronlySystem.Posix.Directory.Foreign
packDirStreamSystem.Posix.Directory.Traversals
parseAbsHPath
parseFnHPath
parseRelHPath
Path 
1 (Type/Class)HPath
2 (Data Constructor)HPath
PathExceptionHPath
pathMaxSystem.Posix.Directory.Foreign
PathParseExceptionHPath
pathSeparatorSystem.Posix.FilePath
peekFilePathSystem.Posix.FilePath
peekFilePathLenSystem.Posix.FilePath
RawFilePathSystem.Posix.FilePath
reactOnErrorHPath.IO.Errors
readDirEntSystem.Posix.Directory.Traversals
realpathSystem.Posix.Directory.Traversals
recreateSymlinkHPath.IO
RecursiveErrorModeHPath.IO
RecursiveFailureHPath.IO.Errors
RegularFileHPath.IO
RelHPath
RelCHPath
renameFileHPath.IO
replaceBaseNameSystem.Posix.FilePath
replaceDirectorySystem.Posix.FilePath
replaceExtensionSystem.Posix.FilePath
replaceFileNameSystem.Posix.FilePath
rethrowErrnoAsHPath.IO.Errors
SameFileHPath.IO.Errors
sameFileHPath.IO.Errors
searchPathSeparatorSystem.Posix.FilePath
SocketHPath.IO
splitDirectoriesSystem.Posix.FilePath
splitExtensionSystem.Posix.FilePath
splitExtensionsSystem.Posix.FilePath
splitFileNameSystem.Posix.FilePath
splitPathSystem.Posix.FilePath
splitSearchPathSystem.Posix.FilePath
StrictHPath.IO
stripDirHPath
stripExtensionSystem.Posix.FilePath
SymbolicLinkHPath.IO
takeBaseNameSystem.Posix.FilePath
takeDirectorySystem.Posix.FilePath
takeExtensionSystem.Posix.FilePath
takeExtensionsSystem.Posix.FilePath
takeFileNameSystem.Posix.FilePath
throwCantOpenDirectoryHPath.IO.Errors
throwDestinationInSourceHPath.IO.Errors
throwDirDoesExistHPath.IO.Errors
throwDirDoesNotExistHPath.IO.Errors
throwErrnoPathSystem.Posix.FilePath
throwErrnoPathIfSystem.Posix.FilePath
throwErrnoPathIfMinus1System.Posix.FilePath
throwErrnoPathIfMinus1RetrySystem.Posix.FilePath
throwErrnoPathIfMinus1Retry_System.Posix.FilePath
throwErrnoPathIfMinus1_System.Posix.FilePath
throwErrnoPathIfNullSystem.Posix.FilePath
throwErrnoPathIfNullRetrySystem.Posix.FilePath
throwErrnoPathIfRetrySystem.Posix.FilePath
throwErrnoPathIf_System.Posix.FilePath
throwFileDoesExistHPath.IO.Errors
throwFileDoesNotExistHPath.IO.Errors
throwSameFileHPath.IO.Errors
toFilePathHPath
traverseDirectorySystem.Posix.Directory.Traversals
unFlagsSystem.Posix.Directory.Foreign
unionFlagsSystem.Posix.Directory.Foreign
unlessMHPath.IO.Utils
unpackDirStreamSystem.Posix.Directory.Traversals
UnsupportedFlagSystem.Posix.Directory.Foreign
whenMHPath.IO.Utils
withAbsPathHPath
withFilePathSystem.Posix.FilePath
withFnPathHPath
withRelPathHPath
\ No newline at end of file diff --git a/doc-index-B.html b/doc-index-B.html index bf3b5a5..68b7848 100644 --- a/doc-index-B.html +++ b/doc-index-B.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - B)

hpath-0.7.5: Support for well-typed paths

Index - B

basenameHPath
BlockDeviceHPath.IO
bracketeerHPath.IO.Errors
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - B

basenameHPath
BlockDeviceHPath.IO
bracketeerHPath.IO.Errors
\ No newline at end of file diff --git a/doc-index-C.html b/doc-index-C.html index f57029b..946fff1 100644 --- a/doc-index-C.html +++ b/doc-index-C.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - C)

hpath-0.7.5: Support for well-typed paths

Index - C

Can'tOpenDirectoryHPath.IO.Errors
canonicalizePathHPath.IO
canOpenDirectoryHPath.IO.Errors
catchErrnoHPath.IO.Errors
CharacterDeviceHPath.IO
CollectFailuresHPath.IO
combineSystem.Posix.FilePath
copyDirRecursiveHPath.IO
CopyFailedHPath.IO.Errors
copyFileHPath.IO
CopyModeHPath.IO
createDirHPath.IO
createRegularFileHPath.IO
createSymlinkHPath.IO
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - C

Can'tOpenDirectoryHPath.IO.Errors
canonicalizePathHPath.IO
canOpenDirectoryHPath.IO.Errors
catchErrnoHPath.IO.Errors
CharacterDeviceHPath.IO
CollectFailuresHPath.IO
combineSystem.Posix.FilePath
copyDirRecursiveHPath.IO
CopyFailedHPath.IO.Errors
copyFileHPath.IO
CopyModeHPath.IO
createDirHPath.IO
createRegularFileHPath.IO
createSymlinkHPath.IO
\ No newline at end of file diff --git a/doc-index-D.html b/doc-index-D.html index 6df6353..b7ad658 100644 --- a/doc-index-D.html +++ b/doc-index-D.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - D)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-E.html b/doc-index-E.html index 49770a5..2fd18ec 100644 --- a/doc-index-E.html +++ b/doc-index-E.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - E)

hpath-0.7.5: Support for well-typed paths

Index - E

easyCopyHPath.IO
easyDeleteHPath.IO
equalFilePathSystem.Posix.FilePath
executeFileHPath.IO
extSeparatorSystem.Posix.FilePath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - E

easyCopyHPath.IO
easyDeleteHPath.IO
equalFilePathSystem.Posix.FilePath
executeFileHPath.IO
extSeparatorSystem.Posix.FilePath
\ No newline at end of file diff --git a/doc-index-F.html b/doc-index-F.html index 832d10c..8b72213 100644 --- a/doc-index-F.html +++ b/doc-index-F.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - F)

hpath-0.7.5: Support for well-typed paths

Index - F

FailEarlyHPath.IO
fdOpendirSystem.Posix.Directory.Traversals
FileDoesExistHPath.IO.Errors
FileDoesNotExistHPath.IO.Errors
FileTypeHPath.IO
Flags 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
FnHPath
fromAbsHPath
fromRelHPath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - F

FailEarlyHPath.IO
fdOpendirSystem.Posix.Directory.Traversals
FileDoesExistHPath.IO.Errors
FileDoesNotExistHPath.IO.Errors
FileTypeHPath.IO
Flags 
1 (Type/Class)System.Posix.Directory.Foreign
2 (Data Constructor)System.Posix.Directory.Foreign
FnHPath
fromAbsHPath
fromRelHPath
\ No newline at end of file diff --git a/doc-index-G.html b/doc-index-G.html index bd34be5..a64ef1c 100644 --- a/doc-index-G.html +++ b/doc-index-G.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - G)

hpath-0.7.5: Support for well-typed paths

Index - G

getAllParentsHPath
getDirectoryContentsSystem.Posix.Directory.Traversals
getDirectoryContents'System.Posix.Directory.Traversals
getDirsFilesHPath.IO
getFileTypeHPath.IO
getSearchPathSystem.Posix.FilePath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - G

getAllParentsHPath
getDirectoryContentsSystem.Posix.Directory.Traversals
getDirectoryContents'System.Posix.Directory.Traversals
getDirsFilesHPath.IO
getFileTypeHPath.IO
getSearchPathSystem.Posix.FilePath
\ No newline at end of file diff --git a/doc-index-H.html b/doc-index-H.html index d985906..43b5aa9 100644 --- a/doc-index-H.html +++ b/doc-index-H.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - H)

hpath-0.7.5: Support for well-typed paths

Index - H

handleIOErrorHPath.IO.Errors
hasExtensionSystem.Posix.FilePath
hasParentDirSystem.Posix.FilePath
hasTrailingPathSeparatorSystem.Posix.FilePath
hiddenFileSystem.Posix.FilePath
HPathIOExceptionHPath.IO.Errors
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - H

handleIOErrorHPath.IO.Errors
hasExtensionSystem.Posix.FilePath
hasParentDirSystem.Posix.FilePath
hasTrailingPathSeparatorSystem.Posix.FilePath
hiddenFileSystem.Posix.FilePath
HPathIOExceptionHPath.IO.Errors
\ No newline at end of file diff --git a/doc-index-I.html b/doc-index-I.html index fa0d8fb..eeae30c 100644 --- a/doc-index-I.html +++ b/doc-index-I.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - I)

hpath-0.7.5: Support for well-typed paths

Index - I

InvalidOperationHPath.IO.Errors
isAbsoluteSystem.Posix.FilePath
isCan'tOpenDirectoryHPath.IO.Errors
isCopyFailedHPath.IO.Errors
isDestinationInSourceHPath.IO.Errors
isDirDoesExistHPath.IO.Errors
isDirDoesNotExistHPath.IO.Errors
isExtSeparatorSystem.Posix.FilePath
isFileDoesExistHPath.IO.Errors
isFileDoesNotExistHPath.IO.Errors
isFileNameSystem.Posix.FilePath
isInvalidOperationHPath.IO.Errors
isParentOfHPath
isPathSeparatorSystem.Posix.FilePath
isRecursiveFailureHPath.IO.Errors
isRelativeSystem.Posix.FilePath
isSameFileHPath.IO.Errors
isSearchPathSeparatorSystem.Posix.FilePath
isSupportedSystem.Posix.Directory.Foreign
isValidSystem.Posix.FilePath
isWritableHPath.IO.Errors
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - I

InvalidOperationHPath.IO.Errors
isAbsoluteSystem.Posix.FilePath
isCan'tOpenDirectoryHPath.IO.Errors
isCopyFailedHPath.IO.Errors
isDestinationInSourceHPath.IO.Errors
isDirDoesExistHPath.IO.Errors
isDirDoesNotExistHPath.IO.Errors
isExtSeparatorSystem.Posix.FilePath
isFileDoesExistHPath.IO.Errors
isFileDoesNotExistHPath.IO.Errors
isFileNameSystem.Posix.FilePath
isInvalidOperationHPath.IO.Errors
isParentOfHPath
isPathSeparatorSystem.Posix.FilePath
isRecursiveFailureHPath.IO.Errors
isRelativeSystem.Posix.FilePath
isSameFileHPath.IO.Errors
isSearchPathSeparatorSystem.Posix.FilePath
isSupportedSystem.Posix.Directory.Foreign
isValidSystem.Posix.FilePath
isWritableHPath.IO.Errors
\ No newline at end of file diff --git a/doc-index-J.html b/doc-index-J.html index a8c3d66..705a1d8 100644 --- a/doc-index-J.html +++ b/doc-index-J.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - J)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-M.html b/doc-index-M.html index 9e1c2e8..1fd8e82 100644 --- a/doc-index-M.html +++ b/doc-index-M.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - M)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-N.html b/doc-index-N.html index 28be034..293cdc2 100644 --- a/doc-index-N.html +++ b/doc-index-N.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - N)

hpath-0.7.5: Support for well-typed paths

Index - N

NamedPipeHPath.IO
newDirPermsHPath.IO
newFilePermsHPath.IO
normaliseSystem.Posix.FilePath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - N

NamedPipeHPath.IO
newDirPermsHPath.IO
newFilePermsHPath.IO
normaliseSystem.Posix.FilePath
\ No newline at end of file diff --git a/doc-index-O.html b/doc-index-O.html index 1cc8121..51ed9aa 100644 --- a/doc-index-O.html +++ b/doc-index-O.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - O)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-P.html b/doc-index-P.html index 05904ed..884435e 100644 --- a/doc-index-P.html +++ b/doc-index-P.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - P)

hpath-0.7.5: Support for well-typed paths

Index - P

packDirStreamSystem.Posix.Directory.Traversals
parseAbsHPath
parseFnHPath
parseRelHPath
Path 
1 (Type/Class)HPath
2 (Data Constructor)HPath
PathExceptionHPath
pathMaxSystem.Posix.Directory.Foreign
PathParseExceptionHPath
pathSeparatorSystem.Posix.FilePath
peekFilePathSystem.Posix.FilePath
peekFilePathLenSystem.Posix.FilePath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - P

packDirStreamSystem.Posix.Directory.Traversals
parseAbsHPath
parseFnHPath
parseRelHPath
Path 
1 (Type/Class)HPath
2 (Data Constructor)HPath
PathExceptionHPath
pathMaxSystem.Posix.Directory.Foreign
PathParseExceptionHPath
pathSeparatorSystem.Posix.FilePath
peekFilePathSystem.Posix.FilePath
peekFilePathLenSystem.Posix.FilePath
\ No newline at end of file diff --git a/doc-index-R.html b/doc-index-R.html index 64b2cde..486e825 100644 --- a/doc-index-R.html +++ b/doc-index-R.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - R)

hpath-0.7.5: Support for well-typed paths

Index - R

RawFilePathSystem.Posix.FilePath
reactOnErrorHPath.IO.Errors
readDirEntSystem.Posix.Directory.Traversals
realpathSystem.Posix.Directory.Traversals
recreateSymlinkHPath.IO
RecursiveFailureHPath.IO.Errors
RecursiveModeHPath.IO
RegularFileHPath.IO
RelHPath
RelCHPath
renameFileHPath.IO
replaceBaseNameSystem.Posix.FilePath
replaceDirectorySystem.Posix.FilePath
replaceExtensionSystem.Posix.FilePath
replaceFileNameSystem.Posix.FilePath
rethrowErrnoAsHPath.IO.Errors
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - R

RawFilePathSystem.Posix.FilePath
reactOnErrorHPath.IO.Errors
readDirEntSystem.Posix.Directory.Traversals
realpathSystem.Posix.Directory.Traversals
recreateSymlinkHPath.IO
RecursiveErrorModeHPath.IO
RecursiveFailureHPath.IO.Errors
RegularFileHPath.IO
RelHPath
RelCHPath
renameFileHPath.IO
replaceBaseNameSystem.Posix.FilePath
replaceDirectorySystem.Posix.FilePath
replaceExtensionSystem.Posix.FilePath
replaceFileNameSystem.Posix.FilePath
rethrowErrnoAsHPath.IO.Errors
\ No newline at end of file diff --git a/doc-index-S.html b/doc-index-S.html index ff1dd7c..9665961 100644 --- a/doc-index-S.html +++ b/doc-index-S.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - S)

hpath-0.7.5: Support for well-typed paths

Index - S

SameFileHPath.IO.Errors
sameFileHPath.IO.Errors
searchPathSeparatorSystem.Posix.FilePath
SocketHPath.IO
splitDirectoriesSystem.Posix.FilePath
splitExtensionSystem.Posix.FilePath
splitExtensionsSystem.Posix.FilePath
splitFileNameSystem.Posix.FilePath
splitPathSystem.Posix.FilePath
splitSearchPathSystem.Posix.FilePath
StrictHPath.IO
stripDirHPath
stripExtensionSystem.Posix.FilePath
SymbolicLinkHPath.IO
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - S

SameFileHPath.IO.Errors
sameFileHPath.IO.Errors
searchPathSeparatorSystem.Posix.FilePath
SocketHPath.IO
splitDirectoriesSystem.Posix.FilePath
splitExtensionSystem.Posix.FilePath
splitExtensionsSystem.Posix.FilePath
splitFileNameSystem.Posix.FilePath
splitPathSystem.Posix.FilePath
splitSearchPathSystem.Posix.FilePath
StrictHPath.IO
stripDirHPath
stripExtensionSystem.Posix.FilePath
SymbolicLinkHPath.IO
\ No newline at end of file diff --git a/doc-index-T.html b/doc-index-T.html index 713e810..9259e67 100644 --- a/doc-index-T.html +++ b/doc-index-T.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - T)

hpath-0.7.5: Support for well-typed paths

Index - T

takeBaseNameSystem.Posix.FilePath
takeDirectorySystem.Posix.FilePath
takeExtensionSystem.Posix.FilePath
takeExtensionsSystem.Posix.FilePath
takeFileNameSystem.Posix.FilePath
throwCantOpenDirectoryHPath.IO.Errors
throwDestinationInSourceHPath.IO.Errors
throwDirDoesExistHPath.IO.Errors
throwDirDoesNotExistHPath.IO.Errors
throwErrnoPathSystem.Posix.FilePath
throwErrnoPathIfSystem.Posix.FilePath
throwErrnoPathIfMinus1System.Posix.FilePath
throwErrnoPathIfMinus1RetrySystem.Posix.FilePath
throwErrnoPathIfMinus1Retry_System.Posix.FilePath
throwErrnoPathIfMinus1_System.Posix.FilePath
throwErrnoPathIfNullSystem.Posix.FilePath
throwErrnoPathIfNullRetrySystem.Posix.FilePath
throwErrnoPathIfRetrySystem.Posix.FilePath
throwErrnoPathIf_System.Posix.FilePath
throwFileDoesExistHPath.IO.Errors
throwFileDoesNotExistHPath.IO.Errors
throwSameFileHPath.IO.Errors
toFilePathHPath
traverseDirectorySystem.Posix.Directory.Traversals
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - T

takeBaseNameSystem.Posix.FilePath
takeDirectorySystem.Posix.FilePath
takeExtensionSystem.Posix.FilePath
takeExtensionsSystem.Posix.FilePath
takeFileNameSystem.Posix.FilePath
throwCantOpenDirectoryHPath.IO.Errors
throwDestinationInSourceHPath.IO.Errors
throwDirDoesExistHPath.IO.Errors
throwDirDoesNotExistHPath.IO.Errors
throwErrnoPathSystem.Posix.FilePath
throwErrnoPathIfSystem.Posix.FilePath
throwErrnoPathIfMinus1System.Posix.FilePath
throwErrnoPathIfMinus1RetrySystem.Posix.FilePath
throwErrnoPathIfMinus1Retry_System.Posix.FilePath
throwErrnoPathIfMinus1_System.Posix.FilePath
throwErrnoPathIfNullSystem.Posix.FilePath
throwErrnoPathIfNullRetrySystem.Posix.FilePath
throwErrnoPathIfRetrySystem.Posix.FilePath
throwErrnoPathIf_System.Posix.FilePath
throwFileDoesExistHPath.IO.Errors
throwFileDoesNotExistHPath.IO.Errors
throwSameFileHPath.IO.Errors
toFilePathHPath
traverseDirectorySystem.Posix.Directory.Traversals
\ No newline at end of file diff --git a/doc-index-U.html b/doc-index-U.html index c247dc0..6bcf4d7 100644 --- a/doc-index-U.html +++ b/doc-index-U.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - U)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/doc-index-W.html b/doc-index-W.html index 8ed21d3..48e7aac 100644 --- a/doc-index-W.html +++ b/doc-index-W.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index - W)

hpath-0.7.5: Support for well-typed paths

Index - W

whenMHPath.IO.Utils
withAbsPathHPath
withFilePathSystem.Posix.FilePath
withFnPathHPath
withRelPathHPath
\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

Index - W

whenMHPath.IO.Utils
withAbsPathHPath
withFilePathSystem.Posix.FilePath
withFnPathHPath
withRelPathHPath
\ No newline at end of file diff --git a/doc-index.html b/doc-index.html index 5a91dbf..a61da87 100644 --- a/doc-index.html +++ b/doc-index.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths (Index)

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

\ No newline at end of file diff --git a/frames.html b/frames.html index e86edb6..1b4e38d 100644 --- a/frames.html +++ b/frames.html @@ -1,4 +1,4 @@ - diff --git a/haddock-util.js b/haddock-util.js index fc7743f..9a6fccf 100644 --- a/haddock-util.js +++ b/haddock-util.js @@ -131,11 +131,11 @@ function perform_search(full) var text = document.getElementById("searchbox").value.toLowerCase(); if (text == last_search && !full) return; last_search = text; - + var table = document.getElementById("indexlist"); var status = document.getElementById("searchmsg"); var children = table.firstChild.childNodes; - + // first figure out the first node with the prefix var first = bisect(-1); var last = (first == -1 ? -1 : bisect(1)); @@ -166,7 +166,7 @@ function perform_search(full) status.innerHTML = ""; } - + function setclass(first, last, status) { for (var i = first; i <= last; i++) @@ -174,8 +174,8 @@ function perform_search(full) children[i].className = status; } } - - + + // do a binary search, treating 0 as ... // return either -1 (no 0's found) or location of most far match function bisect(dir) @@ -201,9 +201,9 @@ function perform_search(full) if (checkitem(i) == 0) return i; } return -1; - } - - + } + + // from an index, decide what the result is // 0 = match, -1 is lower, 1 is higher function checkitem(i) @@ -212,8 +212,8 @@ function perform_search(full) if (s == text) return 0; else return (s > text ? -1 : 1); } - - + + // from an index, get its string // this abstracts over alternates function getitem(i) @@ -229,7 +229,7 @@ function perform_search(full) } function setSynopsis(filename) { - if (parent.window.synopsis && parent.window.synopsis.location) { + if (parent.window.synopsis) { if (parent.window.synopsis.location.replace) { // In Firefox this avoids adding the change to the history. parent.window.synopsis.location.replace(filename); @@ -250,7 +250,7 @@ function addMenuItem(html) { function adjustForFrames() { var bodyCls; - + if (parent.location.href == window.location.href) { // not in frames, so add Frames button addMenuItem("Frames"); diff --git a/hpath.haddock b/hpath.haddock index 8481118..6e0fd98 100644 Binary files a/hpath.haddock and b/hpath.haddock differ diff --git a/index-frames.html b/index-frames.html index 97ad260..fc92ed5 100644 --- a/index-frames.html +++ b/index-frames.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths \ No newline at end of file diff --git a/index.html b/index.html index 4705233..15ec5a3 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ -hpath-0.7.5: Support for well-typed paths

hpath-0.7.5: Support for well-typed paths

hpath-0.7.5: Support for well-typed paths

Support for well-typed paths, utilizing ByteString under the hood.

\ No newline at end of file +

hpath-0.7.5: Support for well-typed paths

hpath-0.7.5: Support for well-typed paths

Support for well-typed paths, utilizing ByteString under the hood.

\ No newline at end of file diff --git a/mini_HPath-IO-Errors.html b/mini_HPath-IO-Errors.html index 3134e89..b044600 100644 --- a/mini_HPath-IO-Errors.html +++ b/mini_HPath-IO-Errors.html @@ -1,4 +1,4 @@ -HPath.IO.Errors

HPath.IO.Errors

\ No newline at end of file diff --git a/mini_HPath-IO-Utils.html b/mini_HPath-IO-Utils.html index 1ce788b..26280b4 100644 --- a/mini_HPath-IO-Utils.html +++ b/mini_HPath-IO-Utils.html @@ -1,4 +1,4 @@ -HPath.IO.Utils

HPath.IO.Utils

\ No newline at end of file diff --git a/mini_HPath-IO.html b/mini_HPath-IO.html index 3e33624..b2fecc9 100644 --- a/mini_HPath-IO.html +++ b/mini_HPath-IO.html @@ -1,4 +1,4 @@ -HPath.IO

HPath.IO

\ No newline at end of file +

HPath.IO

\ No newline at end of file diff --git a/mini_HPath.html b/mini_HPath.html index f1b0237..508fa77 100644 --- a/mini_HPath.html +++ b/mini_HPath.html @@ -1,4 +1,4 @@ -HPath

HPath

Types

data Abs

data Path b

data Rel

data Fn

class RelC m

PatternSynonyms/ViewPatterns

Path Parsing

Path Conversion

Path Operations

Path IO helpers

\ No newline at end of file diff --git a/mini_System-Posix-Directory-Foreign.html b/mini_System-Posix-Directory-Foreign.html index 991dcbd..e45f7a2 100644 --- a/mini_System-Posix-Directory-Foreign.html +++ b/mini_System-Posix-Directory-Foreign.html @@ -1,4 +1,4 @@ -System.Posix.Directory.Foreign

System.Posix.Directory.Foreign

\ No newline at end of file diff --git a/mini_System-Posix-Directory-Traversals.html b/mini_System-Posix-Directory-Traversals.html index 281fb1a..dc1b13d 100644 --- a/mini_System-Posix-Directory-Traversals.html +++ b/mini_System-Posix-Directory-Traversals.html @@ -1,4 +1,4 @@ -System.Posix.Directory.Traversals

System.Posix.Directory.Traversals

\ No newline at end of file diff --git a/mini_System-Posix-FD.html b/mini_System-Posix-FD.html index 6c7914a..e5f3904 100644 --- a/mini_System-Posix-FD.html +++ b/mini_System-Posix-FD.html @@ -1,4 +1,4 @@ -System.Posix.FD

System.Posix.FD

\ No newline at end of file diff --git a/mini_System-Posix-FilePath.html b/mini_System-Posix-FilePath.html index e1d7491..578f4c9 100644 --- a/mini_System-Posix-FilePath.html +++ b/mini_System-Posix-FilePath.html @@ -1,4 +1,4 @@ -System.Posix.FilePath

System.Posix.FilePath

\ No newline at end of file diff --git a/ocean.css b/ocean.css index 3ebb14d..1110b40 100644 --- a/ocean.css +++ b/ocean.css @@ -41,9 +41,6 @@ a[href]:link { color: rgb(196,69,29); } a[href]:visited { color: rgb(171,105,84); } a[href]:hover { text-decoration:underline; } -a[href].def:link, a[href].def:visited { color: black; } -a[href].def:hover { color: rgb(78, 98, 114); } - /* @end */ /* @group Fonts & Sizes */ @@ -146,23 +143,15 @@ ul.links li a { background-image: url(plus.gif); background-repeat: no-repeat; } +p.caption.collapser, +p.caption.expander { + background-position: 0 0.4em; +} .collapser, .expander { padding-left: 14px; margin-left: -14px; cursor: pointer; } -p.caption.collapser, -p.caption.expander { - background-position: 0 0.4em; -} - -.instance.collapser, .instance.expander { - margin-left: 0px; - background-position: left center; - min-width: 9px; - min-height: 9px; -} - pre { padding: 0.25em; @@ -183,9 +172,6 @@ pre { .keyword { font-weight: normal; } .def { font-weight: bold; } -@media print { - #footer { display: none; } -} /* @end */ @@ -384,16 +370,21 @@ div#style-menu-holder { #interface h5 + div.top { margin-top: 1em; } -#interface .src .selflink, -#interface .src .link { +#interface p.src .link { float: right; color: #919191; + border-left: 1px solid #919191; background: #f0f0f0; padding: 0 0.5em 0.2em; - margin: 0 -0.5em 0 0; + margin: 0 -0.5em 0 0.5em; } -#interface .src .selflink { + +#interface td.src .link { + float: right; + color: #919191; border-left: 1px solid #919191; + background: #f0f0f0; + padding: 0 0.5em 0.2em; margin: 0 -0.5em 0 0.5em; } @@ -433,31 +424,30 @@ div#style-menu-holder { visibility: hidden; } -.subs ul { - list-style: none; - display: table; +.subs dl { margin: 0; } -.subs ul li { - display: table-row; -} - -.subs ul li dfn { - display: table-cell; - font-style: normal; - font-weight: bold; +.subs dt { + float: left; + clear: left; + display: block; margin: 1px 0; - white-space: nowrap; } -.subs ul li > .doc { - display: table-cell; +.subs dd { + float: right; + width: 90%; + display: block; padding-left: 0.5em; margin-bottom: 0.5em; } -.subs ul li > .doc p { +.subs dd.empty { + display: none; +} + +.subs dd p { margin: 0; } diff --git a/src/HPath-IO-Errors.html b/src/HPath-IO-Errors.html index 7b17c35..028d2c4 100644 --- a/src/HPath-IO-Errors.html +++ b/src/HPath-IO-Errors.html @@ -18,366 +18,367 @@ -- -- Provides error handling. -{-# LANGUAGE ScopedTypeVariables #-} - -module HPath.IO.Errors - ( - -- * Types - HPathIOException(..) - - -- * Exception identifiers - , isFileDoesNotExist - , isDirDoesNotExist - , isSameFile - , isDestinationInSource - , isFileDoesExist - , isDirDoesExist - , isInvalidOperation - , isCan'tOpenDirectory - , isCopyFailed - , isRecursiveFailure - - -- * Path based functions - , throwFileDoesExist - , throwDirDoesExist - , throwFileDoesNotExist - , throwDirDoesNotExist - , throwSameFile - , sameFile - , throwDestinationInSource - , doesFileExist - , doesDirectoryExist - , isWritable - , canOpenDirectory - , throwCantOpenDirectory - - -- * Error handling functions - , catchErrno - , rethrowErrnoAs - , handleIOError - , bracketeer - , reactOnError - ) - where - +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module HPath.IO.Errors + ( + -- * Types + HPathIOException(..) + + -- * Exception identifiers + , isFileDoesNotExist + , isDirDoesNotExist + , isSameFile + , isDestinationInSource + , isFileDoesExist + , isDirDoesExist + , isInvalidOperation + , isCan'tOpenDirectory + , isCopyFailed + , isRecursiveFailure + + -- * Path based functions + , throwFileDoesExist + , throwDirDoesExist + , throwFileDoesNotExist + , throwDirDoesNotExist + , throwSameFile + , sameFile + , throwDestinationInSource + , doesFileExist + , doesDirectoryExist + , isWritable + , canOpenDirectory + , throwCantOpenDirectory + + -- * Error handling functions + , catchErrno + , rethrowErrnoAs + , handleIOError + , bracketeer + , reactOnError + ) + where -import Control.Applicative - ( - (<$>) - ) -import Control.Exception -import Control.Monad - ( - forM - , when - ) -import Data.ByteString - ( - ByteString - ) -import Data.ByteString.UTF8 - ( - toString - ) -import Data.Typeable -import Foreign.C.Error - ( - getErrno - , Errno - ) -import GHC.IO.Exception - ( - IOErrorType - ) -import HPath -import {-# SOURCE #-} HPath.IO - ( - canonicalizePath - ) -import HPath.IO.Utils -import System.IO.Error - ( - catchIOError - , ioeGetErrorType - ) - -import qualified System.Posix.Directory.ByteString as PFD -import System.Posix.Files.ByteString - ( - fileAccess - , getFileStatus - ) -import qualified System.Posix.Files.ByteString as PF - + +import Control.Applicative + ( + (<$>) + ) +import Control.Exception +import Control.Monad + ( + forM + , when + ) +import Data.ByteString + ( + ByteString + ) +import Data.ByteString.UTF8 + ( + toString + ) +import Data.Typeable +import Foreign.C.Error + ( + getErrno + , Errno + ) +import GHC.IO.Exception + ( + IOErrorType + ) +import HPath +import {-# SOURCE #-} HPath.IO + ( + canonicalizePath + ) +import HPath.IO.Utils +import System.IO.Error + ( + catchIOError + , ioeGetErrorType + ) + +import qualified System.Posix.Directory.ByteString as PFD +import System.Posix.Files.ByteString + ( + fileAccess + , getFileStatus + ) +import qualified System.Posix.Files.ByteString as PF -data HPathIOException = FileDoesNotExist ByteString - | DirDoesNotExist ByteString - | SameFile ByteString ByteString - | DestinationInSource ByteString ByteString - | FileDoesExist ByteString - | DirDoesExist ByteString - | InvalidOperation String - | Can'tOpenDirectory ByteString - | CopyFailed String - | RecursiveFailure [IOException] - deriving (Typeable, Eq) - + +data HPathIOException = FileDoesNotExist ByteString + | DirDoesNotExist ByteString + | SameFile ByteString ByteString + | DestinationInSource ByteString ByteString + | FileDoesExist ByteString + | DirDoesExist ByteString + | InvalidOperation String + | Can'tOpenDirectory ByteString + | CopyFailed String + | RecursiveFailure [IOException] + deriving (Typeable, Eq) -instance Show HPathIOException where - show (FileDoesNotExist fp) = "File does not exist:" ++ toString fp - show (DirDoesNotExist fp) = "Directory does not exist: " - ++ toString fp - show (SameFile fp1 fp2) = toString fp1 - ++ " and " ++ toString fp2 - ++ " are the same file!" - show (DestinationInSource fp1 fp2) = toString fp1 - ++ " is contained in " - ++ toString fp2 - show (FileDoesExist fp) = "File does exist: " ++ toString fp - show (DirDoesExist fp) = "Directory does exist: " ++ toString fp - show (InvalidOperation str) = "Invalid operation: " ++ str - show (Can'tOpenDirectory fp) = "Can't open directory: " - ++ toString fp - show (CopyFailed str) = "Copying failed: " ++ str - show (RecursiveFailure exs) = "Recursive operation failed: " - ++ show exs - + +instance Show HPathIOException where + show (FileDoesNotExist fp) = "File does not exist:" ++ toString fp + show (DirDoesNotExist fp) = "Directory does not exist: " + ++ toString fp + show (SameFile fp1 fp2) = toString fp1 + ++ " and " ++ toString fp2 + ++ " are the same file!" + show (DestinationInSource fp1 fp2) = toString fp1 + ++ " is contained in " + ++ toString fp2 + show (FileDoesExist fp) = "File does exist: " ++ toString fp + show (DirDoesExist fp) = "Directory does exist: " ++ toString fp + show (InvalidOperation str) = "Invalid operation: " ++ str + show (Can'tOpenDirectory fp) = "Can't open directory: " + ++ toString fp + show (CopyFailed str) = "Copying failed: " ++ str + show (RecursiveFailure exs) = "Recursive operation failed: " + ++ show exs -toConstr :: HPathIOException -> String -toConstr FileDoesNotExist {} = "FileDoesNotExist" -toConstr DirDoesNotExist {} = "DirDoesNotExist" -toConstr SameFile {} = "SameFile" -toConstr DestinationInSource {} = "DestinationInSource" -toConstr FileDoesExist {} = "FileDoesExist" -toConstr DirDoesExist {} = "DirDoesExist" -toConstr InvalidOperation {} = "InvalidOperation" -toConstr Can'tOpenDirectory {} = "Can'tOpenDirectory" -toConstr CopyFailed {} = "CopyFailed" -toConstr RecursiveFailure {} = "RecursiveFailure" - + +toConstr :: HPathIOException -> String +toConstr FileDoesNotExist {} = "FileDoesNotExist" +toConstr DirDoesNotExist {} = "DirDoesNotExist" +toConstr SameFile {} = "SameFile" +toConstr DestinationInSource {} = "DestinationInSource" +toConstr FileDoesExist {} = "FileDoesExist" +toConstr DirDoesExist {} = "DirDoesExist" +toConstr InvalidOperation {} = "InvalidOperation" +toConstr Can'tOpenDirectory {} = "Can'tOpenDirectory" +toConstr CopyFailed {} = "CopyFailed" +toConstr RecursiveFailure {} = "RecursiveFailure" -instance Exception HPathIOException - + +instance Exception HPathIOException - ----------------------------- - --[ Exception identifiers ]-- - ----------------------------- - -isFileDoesNotExist, isDirDoesNotExist, isSameFile, isDestinationInSource, isFileDoesExist, isDirDoesExist, isInvalidOperation, isCan'tOpenDirectory, isCopyFailed, isRecursiveFailure :: HPathIOException -> Bool -isFileDoesNotExist ex = toConstr (ex :: HPathIOException) == toConstr FileDoesNotExist{} -isDirDoesNotExist ex = toConstr (ex :: HPathIOException) == toConstr DirDoesNotExist{} -isSameFile ex = toConstr (ex :: HPathIOException) == toConstr SameFile{} -isDestinationInSource ex = toConstr (ex :: HPathIOException) == toConstr DestinationInSource{} -isFileDoesExist ex = toConstr (ex :: HPathIOException) == toConstr FileDoesExist{} -isDirDoesExist ex = toConstr (ex :: HPathIOException) == toConstr DirDoesExist{} -isInvalidOperation ex = toConstr (ex :: HPathIOException) == toConstr InvalidOperation{} -isCan'tOpenDirectory ex = toConstr (ex :: HPathIOException) == toConstr Can'tOpenDirectory{} -isCopyFailed ex = toConstr (ex :: HPathIOException) == toConstr CopyFailed{} -isRecursiveFailure ex = toConstr (ex :: HPathIOException) == toConstr RecursiveFailure{} - + + ----------------------------- + --[ Exception identifiers ]-- + ----------------------------- + +isFileDoesNotExist, isDirDoesNotExist, isSameFile, isDestinationInSource, isFileDoesExist, isDirDoesExist, isInvalidOperation, isCan'tOpenDirectory, isCopyFailed, isRecursiveFailure :: HPathIOException -> Bool +isFileDoesNotExist ex = toConstr (ex :: HPathIOException) == toConstr FileDoesNotExist{} +isDirDoesNotExist ex = toConstr (ex :: HPathIOException) == toConstr DirDoesNotExist{} +isSameFile ex = toConstr (ex :: HPathIOException) == toConstr SameFile{} +isDestinationInSource ex = toConstr (ex :: HPathIOException) == toConstr DestinationInSource{} +isFileDoesExist ex = toConstr (ex :: HPathIOException) == toConstr FileDoesExist{} +isDirDoesExist ex = toConstr (ex :: HPathIOException) == toConstr DirDoesExist{} +isInvalidOperation ex = toConstr (ex :: HPathIOException) == toConstr InvalidOperation{} +isCan'tOpenDirectory ex = toConstr (ex :: HPathIOException) == toConstr Can'tOpenDirectory{} +isCopyFailed ex = toConstr (ex :: HPathIOException) == toConstr CopyFailed{} +isRecursiveFailure ex = toConstr (ex :: HPathIOException) == toConstr RecursiveFailure{} - ---------------------------- - --[ Path based functions ]-- - ---------------------------- - + + ---------------------------- + --[ Path based functions ]-- + ---------------------------- -throwFileDoesExist :: Path Abs -> IO () -throwFileDoesExist fp = - whenM (doesFileExist fp) (throwIO . FileDoesExist - . fromAbs $ fp) - + +throwFileDoesExist :: Path Abs -> IO () +throwFileDoesExist fp = + whenM (doesFileExist fp) (throwIO . FileDoesExist + . fromAbs $ fp) -throwDirDoesExist :: Path Abs -> IO () -throwDirDoesExist fp = - whenM (doesDirectoryExist fp) (throwIO . DirDoesExist - . fromAbs $ fp) - + +throwDirDoesExist :: Path Abs -> IO () +throwDirDoesExist fp = + whenM (doesDirectoryExist fp) (throwIO . DirDoesExist + . fromAbs $ fp) -throwFileDoesNotExist :: Path Abs -> IO () -throwFileDoesNotExist fp = - unlessM (doesFileExist fp) (throwIO . FileDoesNotExist - . fromAbs $ fp) - + +throwFileDoesNotExist :: Path Abs -> IO () +throwFileDoesNotExist fp = + unlessM (doesFileExist fp) (throwIO . FileDoesNotExist + . fromAbs $ fp) -throwDirDoesNotExist :: Path Abs -> IO () -throwDirDoesNotExist fp = - unlessM (doesDirectoryExist fp) (throwIO . DirDoesNotExist - . fromAbs $ fp) - + +throwDirDoesNotExist :: Path Abs -> IO () +throwDirDoesNotExist fp = + unlessM (doesDirectoryExist fp) (throwIO . DirDoesNotExist + . fromAbs $ fp) --- |Uses `isSameFile` and throws `SameFile` if it returns True. -throwSameFile :: Path Abs - -> Path Abs - -> IO () -throwSameFile fp1 fp2 = - whenM (sameFile fp1 fp2) - (throwIO $ SameFile (fromAbs fp1) (fromAbs fp2)) - + +-- |Uses `isSameFile` and throws `SameFile` if it returns True. +throwSameFile :: Path Abs + -> Path Abs + -> IO () +throwSameFile fp1 fp2 = + whenM (sameFile fp1 fp2) + (throwIO $ SameFile (fromAbs fp1) (fromAbs fp2)) --- |Check if the files are the same by examining device and file id. --- This follows symbolic links. -sameFile :: Path Abs -> Path Abs -> IO Bool -sameFile fp1 fp2 = - withAbsPath fp1 $ \fp1' -> withAbsPath fp2 $ \fp2' -> - handleIOError (\_ -> return False) $ do - fs1 <- getFileStatus fp1' - fs2 <- getFileStatus fp2' - - if ((PF.deviceID fs1, PF.fileID fs1) == - (PF.deviceID fs2, PF.fileID fs2)) - then return True - else return False - + +-- |Check if the files are the same by examining device and file id. +-- This follows symbolic links. +sameFile :: Path Abs -> Path Abs -> IO Bool +sameFile fp1 fp2 = + withAbsPath fp1 $ \fp1' -> withAbsPath fp2 $ \fp2' -> + handleIOError (\_ -> return False) $ do + fs1 <- getFileStatus fp1' + fs2 <- getFileStatus fp2' + + if ((PF.deviceID fs1, PF.fileID fs1) == + (PF.deviceID fs2, PF.fileID fs2)) + then return True + else return False --- TODO: make this more robust when destination does not exist --- |Checks whether the destination directory is contained --- within the source directory by comparing the device+file ID of the --- source directory with all device+file IDs of the parent directories --- of the destination. -throwDestinationInSource :: Path Abs -- ^ source dir - -> Path Abs -- ^ full destination, @dirname dest@ - -- must exist - -> IO () -throwDestinationInSource source dest = do - dest' <- (\x -> maybe x (\y -> x </> y) $ basename dest) - <$> (canonicalizePath $ dirname dest) - dids <- forM (getAllParents dest') $ \p -> do - fs <- PF.getSymbolicLinkStatus (fromAbs p) - return (PF.deviceID fs, PF.fileID fs) - sid <- fmap (\x -> (PF.deviceID x, PF.fileID x)) - $ PF.getFileStatus (fromAbs source) - when (elem sid dids) - (throwIO $ DestinationInSource (fromAbs dest) - (fromAbs source)) - + +-- TODO: make this more robust when destination does not exist +-- |Checks whether the destination directory is contained +-- within the source directory by comparing the device+file ID of the +-- source directory with all device+file IDs of the parent directories +-- of the destination. +throwDestinationInSource :: Path Abs -- ^ source dir + -> Path Abs -- ^ full destination, @dirname dest@ + -- must exist + -> IO () +throwDestinationInSource source dest = do + dest' <- (\x -> maybe x (\y -> x </> y) $ basename dest) + <$> (canonicalizePath $ dirname dest) + dids <- forM (getAllParents dest') $ \p -> do + fs <- PF.getSymbolicLinkStatus (fromAbs p) + return (PF.deviceID fs, PF.fileID fs) + sid <- fmap (\x -> (PF.deviceID x, PF.fileID x)) + $ PF.getFileStatus (fromAbs source) + when (elem sid dids) + (throwIO $ DestinationInSource (fromAbs dest) + (fromAbs source)) --- |Checks if the given file exists and is not a directory. --- Does not follow symlinks. -doesFileExist :: Path Abs -> IO Bool -doesFileExist fp = - handleIOError (\_ -> return False) $ do - fs <- PF.getSymbolicLinkStatus (fromAbs fp) - return $ not . PF.isDirectory $ fs - + +-- |Checks if the given file exists and is not a directory. +-- Does not follow symlinks. +doesFileExist :: Path Abs -> IO Bool +doesFileExist fp = + handleIOError (\_ -> return False) $ do + fs <- PF.getSymbolicLinkStatus (fromAbs fp) + return $ not . PF.isDirectory $ fs --- |Checks if the given file exists and is a directory. --- Does not follow symlinks. -doesDirectoryExist :: Path Abs -> IO Bool -doesDirectoryExist fp = - handleIOError (\_ -> return False) $ do - fs <- PF.getSymbolicLinkStatus (fromAbs fp) - return $ PF.isDirectory fs - + +-- |Checks if the given file exists and is a directory. +-- Does not follow symlinks. +doesDirectoryExist :: Path Abs -> IO Bool +doesDirectoryExist fp = + handleIOError (\_ -> return False) $ do + fs <- PF.getSymbolicLinkStatus (fromAbs fp) + return $ PF.isDirectory fs --- |Checks whether a file or folder is writable. -isWritable :: Path Abs -> IO Bool -isWritable fp = - handleIOError (\_ -> return False) $ - fileAccess (fromAbs fp) False True False - + +-- |Checks whether a file or folder is writable. +isWritable :: Path Abs -> IO Bool +isWritable fp = + handleIOError (\_ -> return False) $ + fileAccess (fromAbs fp) False True False --- |Checks whether the directory at the given path exists and can be --- opened. This invokes `openDirStream` which follows symlinks. -canOpenDirectory :: Path Abs -> IO Bool -canOpenDirectory fp = - handleIOError (\_ -> return False) $ do - bracket (PFD.openDirStream . fromAbs $ fp) - PFD.closeDirStream - (\_ -> return ()) - return True - + +-- |Checks whether the directory at the given path exists and can be +-- opened. This invokes `openDirStream` which follows symlinks. +canOpenDirectory :: Path Abs -> IO Bool +canOpenDirectory fp = + handleIOError (\_ -> return False) $ do + bracket (PFD.openDirStream . fromAbs $ fp) + PFD.closeDirStream + (\_ -> return ()) + return True --- |Throws a `Can'tOpenDirectory` HPathIOException if the directory at the given --- path cannot be opened. -throwCantOpenDirectory :: Path Abs -> IO () -throwCantOpenDirectory fp = - unlessM (canOpenDirectory fp) - (throwIO . Can'tOpenDirectory . fromAbs $ fp) - + +-- |Throws a `Can'tOpenDirectory` HPathIOException if the directory at the given +-- path cannot be opened. +throwCantOpenDirectory :: Path Abs -> IO () +throwCantOpenDirectory fp = + unlessM (canOpenDirectory fp) + (throwIO . Can'tOpenDirectory . fromAbs $ fp) - -------------------------------- - --[ Error handling functions ]-- - -------------------------------- - + + -------------------------------- + --[ Error handling functions ]-- + -------------------------------- --- |Carries out an action, then checks if there is an IOException and --- a specific errno. If so, then it carries out another action, otherwise --- it rethrows the error. -catchErrno :: [Errno] -- ^ errno to catch - -> IO a -- ^ action to try, which can raise an IOException - -> IO a -- ^ action to carry out in case of an IOException and - -- if errno matches - -> IO a -catchErrno en a1 a2 = - catchIOError a1 $ \e -> do - errno <- getErrno - if errno `elem` en - then a2 - else ioError e - + +-- |Carries out an action, then checks if there is an IOException and +-- a specific errno. If so, then it carries out another action, otherwise +-- it rethrows the error. +catchErrno :: [Errno] -- ^ errno to catch + -> IO a -- ^ action to try, which can raise an IOException + -> IO a -- ^ action to carry out in case of an IOException and + -- if errno matches + -> IO a +catchErrno en a1 a2 = + catchIOError a1 $ \e -> do + errno <- getErrno + if errno `elem` en + then a2 + else ioError e --- |Execute the given action and retrow IO exceptions as a new Exception --- that have the given errno. If errno does not match the exception is rethrown --- as is. -rethrowErrnoAs :: Exception e - => [Errno] -- ^ errno to catch - -> e -- ^ rethrow as if errno matches - -> IO a -- ^ action to try - -> IO a -rethrowErrnoAs en fmex action = catchErrno en action (throwIO fmex) - + +-- |Execute the given action and retrow IO exceptions as a new Exception +-- that have the given errno. If errno does not match the exception is rethrown +-- as is. +rethrowErrnoAs :: Exception e + => [Errno] -- ^ errno to catch + -> e -- ^ rethrow as if errno matches + -> IO a -- ^ action to try + -> IO a +rethrowErrnoAs en fmex action = catchErrno en action (throwIO fmex) --- |Like `catchIOError`, with arguments swapped. -handleIOError :: (IOError -> IO a) -> IO a -> IO a -handleIOError = flip catchIOError - + +-- |Like `catchIOError`, with arguments swapped. +handleIOError :: (IOError -> IO a) -> IO a -> IO a +handleIOError = flip catchIOError --- |Like `bracket`, but allows to have different clean-up --- actions depending on whether the in-between computation --- has raised an exception or not. -bracketeer :: IO a -- ^ computation to run first - -> (a -> IO b) -- ^ computation to run last, when - -- no exception was raised - -> (a -> IO b) -- ^ computation to run last, - -- when an exception was raised - -> (a -> IO c) -- ^ computation to run in-between - -> IO c -bracketeer before after afterEx thing = - mask $ \restore -> do - a <- before - r <- restore (thing a) `onException` afterEx a - _ <- after a - return r - + +-- |Like `bracket`, but allows to have different clean-up +-- actions depending on whether the in-between computation +-- has raised an exception or not. +bracketeer :: IO a -- ^ computation to run first + -> (a -> IO b) -- ^ computation to run last, when + -- no exception was raised + -> (a -> IO b) -- ^ computation to run last, + -- when an exception was raised + -> (a -> IO c) -- ^ computation to run in-between + -> IO c +bracketeer before after afterEx thing = + mask $ \restore -> do + a <- before + r <- restore (thing a) `onException` afterEx a + _ <- after a + return r -reactOnError :: IO a - -> [(IOErrorType, IO a)] -- ^ reaction on IO errors - -> [(HPathIOException, IO a)] -- ^ reaction on HPathIOException - -> IO a -reactOnError a ios fmios = - a `catches` [iohandler, fmiohandler] - where - iohandler = Handler $ - \(ex :: IOException) -> - foldr (\(t, a') y -> if ioeGetErrorType ex == t - then a' - else y) - (throwIO ex) - ios - fmiohandler = Handler $ - \(ex :: HPathIOException) -> - foldr (\(t, a') y -> if toConstr ex == toConstr t - then a' - else y) - (throwIO ex) - fmios + +reactOnError :: IO a + -> [(IOErrorType, IO a)] -- ^ reaction on IO errors + -> [(HPathIOException, IO a)] -- ^ reaction on HPathIOException + -> IO a +reactOnError a ios fmios = + a `catches` [iohandler, fmiohandler] + where + iohandler = Handler $ + \(ex :: IOException) -> + foldr (\(t, a') y -> if ioeGetErrorType ex == t + then a' + else y) + (throwIO ex) + ios + fmiohandler = Handler $ + \(ex :: HPathIOException) -> + foldr (\(t, a') y -> if toConstr ex == toConstr t + then a' + else y) + (throwIO ex) + fmios diff --git a/src/HPath-IO.html b/src/HPath-IO.html index a978998..299159e 100644 --- a/src/HPath-IO.html +++ b/src/HPath-IO.html @@ -46,7 +46,7 @@ ( -- * Types FileType(..) - , RecursiveMode(..) + , RecursiveErrorMode(..) , CopyMode(..) -- * File copying , copyDirRecursive @@ -228,17 +228,17 @@ --- |The mode for any recursive operation. --- --- On `FailEarly` the whole operation fails immediately if any of the --- recursive sub-operations fail, which is sort of the default --- for IO operations. --- --- On `CollectFailures` skips errors in the recursion and keeps on recursing. --- However all errors are collected in the `RecursiveFailure` error type, --- which is raised finally if there was any error. -data RecursiveMode = FailEarly - | CollectFailures +-- |The error mode for any recursive operation. +-- +-- On `FailEarly` the whole operation fails immediately if any of the +-- recursive sub-operations fail, which is sort of the default +-- for IO operations. +-- +-- On `CollectFailures` skips errors in the recursion and keeps on recursing. +-- However all errors are collected in the `RecursiveFailure` error type, +-- which is raised finally if there was any error. +data RecursiveErrorMode = FailEarly + | CollectFailures -- |The mode for copy and file moves. @@ -262,12 +262,12 @@ -- For directory contents, this will ignore any file type that is not -- `RegularFile`, `SymbolicLink` or `Directory`. -- --- For `Overwrite` mode this does not prune destination directory contents, +-- For `Overwrite` copy mode this does not prune destination directory contents, -- so the destination might contain more files than the source after -- the operation has completed. -- -- Note that there is no guaranteed ordering of the exceptions --- contained within `RecursiveFailure` in `CollectFailures` RecursiveMode. +-- contained within `RecursiveFailure` in `CollectFailures` RecursiveErrorMode. -- -- Safety/reliability concerns: -- @@ -287,16 +287,16 @@ -- - `DestinationInSource` if destination is contained in source -- (`HPathIOException`) -- --- Throws in `FailEarly` RecursiveMode only: +-- Throws in `FailEarly` RecursiveErrorMode only: -- -- - `PermissionDenied` if output directory is not writable -- - `InvalidArgument` if source directory is wrong type (symlink) -- - `InappropriateType` if source directory is wrong type (regular file) -- --- Throws in `CollectFailures` RecursiveMode only: +-- Throws in `CollectFailures` RecursiveErrorMode only: -- -- - `RecursiveFailure` if any of the recursive operations that are not --- part of the top-directory sanity-checks fails (`HPathIOException`) +-- part of the top-directory sanity-checks fail (`HPathIOException`) -- -- Throws in `Strict` CopyMode only: -- @@ -304,7 +304,7 @@ copyDirRecursive :: Path Abs -- ^ source dir -> Path Abs -- ^ full destination -> CopyMode - -> RecursiveMode + -> RecursiveErrorMode -> IO () copyDirRecursive fromp destdirp cm rm = do @@ -357,7 +357,7 @@ -- |Recreate a symlink. -- --- In `Overwrite` mode only files and empty directories are deleted. +-- In `Overwrite` copy mode only files and empty directories are deleted. -- -- Safety/reliability concerns: -- @@ -408,7 +408,7 @@ -- examine file types. For a more high-level version, use `easyCopy` -- instead. -- --- In `Overwrite` mode only overwrites actual files, not directories. +-- In `Overwrite` copy mode only overwrites actual files, not directories. -- -- Safety/reliability concerns: -- @@ -523,7 +523,7 @@ easyCopy :: Path Abs -> Path Abs -> CopyMode - -> RecursiveMode + -> RecursiveErrorMode -> IO () easyCopy from to cm rm = do ftype <- getFileType from diff --git a/src/System-Posix-Directory-Traversals.html b/src/System-Posix-Directory-Traversals.html index 12a4f80..66e21a8 100644 --- a/src/System-Posix-Directory-Traversals.html +++ b/src/System-Posix-Directory-Traversals.html @@ -19,253 +19,257 @@ -- Traversal and read operations on directories. -{-# LANGUAGE ForeignFunctionInterface #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PackageImports #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE ViewPatterns #-} - -{-# OPTIONS_GHC -Wall #-} - +{-# LANGUAGE CPP #-} +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE ViewPatterns #-} + +{-# OPTIONS_GHC -Wall #-} -module System.Posix.Directory.Traversals ( - - getDirectoryContents -, getDirectoryContents' - -, allDirectoryContents -, allDirectoryContents' -, traverseDirectory - --- lower-level stuff -, readDirEnt -, packDirStream -, unpackDirStream -, fdOpendir - -, realpath -) where - -import Control.Applicative -import Control.Monad -import System.Posix.FilePath ((</>)) -import System.Posix.Directory.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 - - - - ----------------------------------------------------------- + +module System.Posix.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.Directory.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. + + +---------------------------------------------------------- + +-- | Get all files from a directory and its subdirectories. -- --- 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 +-- 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 -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 - + +---------------------------------------------------------- +-- 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 ()) -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.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 +---------------------------------------------------------- +-- 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.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