readdir_r(): uses the logic of readdir()...

to retrieve more than one entry.
* readdir_r() is now affected by rewinddir(), thus fixing #12755.
* extends dirent_test with readdir_r().
This commit is contained in:
Jérôme Duval
2016-05-07 16:40:53 +02:00
parent 60f1f7efe4
commit f022c304b0
2 changed files with 72 additions and 3 deletions
+26 -2
View File
@@ -243,7 +243,26 @@ readdir(DIR* dir)
int
readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result)
{
ssize_t count = _kern_read_dir(dir->fd, entry, sizeof(struct dirent)
ssize_t count;
if (dir->seek_position != dir->current_position) {
if (do_seek_dir(dir) != 0)
return -1;
}
if (dir->entries_left > 0) {
*_result
= (struct dirent *)((uint8 *)&dir->first_entry + dir->next_entry);
dir->entries_left--;
dir->next_entry += (*_result)->d_reclen;
dir->seek_position++;
dir->current_position++;
return 0;
}
count = _kern_read_dir(dir->fd, entry, sizeof(struct dirent)
+ B_FILE_NAME_LENGTH, 1);
if (count < B_OK)
return count;
@@ -251,8 +270,13 @@ readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result)
if (count == 0) {
// end of directory
*_result = NULL;
} else
} else {
*_result = entry;
dir->entries_left = count - 1;
dir->next_entry = dir->first_entry.d_reclen;
dir->seek_position++;
dir->current_position++;
}
return 0;
}
+46 -1
View File
@@ -6,15 +6,18 @@
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char** argv)
{
dirent *buf, *dirent;
DIR* dir = opendir(".");
printf("first pass:\n");
while (true) {
dirent* dirent = readdir(dir);
dirent = readdir(dir);
if (dirent == NULL)
break;
@@ -23,6 +26,48 @@ main(int argc, char** argv)
//printf(" left: %u, next: %d\n", dir->entries_left, dir->next_entry);
}
rewinddir(dir);
printf("second pass:\n");
while (true) {
dirent = readdir(dir);
if (dirent == NULL)
break;
printf("Entry: dev %ld, ino %Ld, name \"%s\"\n", dirent->d_dev,
dirent->d_ino, dirent->d_name);
//printf(" left: %u, next: %d\n", dir->entries_left, dir->next_entry);
}
closedir(dir);
dirent = NULL;
buf = (struct dirent*)malloc(sizeof(struct dirent) + NAME_MAX);
dir = opendir(".");
printf("first pass:\n");
while (true) {
if (readdir_r(dir, buf, &dirent) != 0 || dirent == NULL)
break;
printf("Entry: dev %ld, ino %Ld, name \"%s\"\n", dirent->d_dev,
dirent->d_ino, dirent->d_name);
//printf(" left: %u, next: %d\n", dir->entries_left, dir->next_entry);
}
rewinddir(dir);
printf("second pass:\n");
while (true) {
if (readdir_r(dir, buf, &dirent) != 0 || dirent == NULL)
break;
printf("Entry: dev %ld, ino %Ld, name \"%s\"\n", dirent->d_dev,
dirent->d_ino, dirent->d_name);
//printf(" left: %u, next: %d\n", dir->entries_left, dir->next_entry);
}
closedir(dir);
return 0;
}