0

Can I use readdir_r like this? I don't find anything about it in the spec, but maybe I'm just blind...

readdir_r(dir, entry, &entry);
thejh
  • 44,854
  • 16
  • 96
  • 107
  • `man readdir_r` in your system. – MYMNeo Jun 19 '12 at 16:26
  • 2
    `readdir_t()` sets its `result` argument to `NULL` when the end of the directory is reached. Keep this in mind if you allocate `entry` with `malloc()` (possible memory leak). Otherwise you can do what you do since both `entry` and `&entry` are passed by value to the function. – Hristo Iliev Jun 19 '12 at 16:28
  • @MYMNeo: There's no seperate manpage about it on my system, and there's nothing about my question in the `readdir` manpage. – thejh Jun 19 '12 at 16:34

1 Answers1

3

It's readdir_r, and the second argument is a pointer to a struct dirent, not a struct dirent itself, and the third argument is a pointer to pointer to a struct dirent, which receives the address of the struct dirent or NULL for end-of-directory. The usage is something like

struct dirent* pentry = malloc(offsetof(struct dirent, d_name) +
                             pathconf(dirpath, _PC_NAME_MAX) + 1);
if (!pentry)
    out_of_memory();

for (;;){
   struct dirent* result;
   readdir_r(dirp, pentry, &result); // you can check the return code, but it only fails if dirp is invalid
   if( !result )
       break;
   // process result
}
free(pentry);

As Hristo points out above, the arguments are passed by value so you could pass the address of the second arg (pentry) as the third arg (i.e., &pentry) -- it doesn't affect readir_r, which has no way to tell. But that will store NULL in pentry when you reach the end of the directory, but you need the value of pentry in order to free the malloced buffer it points to. So forget about whether using the address of the second argument is allowed ... doing so is pointless, misleading, and results in a memory leak.

For the spec of readdir_r, see http://www.kernel.org/doc/man-pages/online/pages/man3/readdir.3.html or http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir.html

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
  • so can I not use `readdir_r()` without using a `malloc()` for dirent? or can I just pass a pointer pointing my `dirent struct` on the stack? – ajax_velu Apr 28 '15 at 22:31
  • @Jawsmerc Yes, you can allocate a `struct dirent` on the stack. The d_name member will have enough room for a path of length NAME_MAX. – Jim Balter Apr 29 '15 at 00:20