From 31a26883ebb253e9a73686b1cb0699b53884885e Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 9 Aug 2015 19:28:12 +0200 Subject: [PATCH] fix error in make_dirs and add is_file trailing separator caused make_dir to be called twice with the same path which caused it to fail the second time --- src/app/io.cpp | 35 +++++++++++++++++++++++++++++++---- src/app/io.hpp | 11 +++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/app/io.cpp b/src/app/io.cpp index 7996be6..f9c5805 100644 --- a/src/app/io.cpp +++ b/src/app/io.cpp @@ -21,7 +21,23 @@ bool is_dir(const char *path) { if (stat(path, &info) != 0) { return false; } - return (info.st_mode & S_IFDIR) != 0; + return S_ISDIR(info.st_mode); +#endif +} + +bool is_file(const char *path) { +#ifdef _WIN32 + struct _stat info; + if (_stat(path, &info) != 0) { + return false; + } + return (info.st_mode & _S_IFREG) != 0; +#else + struct stat info; + if (stat(path, &info) != 0) { + return false; + } + return S_ISREG(info.st_mode); #endif } @@ -37,7 +53,7 @@ bool make_dir(const char *path) { bool make_dirs(const std::string &path) { - if (make_dir(path.c_str())) { + if (make_dir(path)) { return true; } @@ -54,16 +70,27 @@ bool make_dirs(const std::string &path) { if (pos == std::string::npos) { return false; } + if (pos == path.length() - 1) { + // trailing separator, would make final make_dir fail +#ifdef _WIN32 + pos = path.find_last_of("\\/", pos - 1); +#else + pos = path.find_last_of('/', pos - 1); +#endif + if (pos == std::string::npos) { + return false; + } + } if (!make_dirs(path.substr(0, pos))) { return false; } } // try again - return make_dir(path.c_str()); + return make_dir(path); case EEXIST: // something's there, check if it's a dir and we're good - return is_dir(path.c_str()); + return is_dir(path); default: // whatever else went wrong, it can't be good diff --git a/src/app/io.hpp b/src/app/io.hpp index 4869238..966c4dc 100644 --- a/src/app/io.hpp +++ b/src/app/io.hpp @@ -8,11 +8,22 @@ namespace blank { /// check if give path points to an existing directory bool is_dir(const char *); +inline bool is_dir(const std::string &s) { + return is_dir(s.c_str()); +} +/// check if give path points to an existing file +bool is_file(const char *); +inline bool is_file(const std::string &s) { + return is_file(s.c_str()); +} /// create given directory /// @return true if the directory was created /// the directory might already exist, see errno bool make_dir(const char *); +inline bool make_dir(const std::string &s) { + return make_dir(s.c_str()); +} /// create given directory and all parents /// @return true if the directory was created or already exists bool make_dirs(const std::string &); -- 2.39.2