X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=System%2FDirectory.hs;h=42ed6afe51c88e85171a9ef3763c419ee7815c6a;hb=e5bc07906c3690afa056029f94e6aae5ef4dbaa6;hp=fcdb937916240718d625f8f04562348e3736cfde;hpb=1b72414cedb0fc9f723f23ccced5526496bde138;p=haskell-directory.git diff --git a/System/Directory.hs b/System/Directory.hs index fcdb937..42ed6af 100644 --- a/System/Directory.hs +++ b/System/Directory.hs @@ -70,12 +70,14 @@ import Prelude hiding ( catch ) import System.Environment ( getEnv ) import System.FilePath +import System.IO import System.IO.Error hiding ( catch, try ) import Control.Monad ( when, unless ) import Control.Exception #ifdef __NHC__ import Directory +import System (system) #endif /* __NHC__ */ #ifdef __HUGS__ @@ -91,7 +93,6 @@ import Foreign.C import System.Posix.Types import System.Posix.Internals import System.Time ( ClockTime(..) ) -import System.IO import GHC.IOBase ( IOException(..), IOErrorType(..), ioException ) @@ -100,7 +101,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. @@ -154,6 +155,29 @@ The operation may fail with: getPermissions :: FilePath -> IO Permissions getPermissions name = do withCString name $ \s -> do +#ifdef mingw32_HOST_OS + -- stat() does a better job of guessing the permissions on Windows + -- than access() does. e.g. for execute permission, it looks at the + -- filename extension :-) + -- + -- I tried for a while to do this properly, using the Windows security API, + -- and eventually gave up. getPermissions is a flawed API anyway. -- SimonM + 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 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 + } + ) +#else read <- c_access s r_OK write <- c_access s w_OK exec <- c_access s x_OK @@ -167,6 +191,7 @@ getPermissions name = do searchable = is_dir && exec == 0 } ) +#endif {- |The 'setPermissions' operation sets the permissions for the file or directory. @@ -513,6 +538,12 @@ copied to /new/, if possible. -} copyFile :: FilePath -> FilePath -> IO () +#ifdef __NHC__ +copyFile fromFPath toFPath = + do readFile fromFPath >>= writeFile toFPath + try (copyPermissions fromFPath toFPath) + return () +#else copyFile fromFPath toFPath = copy `catch` (\e -> case e of IOException e -> @@ -522,7 +553,7 @@ copyFile fromFPath toFPath = bracketOnError openTmp cleanTmp $ \(tmpFPath, hTmp) -> do allocaBytes bufferSize $ copyContents hFrom hTmp hClose hTmp - try (copyPermissions fromFPath toFPath) + try (copyPermissions fromFPath tmpFPath) renameFile tmpFPath toFPath openTmp = openBinaryTempFile (takeDirectory toFPath) ".copyFile.tmp" cleanTmp (tmpFPath, hTmp) = do try $ hClose hTmp @@ -534,6 +565,7 @@ copyFile fromFPath toFPath = when (count > 0) $ do hPutBuf hTo buffer count copyContents hFrom hTo buffer +#endif -- | Given path referring to a file or directory, returns a -- canonicalized path, with the intent that two paths referring @@ -841,6 +873,7 @@ 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 +foreign import ccall unsafe "__hscore_S_IFDIR" s_IFDIR :: CMode foreign import ccall unsafe "__hscore_long_path_size" long_path_size :: Int