summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-05-01 10:01:56 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2024-05-02 09:33:29 -0400
commit0c737d3b2e4728347cf4d52025f9fc2ebbee6e90 (patch)
tree52d09ce760fb38e4f8f4752556a94a5f478cbc2f
parentf2f5543856b91b664bb124b3e9fcfb519f53cb33 (diff)
downloadrockbox-0c737d3b2e.tar.gz
rockbox-0c737d3b2e.zip
readdir_r use in tagcache.check_dir, ft_load
Change-Id: Ibcde39ed247e100dd47ae877fb2a3625bbb38d8b
-rw-r--r--apps/filetree.c20
-rw-r--r--apps/tagcache.c6
-rw-r--r--firmware/common/dir.c40
-rw-r--r--firmware/target/hosted/filesystem-app.c50
-rw-r--r--firmware/target/hosted/filesystem-app.h1
-rw-r--r--uisimulator/common/filesystem-sim.c35
-rw-r--r--uisimulator/common/filesystem-sim.h1
7 files changed, 129 insertions, 24 deletions
diff --git a/apps/filetree.c b/apps/filetree.c
index b5f5dece5a..99bb1340d7 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -292,6 +292,7 @@ int ft_load(struct tree_context* c, const char* tempdir)
int files_in_dir = 0;
int name_buffer_used = 0;
+ struct dirent direntry;
struct dirent *entry;
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
DIR *dir;
@@ -313,7 +314,7 @@ int ft_load(struct tree_context* c, const char* tempdir)
c->dirfull = false;
tree_lock_cache(c);
- while ((entry = readdir(dir))) {
+ while (readdir_r(dir, &direntry, &entry) == 0 && entry) {
int len;
struct dirinfo info;
struct entry* dptr = tree_get_entry_at(c, files_in_dir);
@@ -326,18 +327,18 @@ int ft_load(struct tree_context* c, const char* tempdir)
info = dir_get_info(dir, entry);
len = strlen((char *)entry->d_name);
- /* skip directories . and .. */
- if ((info.attribute & ATTR_DIRECTORY) &&
- (((len == 1) && (!strncmp((char *)entry->d_name, ".", 1))) ||
- ((len == 2) && (!strncmp((char *)entry->d_name, "..", 2))))) {
- continue;
- }
-
/* Skip FAT volume ID */
if (info.attribute & ATTR_VOLUME_ID) {
continue;
}
+ dptr->attr = info.attribute;
+ int dir_attr = (dptr->attr & ATTR_DIRECTORY);
+
+ /* skip directories . and .. */
+ if (dir_attr && is_dotdir_name(entry->d_name))
+ continue;
+
/* filter out dotfiles and hidden files */
if (*c->dirfilter != SHOW_ALL &&
((entry->d_name[0]=='.') ||
@@ -345,9 +346,6 @@ int ft_load(struct tree_context* c, const char* tempdir)
continue;
}
- dptr->attr = info.attribute;
- int dir_attr = (dptr->attr & ATTR_DIRECTORY);
-
/* check for known file types */
if ( !(dir_attr) )
dptr->attr |= filetype_get_attr((char *)entry->d_name);
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 9463d7c865..302b6ad9de 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -4863,8 +4863,8 @@ static int free_search_roots(struct search_roots_ll * start)
static bool check_dir(const char *dirname, int add_files)
{
+ static struct dirent direntry; /* function is recursive, static uses less stack */
int success = false;
-
DIR *dir = opendir(dirname);
if (!dir)
{
@@ -4883,7 +4883,9 @@ static bool check_dir(const char *dirname, int add_files)
/* Recursively scan the dir. */
while (!check_event_queue())
{
- struct dirent *entry = readdir(dir);
+ struct dirent *entry;
+ readdir_r(dir, &direntry, &entry);
+
if (entry == NULL)
{
success = true;
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index 9a78d910a7..27af5f7fca 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -159,6 +159,7 @@ file_error:
return rc;
}
+#if 0
/* read a directory */
struct dirent * readdir(DIR *dirp)
{
@@ -182,23 +183,19 @@ file_error:
return res;
}
+#endif
-#if 0 /* not included now but probably should be */
-/* read a directory (reentrant) */
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+/* readdir, readdir_r common fn */
+static int readdir_common(DIR *dirp, struct dirent *entry, struct dirent **result)
{
- if (!result)
- FILE_ERROR_RETURN(EFAULT, -2);
-
- *result = NULL;
-
- if (!entry)
- FILE_ERROR_RETURN(EFAULT, -3);
-
+ *result = NULL; /* we checked for validity before calling, yes? */
struct dirstr_desc * const dir = GET_DIRSTR(READER, dirp);
if (!dir)
FILE_ERROR_RETURN(ERRNO, -1);
+ if (!entry)
+ entry = &dir->entry;
+
int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry);
if (rc < 0)
FILE_ERROR(EIO, rc * 10 - 4);
@@ -218,6 +215,27 @@ file_error:
return rc;
}
+/* read a directory */
+struct dirent * readdir(DIR *dirp)
+{
+ struct dirent *entry;
+ readdir_common(dirp, NULL, &entry);
+ return entry;
+}
+
+/* read a directory (reentrant) */
+int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ if (!result)
+ FILE_ERROR_RETURN(EFAULT, -2);
+ *result = NULL;
+ if (!entry)
+ FILE_ERROR_RETURN(EFAULT, -3);
+ return readdir_common(dirp, entry, result);
+}
+
+
+#if 0 /* not included now but probably should be */
/* reset the position of a directory stream to the beginning of a directory */
void rewinddir(DIR *dirp)
{
diff --git a/firmware/target/hosted/filesystem-app.c b/firmware/target/hosted/filesystem-app.c
index 7d59a174dc..fc4fff0eb5 100644
--- a/firmware/target/hosted/filesystem-app.c
+++ b/firmware/target/hosted/filesystem-app.c
@@ -453,6 +453,56 @@ struct dirent * app_readdir(DIR *dirp)
return (struct dirent *)osdirent;
}
+/* read a directory (reentrant) */
+int app_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ struct __dir *this = (struct __dir *)dirp;
+ if (!this)
+ FILE_ERROR_RETURN(EBADF, -6);
+
+ if (!result)
+ FILE_ERROR_RETURN(EFAULT, -2);
+
+ *result = NULL;
+
+ if (!entry)
+ FILE_ERROR_RETURN(EFAULT, -3);
+
+#ifdef HAVE_MULTIDRIVE
+ if (this->volumes_returned < NUM_VOLUMES)
+ {
+ while (++this->volumes_returned < NUM_VOLUMES)
+ {
+ if (!volume_present(this->volumes_returned))
+ continue;
+
+ get_volume_name(this->volumes_returned, entry->d_name);
+ *result = entry;
+ return 0;
+ }
+ }
+ /* do normal directory reads */
+#endif /* HAVE_MULTIDRIVE */
+
+ OS_DIRENT_T *osdirent = os_readdir(this->osdirp);
+ if (!osdirent)
+ FILE_ERROR_RETURN(ERRNO, -4);
+#ifdef OS_DIRENT_CONVERT
+ size_t name_size = sizeof (entry->d_name);
+ if (strlcpy_from_os(entry->d_name, osdirent->d_name,
+ name_size) >= name_size)
+ {
+ entry->d_name[0] = '\0';
+ errno = EOVERFLOW;
+ FILE_ERROR_RETURN(ENAMETOOLONG, -5);
+ }
+
+ *result = entry;
+#endif /* OS_DIRENT_CONVERT */
+
+ return 0;
+}
+
int app_mkdir(const char *path)
{
char realpath[MAX_PATH];
diff --git a/firmware/target/hosted/filesystem-app.h b/firmware/target/hosted/filesystem-app.h
index b35b63e95f..2d7d6e817d 100644
--- a/firmware/target/hosted/filesystem-app.h
+++ b/firmware/target/hosted/filesystem-app.h
@@ -107,6 +107,7 @@ ssize_t app_readlink(const char *path, char *buf, size_t bufsize);
#ifndef DIRFUNCTIONS_DECLARED
DIR * app_opendir(const char *dirname);
struct dirent * app_readdir(DIR *dirp);
+int app_readdir_r(DIR *dirp, struct dirent* entry, struct dirent **result);
int app_closedir(DIR *dirp);
int app_mkdir(const char *path);
int app_rmdir(const char *path);
diff --git a/uisimulator/common/filesystem-sim.c b/uisimulator/common/filesystem-sim.c
index f4f6321b7d..54e703ff40 100644
--- a/uisimulator/common/filesystem-sim.c
+++ b/uisimulator/common/filesystem-sim.c
@@ -704,6 +704,41 @@ struct sim_dirent * sim_readdir(DIR *dirp)
return entry;
}
+/* read a directory (reentrant) */
+int sim_readdir_r(DIR *dirp, struct sim_dirent *entry, struct sim_dirent **result)
+{
+ if (!result)
+ FILE_ERROR_RETURN(EFAULT, -2);
+
+ *result = NULL;
+
+ if (!entry)
+ FILE_ERROR_RETURN(EFAULT, -3);
+
+ struct dirstr_desc *dirstr = get_dirstr(dirp);
+ if (!dirstr)
+ FILE_ERROR_RETURN(ERRNO, -1);
+
+ entry->info.osdirent = NULL;
+
+ if (readdir_volume(dirstr, entry))
+ {
+ *result = entry;
+ return 0;
+ }
+ OS_DIRENT_T *osdirent = os_readdir(dirstr->osdirp);
+ if (!osdirent)
+ FILE_ERROR_RETURN(ERRNO, -4);
+
+ size_t size = sizeof (entry->d_name);
+ if (strlcpy_from_os(entry->d_name, osdirent->d_name, size) >= size)
+ FILE_ERROR_RETURN(ENAMETOOLONG, -5);
+
+ entry->info.osdirent = osdirent;
+ *result = entry;
+ return 0;
+}
+
int sim_mkdir(const char *path)
{
char ospath[SIM_TMPBUF_MAX_PATH];
diff --git a/uisimulator/common/filesystem-sim.h b/uisimulator/common/filesystem-sim.h
index 346d6fa74e..1b6c6dfe69 100644
--- a/uisimulator/common/filesystem-sim.h
+++ b/uisimulator/common/filesystem-sim.h
@@ -98,6 +98,7 @@ struct dirinfo_native
#ifndef DIRFUNCTIONS_DECLARED
DIR * sim_opendir(const char *dirname);
struct sim_dirent * sim_readdir(DIR *dirp);
+int sim_readdir_r(DIR *dirp, struct sim_dirent* entry, struct sim_dirent **result);
int sim_closedir(DIR *dirp);
int sim_mkdir(const char *path);
int sim_rmdir(const char *path);