summaryrefslogtreecommitdiff
path: root/firmware/common/dir.c
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-08-20 21:54:00 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-08-20 21:54:00 -0400
commitf850bbbbc4b7345bebde241f651bad1c5c28df66 (patch)
tree1574bcca604f0617130aa9f1c426cfcdc097c901 /firmware/common/dir.c
parentbd744059cf959c8b9086978b32660efef5925b7d (diff)
downloadrockbox-f850bbbbc4b7345bebde241f651bad1c5c28df66.tar.gz
rockbox-f850bbbbc4b7345bebde241f651bad1c5c28df66.zip
Revert root_redirect :(
This reverts commit 31fc46ded69be7438cca2ba2c2b93c1f200165a6. Change-Id: Ia78618c0e8b25ca65f7c8ae0db1cb9c9b321bad9
Diffstat (limited to 'firmware/common/dir.c')
-rw-r--r--firmware/common/dir.c92
1 files changed, 80 insertions, 12 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index 85e6ff316b..f89129ae34 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -27,14 +27,17 @@
27#include "dir.h" 27#include "dir.h"
28#include "pathfuncs.h" 28#include "pathfuncs.h"
29#include "fileobj_mgr.h" 29#include "fileobj_mgr.h"
30#include "rb_namespace.h" 30#include "dircache_redirect.h"
31 31
32/* structure used for open directory streams */ 32/* structure used for open directory streams */
33static struct dirstr_desc 33static struct dirstr_desc
34{ 34{
35 struct filestr_base stream; /* basic stream info (first!) */ 35 struct filestr_base stream; /* basic stream info (first!) */
36 struct ns_scan_info scan; /* directory scan cursor */ 36 struct dirscan_info scan; /* directory scan cursor */
37 struct dirent entry; /* current parsed entry information */ 37 struct dirent entry; /* current parsed entry information */
38#ifdef HAVE_MULTIVOLUME
39 int volumecounter; /* counter for root volume entries */
40#endif
38} open_streams[MAX_OPEN_DIRS]; 41} open_streams[MAX_OPEN_DIRS];
39 42
40/* check and return a struct dirstr_desc* from a DIR* */ 43/* check and return a struct dirstr_desc* from a DIR* */
@@ -44,7 +47,7 @@ static struct dirstr_desc * get_dirstr(DIR *dirp)
44 47
45 if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS)) 48 if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS))
46 dir = NULL; 49 dir = NULL;
47 else if (dir->stream.flags & (FDO_BUSY|FD_VALID)) 50 else if (dir->stream.flags & FDO_BUSY)
48 return dir; 51 return dir;
49 52
50 int errnum; 53 int errnum;
@@ -101,6 +104,49 @@ static struct dirstr_desc * alloc_dirstr(void)
101 return NULL; 104 return NULL;
102} 105}
103 106
107#ifdef HAVE_MULTIVOLUME
108static int readdir_volume_inner(struct dirstr_desc *dir, struct dirent *entry)
109{
110 /* Volumes (secondary file systems) get inserted into the system root
111 * directory. If the path specified volume 0, enumeration will not
112 * include other volumes, but just its own files and directories.
113 *
114 * Fake special directories, which don't really exist, that will get
115 * redirected upon opendir()
116 */
117 while (++dir->volumecounter < NUM_VOLUMES)
118 {
119 /* on the system root */
120 if (!fat_ismounted(dir->volumecounter))
121 continue;
122
123 get_volume_name(dir->volumecounter, entry->d_name);
124 dir->entry.info.attr = ATTR_MOUNT_POINT;
125 dir->entry.info.size = 0;
126 dir->entry.info.wrtdate = 0;
127 dir->entry.info.wrttime = 0;
128 return 1;
129 }
130
131 /* do normal directory entry fetching */
132 return 0;
133}
134#endif /* HAVE_MULTIVOLUME */
135
136static inline int readdir_volume(struct dirstr_desc *dir,
137 struct dirent *entry)
138{
139#ifdef HAVE_MULTIVOLUME
140 /* fetch virtual volume entries? */
141 if (dir->volumecounter < NUM_VOLUMES)
142 return readdir_volume_inner(dir, entry);
143#endif /* HAVE_MULTIVOLUME */
144
145 /* do normal directory entry fetching */
146 return 0;
147 (void)dir; (void)entry;
148}
149
104 150
105/** POSIX interface **/ 151/** POSIX interface **/
106 152
@@ -119,13 +165,21 @@ DIR * opendir(const char *dirname)
119 if (!dir) 165 if (!dir)
120 FILE_ERROR(EMFILE, RC); 166 FILE_ERROR(EMFILE, RC);
121 167
122 rc = ns_open_stream(dirname, FF_DIR, &dir->stream, &dir->scan); 168 rc = open_stream_internal(dirname, FF_DIR, &dir->stream, NULL);
123 if (rc < 0) 169 if (rc < 0)
124 { 170 {
125 DEBUGF("Open failed: %d\n", rc); 171 DEBUGF("Open failed: %d\n", rc);
126 FILE_ERROR(ERRNO, RC); 172 FILE_ERROR(ERRNO, RC);
127 } 173 }
128 174
175#ifdef HAVE_MULTIVOLUME
176 /* volume counter is relevant only to the system root */
177 dir->volumecounter = rc > 1 ? 0 : INT_MAX;
178#endif /* HAVE_MULTIVOLUME */
179
180 fat_rewind(&dir->stream.fatstr);
181 rewinddir_dirent(&dir->scan);
182
129 dirp = (DIR *)dir; 183 dirp = (DIR *)dir;
130file_error: 184file_error:
131 file_internal_unlock_WRITER(); 185 file_internal_unlock_WRITER();
@@ -150,7 +204,7 @@ int closedir(DIR *dirp)
150 FILE_ERROR(EBADF, -2); 204 FILE_ERROR(EBADF, -2);
151 } 205 }
152 206
153 rc = ns_close_stream(&dir->stream); 207 rc = close_stream_internal(&dir->stream);
154 if (rc < 0) 208 if (rc < 0)
155 FILE_ERROR(ERRNO, rc * 10 - 3); 209 FILE_ERROR(ERRNO, rc * 10 - 3);
156 210
@@ -168,11 +222,16 @@ struct dirent * readdir(DIR *dirp)
168 222
169 struct dirent *res = NULL; 223 struct dirent *res = NULL;
170 224
171 int rc = ns_readdir_dirent(&dir->stream, &dir->scan, &dir->entry); 225 int rc = readdir_volume(dir, &dir->entry);
226 if (rc == 0)
227 {
228 rc = readdir_dirent(&dir->stream, &dir->scan, &dir->entry);
229 if (rc < 0)
230 FILE_ERROR(EIO, RC);
231 }
232
172 if (rc > 0) 233 if (rc > 0)
173 res = &dir->entry; 234 res = &dir->entry;
174 else if (rc < 0)
175 FILE_ERROR(EIO, RC);
176 235
177file_error: 236file_error:
178 RELEASE_DIRSTR(READER, dir); 237 RELEASE_DIRSTR(READER, dir);
@@ -199,9 +258,13 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
199 if (!dir) 258 if (!dir)
200 FILE_ERROR_RETURN(ERRNO, -1); 259 FILE_ERROR_RETURN(ERRNO, -1);
201 260
202 int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry); 261 int rc = readdir_volume(dir, entry);
203 if (rc < 0) 262 if (rc == 0)
204 FILE_ERROR(EIO, rc * 10 - 4); 263 {
264 rc = readdir_dirent(&dir->stream, &dir->scan, entry);
265 if (rc < 0)
266 FILE_ERROR(EIO, rc * 10 - 4);
267 }
205 268
206file_error: 269file_error:
207 RELEASE_DIRSTR(READER, dir); 270 RELEASE_DIRSTR(READER, dir);
@@ -225,7 +288,12 @@ void rewinddir(DIR *dirp)
225 if (!dir) 288 if (!dir)
226 FILE_ERROR_RETURN(ERRNO); 289 FILE_ERROR_RETURN(ERRNO);
227 290
228 ns_dirscan_rewind(&dir->scan); 291 rewinddir_dirent(&dir->scan);
292
293#ifdef HAVE_MULTIVOLUME
294 if (dir->volumecounter != INT_MAX)
295 dir->volumecounter = 0;
296#endif /* HAVE_MULTIVOLUME */
229 297
230 RELEASE_DIRSTR(READER, dir); 298 RELEASE_DIRSTR(READER, dir);
231} 299}