in reply to Re^3: using syscalls in perl through inline c
in thread using syscalls in perl through inline c

I added a second loop to list the files recursively, next in line is C multi threads and another sub hash to divide the record types easily.
#!/usr/bin/env perl use 5.012; use strict; use warnings; use Data::Dumper qw(Dumper); my $str = &listfiles('<directory>'); print Dumper \$str; use Inline C => <<'END_OF_C_CODE'; #include <dirent.h> /* Defines DT_* constants */ #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/syscall.h> #define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } whil +e (0) struct linux_dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[]; }; #define BUF_SIZE 1024*1024*5 SV* listfiles(const char * dir) { int fd, nread; struct linux_dirent *d; int bpos; char inode, d_type; char * buf = malloc(BUF_SIZE); static HV* hash; if (!(hash)) hash = newHV(); fd = open(dir, 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); d_type = *(buf + bpos + d->d_reclen - 1); bpos += d->d_reclen; if(d->d_ino && strcmp(d->d_name, ".") && strcmp(d->d_name, + "..") && strcmp(d->d_name, ".snapshot")) { size_t nbytes = snprintf(NULL, 0, "%d", d->d_ino) + 1; char *inode = malloc(nbytes); snprintf(inode, nbytes, "%d", d->d_ino); hv_store(hash, inode, strlen(inode), newSVpvf("%s/%s",( +char *) dir,d->d_name, 0), 0); if(d_type == DT_DIR) { int dir_len = strlen(dir); char * subdir = calloc(1, PATH_MAX + 1); strcat(subdir, dir); strcat(subdir + dir_len, "/"); strcat(subdir + dir_len + 1, d->d_name); listfiles(subdir); free(subdir); } } } } close(fd); free(buf); return newRV_noinc((SV*) hash); } END_OF_C_CODE