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:
@@ -243,7 +243,26 @@ readdir(DIR* dir)
|
|||||||
int
|
int
|
||||||
readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result)
|
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);
|
+ B_FILE_NAME_LENGTH, 1);
|
||||||
if (count < B_OK)
|
if (count < B_OK)
|
||||||
return count;
|
return count;
|
||||||
@@ -251,8 +270,13 @@ readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result)
|
|||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
// end of directory
|
// end of directory
|
||||||
*_result = NULL;
|
*_result = NULL;
|
||||||
} else
|
} else {
|
||||||
*_result = entry;
|
*_result = entry;
|
||||||
|
dir->entries_left = count - 1;
|
||||||
|
dir->next_entry = dir->first_entry.d_reclen;
|
||||||
|
dir->seek_position++;
|
||||||
|
dir->current_position++;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,18 @@
|
|||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
dirent *buf, *dirent;
|
||||||
DIR* dir = opendir(".");
|
DIR* dir = opendir(".");
|
||||||
|
|
||||||
|
printf("first pass:\n");
|
||||||
while (true) {
|
while (true) {
|
||||||
dirent* dirent = readdir(dir);
|
dirent = readdir(dir);
|
||||||
if (dirent == NULL)
|
if (dirent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -23,6 +26,48 @@ main(int argc, char** argv)
|
|||||||
//printf(" left: %u, next: %d\n", dir->entries_left, dir->next_entry);
|
//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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user