posix: fs: implement readdir_r
Add implementation for `readdir_r()`. Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
parent
33d92b4acd
commit
b7ad4c53b0
5 changed files with 65 additions and 5 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue