System.Directory.removeDirectoryRecursive and symlinks

Isaac Dupree ml at isaac.cedarswampstudios.org
Tue Jun 10 15:23:37 UTC 2014


The documentation also says "Be careful, if the directory contains 
symlinks, the function will follow them.", which is dangerous and 
inappropriate but thankfully not actually what removeDirectoryRecursive 
does (based on testing and also on reading the code).  That statement 
should be removed from the documentation.

I'm indifferent on whether the argument path itself should be able to be 
a symlink to a directory, and if so, whether the target directory and/or 
the symlink should be removed, and whether this should differ based on 
whether the path ends in a "/" or not.  (Many Unix operations on 
symlinks, like `ls`, do differ based on a trailing slash. `rm -rf 
symlink` removes just the symlink; `rm -rf symlink/` appears to remove 
the contents of the target directory but neither the symlink nor the 
target directory itself...)

-Isaac

On 06/10/2014 09:42 AM, Gracjan Polak wrote:
> Hi all,
>
> A crime scene:
>
> Prelude System.Directory> :!mkdir a-directory
> Prelude System.Directory> :!touch a-directory/a-file.txt
> Prelude System.Directory> :!ln -s "a-directory" "a-symlink-to-a-directory"
> Prelude System.Directory> :!ls a-directory
> a-file.txt
> Prelude System.Directory> :!ls a-symlink-to-a-directory
> a-file.txt
> Prelude System.Directory> removeDirectoryRecursive
>                               "a-symlink-to-a-directory"
> *** Exception: a-symlink-to-a-directory: removeDirectory:
>      inappropriate type (Not a directory)
> Prelude System.Directory> :!ls a-symlink-to-a-directory
> Prelude System.Directory> :!ls a-directory
> Prelude System.Directory> :!ls -a a-directory
> .	..
> Prelude System.Directory> :!ls -a a-symlink-to-a-directory
> .	..
> Prelude System.Directory>
>
> removeDirectoryRecursive is removing all contents *of the directory linked*
> but is unable to remove the symlink itself.
>
> This behavior is surprizing if not dangerous. I understand that this mimics
> behavior of unlink/rmdir and DeleteFile/RemoveDirectory. but let me quote
> relevant manuals:
>
> man rm:
> The rm utility removes symbolic links, not the files referenced by the links.
>
> DeleteFile docs:
> If the path points to a symbolic link, the symbolic link is deleted, not the
> target. To delete a target, you must call CreateFile and specify
> FILE_FLAG_DELETE_ON_CLOSE.
>
> RemoveDirectory removes a directory junction, even if the contents of the
> target are not empty; the function removes directory junctions regardless of
> the state of the target object.
>
> Note: doesDirectoryExist and doesFileExist follow symlinks so they add more
> surprize to the scenario.
>
> What can we do about this?
>



More information about the Libraries mailing list