hrev50292 adds 1 changeset to branch 'master'
old head: 60f1f7efe4cf56aa3c2ce4542dbdc07cebfa326f
new head: f022c304b0bb15a43ed08a34e0bf18a751db8341
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=f022c304b0bb+%5E60f1f7efe4cf
----------------------------------------------------------------------------
f022c304b0bb: 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().
[ Jérôme Duval <jerome.duval@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50292
Commit: f022c304b0bb15a43ed08a34e0bf18a751db8341
URL: http://cgit.haiku-os.org/haiku/commit/?id=f022c304b0bb
Author: Jérôme Duval <jerome.duval@xxxxxxxxx>
Date: Sat May 7 14:35:14 2016 UTC
Ticket: https://dev.haiku-os.org/ticket/12755
----------------------------------------------------------------------------
2 files changed, 72 insertions(+), 3 deletions(-)
src/system/libroot/posix/dirent.c | 28 ++++++++++++-
src/tests/system/libroot/posix/dirent_test.cpp | 47 +++++++++++++++++++++-
----------------------------------------------------------------------------
diff --git a/src/system/libroot/posix/dirent.c
b/src/system/libroot/posix/dirent.c
index 09f5f5f..198c23d 100644
--- a/src/system/libroot/posix/dirent.c
+++ b/src/system/libroot/posix/dirent.c
@@ -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;
}
diff --git a/src/tests/system/libroot/posix/dirent_test.cpp
b/src/tests/system/libroot/posix/dirent_test.cpp
index 833417e..da5a470 100644
--- a/src/tests/system/libroot/posix/dirent_test.cpp
+++ b/src/tests/system/libroot/posix/dirent_test.cpp
@@ -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;
}