diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-11-11 16:18:48 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-11-22 12:36:48 +0000 |
commit | 34c7bf896f19b182cf6fa104e057f1df9df1254a (patch) | |
tree | abdb8264ae52c62263fc0fb4b395906a64acb104 /tests/fileStatusByteString.hs | |
parent | c213ae2ec6d9c71266aebc8e5b2326a9625fba7a (diff) |
Provide a raw ByteString version of FilePath and environment APIs
The new module System.Posix.ByteString provides exactly the same API
as System.Posix, except that:
- There is a new type: RawFilePath = ByteString
- All functions mentioning FilePath in the System.Posix API
use RawFilePath in the System.Posix.ByteString API
- RawFilePaths are not subject to Unicode locale encoding and
decoding, unlike FilePaths. They are the exact bytes passed to and
returned from the underlying POSIX API.
- Similarly for functions that deal in environment
strings (System.Posix.Env): these use untranslated ByteStrings
in System.Posix.Environment
- There is a new function
System.Posix.ByteString.getArgs :: [ByteString]
returning the raw untranslated arguments as passed to exec() when
the program was started.
Diffstat (limited to 'tests/fileStatusByteString.hs')
-rw-r--r-- | tests/fileStatusByteString.hs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/fileStatusByteString.hs b/tests/fileStatusByteString.hs new file mode 100644 index 0000000..35d52d8 --- /dev/null +++ b/tests/fileStatusByteString.hs @@ -0,0 +1,105 @@ +{-# LANGUAGE OverloadedStrings #-} + +-- GHC trac #2969 + +import System.Posix.ByteString +import Control.Exception as E +import Control.Monad + +main = do + cleanup + fs <- testRegular + ds <- testDir + testSymlink fs ds + cleanup + +regular = "regular2" +dir = "dir2" +link_regular = "link-regular2" +link_dir = "link-dir2" + +testRegular = do + createFile regular ownerReadMode + (fs, _) <- getStatus regular + let expected = (False,False,False,True,False,False,False) + actual = snd (statusElements fs) + when (actual /= expected) $ + fail "unexpected file status bits for regular file" + return fs + +testDir = do + createDirectory dir ownerReadMode + (ds, _) <- getStatus dir + let expected = (False,False,False,False,True,False,False) + actual = snd (statusElements ds) + when (actual /= expected) $ + fail "unexpected file status bits for directory" + return ds + +testSymlink fs ds = do + createSymbolicLink regular link_regular + createSymbolicLink dir link_dir + (fs', ls) <- getStatus link_regular + (ds', lds) <- getStatus link_dir + + let expected = (False,False,False,False,False,True,False) + actualF = snd (statusElements ls) + actualD = snd (statusElements lds) + + when (actualF /= expected) $ + fail "unexpected file status bits for symlink to regular file" + + when (actualD /= expected) $ + fail "unexpected file status bits for symlink to directory" + + when (statusElements fs /= statusElements fs') $ + fail "status for a file does not match when it's accessed via a symlink" + + when (statusElements ds /= statusElements ds') $ + fail "status for a directory does not match when it's accessed via a symlink" + +cleanup = do + ignoreIOExceptions $ removeDirectory dir + mapM_ (ignoreIOExceptions . removeLink) + [regular, link_regular, link_dir] + +ignoreIOExceptions io = io `E.catch` + ((\_ -> return ()) :: IOException -> IO ()) + +getStatus f = do + fs <- getFileStatus f + ls <- getSymbolicLinkStatus f + + fd <- openFd f ReadOnly Nothing defaultFileFlags + fs' <- getFdStatus fd + + when (statusElements fs /= statusElements fs') $ + fail "getFileStatus and getFdStatus give inconsistent results" + + when (not (isSymbolicLink ls) && statusElements fs /= statusElements fs') $ + fail $ "getFileStatus and getSymbolicLinkStatus give inconsistent results " + ++ "on a file that is not a symbolic link" + + return (fs, ls) + +-- Yay for 17-element tuples! +statusElements fs = (,) + (deviceID fs + ,fileMode fs + ,linkCount fs + ,fileOwner fs + ,fileGroup fs + ,specialDeviceID fs + ,fileSize fs + ,accessTime fs + ,modificationTime fs + ,statusChangeTime fs + ) + (isBlockDevice fs + ,isCharacterDevice fs + ,isNamedPipe fs + ,isRegularFile fs + ,isDirectory fs + ,isSymbolicLink fs + ,isSocket fs + ) |