[GHC] #7971: doesDirectoryExist description differs from its behavior

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- The documentation for doesDirectoryExist should read: The operation 'doesDirectoryExist' returns 'True' if the argument file exists and is either a directory '''or a symbolic link to a directory''', and 'False' otherwise. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by Fuuzetsu): Where are you getting these docs from? http://hackage.haskell.org/packages/archive/directory/latest/doc/html /System-Directory.html#v:doesDirectoryExist says nothing about symlinks (and even the docs for 7.4.2 said nothing). The source (HEAD) states: {{{ #ifdef __GLASGOW_HASKELL__ {- |The operation 'doesDirectoryExist' returns 'True' if the argument file exists and is a directory, and 'False' otherwise. -} doesDirectoryExist :: FilePath -> IO Bool doesDirectoryExist name = #ifdef mingw32_HOST_OS (withFileStatus "doesDirectoryExist" name $ \st -> isDirectory st) #else (do stat <- Posix.getFileStatus name return (Posix.isDirectory stat)) #endif `E.catch` ((\ _ -> return False) :: IOException -> IO Bool) }}} so I just can't see where you are getting this from. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by Fuuzetsu): Oops, just re-read your post. Creating a symlink to a directory with ‘ln -s’ and then using ‘doesDirectoryExist’ yields False. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by dsf): Are you sure? I'm seeing this: {{{ $ ls -l bin lrwxrwxrwx 1 dsf dsf 15 Jun 18 2012 bin -> darcs/home/bin/ $ ghci GHCi, version 7.6.2: http://www.haskell.org/ghc/ :? for help Prelude> :m +System.Directory Prelude System.Directory> doesDirectoryExist "bin" True Prelude System.Directory> }}} -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by dsf): The documentation of removeDirectoryRecursive ("Be careful...") also seems to imply that doesDirectoryExist returns True for links to directories. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by Fuuzetsu): Why have you filed a bug for 7.6.3 when you are using 7.6.2? I don't think that's an issue here but you should probably be more careful next time. Here's my output for 7.6.3 {{{ ✓ misaki shana % cd /tmp/7971 ✓ misaki shana % l total 0 -rw-r--r-- 1 shana games 0 Jun 8 16:39 file lrwxrwxrwx 1 shana games 7 Jun 8 16:39 testDirLink -> testDir ✓ misaki shana % ghci GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> import System.Directory Prelude System.Directory> doesDirectoryExist "testDirLink" Loading package filepath-1.3.0.1 ... linking ... done. Loading package array-0.4.0.1 ... linking ... done. Loading package deepseq-1.3.0.1 ... linking ... done. Loading package old-locale-1.0.0.5 ... linking ... done. Loading package time-1.4.0.1 ... linking ... done. Loading package bytestring-0.10.0.2 ... linking ... done. Loading package unix-2.6.0.1 ... linking ... done. Loading package directory-1.2.0.1 ... linking ... done. False Prelude System.Directory> }}} I had a look at what removeDirectoryRecursive is doing and nothing from the source seems to point that it will follow links. It will call ‘unlink’ on the symlink because doesDirectoryExist will return False and therefore will not follow the link. Testing with actual files confirms that calling removeDirectoryRecursive that has the link inside of it in fact does not do anything beyond removing the linked. Directory linked to is intact. Bah, it will never even check if something is the directory unless ‘unlink’ fails somehow at which point we get an exception in Either: ‘Left e’ and only then we check that something is directory. ‘unlink’ will work fine on the symlinks without following them. If anything, I think that the ‘Be careful’ message should be investigated. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by dsf): Sorry about the compiler version. In your test you created "file" instead of "testDir". -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by dsf): Replying to [comment:6 dsf]:
Sorry about the compiler version. In your test you created "file" instead of "testDir".
I mean, you didn't create the directory testDir. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by dsf): I have satisfied myself that removeDirectoryRecursive will not follow symlinks. Although doesDirectoryExist will return true for a symlink to an existing directory, before that can happen the call to removeFile would remove the symlink. That caution in the documentation can be removed. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by Fuuzetsu): I have created testDir: it was one level up. It seems that the formatting swallowed up ‘../’ as is also apparent in your own snippet (so my link was pointing to ‘../testDir’ which existed (I guess ‘/tmp/testDir’ should be used in the future to avoid swallowing up in the WikiFormatting blocks)). Having said that, I did some further investigation and here's what I uncovered: If the directory linked to exists in the same directory or in any subdirectories, doesDirectoryExists will return True. If the directory linked to exists higher up in the file hierarchy, it will return False. relative/absolute paths seem to not matter. So a link ‘/tmp/test/linkToSomething’ to ‘/tmp/something’ will return False even if ‘/tmp/something’ is present on the filesystem. A link in ‘/tmp/test/linkToOther’ to ‘/tmp/test/foo/bar/baz/someDir’ will return True given that the someDir exists. This also means that it might in fact be following symlinks: it just doesn't matter because the only links to return True for directories are in the same/subdirectory that is being removed so they would be gone anyway. I don't think this strange behaviour is by design and should be fixed, or carefully documented if it is by design. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7971: doesDirectoryExist description differs from its behavior ----------------------------------------+----------------------------------- Reporter: dsf | Owner: Type: bug | Status: new Priority: normal | Component: libraries/directory Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Incorrect result at runtime | Blockedby: Blocking: | Related: ----------------------------------------+----------------------------------- Comment(by Fuuzetsu): Apparently I can no longer reproduce this morning and I get True for symlinks. I have no idea how it happened but I must have messed up somewhere when testing. Feel free to ignore my previous posts: I stand corrected. The documentation should be changed to reflect that symbolic links will also return True. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7971#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC