posix: fs: implement readdir_r

Add implementation for `readdir_r()`.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2024-06-14 16:18:20 +08:00 committed by Carles Cufí
commit b7ad4c53b0
5 changed files with 65 additions and 5 deletions

View file

@ -997,7 +997,7 @@ Enable this option with :kconfig:option:`CONFIG_POSIX_THREAD_SAFE_FUNCTIONS`.
putc_unlocked(),
putchar_unlocked(),
rand_r(), yes
readdir_r(),
readdir_r(), yes
strerror_r(), yes
strtok_r(), yes

View file

@ -27,6 +27,8 @@ struct dirent {
DIR *opendir(const char *dirname);
int closedir(DIR *dirp);
struct dirent *readdir(DIR *dirp);
int readdir_r(DIR *ZRESTRICT dirp, struct dirent *ZRESTRICT entry,
struct dirent **ZRESTRICT result);
#ifdef __cplusplus
}

View file

@ -314,6 +314,40 @@ struct dirent *readdir(DIR *dirp)
return &pdirent;
}
#ifdef CONFIG_POSIX_THREAD_SAFE_FUNCTIONS
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
{
struct dirent *dir;
errno = 0;
dir = readdir(dirp);
if (dir == NULL) {
int error = errno;
if (error != 0) {
if (result != NULL) {
*result = NULL;
}
return 0;
} else {
return error;
}
}
if (entry != NULL) {
memcpy(entry, dir, sizeof(struct dirent));
}
if (result != NULL) {
*result = entry;
}
return 0;
}
#endif /* CONFIG_POSIX_THREAD_SAFE_FUNCTIONS */
/**
* @brief Rename a file.
*

View file

@ -51,7 +51,21 @@ static int test_mkdir(void)
return res;
}
static int test_lsdir(const char *path)
static struct dirent *readdir_wrap(DIR *dirp, bool thread_safe)
{
if (thread_safe) {
struct dirent *entry = NULL;
struct dirent *result = NULL;
zassert_ok(readdir_r(dirp, entry, &result));
return result;
} else {
return readdir(dirp);
}
}
static int test_lsdir(const char *path, bool thread_safe)
{
DIR *dirp;
int res = 0;
@ -69,7 +83,7 @@ static int test_lsdir(const char *path)
TC_PRINT("\nListing dir %s:\n", path);
/* Verify fs_readdir() */
errno = 0;
while ((entry = readdir(dirp)) != NULL) {
while ((entry = readdir_wrap(dirp, thread_safe)) != NULL) {
if (entry->d_name[0] == 0) {
res = -EIO;
break;
@ -124,5 +138,15 @@ ZTEST(posix_fs_dir_test, test_fs_readdir)
{
/* FIXME: restructure tests as per #46897 */
zassert_true(test_mkdir() == TC_PASS);
zassert_true(test_lsdir(TEST_DIR) == TC_PASS);
zassert_true(test_lsdir(TEST_DIR, false) == TC_PASS);
}
/**
* Same test as `test_fs_readdir`, but use thread-safe `readdir_r()` function
*/
ZTEST(posix_fs_dir_test, test_fs_readdir_threadsafe)
{
/* FIXME: restructure tests as per #46897 */
zassert_true(test_mkdir() == TC_PASS);
zassert_true(test_lsdir(TEST_DIR, true) == TC_PASS);
}

View file

@ -31,7 +31,7 @@ ZTEST(posix_headers, test_dirent_h)
/* zassert_not_null(fdopendir); */ /* not implemented */
zassert_not_null(opendir);
zassert_not_null(readdir);
/* zassert_not_null(readdir_r); */ /* not implemented */
zassert_not_null(readdir_r);
/* zassert_not_null(rewinddir); */ /* not implemented */
/* zassert_not_null(scandir); */ /* not implemented */
/* zassert_not_null(seekdir); */ /* not implemented */