#define _GNU_SOURCE #include /* Defines DT_* constants */ #include #include #include #include #include #include #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) struct linux_dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[]; }; #define BUF_SIZE 1024*1024*5 int main(int argc, char *argv[]) { int fd, nread; char buf[BUF_SIZE]; struct linux_dirent *d; int bpos; char d_type; fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY); if (fd == -1) handle_error("open"); for ( ; ; ) { nread = syscall(SYS_getdents, fd, buf, BUF_SIZE); if (nread == -1) handle_error("getdents"); if (nread == 0) break; for (bpos = 0; bpos < nread;) { d = (struct linux_dirent *) (buf + bpos); if (d->d_ino != 0) printf("%s\n", (char *) d->d_name); bpos += d->d_reclen; } } exit(EXIT_SUCCESS); } #### struct linux_dirent { unsigned long d_ino; /* Inode number 32*/ unsigned long d_off; /* Offset to next linux_dirent 32*/ unsigned short d_reclen; /* Length of this linux_dirent 16*/ char d_name[]; /* Filename (null-terminated) */ /* length is actually (d_reclen - 2 - offsetof(struct linux_dirent, d_name)) */ } #### #!/usr/bin/env perl use warnings; use strict; use Cwd; use File::Spec; use Data::Dumper; use Fcntl; use Convert::Binary::C; use constant BUF_SIZE => 4096; use lib '/home/myself/perl5/perls/perl-5.20.1/lib/site_perl/5.20.3/i686-linux/sys'; require 'syscall.ph'; my $dir = File::Spec->catdir( getcwd(), 'test' ); sysopen( my $fd, $dir, O_RDONLY | O_DIRECTORY ); my $buf = "\0" x 128; $! = 0; my $converter = Convert::Binary::C->new(); my $struct = <parse($struct); my $read = syscall( &SYS_getdents, fileno($fd), $buf, BUF_SIZE ); if ( ( $read == -1 ) and ( $! != 0 ) ) { die "failed to syscal getdents: $!"; } #print Dumper($read), "\n"; #print Dumper($buf), "\n"; close($fd); my $data = $converter->unpack( 'foo', $buf ); print Dumper($data); #### #!/usr/bin/env perl use warnings; use strict; use File::Spec; use Getopt::Std; use Fcntl; use constant BUF_SIZE => 4096; use lib '/home/myself/perl5/perls/perl-5.20.1/lib/site_perl/5.20.3/i686-linux/sys'; require 'syscall.ph'; my %opts; getopts( 'd:', \%opts ); die 'option -d is required' unless ( ( exists( $opts{d} ) ) and ( defined( $opts{d} ) ) ); sysopen( my $fd, $opts{d}, O_RDONLY | O_DIRECTORY ); while (1) { my $buf = "\0" x BUF_SIZE; my $read = syscall( &SYS_getdents, fileno($fd), $buf, BUF_SIZE ); if ( ( $read == -1 ) and ( $! != 0 ) ) { die "failed to syscal getdents: $!"; } last if ( $read == 0 ); while ( $read != 0 ) { my ( $ino, $off, $len, $name ) = unpack( "LLSZ*", $buf ); #print $name, "\n" if ( $ino != 0 ); unless ( ( $name eq '.' ) or ( $name eq '..' ) ) { my $path = File::Spec->catfile( $opts{d}, $name ); unlink $path or die "Cannot remove $path: $!"; } substr( $buf, 0, $len ) = ''; $read -= $len; } } close($fd);