From 1eb77b0cd7e03b8e22772c804630c0df5f42e1fb Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Fri, 13 Jun 2014 09:10:35 +0200 Subject: [PATCH] Replace recursive implementation with a forward loop in Utility::MkDirP() That way we always move into the tree, but not start in the deepest level and may limit the tree level too in the future, if required. Solves the Win32 implementation by moving the general mkdir() call into Utility::MkDir(). refs #6328 --- lib/base/utility.cpp | 37 +++++++++++++++++++-------------- lib/base/utility.hpp | 3 ++- lib/remote/apilistener-sync.cpp | 4 ++-- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 9f10f5578..5eac40d35 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -671,28 +671,33 @@ bool Utility::GlobRecursive(const String& path, const String& pattern, const boo return true; } -int Utility::MkDirP(const String& path, int flags) + +bool Utility::MkDir(const String& path, int flags) { - -#ifdef _WIN32 - /* TODO */ - return 0; -#else /* _WIN32 */ - - if (path.IsEmpty()) { - errno = EINVAL; - return 1; +#ifndef _WIN32 + if (mkdir(path.CStr(), flags) < 0 && errno != EEXIST) { +#else /*_ WIN32 */ + if (mkdir(path.CStr()) < 0 && errno != EEXIST) { +#endif /* _WIN32 */ + //TODO handle missing dirs properly + return false; } - if (path.GetLength() == 1 && path[0] == '.') - return 0; + return true; +} - String dir = DirName(path); +bool Utility::MkDirP(const String& path, int flags) +{ + size_t pos = 0; - MkDirP(dir, flags); + bool ret = true; - return mkdir(dir.CStr(), flags); -#endif /* _WIN32 */ + while (ret && pos != String::NPos) { + pos = path.Find("/", pos + 1); + ret = MkDir(path.SubStr(0, pos), flags); + } + + return ret; } diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index 5e5a36999..f3e931850 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -81,7 +81,8 @@ public: static bool Glob(const String& pathSpec, const boost::function& callback, int type = GlobFile | GlobDirectory); static bool GlobRecursive(const String& path, const String& pattern, const boost::function& callback, int type = GlobFile | GlobDirectory); - static int MkDirP(const String& path, int flags); + static bool MkDir(const String& path, int flags); + static bool MkDirP(const String& path, int flags); static void QueueAsyncCallback(const boost::function& callback); diff --git a/lib/remote/apilistener-sync.cpp b/lib/remote/apilistener-sync.cpp index dc98fed30..fab2d92f9 100644 --- a/lib/remote/apilistener-sync.cpp +++ b/lib/remote/apilistener-sync.cpp @@ -76,8 +76,8 @@ bool ApiListener::UpdateConfigDir(const Dictionary::Ptr& oldConfig, const Dictio String path = configDir + "/" + kv.first; Log(LogInformation, "ApiListener", "Updating configuration file: " + path); - //TODO mkdir -p? - Utility::MkDirP(path, 0755); + //pass the directory and generate a dir tree, if not existing already + Utility::MkDirP(Utility::DirName(path), 0755); std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc); fp << kv.second; fp.close();