Ticket #2709 (closed bug: fixed)

Opened 5 years ago

Last modified 4 years ago

System.Directory.doesDirectoryExist "\\" is False on Windows

Reported by: Deewiant Owned by: igloo
Priority: high Milestone: 6.10.2
Component: libraries/directory Version: 6.10.1
Keywords: Cc: ndmitchell@…
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

import System.Directory

main = do
   print =<< doesDirectoryExist "\\"
   print =<< doesDirectoryExist "\\."

The above prints False followed by True, and both should definitely be True. It seems like it might even be a bug in MinGW or the MSVCRT.

The following does work, giving both as True:

import Data.Bits
import System.Win32.Types
import System.Win32.File

doesDirectoryExist = flip withTString $ \s -> do
   a <- c_GetFileAttributes s
   return (a /= 0xffffffff && a.&.fILE_ATTRIBUTE_DIRECTORY /= 0)

main = do
   print =<< doesDirectoryExist "\\"
   print =<< doesDirectoryExist "\\."

Change History

Changed 5 years ago by igloo

  • priority changed from normal to high
  • difficulty set to Unknown
  • milestone set to 6.10.1

I think this is because of these FilePath? behaviour changes:

6.8.2:

Prelude System.FilePath.Windows> isDrive "\\"
True
Prelude System.FilePath.Windows> dropTrailingPathSeparator "\\"
"\\"

6.10:

Prelude System.FilePath.Windows> isDrive "\\"
False
Prelude System.FilePath.Windows> dropTrailingPathSeparator "\\"
""

Changed 5 years ago by igloo

  • milestone changed from 6.10.1 to 6.10.2

Changed 4 years ago by igloo

  • owner set to igloo

Changed 4 years ago by igloo

  • cc ndmitchell@… added

I think treating "\\" as not a drive is probably the right behaviour, so a patch along these lines should be applied to System/FilePath/Internal.hs; Neil, does that sound good to you?

 -- > dropTrailingPathSeparator "file/test/" == "file/test"
 -- > not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
 -- > Posix:    dropTrailingPathSeparator "/" == "/"
+-- > Windows:  dropTrailingPathSeparator "\\" == "\\"
 dropTrailingPathSeparator :: FilePath -> FilePath
 dropTrailingPathSeparator x =
     if hasTrailingPathSeparator x && not (isDrive x)
-    then reverse $ dropWhile isPathSeparator $ reverse x
+    then let x' = reverse $ dropWhile isPathSeparator $ reverse x
+         in if null x' then [pathSeparator] else x'
     else x

Changed 4 years ago by igloo

  • status changed from new to closed
  • resolution set to fixed

Fixed in HEAD and 6.10 branch:

Sun Feb  8 11:16:54 PST 2009  Ian Lynagh <igloo@earth.li>
  * Make dropTrailingPathSeparator not return empty string
  dropTrailingPathSeparator "\\" was evaluating to "". Now if it would
  return "" it returns a single path separator instead. Fixes trac #2709.
Note: See TracTickets for help on using tickets.