aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/fileStatusByteString.hs
diff options
context:
space:
mode:
authorGravatar Simon Marlow <marlowsd@gmail.com>2011-11-11 16:18:48 +0000
committerGravatar Simon Marlow <marlowsd@gmail.com>2011-11-22 12:36:48 +0000
commit34c7bf896f19b182cf6fa104e057f1df9df1254a (patch)
treeabdb8264ae52c62263fc0fb4b395906a64acb104 /tests/fileStatusByteString.hs
parentc213ae2ec6d9c71266aebc8e5b2326a9625fba7a (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.hs105
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
+ )