X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=System%2FDirectory.hs;h=1df632f25ead83d2ab0d0003d44019c22691345d;hb=12608d12873e6b88c44881b3ff91bba6807affe5;hp=d5d54e82a216c1a808df820ddf2fd871b1042608;hpb=1f866f6625c7ed42b34bf1c77e0f0dddd5280315;p=haskell-directory.git diff --git a/System/Directory.hs b/System/Directory.hs index d5d54e8..1df632f 100644 --- a/System/Directory.hs +++ b/System/Directory.hs @@ -1,3 +1,6 @@ +{-# OPTIONS_GHC -w #-} +-- XXX We get some warnings on Windows + ----------------------------------------------------------------------------- -- | -- Module : System.Directory @@ -67,6 +70,7 @@ module System.Directory ) where import Prelude hiding ( catch ) +import qualified Prelude import System.Environment ( getEnv ) import System.FilePath @@ -101,7 +105,7 @@ A directory contains a series of entries, each of which is a named reference to a file system object (file, directory etc.). Some entries may be hidden, inaccessible, or have some administrative function (e.g. `.' or `..' under POSIX -), but in +), but in this standard all such entries are considered to form part of the directory contents. Entries in sub-directories are not, however, considered to form part of the directory contents. @@ -165,30 +169,30 @@ getPermissions name = do allocaBytes sizeof_stat $ \ p_stat -> do throwErrnoIfMinus1_ "getPermissions" $ c_stat s p_stat mode <- st_mode p_stat - let read = mode .&. s_IRUSR - let write = mode .&. s_IWUSR - let exec = mode .&. s_IXUSR + let usr_read = mode .&. s_IRUSR + let usr_write = mode .&. s_IWUSR + let usr_exec = mode .&. s_IXUSR let is_dir = mode .&. s_IFDIR return ( Permissions { - readable = read /= 0, - writable = write /= 0, - executable = is_dir == 0 && exec /= 0, - searchable = is_dir /= 0 && exec /= 0 + readable = usr_read /= 0, + writable = usr_write /= 0, + executable = is_dir == 0 && usr_exec /= 0, + searchable = is_dir /= 0 && usr_exec /= 0 } ) #else - read <- c_access s r_OK - write <- c_access s w_OK - exec <- c_access s x_OK + read_ok <- c_access s r_OK + write_ok <- c_access s w_OK + exec_ok <- c_access s x_OK withFileStatus "getPermissions" name $ \st -> do is_dir <- isDirectory st return ( Permissions { - readable = read == 0, - writable = write == 0, - executable = not is_dir && exec == 0, - searchable = is_dir && exec == 0 + readable = read_ok == 0, + writable = write_ok == 0, + executable = not is_dir && exec_ok == 0, + searchable = is_dir && exec_ok == 0 } ) #endif @@ -365,7 +369,7 @@ removeDirectoryRecursive startLoc = do case temp of Left e -> do isDir <- doesDirectoryExist f -- If f is not a directory, re-throw the error - unless isDir $ throw e + unless isDir $ throw (e :: SomeException) removeDirectoryRecursive f Right _ -> return () @@ -545,19 +549,17 @@ copyFile fromFPath toFPath = return () #else copyFile fromFPath toFPath = - copy `catch` (\e -> case e of - IOException e -> - throw $ IOException $ ioeSetLocation e "copyFile" - _ -> throw e) + copy `Prelude.catch` (\exc -> throw $ ioeSetLocation exc "copyFile") where copy = bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom -> bracketOnError openTmp cleanTmp $ \(tmpFPath, hTmp) -> do allocaBytes bufferSize $ copyContents hFrom hTmp hClose hTmp - try (copyPermissions fromFPath tmpFPath) + ignoreIOExceptions $ copyPermissions fromFPath tmpFPath renameFile tmpFPath toFPath openTmp = openBinaryTempFile (takeDirectory toFPath) ".copyFile.tmp" - cleanTmp (tmpFPath, hTmp) = do try $ hClose hTmp - try $ removeFile tmpFPath + cleanTmp (tmpFPath, hTmp) + = do ignoreIOExceptions $ hClose hTmp + ignoreIOExceptions $ removeFile tmpFPath bufferSize = 1024 copyContents hFrom hTo buffer = do @@ -565,6 +567,10 @@ copyFile fromFPath toFPath = when (count > 0) $ do hPutBuf hTo buffer count copyContents hFrom hTo buffer + + ignoreIOExceptions io = io `catch` ioExceptionIgnorer + ioExceptionIgnorer :: IOException -> IO () + ioExceptionIgnorer _ = return () #endif -- | Given path referring to a file or directory, returns a @@ -584,7 +590,9 @@ canonicalizePath fpath = #else do c_realpath pInPath pOutPath #endif - peekCString pOutPath + path <- peekCString pOutPath + return (normalise path) + -- normalise does more stuff, like upper-casing the drive letter #if defined(mingw32_HOST_OS) foreign import stdcall unsafe "GetFullPathNameA" @@ -755,8 +763,8 @@ getCurrentDirectory = do else do errno <- getErrno if errno == eRANGE then do let bytes' = bytes * 2 - p' <- reallocBytes p bytes' - go p' bytes' + p'' <- reallocBytes p bytes' + go p'' bytes' else throwErrno "getCurrentDirectory" {- |If the operating system has a notion of current directories, @@ -803,20 +811,18 @@ exists and is a directory, and 'False' otherwise. -} doesDirectoryExist :: FilePath -> IO Bool -doesDirectoryExist name = - catch +doesDirectoryExist name = (withFileStatus "doesDirectoryExist" name $ \st -> isDirectory st) - (\ _ -> return False) + `catch` ((\ _ -> return False) :: IOException -> IO Bool) {- |The operation 'doesFileExist' returns 'True' if the argument file exists and is not a directory, and 'False' otherwise. -} doesFileExist :: FilePath -> IO Bool -doesFileExist name = do - catch +doesFileExist name = (withFileStatus "doesFileExist" name $ \st -> do b <- isDirectory st; return (not b)) - (\ _ -> return False) + `catch` ((\ _ -> return False) :: IOException -> IO Bool) {- |The 'getModificationTime' operation returns the clock time at which the file or directory was last modified. @@ -873,7 +879,9 @@ foreign import ccall unsafe "__hscore_X_OK" x_OK :: CInt foreign import ccall unsafe "__hscore_S_IRUSR" s_IRUSR :: CMode foreign import ccall unsafe "__hscore_S_IWUSR" s_IWUSR :: CMode foreign import ccall unsafe "__hscore_S_IXUSR" s_IXUSR :: CMode +#ifdef mingw32_HOST_OS foreign import ccall unsafe "__hscore_S_IFDIR" s_IFDIR :: CMode +#endif foreign import ccall unsafe "__hscore_long_path_size" long_path_size :: Int @@ -909,11 +917,11 @@ getHomeDirectory :: IO FilePath getHomeDirectory = #if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do - r <- c_SHGetFolderPath nullPtr csidl_PROFILE nullPtr 0 pPath - if (r < 0) + r0 <- c_SHGetFolderPath nullPtr csidl_PROFILE nullPtr 0 pPath + if (r0 < 0) then do - r <- c_SHGetFolderPath nullPtr csidl_WINDOWS nullPtr 0 pPath - when (r < 0) (raiseUnsupported "System.Directory.getHomeDirectory") + r1 <- c_SHGetFolderPath nullPtr csidl_WINDOWS nullPtr 0 pPath + when (r1 < 0) (raiseUnsupported "System.Directory.getHomeDirectory") else return () peekCString pPath #else @@ -1022,10 +1030,16 @@ getTemporaryDirectory :: IO FilePath getTemporaryDirectory = do #if defined(mingw32_HOST_OS) allocaBytes long_path_size $ \pPath -> do - r <- c_GetTempPath (fromIntegral long_path_size) pPath + _r <- c_GetTempPath (fromIntegral long_path_size) pPath peekCString pPath #else - catch (getEnv "TMPDIR") (\ex -> return "/tmp") + getEnv "TMPDIR" +#if !__NHC__ + `Prelude.catch` \e -> if isDoesNotExistError e then return "/tmp" + else throw e +#else + `catch` (\ex -> return "/tmp") +#endif #endif #if defined(mingw32_HOST_OS) @@ -1043,6 +1057,7 @@ foreign import ccall unsafe "__hscore_CSIDL_PERSONAL" csidl_PERSONAL :: CInt foreign import stdcall unsafe "GetTempPathA" c_GetTempPath :: CInt -> CString -> IO CInt +raiseUnsupported :: String -> IO () raiseUnsupported loc = ioException (IOError Nothing UnsupportedOperation loc "unsupported operation" Nothing)