From eea5c9f08af7845de034556cb0a24bc93d5b07a2 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 13 Feb 2017 13:19:57 -0600 Subject: [PATCH] Filesystem: Integration with retarget code --- drivers/DirHandle.h | 28 ++--- drivers/FileBase.cpp | 6 + drivers/FileBase.h | 21 ---- drivers/FileHandle.h | 9 +- drivers/FileLike.cpp | 28 ----- drivers/FileLike.h | 127 ++++++++++++++++++++-- drivers/FilePath.cpp | 4 +- drivers/FilePath.h | 3 +- drivers/FileSystemLike.cpp | 2 +- drivers/FileSystemLike.h | 6 + drivers/Stream.cpp | 13 ++- drivers/Stream.h | 9 +- features/filesystem/File.cpp | 12 +- features/filesystem/File.h | 5 +- features/filesystem/FileSystem.cpp | 7 +- features/filesystem/FileSystem.h | 7 +- features/filesystem/fat/FATFileSystem.cpp | 18 ++- features/filesystem/fat/FATFileSystem.h | 9 +- platform/mbed_retarget.cpp | 86 +++++++++------ platform/platform.h | 2 + platform/retarget.h | 28 +++++ 21 files changed, 279 insertions(+), 151 deletions(-) delete mode 100644 drivers/FileLike.cpp diff --git a/drivers/DirHandle.h b/drivers/DirHandle.h index 479237df61..6be86f969a 100644 --- a/drivers/DirHandle.h +++ b/drivers/DirHandle.h @@ -17,7 +17,7 @@ #define MBED_DIRHANDLE_H #include -#include "retarget.h" +#include "platform/platform.h" #include "FileHandle.h" @@ -41,8 +41,12 @@ namespace mbed { * @Note Synchronization level: Set by subclass */ class DirHandle { - public: + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "The mbed 2 filesystem classes have been superseeded by the FileSystem api, " + "Replaced by File") + DirHandle() {} + /** Closes the directory. * * @returns @@ -94,22 +98,18 @@ protected: virtual void unlock() { // Stub } + +protected: + /** Internal-only constructor to work around deprecated notices when not used + *. due to nested deprecations and difficulty of compilers finding their way around + * the class hierarchy + */ + friend class FileSystemLike; + DirHandle(int) {} }; } // namespace mbed -typedef mbed::DirHandle DIR; - -extern "C" { - DIR *opendir(const char*); - struct dirent *readdir(DIR *); - int closedir(DIR*); - void rewinddir(DIR*); - long telldir(DIR*); - void seekdir(DIR*, long); - int mkdir(const char *name, mode_t n); -}; - #endif /* MBED_DIRHANDLE_H */ /** @}*/ diff --git a/drivers/FileBase.cpp b/drivers/FileBase.cpp index 3be746e885..862dc74b0d 100644 --- a/drivers/FileBase.cpp +++ b/drivers/FileBase.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ #include "drivers/FileBase.h" +#include "drivers/FileLike.h" namespace mbed { @@ -49,6 +50,11 @@ FileBase::~FileBase() { } } _mutex->unlock(); + + if (getPathType() == FilePathType) { + extern void remove_filehandle(FileLike *file); + remove_filehandle(static_cast(this)); + } } FileBase *FileBase::lookup(const char *name, unsigned int len) { diff --git a/drivers/FileBase.h b/drivers/FileBase.h index 2ad9703dab..2101084cb7 100644 --- a/drivers/FileBase.h +++ b/drivers/FileBase.h @@ -21,26 +21,6 @@ typedef int FILEHANDLE; #include #include -#if defined(__ARMCC_VERSION) || defined(__ICCARM__) -# define O_RDONLY 0 -# define O_WRONLY 1 -# define O_RDWR 2 -# define O_CREAT 0x0200 -# define O_TRUNC 0x0400 -# define O_APPEND 0x0008 - -# define NAME_MAX 255 - -typedef int mode_t; -typedef int ssize_t; -typedef long off_t; - -#else -# include -# include -# include -#endif - #include "platform/platform.h" #include "platform/SingletonPtr.h" #include "platform/PlatformMutex.h" @@ -57,7 +37,6 @@ typedef enum { class FileBase { public: FileBase(const char *name, PathType t); - virtual ~FileBase(); const char* getName(void); diff --git a/drivers/FileHandle.h b/drivers/FileHandle.h index 08f498569e..696c8365ed 100644 --- a/drivers/FileHandle.h +++ b/drivers/FileHandle.h @@ -19,7 +19,7 @@ typedef int FILEHANDLE; #include -#include "retarget.h" +#include "platform/platform.h" namespace mbed { /** \addtogroup drivers */ @@ -39,6 +39,11 @@ namespace mbed { class FileHandle { public: + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "The mbed 2 filesystem classes have been superseeded by the FileSystem api, " + "Replaced by File") + FileHandle() {} + /** Write the contents of a buffer to the file * * @param buffer the buffer to write from @@ -113,7 +118,7 @@ public: return res; } - virtual ~FileHandle(); + virtual ~FileHandle() {}; protected: diff --git a/drivers/FileLike.cpp b/drivers/FileLike.cpp deleted file mode 100644 index da9984050c..0000000000 --- a/drivers/FileLike.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "drivers/FileLike.h" - -namespace mbed { - -FileLike::FileLike(const char *name) : FileHandle(), FileBase(name, FilePathType) { - -} - -FileLike::~FileLike() { - -} - -} // namespace mbed diff --git a/drivers/FileLike.h b/drivers/FileLike.h index 906114455a..e4f323918e 100644 --- a/drivers/FileLike.h +++ b/drivers/FileLike.h @@ -16,36 +16,139 @@ #ifndef MBED_FILELIKE_H #define MBED_FILELIKE_H +#include "platform/toolchain.h" #include "drivers/FileBase.h" -#include "drivers/FileHandle.h" namespace mbed { /** \addtogroup drivers */ /** @{*/ + /* Class FileLike * A file-like object is one that can be opened with fopen by - * fopen("/name", mode). It is intersection of the classes Base and - * FileHandle. + * fopen("/name", mode). * * @Note Synchronization level: Set by subclass */ -class FileLike : public FileHandle, public FileBase { - +class FileLike : public FileBase { public: - /* Constructor FileLike + /** Constructor FileLike * - * Variables - * name - The name to use to open the file. + * @param name The name to use to open the file. */ - FileLike(const char *name); + FileLike(const char *name = NULL) : FileBase(name, FilePathType) {} + virtual ~FileLike() {} - virtual ~FileLike(); + /** Read the contents of a file into a buffer + * + * @param buffer The buffer to read in to + * @param size The number of bytes to read + * @return The number of bytes read, 0 at end of file, negative error on failure + */ + virtual ssize_t read(void *buffer, size_t len) = 0; + /** Write the contents of a buffer to a file + * + * @param buffer The buffer to write from + * @param size The number of bytes to write + * @return The number of bytes written, negative error on failure + */ + virtual ssize_t write(const void *buffer, size_t len) = 0; + + /** Close a file + * + * @return 0 on success, negative error code on failure + */ + virtual int close() = 0; + + /** Flush any buffers associated with the file + * + * @return 0 on success, negative error code on failure + */ + virtual int sync() = 0; + + /** Check if the file in an interactive terminal device + * + * @return True if the file is a terminal + */ + virtual int isatty() = 0; + + /** Move the file position to a given offset from from a given location + * + * @param offset The offset from whence to move to + * @param whence The start of where to seek + * SEEK_SET to start from beginning of file, + * SEEK_CUR to start from current position in file, + * SEEK_END to start from end of file + * @return The new offset of the file + */ + virtual off_t seek(off_t offset, int whence = SEEK_SET) = 0; + + /** Get the file position of the file + * + * @return The current offset in the file + */ + virtual off_t tell() = 0; + + /** Rewind the file position to the beginning of the file + * + * @note This is equivalent to file_seek(file, 0, FS_SEEK_SET) + */ + virtual void rewind() = 0; + + /** Get the size of the file + * + * @return Size of the file in bytes + */ + virtual size_t size() = 0; + + /** Move the file position to a given offset from a given location. + * + * @param offset The offset from whence to move to + * @param whence SEEK_SET for the start of the file, SEEK_CUR for the + * current file position, or SEEK_END for the end of the file. + * + * @returns + * new file position on success, + * -1 on failure or unsupported + */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", "Replaced by FileLike::seek") + virtual off_t lseek(off_t offset, int whence) { return seek(offset, whence); } + + /** Flush any buffers associated with the FileHandle, ensuring it + * is up to date on disk + * + * @returns + * 0 on success or un-needed, + * -1 on error + */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", "Replaced by FileLike::sync") + virtual int fsync() { return sync(); } + + /** Find the length of the file + * + * @returns + * Length of the file + */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", "Replaced by FileLike::size") + virtual off_t flen() { return size(); } + +protected: + /** Acquire exclusive access to this object. + */ + virtual void lock() { + // Stub + } + + /** Release exclusive access to this object. + */ + virtual void unlock() { + // Stub + } }; + +/** @}*/ } // namespace mbed #endif - -/** @}*/ diff --git a/drivers/FilePath.cpp b/drivers/FilePath.cpp index 1d9739b15a..cdd64f5d9c 100644 --- a/drivers/FilePath.cpp +++ b/drivers/FilePath.cpp @@ -49,9 +49,9 @@ bool FilePath::isFileSystem(void) { return (fb->getPathType() == FileSystemPathType); } -FileSystemLike* FilePath::fileSystem(void) { +FileSystem* FilePath::fileSystem(void) { if (isFileSystem()) { - return (FileSystemLike*)fb; + return (FileSystem*)fb; } return NULL; } diff --git a/drivers/FilePath.h b/drivers/FilePath.h index 5952ba5de9..bc4448fd31 100644 --- a/drivers/FilePath.h +++ b/drivers/FilePath.h @@ -20,6 +20,7 @@ #include "drivers/FileSystemLike.h" #include "drivers/FileLike.h" +#include "filesystem/FileSystem.h" namespace mbed { /** \addtogroup drivers */ @@ -32,7 +33,7 @@ public: const char* fileName(void); bool isFileSystem(void); - FileSystemLike* fileSystem(void); + FileSystem* fileSystem(void); bool isFile(void); FileLike* file(void); diff --git a/drivers/FileSystemLike.cpp b/drivers/FileSystemLike.cpp index e435cf3162..167936af32 100644 --- a/drivers/FileSystemLike.cpp +++ b/drivers/FileSystemLike.cpp @@ -29,7 +29,7 @@ public: off_t n; struct dirent cur_entry; - BaseDirHandle() : n(0), cur_entry() { + BaseDirHandle() : DirHandle(0), n(0), cur_entry() { } virtual int closedir() { diff --git a/drivers/FileSystemLike.h b/drivers/FileSystemLike.h index e6ec3b5326..c08b8c94eb 100644 --- a/drivers/FileSystemLike.h +++ b/drivers/FileSystemLike.h @@ -41,10 +41,16 @@ public: * * @param name The name to use for the filesystem. */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "The mbed 2 filesystem classes have been superseeded by the FileSystem api, " + "Replaced by FileSystem") FileSystemLike(const char *name); virtual ~FileSystemLike(); + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "The mbed 2 filesystem classes have been superseeded by the FileSystem api, " + "Replaced by FileSystem") static DirHandle *opendir(); friend class BaseDirHandle; diff --git a/drivers/Stream.cpp b/drivers/Stream.cpp index d4bead1c32..9837c81297 100644 --- a/drivers/Stream.cpp +++ b/drivers/Stream.cpp @@ -94,19 +94,26 @@ ssize_t Stream::read(void* buffer, size_t length) { return ptr - (const char*)buffer; } -off_t Stream::lseek(off_t offset, int whence) { +off_t Stream::seek(off_t offset, int whence) { return 0; } +off_t Stream::tell() { + return 0; +} + +void Stream::rewind() { +} + int Stream::isatty() { return 0; } -int Stream::fsync() { +int Stream::sync() { return 0; } -off_t Stream::flen() { +size_t Stream::size() { return 0; } diff --git a/drivers/Stream.h b/drivers/Stream.h index 3cadbc3597..6f8292118a 100644 --- a/drivers/Stream.h +++ b/drivers/Stream.h @@ -18,6 +18,7 @@ #include "platform/platform.h" #include "drivers/FileLike.h" +#include "drivers/FileHandle.h" #include namespace mbed { @@ -53,10 +54,12 @@ protected: virtual int close(); virtual ssize_t write(const void* buffer, size_t length); virtual ssize_t read(void* buffer, size_t length); - virtual off_t lseek(off_t offset, int whence); + virtual off_t seek(off_t offset, int whence); + virtual off_t tell(); + virtual void rewind(); virtual int isatty(); - virtual int fsync(); - virtual off_t flen(); + virtual int sync(); + virtual size_t size(); virtual int _putc(int c) = 0; virtual int _getc() = 0; diff --git a/features/filesystem/File.cpp b/features/filesystem/File.cpp index 019479a0fa..15e4be4b1d 100644 --- a/features/filesystem/File.cpp +++ b/features/filesystem/File.cpp @@ -24,7 +24,7 @@ File::File() } File::File(FileSystem *fs, const char *path, int flags) - : _fs(0), _file(0) + : FileLike(path), _fs(0), _file(0) { open(fs, path, flags); } @@ -42,8 +42,12 @@ int File::open(FileSystem *fs, const char *path, int flags) return FS_ERROR_PARAMETER; } - _fs = fs; - return _fs->file_open(&_file, path, flags); + int err = fs->file_open(&_file, path, flags); + if (!err) { + _fs = fs; + } + + return err; } int File::close() @@ -75,7 +79,7 @@ int File::sync() return _fs->file_sync(_file); } -bool File::isatty() +int File::isatty() { MBED_ASSERT(_fs); return _fs->file_isatty(_file); diff --git a/features/filesystem/File.h b/features/filesystem/File.h index 36d839429b..4a3da361f9 100644 --- a/features/filesystem/File.h +++ b/features/filesystem/File.h @@ -18,6 +18,7 @@ #define FILE_H #include "filesystem/FileSystem.h" +#include "drivers/FileLike.h" namespace mbed { /** \addtogroup filesystem */ @@ -26,7 +27,7 @@ namespace mbed { /** File class */ -class File { +class File : public FileLike { public: /** Create an uninitialized file * @@ -94,7 +95,7 @@ public: * * @return True if the file is a terminal */ - virtual bool isatty(); + virtual int isatty(); /** Move the file position to a given offset from from a given location * diff --git a/features/filesystem/FileSystem.cpp b/features/filesystem/FileSystem.cpp index 0e0df7ba8a..9310c42b35 100644 --- a/features/filesystem/FileSystem.cpp +++ b/features/filesystem/FileSystem.cpp @@ -19,12 +19,17 @@ #include "filesystem/FileSystem.h" +FileSystem::FileSystem(const char *name) + : FileBase(name, FileSystemPathType) +{ +} + int FileSystem::file_sync(fs_file_t file) { return 0; } -bool FileSystem::file_isatty(fs_file_t file) +int FileSystem::file_isatty(fs_file_t file) { return false; } diff --git a/features/filesystem/FileSystem.h b/features/filesystem/FileSystem.h index bf2c31efe6..2e1c8b143b 100644 --- a/features/filesystem/FileSystem.h +++ b/features/filesystem/FileSystem.h @@ -20,8 +20,6 @@ #include "platform/platform.h" #include "drivers/FileBase.h" -#include "drivers/FileHandle.h" -#include "drivers/DirHandle.h" #include "BlockDevice.h" namespace mbed { @@ -53,10 +51,11 @@ typedef void *fs_dir_t; * * @Note Synchronization level: Set by subclass */ -class FileSystem { +class FileSystem : public FileBase { public: /** FileSystem lifetime */ + FileSystem(const char *name = NULL); virtual ~FileSystem() {} /** Mounts a filesystem to a block device @@ -155,7 +154,7 @@ protected: * @param file File handle * @return True if the file is a terminal */ - virtual bool file_isatty(fs_file_t file); + virtual int file_isatty(fs_file_t file); /** Move the file position to a given offset from from a given location * diff --git a/features/filesystem/fat/FATFileSystem.cpp b/features/filesystem/fat/FATFileSystem.cpp index 21a359bdf1..86236109d9 100644 --- a/features/filesystem/fat/FATFileSystem.cpp +++ b/features/filesystem/fat/FATFileSystem.cpp @@ -184,8 +184,7 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) // Filesystem implementation (See FATFilySystem.h) FATFileSystem::FATFileSystem(const char *name, BlockDevice *bd) - : /*FileSystem(n),*/ _id(-1) { - // TODO handle mount name + : FileSystem(name), _id(-1) { if (bd) { mount(bd); } @@ -215,7 +214,7 @@ int FATFileSystem::mount(BlockDevice *bd, bool force) { _ffs[_id] = bd; _fsid[0] = '0' + _id; _fsid[1] = '\0'; - //debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", getName(), _fsid); TODO FIXME + debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", getName(), _fsid); FRESULT res = f_mount(&_fs, _fsid, force); fat_filesystem_set_errno(res); unlock(); @@ -245,9 +244,8 @@ int FATFileSystem::unmount() /* See http://elm-chan.org/fsw/ff/en/mkfs.html for details of f_mkfs() and * associated arguments. */ -int FATFileSystem::format(BlockDevice *bd, int allocation_unit) -{ - FATFileSystem fs(""); +int FATFileSystem::format(BlockDevice *bd, int allocation_unit) { + FATFileSystem fs; int err = fs.mount(bd, false); if (err) { return -1; @@ -337,9 +335,9 @@ void FATFileSystem::unlock() { ////// File operations ////// int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags) { lock(); - //debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", name, getName(), _fsid); TODO FIXME - char n[64]; - sprintf(n, "%s:/%s", _fsid, path); + debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", path, getName(), _fsid); + char *buffer = new char[strlen(_fsid) + strlen(path) + 3]; + sprintf(buffer, "%s:/%s", _fsid, path); /* POSIX flags -> FatFS open mode */ BYTE openmode; @@ -359,7 +357,7 @@ int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags) { } FIL *fh = new FIL; - FRESULT res = f_open(fh, n, openmode); + FRESULT res = f_open(fh, buffer, openmode); fat_filesystem_set_errno(res); if (res) { debug_if(FFS_DBG, "f_open('w') failed: %d\n", res); diff --git a/features/filesystem/fat/FATFileSystem.h b/features/filesystem/fat/FATFileSystem.h index 7c12fa1662..6fcc6300bf 100644 --- a/features/filesystem/fat/FATFileSystem.h +++ b/features/filesystem/fat/FATFileSystem.h @@ -41,7 +41,7 @@ public: * @param name Name to add filesystem to tree as * @param bd BlockDevice to mount, may be passed instead to mount call */ - FATFileSystem(const char *name, BlockDevice *bd = NULL); + FATFileSystem(const char *name = NULL, BlockDevice *bd = NULL); virtual ~FATFileSystem(); /** Formats a logical drive, FDISK partitioning rule. @@ -235,13 +235,6 @@ protected: * @param dir Dir handle */ virtual void dir_rewind(fs_dir_t dir); - - /** Get the sizeof the directory - * - * @param dir Dir handle - * @return Number of files in the directory - */ - virtual size_t dir_size(fs_dir_t dir); private: FATFS _fs; // Work area (file system object) for logical drive diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index d2382f17d2..21826c959a 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ #include "platform/platform.h" -#include "drivers/FileHandle.h" -#include "drivers/FileSystemLike.h" #include "drivers/FilePath.h" #include "hal/serial_api.h" #include "platform/mbed_toolchain.h" @@ -25,6 +23,9 @@ #include "platform/PlatformMutex.h" #include "platform/mbed_error.h" #include "platform/mbed_stats.h" +#include "filesystem/FileSystem.h" +#include "filesystem/File.h" +#include "filesystem/Dir.h" #include #include #if DEVICE_STDIO_MESSAGES @@ -82,19 +83,22 @@ uint32_t mbed_heap_size = 0; * put it in a filehandles array and return the index into that array * (or rather index+3, as filehandles 0-2 are stdin/out/err). */ -static FileHandle *filehandles[OPEN_MAX]; +static FileLike *filehandles[OPEN_MAX]; +static File fileobjects[OPEN_MAX]; static SingletonPtr filehandle_mutex; -FileHandle::~FileHandle() { +namespace mbed { +void remove_filehandle(FileLike *file) { filehandle_mutex->lock(); /* Remove all open filehandles for this */ for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { - if (filehandles[fh_i] == this) { + if (filehandles[fh_i] == file) { filehandles[fh_i] = NULL; } } filehandle_mutex->unlock(); } +} #if DEVICE_SERIAL extern int stdio_uart_inited; @@ -207,16 +211,16 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { filehandle_mutex->unlock(); return -1; } - filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; + filehandles[fh_i] = (FileLike*)FILE_HANDLE_RESERVED; filehandle_mutex->unlock(); - FileHandle *res; + FileLike *res = NULL; /* FILENAME: ":0x12345678" describes a FileLike* */ if (name[0] == ':') { void *p; sscanf(name, ":%p", &p); - res = (FileHandle*)p; + res = (FileLike*)p; /* FILENAME: "/file_system/file_name" */ } else { @@ -233,7 +237,7 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { } else if (path.isFile()) { res = path.file(); } else { - FileSystemLike *fs = path.fileSystem(); + FileSystem *fs = path.fileSystem(); if (fs == NULL) { /* The filesystem instance managing the namespace under the mount point * has not been found. Free file handle */ @@ -242,7 +246,10 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { return -1; } int posix_mode = openmode_to_posix(openmode); - res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ + int err = fileobjects[fh_i].open(fs, path.fileName(), posix_mode); + if (!err) { + res = &fileobjects[fh_i]; + } } } @@ -260,7 +267,7 @@ extern "C" int PREFIX(_close)(FILEHANDLE fh) { if (fh < 3) return 0; errno = EBADF; - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; filehandles[fh-3] = NULL; if (fhc == NULL) return -1; @@ -294,7 +301,7 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign #endif n = length; } else { - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; n = fhc->write(buffer, length); @@ -343,7 +350,7 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int #endif n = 1; } else { - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; n = fhc->read(buffer, length); @@ -365,7 +372,7 @@ extern "C" int _isatty(FILEHANDLE fh) /* stdin, stdout and stderr should be tty */ if (fh < 3) return 1; - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; return fhc->isatty(); @@ -383,13 +390,13 @@ int _lseek(FILEHANDLE fh, int offset, int whence) errno = EBADF; if (fh < 3) return 0; - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; #if defined(__ARMCC_VERSION) - return fhc->lseek(position, SEEK_SET); + return fhc->seek(position, SEEK_SET); #else - return fhc->lseek(offset, whence); + return fhc->seek(offset, whence); #endif } @@ -398,7 +405,7 @@ extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { errno = EBADF; if (fh < 3) return 0; - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; return fhc->fsync(); @@ -408,7 +415,7 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh) { errno = EBADF; if (fh < 3) return 0; - FileHandle* fhc = filehandles[fh-3]; + FileLike* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; return fhc->flen(); @@ -431,7 +438,7 @@ namespace std { extern "C" int remove(const char *path) { errno = EBADF; FilePath fp(path); - FileSystemLike *fs = fp.fileSystem(); + FileSystem *fs = fp.fileSystem(); if (fs == NULL) return -1; return fs->remove(fp.fileName()); @@ -441,8 +448,8 @@ extern "C" int rename(const char *oldname, const char *newname) { errno = EBADF; FilePath fpOld(oldname); FilePath fpNew(newname); - FileSystemLike *fsOld = fpOld.fileSystem(); - FileSystemLike *fsNew = fpNew.fileSystem(); + FileSystem *fsOld = fpOld.fileSystem(); + FileSystem *fsNew = fpNew.fileSystem(); /* rename only if both files are on the same FS */ if (fsOld != fsNew || fsOld == NULL) return -1; @@ -469,41 +476,50 @@ extern "C" char *_sys_command_string(char *cmd, int len) { extern "C" DIR *opendir(const char *path) { errno = EBADF; - /* root dir is FileSystemLike */ - if (path[0] == '/' && path[1] == 0) { - return FileSystemLike::opendir(); - } FilePath fp(path); - FileSystemLike* fs = fp.fileSystem(); + FileSystem* fs = fp.fileSystem(); if (fs == NULL) return NULL; - return fs->opendir(fp.fileName()); + Dir *dir = new Dir; + int err = dir->open(fs, fp.fileName()); + if (err) { + delete dir; + dir = NULL; + } + + return dir; } extern "C" struct dirent *readdir(DIR *dir) { - return dir->readdir(); + static struct dirent ent; + int err = dir->read(ent.d_name, NAME_MAX, &ent.d_type); + if (err) { + return NULL; + } + + return &ent; } extern "C" int closedir(DIR *dir) { - return dir->closedir(); + return dir->close(); } extern "C" void rewinddir(DIR *dir) { - dir->rewinddir(); + dir->rewind(); } extern "C" off_t telldir(DIR *dir) { - return dir->telldir(); + return dir->tell(); } extern "C" void seekdir(DIR *dir, off_t off) { - dir->seekdir(off); + dir->seek(off); } extern "C" int mkdir(const char *path, mode_t mode) { FilePath fp(path); - FileSystemLike *fs = fp.fileSystem(); + FileSystem *fs = fp.fileSystem(); if (fs == NULL) return -1; return fs->mkdir(fp.fileName(), mode); @@ -511,7 +527,7 @@ extern "C" int mkdir(const char *path, mode_t mode) { extern "C" int stat(const char *path, struct stat *st) { FilePath fp(path); - FileSystemLike *fs = fp.fileSystem(); + FileSystem *fs = fp.fileSystem(); if (fs == NULL) return -1; return fs->stat(fp.fileName(), st); diff --git a/platform/platform.h b/platform/platform.h index 8ef3e1a729..6e2996ae32 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -24,6 +24,8 @@ #include #include +#include "platform/retarget.h" +#include "platform/toolchain.h" #include "device.h" #include "PinNames.h" #include "PeripheralNames.h" diff --git a/platform/retarget.h b/platform/retarget.h index bb23fe7870..f24eab06ad 100644 --- a/platform/retarget.h +++ b/platform/retarget.h @@ -19,6 +19,8 @@ #ifndef RETARGET_H #define RETARGET_H +#include + /* We can get the following standard types from sys/types for gcc, but we * need to define the types ourselves for the other compilers that normally * target embedded systems */ @@ -27,13 +29,39 @@ typedef int ssize_t; ///< Signed size type, usually encodes negative errors typedef long off_t; ///< Offset in a data stream typedef int mode_t; ///< Mode for opening files +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_CREAT 0x0200 +#define O_TRUNC 0x0400 +#define O_APPEND 0x0008 + #define NAME_MAX 255 ///< Maximum size of a name in a file path + #else +#include #include #include #endif +/* DIR declarations must also be here */ +#if __cplusplus +namespace mbed { class Dir; } +typedef mbed::Dir DIR; + +extern "C" { + DIR *opendir(const char*); + struct dirent *readdir(DIR *); + int closedir(DIR*); + void rewinddir(DIR*); + long telldir(DIR*); + void seekdir(DIR*, long); + int mkdir(const char *name, mode_t n); +}; +#endif + + #if defined(__ARMCC_VERSION) || defined(__ICCARM__) /* The intent of this section is to unify the errno error values to match * the POSIX definitions for the GCC_ARM, ARMCC and IAR compilers. This is