diff options
author | Maxim Pimenov <m@maps.me> | 2017-09-20 16:54:07 +0300 |
---|---|---|
committer | Yuri Gorshenin <mipt.vi002@gmail.com> | 2017-09-25 15:21:27 +0300 |
commit | f836620d552d361d8d24d46f002243ff3b94c6f3 (patch) | |
tree | 0333341a83f01f1101feec0609fc021457097722 | |
parent | fd46f8ce23efd7e0a2107a8f2c1abc72b5bd01d5 (diff) |
Review fixes.beta-1015
-rw-r--r-- | platform/platform.hpp | 6 | ||||
-rw-r--r-- | platform/platform_linux.cpp | 74 |
2 files changed, 58 insertions, 22 deletions
diff --git a/platform/platform.hpp b/platform/platform.hpp index dd0eb2bd3b..a0b58bb86f 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -127,10 +127,10 @@ public: /// Client app should not replace default resource dir. void SetResourceDir(string const & path); - /// Creates directory in the filesystem. - static EError MkDir(string const & dirName); + /// Creates the directory in the filesystem. + WARN_UNUSED_RESULT static EError MkDir(string const & dirName); - /// Creates a directory. Returns true on success. + /// Creates the directory. Returns true on success. /// Returns false and logs the reason on failure. WARN_UNUSED_RESULT static bool MkDirChecked(string const & dirName); diff --git a/platform/platform_linux.cpp b/platform/platform_linux.cpp index bb92db9c5c..99f40969e9 100644 --- a/platform/platform_linux.cpp +++ b/platform/platform_linux.cpp @@ -9,7 +9,9 @@ #include "base/macros.hpp" #include "base/scope_guard.hpp" +#include "std/algorithm.hpp" #include "std/bind.hpp" +#include "std/initializer_list.hpp" #include "std/string.hpp" #include <stdlib.h> @@ -41,28 +43,64 @@ bool GetBinaryDir(string & outPath) // Returns true if EULA file exists in directory. bool IsEulaExist(string const & directory) { - return Platform::IsFileExistsByFullPath(my::JoinFoldersToPath(directory, "eula.html")); + return Platform::IsFileExistsByFullPath(my::JoinPath(directory, "eula.html")); +} + +// Makes my::JoinPath(path, dirs) and all intermediate dirs. +// The directory |path| is assumed to exist already. +bool MkDirsChecked(string path, initializer_list<string> const & dirs) +{ + string accumulatedDirs = path; + // Storing full paths is redundant but makes the implementation easier. + vector<string> madeDirs; + bool ok = true; + for (auto const & dir : dirs) + { + accumulatedDirs = my::JoinPath(accumulatedDirs, dir); + auto const result = Platform::MkDir(accumulatedDirs); + switch (result) + { + case Platform::ERR_OK: madeDirs.push_back(accumulatedDirs); break; + case Platform::ERR_FILE_ALREADY_EXISTS: + { + Platform::EFileType type; + if (Platform::GetFileType(accumulatedDirs, type) != Platform::ERR_OK || + type != Platform::FILE_TYPE_DIRECTORY) + { + ok = false; + } + } + break; + default: ok = false; break; + } + } + + if (ok) + return true; + + for (; !madeDirs.empty(); madeDirs.pop_back()) + Platform::RmDir(madeDirs.back()); + + return false; } string HomeDir() { char const * homePath = ::getenv("HOME"); - return homePath != nullptr ? string(homePath) : ""; + if (homePath == nullptr) + MYTHROW(RootException, ("The environment variable HOME is not set")); + return homePath; } // Returns the default path to the writable dir, creating the dir if needed. // An exception is thrown if the default dir is not already there and we were unable to create it. string DefaultWritableDir() { + initializer_list<string> dirs = {".local", "share", "MapsWithMe"}; + auto const result = my::JoinFoldersToPath(dirs, "" /* file */); auto const home = HomeDir(); - string const result = my::JoinFoldersToPath({home, ".local", "share"}, "MapsWithMe"); - if (!Platform::MkDirChecked(my::JoinFoldersToPath(home, ".local")) || - !Platform::MkDirChecked(my::JoinFoldersToPath({home, ".local"}, "share")) || - !Platform::MkDirChecked(result)) - { - MYTHROW(FileSystemException, ("Can't create directory", result)); - } - + if (!MkDirsChecked(home, dirs)) + MYTHROW(FileSystemException, ("Cannot create directory:", result)); return result; } } // namespace @@ -81,11 +119,11 @@ Platform::Platform() string path; CHECK(GetBinaryDir(path), ("Can't retrieve path to executable")); - m_settingsDir = my::JoinFoldersToPath({HomeDir(), ".config"}, "MapsWithMe"); + m_settingsDir = my::JoinPath(HomeDir(), ".config", "MapsWithMe"); - if (!IsFileExistsByFullPath(my::JoinFoldersToPath(m_settingsDir, SETTINGS_FILE_NAME))) + if (!IsFileExistsByFullPath(my::JoinPath(m_settingsDir, SETTINGS_FILE_NAME))) { - auto const configDir = my::JoinFoldersToPath(HomeDir(), ".config"); + auto const configDir = my::JoinPath(HomeDir(), ".config"); if (!MkDirChecked(configDir)) MYTHROW(FileSystemException, ("Can't create directory", configDir)); if (!MkDirChecked(m_settingsDir)) @@ -106,12 +144,10 @@ Platform::Platform() } else { - string const devBuildWithSymlink = my::JoinFoldersToPath({path, "..", ".."}, "data"); - string const devBuildWithoutSymlink = - my::JoinFoldersToPath({path, "..", "..", "..", "omim"}, "data"); - string const installedVersionWithPackages = my::JoinFoldersToPath({path, ".."}, "share"); - string const installedVersionWithoutPackages = - my::JoinFoldersToPath({path, ".."}, "MapsWithMe"); + string const devBuildWithSymlink = my::JoinPath(path, "..", "..", "data"); + string const devBuildWithoutSymlink = my::JoinPath(path, "..", "..", "..", "omim", "data"); + string const installedVersionWithPackages = my::JoinPath(path, "..", "share"); + string const installedVersionWithoutPackages = my::JoinPath(path, "..", "MapsWithMe"); string const customInstall = path; if (IsEulaExist(devBuildWithSymlink)) |