From 0c3460e1b232e7e45a7e22ddb55fed73d3f9a661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 29 Sep 2021 16:12:22 +0200 Subject: [PATCH 1/3] SD.open() new feature for creating all folders in path This PR adds to the SD.open() function option to create all folders to the file. SD.open(const char* path, const char* mode, const bool create) Default value of create is false. When true folders are created. From issue #5019 --- libraries/FS/src/FS.cpp | 8 ++--- libraries/FS/src/FS.h | 4 +-- libraries/FS/src/FSImpl.h | 2 +- libraries/FS/src/vfs_api.cpp | 56 +++++++++++++++++++++++++++------ libraries/FS/src/vfs_api.h | 2 +- libraries/SPIFFS/src/SPIFFS.cpp | 2 +- 6 files changed, 56 insertions(+), 18 deletions(-) diff --git a/libraries/FS/src/FS.cpp b/libraries/FS/src/FS.cpp index 3050ec41fd8..f5e9a8ab2cc 100644 --- a/libraries/FS/src/FS.cpp +++ b/libraries/FS/src/FS.cpp @@ -186,18 +186,18 @@ void File::rewindDirectory(void) _p->rewindDirectory(); } -File FS::open(const String& path, const char* mode) +File FS::open(const String& path, const char* mode, const bool create) { - return open(path.c_str(), mode); + return open(path.c_str(), mode, create); } -File FS::open(const char* path, const char* mode) +File FS::open(const char* path, const char* mode, const bool create) { if (!_impl) { return File(); } - return File(_impl->open(path, mode)); + return File(_impl->open(path, mode, create)); } bool FS::exists(const char* path) diff --git a/libraries/FS/src/FS.h b/libraries/FS/src/FS.h index 2c4aa3011c1..c3a1c51c5ec 100644 --- a/libraries/FS/src/FS.h +++ b/libraries/FS/src/FS.h @@ -89,8 +89,8 @@ class FS public: FS(FSImplPtr impl) : _impl(impl) { } - File open(const char* path, const char* mode = FILE_READ); - File open(const String& path, const char* mode = FILE_READ); + File open(const char* path, const char* mode = FILE_READ, const bool create = false); + File open(const String& path, const char* mode = FILE_READ, const bool create = false); bool exists(const char* path); bool exists(const String& path); diff --git a/libraries/FS/src/FSImpl.h b/libraries/FS/src/FSImpl.h index 51c5915a069..4c5c9786840 100644 --- a/libraries/FS/src/FSImpl.h +++ b/libraries/FS/src/FSImpl.h @@ -53,7 +53,7 @@ class FSImpl public: FSImpl() : _mountpoint(NULL) { } virtual ~FSImpl() { } - virtual FileImplPtr open(const char* path, const char* mode) = 0; + virtual FileImplPtr open(const char* path, const char* mode, const bool create) = 0; virtual bool exists(const char* path) = 0; virtual bool rename(const char* pathFrom, const char* pathTo) = 0; virtual bool remove(const char* path) = 0; diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp index aea37b1e3d6..e18243dab7b 100644 --- a/libraries/FS/src/vfs_api.cpp +++ b/libraries/FS/src/vfs_api.cpp @@ -16,7 +16,7 @@ using namespace fs; -FileImplPtr VFSImpl::open(const char* fpath, const char* mode) +FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create) { if(!_mountpoint) { log_e("File system is not mounted"); @@ -37,7 +37,7 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) sprintf(temp,"%s%s", _mountpoint, fpath); struct stat st; - //file lound + //file found if(!stat(temp, &st)) { free(temp); if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) { @@ -47,12 +47,6 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) return FileImplPtr(); } - //file not found but mode permits creation - if(mode && mode[0] != 'r') { - free(temp); - return std::make_shared(this, fpath, mode); - } - //try to open this as directory (might be mount point) DIR * d = opendir(temp); if(d) { @@ -61,7 +55,51 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) return std::make_shared(this, fpath, mode); } - log_e("%s does not exist", temp); + //file not found but mode permits file creation without folder creation + if((mode && mode[0] != 'r') && (!create)){ + free(temp); + return std::make_shared(this, fpath, mode); + } + + ////file not found but mode permits file creation and folder creation + if((mode && mode[0] != 'r') && create){ + + char *token; + char *folder = (char *)malloc(strlen(fpath)); + + int start_index = 0; + int end_index = 0; + + token = strchr(fpath+1,'/'); + end_index = (token-fpath); + + while (token != NULL) + { + memccpy(folder,fpath + start_index, NULL, end_index-start_index); + folder[end_index-start_index] = '\0'; + + if(!VFSImpl::mkdir(folder)) + { + log_e("Creating folder: %s failed!",folder); + return FileImplPtr(); + } + + token=strchr(token+1,'/'); + if(token != NULL) + { + end_index = (token-fpath); + memset(folder, 0, strlen(folder)); + } + + } + + free(folder); + free(temp); + return std::make_shared(this, fpath, mode); + + } + + log_e("%s does not exist, no permits for creation", temp); free(temp); return FileImplPtr(); } diff --git a/libraries/FS/src/vfs_api.h b/libraries/FS/src/vfs_api.h index 58fd86fdd26..f79852cdcfe 100644 --- a/libraries/FS/src/vfs_api.h +++ b/libraries/FS/src/vfs_api.h @@ -35,7 +35,7 @@ class VFSImpl : public FSImpl friend class VFSFileImpl; public: - FileImplPtr open(const char* path, const char* mode) override; + FileImplPtr open(const char* path, const char* mode, const bool create) override; bool exists(const char* path) override; bool rename(const char* pathFrom, const char* pathTo) override; bool remove(const char* path) override; diff --git a/libraries/SPIFFS/src/SPIFFS.cpp b/libraries/SPIFFS/src/SPIFFS.cpp index d3e1665491a..0fb2eff08af 100644 --- a/libraries/SPIFFS/src/SPIFFS.cpp +++ b/libraries/SPIFFS/src/SPIFFS.cpp @@ -39,7 +39,7 @@ SPIFFSImpl::SPIFFSImpl() bool SPIFFSImpl::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true) && !f.isDirectory(); } From aef0ad12ef58c22c99b5883f561cdf9835fd2c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 30 Sep 2021 10:09:03 +0200 Subject: [PATCH 2/3] Update vfs_api.cpp memccpy -> memcpy --- libraries/FS/src/vfs_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp index e18243dab7b..e43b4397452 100644 --- a/libraries/FS/src/vfs_api.cpp +++ b/libraries/FS/src/vfs_api.cpp @@ -75,7 +75,7 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create while (token != NULL) { - memccpy(folder,fpath + start_index, NULL, end_index-start_index); + memcpy(folder,fpath + start_index, end_index-start_index); folder[end_index-start_index] = '\0'; if(!VFSImpl::mkdir(folder)) From fa7b9e70e188139e04a8c95f90bbc561c5acd607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 30 Sep 2021 10:40:18 +0200 Subject: [PATCH 3/3] File f = open() edit added false for create --- libraries/FFat/src/FFat.cpp | 2 +- libraries/LittleFS/src/LittleFS.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/FFat/src/FFat.cpp b/libraries/FFat/src/FFat.cpp index 6441dfca4e4..f58bc444c17 100644 --- a/libraries/FFat/src/FFat.cpp +++ b/libraries/FFat/src/FFat.cpp @@ -168,7 +168,7 @@ size_t F_Fat::freeBytes() bool F_Fat::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true) && !f.isDirectory(); } diff --git a/libraries/LittleFS/src/LittleFS.cpp b/libraries/LittleFS/src/LittleFS.cpp index 7989dcb60be..9ea2320ecf9 100644 --- a/libraries/LittleFS/src/LittleFS.cpp +++ b/libraries/LittleFS/src/LittleFS.cpp @@ -45,7 +45,7 @@ LittleFSImpl::LittleFSImpl() bool LittleFSImpl::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true); }