HORIZON HASKELLDocslts/ghc-9.14.xd82dee82026-10-12Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · d82dee8 · 2026-10-12

Modulefs-sim-0.5.0.1Haskell2010

System.FS.Sim.MockFS

Mock file system implementation

Intended for qualified import

import           System.FS.Sim.MockFS (MockFS)
import qualified System.FS.Sim.MockFS as Mock
  • 7 types
  • 31 values
  • Packagefs-sim-0.5.0.1
  • Exports38
  • LanguageHaskell2010
  • LicenceApache-2.0
  • SourceMockFS.hs

Debugging

1 declaration

Operations on files

9 declarations
valuehClose :: CanSimFS m => Handle' -> m ()
#

Mock implementation of hClose

valuehGetSize :: CanSimFS m => Handle' -> m Word64
#

Get file size

NOTE: In the mock implementation this is thread safe, because there can be only one writer, so concurrent threads cannot change the size of the file.

valuehOpen :: CanSimFS m => FsPath -> OpenMode -> m Handle'
#

Mock implementation of hOpen.

NOTE: Differences from Posix:

  • We do not support opening directories.

  • We do not support more than one concurrent writer (we do however allow a writer and multiple concurrent readers)

  • We do not support create file on ReadMode.

valuehSeek :: CanSimFS m => Handle' -> SeekMode -> Int64 -> m ()
#

Mock implementation of hSeek

NOTE: This is more restricted than the IO version, because seek has some odd properties:

  • We do not allow seeking at all on files in append mode

  • We do not allow seeking past the end of the file (this means that when using IO.SeekFromEnd, the only valid offset is 0)

  • We do not return the new file offset

valuehTruncate :: CanSimFS m => Handle' -> Word64 -> m ()
#

Truncate a file

NOTE: Differences from Posix:

  • Although this corresponds to Posix ftruncate, this can only be used to make files smaller, not larger.

  • We only support this in append mode. The reason is that Posix ftruncate does not modify the file offset, and adds padding with zeroes on subsequent writes. This is however not behaviour we want to emulate. In append mode however the Posix file offset is not used (and we don't even record it at all), appends always happen at the end of the file.

Operations on directories

8 declarations
valuedoesDirectoryExist :: CanSimFS m => FsPath -> m Bool
#

Check if directory exists

It seems real I/O maps what would be "inapproriate device" errors to False.

valueremoveFile :: CanSimFS m => FsPath -> m ()
#

Remove a file

The behaviour of unlink is to remove the file after all open file handles that refer to it are closed. The open file handles referring to the file can still be used to write/read to/from, while at the same time, the file is invisible for all other operations.

We do not implement this behaviour and consider this a limitation of the mock file system, and throw an error when removing a file that still has open file handles to it.

In the state machine tests, removing the root directory may cause the IO implementation to throw an FsInsufficientPermissions error, depending on the permissions of the temporary directory used to run the tests in. In theory it should throw a FsResourceInappropriateType error. To avoid this mismatch during testing, we also consider removing the root folder a limitation of the mock file system.

Exported for the benefit of tests only

2 declarations

opaque

datadata ClosedHandleState
#
Instances3Show, Generic, Rep
datadata FilePtr
#

File pointer

This is purely an internal abstraction.

Instances3Show, Generic, Rep
datadata HandleState
#

Mock handle internal state

Instances3Show, Generic, Rep
datadata OpenHandleState
#
Instances3Show, Generic, Rep

opaque

2 declarations
newtypenewtype HandleMock
#

A mock handle to a file on disk.

This is only meaningful when interpreted against a MockFS.

Instances6Enum, Eq, Ord, Show, Generic, Rep
datadata MockFS
#
Instances4Show, Generic, MonadState, Rep

HasBufFS

6 declarations