diff options
author | William Wilgus <wilgus.william@gmail.com> | 2020-08-20 21:54:00 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2020-08-20 21:54:00 -0400 |
commit | f850bbbbc4b7345bebde241f651bad1c5c28df66 (patch) | |
tree | 1574bcca604f0617130aa9f1c426cfcdc097c901 /firmware/common/dir.c | |
parent | bd744059cf959c8b9086978b32660efef5925b7d (diff) | |
download | rockbox-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.c | 92 |
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 */ |
33 | static struct dirstr_desc | 33 | static 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 | ||
108 | static 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 | |||
136 | static 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; |
130 | file_error: | 184 | file_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 | ||
177 | file_error: | 236 | file_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 | ||
206 | file_error: | 269 | file_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 | } |