Filesystem: Last minute changes due to feedback on directory iteration

- Changed to use dirent structure type
- Fixed memory leak in closedir
pull/3773/head
Christopher Haster 2017-02-22 20:14:50 -06:00
parent 7ca4eabf77
commit c4649afba5
7 changed files with 28 additions and 72 deletions

View File

@ -58,16 +58,11 @@ int Dir::close()
return err; return err;
} }
ssize_t Dir::read(char *path, size_t len) ssize_t Dir::read(struct dirent *ent)
{ {
MBED_ASSERT(_fs); MBED_ASSERT(_fs);
return _fs->dir_read(_dir, path, len); memset(ent, 0, sizeof(struct dirent));
} return _fs->dir_read(_dir, ent);
ssize_t Dir::read(char *path, size_t len, uint8_t *type)
{
MBED_ASSERT(_fs);
return _fs->dir_read(_dir, path, len, type);
} }
void Dir::seek(off_t offset) void Dir::seek(off_t offset)

View File

@ -64,20 +64,10 @@ public:
/** Read the next directory entry /** Read the next directory entry
* *
* @param path The buffer to read the null terminated path name in to * @param path The buffer to read the null terminated path name in to
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX * @param ent The directory entry to fill out
* @return 1 on reading a filename, 0 at end of directory, negative error on failure * @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/ */
virtual ssize_t read(char *path, size_t len); virtual ssize_t read(struct dirent *ent);
/** Read the next directory entry
*
* @param dir Dir handle
* @param path The buffer to read the null terminated path name in to
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX
* @param type The type of the file, one of DT_DIR, DT_REG, etc...
* @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/
virtual ssize_t read(char *path, size_t len, uint8_t *type);
/** Set the current position of the directory /** Set the current position of the directory
* *

View File

@ -68,17 +68,11 @@ int FileSystem::dir_close(fs_dir_t dir)
return -ENOSYS; return -ENOSYS;
} }
ssize_t FileSystem::dir_read(fs_dir_t dir, char *path, size_t len) ssize_t FileSystem::dir_read(fs_dir_t dir, struct dirent *ent)
{ {
return -ENOSYS; return -ENOSYS;
} }
ssize_t FileSystem::dir_read(fs_dir_t dir, char *path, size_t len, uint8_t *type)
{
*type = DT_UNKNOWN;
return dir_read(dir, path, len);
}
void FileSystem::dir_seek(fs_dir_t dir, off_t offset) void FileSystem::dir_seek(fs_dir_t dir, off_t offset)
{ {
} }
@ -98,10 +92,11 @@ size_t FileSystem::dir_size(fs_dir_t dir)
{ {
off_t off = dir_tell(dir); off_t off = dir_tell(dir);
size_t size = 0; size_t size = 0;
struct dirent *ent = new struct dirent;
dir_rewind(dir); dir_rewind(dir);
while (true) { while (true) {
int res = dir_read(dir, NULL, 0); int res = dir_read(dir, ent);
if (res <= 0) { if (res <= 0) {
break; break;
} }
@ -110,6 +105,7 @@ size_t FileSystem::dir_size(fs_dir_t dir)
} }
dir_seek(dir, off); dir_seek(dir, off);
delete ent;
return size; return size;
} }

View File

@ -195,21 +195,10 @@ protected:
/** Read the next directory entry /** Read the next directory entry
* *
* @param dir Dir handle * @param dir Dir handle
* @param path The buffer to read the null terminated path name in to * @param ent The directory entry to fill out
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX
* @return 1 on reading a filename, 0 at end of directory, negative error on failure * @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/ */
virtual ssize_t dir_read(fs_dir_t dir, char *path, size_t len); virtual ssize_t dir_read(fs_dir_t dir, struct dirent *ent);
/** Read the next directory entry
*
* @param dir Dir handle
* @param path The buffer to read the null terminated path name in to
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX
* @param type The type of the file, one of DT_DIR, DT_REG, etc...
* @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/
virtual ssize_t dir_read(fs_dir_t dir, char *path, size_t len, uint8_t *type);
/** Set the current position of the directory /** Set the current position of the directory
* *

View File

@ -545,17 +545,13 @@ int FATFileSystem::dir_close(fs_dir_t dir) {
return fat_error_remap(res); return fat_error_remap(res);
} }
ssize_t FATFileSystem::dir_read(fs_dir_t dir, char *path, size_t len) { ssize_t FATFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) {
return dir_read(dir, path, len, NULL);
}
ssize_t FATFileSystem::dir_read(fs_dir_t dir, char *path, size_t len, uint8_t *type) {
FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
FILINFO finfo; FILINFO finfo;
#if _USE_LFN #if _USE_LFN
finfo.lfname = path; finfo.lfname = ent->d_name;
finfo.lfsize = len; finfo.lfsize = NAME_MAX;
#endif // _USE_LFN #endif // _USE_LFN
lock(); lock();
@ -565,23 +561,21 @@ ssize_t FATFileSystem::dir_read(fs_dir_t dir, char *path, size_t len, uint8_t *t
if (res != FR_OK) { if (res != FR_OK) {
return fat_error_remap(res); return fat_error_remap(res);
} else if (finfo.fname[0] == 0) { } else if (finfo.fname[0] == 0) {
return -EINVAL; return 0;
} }
if (type) { ent->d_type = (finfo.fattrib & AM_DIR) ? DT_DIR : DT_REG;
*type = (finfo.fattrib & AM_DIR) ? DT_DIR : DT_REG;
}
#if _USE_LFN #if _USE_LFN
if (path[0] == 0) { if (ent->d_name[0] == 0) {
// No long filename so use short filename. // No long filename so use short filename.
strncpy(path, finfo.fname, len); strncpy(ent->d_name, finfo.fname, NAME_MAX);
} }
#else #else
strncpy(path, finfo.fname, len); strncpy(end->d_name, finfo.fname, len);
#endif #endif
return 0; return 1;
} }
void FATFileSystem::dir_seek(fs_dir_t dir, off_t offset) { void FATFileSystem::dir_seek(fs_dir_t dir, off_t offset) {

View File

@ -199,21 +199,10 @@ protected:
/** Read the next directory entry /** Read the next directory entry
* *
* @param dir Dir handle * @param dir Dir handle
* @param path The buffer to read the null terminated path name in to * @param ent The directory entry to fill out
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX
* @return 1 on reading a filename, 0 at end of directory, negative error on failure * @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/ */
virtual ssize_t dir_read(fs_dir_t dir, char *path, size_t len); virtual ssize_t dir_read(fs_dir_t dir, struct dirent *ent);
/** Read the next directory entry
*
* @param dir Dir handle
* @param path The buffer to read the null terminated path name in to
* @param size The maximum number of bytes in the buffer, this is at most FS_NAME_MAX
* @param type The type of the file, one of DT_DIR, DT_REG, etc...
* @return 1 on reading a filename, 0 at end of directory, negative error on failure
*/
virtual ssize_t dir_read(fs_dir_t dir, char *path, size_t len, uint8_t *type);
/** Set the current position of the directory /** Set the current position of the directory
* *

View File

@ -554,9 +554,11 @@ extern "C" DIR *opendir(const char *path) {
extern "C" struct dirent *readdir(DIR *dir) { extern "C" struct dirent *readdir(DIR *dir) {
#if MBED_CONF_FILESYSTEM_PRESENT #if MBED_CONF_FILESYSTEM_PRESENT
static struct dirent ent; static struct dirent ent;
int err = dir->read(ent.d_name, NAME_MAX, &ent.d_type); int err = dir->read(&ent);
if (err < 0) { if (err < 1) {
errno = -err; if (err < 0) {
errno = -err;
}
return NULL; return NULL;
} }
@ -570,6 +572,7 @@ extern "C" struct dirent *readdir(DIR *dir) {
extern "C" int closedir(DIR *dir) { extern "C" int closedir(DIR *dir) {
#if MBED_CONF_FILESYSTEM_PRESENT #if MBED_CONF_FILESYSTEM_PRESENT
int err = dir->close(); int err = dir->close();
delete dir;
if (err < 0) { if (err < 0) {
errno = -err; errno = -err;
return -1; return -1;