Remove Windows symlinks in perl script?

Suppose I created some Windows symbolic links, for example:

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 symlinks in the shell using

 rd /s /q withlink 

I have the same task to do in a perl script, where we are currently using cygwin 'rm -rf'. Unfortunately, we use cygwin 1.5, and rm and rm -rf do not work properly in this version on symbolic links that I would like to use ( they remove symbolic links instead of symbolic links ).

If I try:

 use File::Path qw( rmtree ) ; rmtree( ['withlink'] ) ; 

This works well if I don't have any symbolic directory links (such as REM'ed in the create-the-links sequence above), then perl rmtree behaves like cygwin, and I get the contents of the directory of my source directory deleted.

Does anyone have a suggestion of an alternative method to delete a recursive directory that I could use. I was only thinking of a shell callout:

 system("rd /s /q withlink") ; 

but this requires me to test the platform and have different perl code for Windows and Unix.

EDIT: Please note: unlike Unix, unlink () does not work to remove a symbolic link to a directory, at least with perl v5.6.0, which is used by our build system. However, rmdir () does work to remove the symbolic link of the Windows directory.

+7
source share
2 answers

You must use rmdir to remove symbolic links and junction points on Windows, and you should simply use unlink to remove symbolic links to files. The reason is that the symbolic link and the connection point of the directory is an empty directory with additional file system metadata (called reprocessing point data ). Similarly, symbolic file links are empty files with reprocessing point data . Such a directory or file is called a reprocessing point when reading Microsoft NTFS documentation. The type of reprocessing point is determined by the so-called TAG reprocessing point . There are two reprocessing point tags visible to users as β€œlinks”:

  • IO_REPARSE_TAG_SYMLINK - if it is installed in the directory - this is a symbolic link to the directory, if it is installed in the file - this is a symbolic link to the file
  • IO_REPARSE_TAG_MOUNT_POINT - can only be set in the directory - this is the so-called "connection point". It can be a β€œlink” to another directory, but it can be a β€œmount point” for the entire device (volume).

Summarizing:

  • You delete symbolic links to directories and junction points as if they were empty directories (in fact, if you check the attributes of such a thing, it has two: FILE_ATTRIBUTE_DIRECTORY and FILE_ATTRIBUTE_REPARSE_POINT).
  • You delete symbolic links to files as if they were files.
  • In both cases mentioned above, only the link / connection is deleted (not the target).
  • To find out if a file / folder is a link (all kinds): if you call GetFileAttributes or GetFileInformationByHandle or FindNextFile , then the attributes contain the FILE_ATTRIBUTE_REPARSE_POINT flag (e.g. WIN32_FIND_DATA::dwFileAttributes ). If this is a directory link, it also contains the FILE_ATTRIBUTE_DIRECTORY flag (see 1. ).

Hope this helps.

+3
source

You must use the unlink("FILE_FOO"); call unlink("FILE_FOO"); in perl script. It is tolerated.

0
source

All Articles