You didn't really ask a question, so I assumed that you were wondering how to fix the C code to get it to do what you want. It looks like you copy/pasted code from different sources or examples online (by the looks of it). In your listfiles() function, you're using argc, argv which is wrong (those are command line arguments, which belong to a main() function in a program. They don't have any use inside of a non-entry-point library, which is essentially what you've got here). I changed the parameter list to a single const char * dir, then changed the argv[1] to dir. I've inserted comments in the C code of what was changed:
#!/usr/bin/env perl use 5.012; use strict; use warnings; my $str = listfiles('/home/steve/test'); print $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 /**** CHANGED LINE BELOW ***/ int listfiles(const char * dir) { int fd, nread; char buf[BUF_SIZE]; struct linux_dirent *d; int bpos; char d_type; /**** CHANGED LINE BELOW ****/ 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); if (d->d_ino != 0) printf("%s\n", (char *) d->d_name); bpos += d->d_reclen; } } exit(EXIT_SUCCESS); } END_OF_C_CODE
Output:
one.txt two.txt
Now, if you want to be able to send in a directory as an argument, do it in Perl:
if (! defined $ARGV[0]){ print "Usage: script.pl <directory>\n"; exit; } my $dir = $ARGV[0]; my $str = listfiles($dir); ...
You may want to do extra argument checking in Perl, or you can just let the back end report any issues with bad dir names.
In reply to Re: using syscalls in perl through inline c
by stevieb
in thread using syscalls in perl through inline c
by ofer
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |