Håkon Hægland Håkon Hægland - 3 months ago 15
Perl Question

Is it safe to rename files while using readdir?

While scanning a directory with

, can you safely rename files without worrying about entering an infinite recursion? For example:

use v5.12; # make readdir set $_ in while loops
use strict;
use warnings;

use File::Spec;

my $dir = 'tdir';
opendir ( my $dh, $dir ) or die "Could not open dir '$dir': $!";
while (readdir $dh) {
next if /^\.\.?\z/;
my $filename = File::Spec->catfile( $dir, $_ );
if ( -f $filename) {
my $newname = File::Spec->catfile( $dir, "prefix_$_" );
rename ($filename, $newname) or warn $!;
}
}

closedir $dh;


So after renaming for example
file
to
prefix_file
,
readdir
will not find
prefix_file
in a later iteration of the
while
loop (and then rename it again to
prefix_prefix_file
and so on? Probably obvious that it will not do this, but since I could not find it mentioned in the documentation I'll ask the question anyway.

Answer

The underlying system call is POSIX's readdir(), and the specification says:

If a file is removed from or added to the directory after the most recent call to opendir() or rewinddir(), whether a subsequent call to readdir() returns an entry for that file is unspecified.

It simply means that you might or might not get to see the files. You might find that a particular platform does specify what happens, but it probably isn't portable to other systems.