From: Michael Friedrich Date: Fri, 13 Jun 2014 07:10:35 +0000 (+0200) Subject: Replace recursive implementation with a forward loop in Utility::MkDirP() X-Git-Tag: v2.0.0~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1eb77b0cd7e03b8e22772c804630c0df5f42e1fb;p=icinga2 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 --- 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) -{ - -#ifdef _WIN32 - /* TODO */ - return 0; -#else /* _WIN32 */ - if (path.IsEmpty()) { - errno = EINVAL; - return 1; +bool Utility::MkDir(const String& path, int flags) +{ +#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();