
http://hackage.haskell.org/packages/archive/directory/1.1.0.1/doc/html/Syste... The documentation says that removeDirectoryRecursive follows symlinks. However, the implementation doesn't (in most cases, see below). ------------------------------------------------------------------------------------------------------------ $ mkdir test-removeDirectoryRecursive $ cd test-removeDirectoryRecursive $ mkdir a b $ touch a/a.txt b/b.txt $ ln -s $PWD/b a/ $ ln -s $PWD/b/b.txt a/ $ ls -l a total 8.2k -rw-rw-r-- 1 john john 0 2012-01-27 23:33 a.txt lrwxrwxrwx 1 john john 65 2012-01-27 23:33 b -> /home/john/test-removeDirectoryRecursive/b lrwxrwxrwx 1 john john 71 2012-01-27 23:34 b.txt -> /home/john/test-removeDirectoryRecursive/b/b.txt # OK, a/ has a normal file and two symlinks in it. Let's recursively remove a/ and see what happens. $ ghci Prelude> import System.Directory Prelude System.Directory> removeDirectoryRecursive "a" Prelude System.Directory> Leaving GHCi. $ ls -l a b ls: cannot access a: No such file or directory b: total 0 -rw-rw-r-- 1 john john 0 2012-01-27 23:33 b.txt # a/ was removed -- good! # # b/ and its contents are untouched, good, but goes against the docs ------------------------------------------------------------------------------------------------------------ Now, there is one case where this function *will* follow symlinks. However, I believe it is a bug because it produces odd behavior: ------------------------------------------------------------------------------------------------------------ $ sudo mkdir a [sudo] password for john: $ sudo ln -s $PWD/b a/ $ ls -l a b a: total 4.1k lrwxrwxrwx 1 root root 65 2012-01-27 23:38 b -> /home/john/test-removeDirectoryRecursive/b b: total 0 -rw-rw-r-- 1 john john 0 2012-01-27 23:33 b.txt # Now a/ has a symlink, which cannot be deleted, because its containing directory is read-only to the current user. $ rm a/b rm: remove symbolic link `a/b'? y rm: cannot remove `a/b': Permission denied # What happens if removeDirectoryRecursive is called now? $ ghci Prelude> import System.Directory Prelude System.Directory> removeDirectoryRecursive "a" *** Exception: a/b: removeDirectory: permission denied (Permission denied) Prelude System.Directory> Leaving GHCi. $ ls -l a b a: total 4.1k lrwxrwxrwx 1 root root 65 2012-01-27 23:38 b -> /home/john/test-removeDirectoryRecursive/b b: total 0 # a/ is untouched, but b/ has been emptied! ------------------------------------------------------------------------------------------------------------ So what is the expected behavior of this function? What should it do in the presence of symlinks? IMO, the function should be documented as *not* following symlinks, and the directory check should be changed so that it returns False for symlink-to-directory.