diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/dir.c | 40 | ||||
-rw-r--r-- | firmware/target/hosted/filesystem-app.c | 50 | ||||
-rw-r--r-- | firmware/target/hosted/filesystem-app.h | 1 |
3 files changed, 80 insertions, 11 deletions
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: | |||
159 | return rc; | 159 | return rc; |
160 | } | 160 | } |
161 | 161 | ||
162 | #if 0 | ||
162 | /* read a directory */ | 163 | /* read a directory */ |
163 | struct dirent * readdir(DIR *dirp) | 164 | struct dirent * readdir(DIR *dirp) |
164 | { | 165 | { |
@@ -182,23 +183,19 @@ file_error: | |||
182 | 183 | ||
183 | return res; | 184 | return res; |
184 | } | 185 | } |
186 | #endif | ||
185 | 187 | ||
186 | #if 0 /* not included now but probably should be */ | 188 | /* readdir, readdir_r common fn */ |
187 | /* read a directory (reentrant) */ | 189 | static int readdir_common(DIR *dirp, struct dirent *entry, struct dirent **result) |
188 | int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) | ||
189 | { | 190 | { |
190 | if (!result) | 191 | *result = NULL; /* we checked for validity before calling, yes? */ |
191 | FILE_ERROR_RETURN(EFAULT, -2); | ||
192 | |||
193 | *result = NULL; | ||
194 | |||
195 | if (!entry) | ||
196 | FILE_ERROR_RETURN(EFAULT, -3); | ||
197 | |||
198 | struct dirstr_desc * const dir = GET_DIRSTR(READER, dirp); | 192 | struct dirstr_desc * const dir = GET_DIRSTR(READER, dirp); |
199 | if (!dir) | 193 | if (!dir) |
200 | FILE_ERROR_RETURN(ERRNO, -1); | 194 | FILE_ERROR_RETURN(ERRNO, -1); |
201 | 195 | ||
196 | if (!entry) | ||
197 | entry = &dir->entry; | ||
198 | |||
202 | int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry); | 199 | int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry); |
203 | if (rc < 0) | 200 | if (rc < 0) |
204 | FILE_ERROR(EIO, rc * 10 - 4); | 201 | FILE_ERROR(EIO, rc * 10 - 4); |
@@ -218,6 +215,27 @@ file_error: | |||
218 | return rc; | 215 | return rc; |
219 | } | 216 | } |
220 | 217 | ||
218 | /* read a directory */ | ||
219 | struct dirent * readdir(DIR *dirp) | ||
220 | { | ||
221 | struct dirent *entry; | ||
222 | readdir_common(dirp, NULL, &entry); | ||
223 | return entry; | ||
224 | } | ||
225 | |||
226 | /* read a directory (reentrant) */ | ||
227 | int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) | ||
228 | { | ||
229 | if (!result) | ||
230 | FILE_ERROR_RETURN(EFAULT, -2); | ||
231 | *result = NULL; | ||
232 | if (!entry) | ||
233 | FILE_ERROR_RETURN(EFAULT, -3); | ||
234 | return readdir_common(dirp, entry, result); | ||
235 | } | ||
236 | |||
237 | |||
238 | #if 0 /* not included now but probably should be */ | ||
221 | /* reset the position of a directory stream to the beginning of a directory */ | 239 | /* reset the position of a directory stream to the beginning of a directory */ |
222 | void rewinddir(DIR *dirp) | 240 | void rewinddir(DIR *dirp) |
223 | { | 241 | { |
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) | |||
453 | return (struct dirent *)osdirent; | 453 | return (struct dirent *)osdirent; |
454 | } | 454 | } |
455 | 455 | ||
456 | /* read a directory (reentrant) */ | ||
457 | int app_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) | ||
458 | { | ||
459 | struct __dir *this = (struct __dir *)dirp; | ||
460 | if (!this) | ||
461 | FILE_ERROR_RETURN(EBADF, -6); | ||
462 | |||
463 | if (!result) | ||
464 | FILE_ERROR_RETURN(EFAULT, -2); | ||
465 | |||
466 | *result = NULL; | ||
467 | |||
468 | if (!entry) | ||
469 | FILE_ERROR_RETURN(EFAULT, -3); | ||
470 | |||
471 | #ifdef HAVE_MULTIDRIVE | ||
472 | if (this->volumes_returned < NUM_VOLUMES) | ||
473 | { | ||
474 | while (++this->volumes_returned < NUM_VOLUMES) | ||
475 | { | ||
476 | if (!volume_present(this->volumes_returned)) | ||
477 | continue; | ||
478 | |||
479 | get_volume_name(this->volumes_returned, entry->d_name); | ||
480 | *result = entry; | ||
481 | return 0; | ||
482 | } | ||
483 | } | ||
484 | /* do normal directory reads */ | ||
485 | #endif /* HAVE_MULTIDRIVE */ | ||
486 | |||
487 | OS_DIRENT_T *osdirent = os_readdir(this->osdirp); | ||
488 | if (!osdirent) | ||
489 | FILE_ERROR_RETURN(ERRNO, -4); | ||
490 | #ifdef OS_DIRENT_CONVERT | ||
491 | size_t name_size = sizeof (entry->d_name); | ||
492 | if (strlcpy_from_os(entry->d_name, osdirent->d_name, | ||
493 | name_size) >= name_size) | ||
494 | { | ||
495 | entry->d_name[0] = '\0'; | ||
496 | errno = EOVERFLOW; | ||
497 | FILE_ERROR_RETURN(ENAMETOOLONG, -5); | ||
498 | } | ||
499 | |||
500 | *result = entry; | ||
501 | #endif /* OS_DIRENT_CONVERT */ | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
456 | int app_mkdir(const char *path) | 506 | int app_mkdir(const char *path) |
457 | { | 507 | { |
458 | char realpath[MAX_PATH]; | 508 | 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); | |||
107 | #ifndef DIRFUNCTIONS_DECLARED | 107 | #ifndef DIRFUNCTIONS_DECLARED |
108 | DIR * app_opendir(const char *dirname); | 108 | DIR * app_opendir(const char *dirname); |
109 | struct dirent * app_readdir(DIR *dirp); | 109 | struct dirent * app_readdir(DIR *dirp); |
110 | int app_readdir_r(DIR *dirp, struct dirent* entry, struct dirent **result); | ||
110 | int app_closedir(DIR *dirp); | 111 | int app_closedir(DIR *dirp); |
111 | int app_mkdir(const char *path); | 112 | int app_mkdir(const char *path); |
112 | int app_rmdir(const char *path); | 113 | int app_rmdir(const char *path); |