tags:

views:

929

answers:

4

On researching another question I noted that the stat function in Perl can take a dirhandle as its argument (instead of a filehandle or filename).

However I can't find any examples of correct use of this - there are none in the Perl manual.

Can anyone show an example of how to use it?

+2  A: 

You use it just like you would stat on a filehandle:

<~> $ mkdir -v foo ; perl -e 'opendir($dh , "./foo"); @s = stat $dh; print "@s"'
mkdir: created directory `foo'
2049 11681802 16877 2 1001 1001 0 4096 1228059876 1228059876 1228059876 4096 8

(Personally, I like using File::stat to get nice named accessors, so that I don't have to remember (or lookup) that the fifth element is the UID...)

genehack
+7  A: 

You use it in the same way you do for a file or filehandle:

#!/usr/bin/perl
use strict;

my $dir = shift;
opendir(DIR, $dir) or die "Failed to open $dir: $!\n";
my @stats = stat DIR;
closedir(DIR);
my $atime = scalar localtime $stats[8];

print "Last access time on $dir: $atime\n";

The ability to use stat on directory handles was just added around Perl 5.10 so it should be avoided if you care about portability.

Robert Gamble
so it just stats() the directory itself, and isn't anything to do with readdir() ?
Alnitak
@Alnitak: that is correct, it is the same as "stat $dir" just as "stat FILEHANDLE" is the same as "stat $file".
Robert Gamble
+1  A: 

Just be aware that a if a handle was ever used as a filehandle, as well as a dirhandle, the stat will apply to the file, not the directory:

$ perl -wl
opendir $h, "." or die;
open $h, "/etc/services" or die;
print "dir:".readdir($h);
print "file:".readline($h);
print stat("/etc/services");
print stat(".");
print stat($h);
close($h);
print stat($h);
__END__
dir:.
file:# Network services, Internet style

205527886633188100018274122800783211967194861209994037409640
20551515522168777410001000020480122803711512280371021228037102409640
205527886633188100018274122800783211967194861209994037409640
stat() on closed filehandle $h at - line 1.
    (Are you trying to call stat() on dirhandle $h?)
ysth
A: 

I use Perl 5.10.1 on windows (ActivePerl) and doing stat on a dirhandle doesn't work. But doing a stat on the path string of the directory works.

works

  my $mtime = (stat( $directory ))[ 9 ];
  print "D $directory $mtime\n";

this doesn't ("The dirfd function is unimplemented...")

  my $dh;
  if( opendir( $dh, $directory ) == 0 ) {
    print "ERROR: can't open directory '$directory': $!\n";
    return;
  }
  $mtime = (stat( $dh ))[ 9 ];
  print "D $directory $mtime\n";
David Anderson