diff options
author | William Wilgus <me.theuser@yahoo.com> | 2017-02-03 17:13:58 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2020-08-20 23:08:57 +0000 |
commit | 5ef28cccf92f5eada6d502fa4b0e16a13e94be5b (patch) | |
tree | 05f9d2f8bdf3c0cc54c5893159a7dcf07c7e3e55 /firmware/common/dir.c | |
parent | 31fc46ded69be7438cca2ba2c2b93c1f200165a6 (diff) | |
download | rockbox-5ef28cccf92f5eada6d502fa4b0e16a13e94be5b.tar.gz rockbox-5ef28cccf92f5eada6d502fa4b0e16a13e94be5b.zip |
Allow mounting of any directory as the root directory.
Provide definitions for the macros:
* RB_ROOT_VOL_HIDDEN(v) to exclude certain items from the root.
* RB_ROOT_CONTENTS to return a string with the name of the
directory to mount in the root.
Defaults are in export/rbpaths.h
It's a bit much for those that don't need the full functionality.
Some conditional define can cut it back a lot to cut out things only
needed if alternate root mounts are required. I'm just not bothering
yet. The basic concept would be applied to all targets to keep file
code from forking too much.
Change-Id: I90b5c0a1c949283d3102c16734b0b6ac73901a30
Diffstat (limited to 'firmware/common/dir.c')
-rw-r--r-- | firmware/common/dir.c | 92 |
1 files changed, 12 insertions, 80 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c index f89129ae34..85e6ff316b 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c | |||
@@ -27,17 +27,14 @@ | |||
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 "dircache_redirect.h" | 30 | #include "rb_namespace.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 dirscan_info scan; /* directory scan cursor */ | 36 | struct ns_scan_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 | ||
41 | } open_streams[MAX_OPEN_DIRS]; | 38 | } open_streams[MAX_OPEN_DIRS]; |
42 | 39 | ||
43 | /* check and return a struct dirstr_desc* from a DIR* */ | 40 | /* check and return a struct dirstr_desc* from a DIR* */ |
@@ -47,7 +44,7 @@ static struct dirstr_desc * get_dirstr(DIR *dirp) | |||
47 | 44 | ||
48 | if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS)) | 45 | if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS)) |
49 | dir = NULL; | 46 | dir = NULL; |
50 | else if (dir->stream.flags & FDO_BUSY) | 47 | else if (dir->stream.flags & (FDO_BUSY|FD_VALID)) |
51 | return dir; | 48 | return dir; |
52 | 49 | ||
53 | int errnum; | 50 | int errnum; |
@@ -104,49 +101,6 @@ static struct dirstr_desc * alloc_dirstr(void) | |||
104 | return NULL; | 101 | return NULL; |
105 | } | 102 | } |
106 | 103 | ||
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 | |||
150 | 104 | ||
151 | /** POSIX interface **/ | 105 | /** POSIX interface **/ |
152 | 106 | ||
@@ -165,21 +119,13 @@ DIR * opendir(const char *dirname) | |||
165 | if (!dir) | 119 | if (!dir) |
166 | FILE_ERROR(EMFILE, RC); | 120 | FILE_ERROR(EMFILE, RC); |
167 | 121 | ||
168 | rc = open_stream_internal(dirname, FF_DIR, &dir->stream, NULL); | 122 | rc = ns_open_stream(dirname, FF_DIR, &dir->stream, &dir->scan); |
169 | if (rc < 0) | 123 | if (rc < 0) |
170 | { | 124 | { |
171 | DEBUGF("Open failed: %d\n", rc); | 125 | DEBUGF("Open failed: %d\n", rc); |
172 | FILE_ERROR(ERRNO, RC); | 126 | FILE_ERROR(ERRNO, RC); |
173 | } | 127 | } |
174 | 128 | ||
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 | |||
183 | dirp = (DIR *)dir; | 129 | dirp = (DIR *)dir; |
184 | file_error: | 130 | file_error: |
185 | file_internal_unlock_WRITER(); | 131 | file_internal_unlock_WRITER(); |
@@ -204,7 +150,7 @@ int closedir(DIR *dirp) | |||
204 | FILE_ERROR(EBADF, -2); | 150 | FILE_ERROR(EBADF, -2); |
205 | } | 151 | } |
206 | 152 | ||
207 | rc = close_stream_internal(&dir->stream); | 153 | rc = ns_close_stream(&dir->stream); |
208 | if (rc < 0) | 154 | if (rc < 0) |
209 | FILE_ERROR(ERRNO, rc * 10 - 3); | 155 | FILE_ERROR(ERRNO, rc * 10 - 3); |
210 | 156 | ||
@@ -222,16 +168,11 @@ struct dirent * readdir(DIR *dirp) | |||
222 | 168 | ||
223 | struct dirent *res = NULL; | 169 | struct dirent *res = NULL; |
224 | 170 | ||
225 | int rc = readdir_volume(dir, &dir->entry); | 171 | int rc = ns_readdir_dirent(&dir->stream, &dir->scan, &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 | |||
233 | if (rc > 0) | 172 | if (rc > 0) |
234 | res = &dir->entry; | 173 | res = &dir->entry; |
174 | else if (rc < 0) | ||
175 | FILE_ERROR(EIO, RC); | ||
235 | 176 | ||
236 | file_error: | 177 | file_error: |
237 | RELEASE_DIRSTR(READER, dir); | 178 | RELEASE_DIRSTR(READER, dir); |
@@ -258,13 +199,9 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) | |||
258 | if (!dir) | 199 | if (!dir) |
259 | FILE_ERROR_RETURN(ERRNO, -1); | 200 | FILE_ERROR_RETURN(ERRNO, -1); |
260 | 201 | ||
261 | int rc = readdir_volume(dir, entry); | 202 | int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry); |
262 | if (rc == 0) | 203 | if (rc < 0) |
263 | { | 204 | FILE_ERROR(EIO, rc * 10 - 4); |
264 | rc = readdir_dirent(&dir->stream, &dir->scan, entry); | ||
265 | if (rc < 0) | ||
266 | FILE_ERROR(EIO, rc * 10 - 4); | ||
267 | } | ||
268 | 205 | ||
269 | file_error: | 206 | file_error: |
270 | RELEASE_DIRSTR(READER, dir); | 207 | RELEASE_DIRSTR(READER, dir); |
@@ -288,12 +225,7 @@ void rewinddir(DIR *dirp) | |||
288 | if (!dir) | 225 | if (!dir) |
289 | FILE_ERROR_RETURN(ERRNO); | 226 | FILE_ERROR_RETURN(ERRNO); |
290 | 227 | ||
291 | rewinddir_dirent(&dir->scan); | 228 | ns_dirscan_rewind(&dir->scan); |
292 | |||
293 | #ifdef HAVE_MULTIVOLUME | ||
294 | if (dir->volumecounter != INT_MAX) | ||
295 | dir->volumecounter = 0; | ||
296 | #endif /* HAVE_MULTIVOLUME */ | ||
297 | 229 | ||
298 | RELEASE_DIRSTR(READER, dir); | 230 | RELEASE_DIRSTR(READER, dir); |
299 | } | 231 | } |