Suppose I create some Windows symbolic links, as in:
rd /s /q source withlink linkdir
mkdir source
mkdir withlink
echo blah > source/myfile
cd withlink
touch blah
mklink mylink ..\source\myfile
@REM mklink /d linkdir ..\source
cd ..
I can delete the directory containing the symlinks in the shell with
rd /s /q withlink
I have the same task to do in a perl script where we currently use cygwin 'rm -rf'. Unfortunately we are using cygwin 1.5 and rm and rm -rf don't work properly in that version on the symbolic links I'd like to use (they delete symbolic link contents instead of the symlinks).
If I try:
use File::Path qw( rmtree ) ;
rmtree( ['withlink'] ) ;
This works nicely, provided I don't have any directory symbolic links (like the one REM'ed out in the create-the-links sequence above), then perl's rmtree ends up behaving like cygwin, and I end up with the directory contents of my original directory deleted.
Does anybody have a suggestion of an alternate perl recursive directory deletion method that I could use. I thought of just a shell callout:
system("rd /s /q withlink") ;
but this requires I test the platform and have different perl code for Windows and Unix.
EDIT: Note that, unlike Unix, unlink() does not work to remove a directory symlink, at least with perl v5.6.0, which is what our build system is currently using. However, rmdir() does work to remove a windows directory symlink.
You must use rmdir
to remove directory symlinks and junction points in Windows and you must use simply unlink
to remove symlinks to files. The reason is that a directory symlink and junction point is really an empty directory with additional file system metadata (called reparse point data). Similarily, symlinks to files are empty files with reparse point data. Such a directory or file is called reparse point when you read Microsoft NTFS documentation. Reparse point type is determined by so called reparse point TAG. There are two reparse points' tags visible to users as "links":
To summarise:
GetFileAttributes
or GetFileInformationByHandle
or FindNextFile
then attributtes contain FILE_ATTRIBUTE_REPARSE_POINT
flag (e.g.: WIN32_FIND_DATA::dwFileAttributes
). If it is a link to a directory it also contains flag FILE_ATTRIBUTE_DIRECTORY
(see 1.).Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With