Browse Source

Made filesystem methods thread safe

merge-requests/386/merge
eidheim 5 years ago
parent
commit
ddaca98476
  1. 46
      src/filesystem.cpp
  2. 24
      tests/filesystem_test.cpp

46
src/filesystem.cpp

@ -83,16 +83,12 @@ std::string filesystem::unescape_argument(const std::string &argument) {
} }
boost::filesystem::path filesystem::get_current_path() noexcept { boost::filesystem::path filesystem::get_current_path() noexcept {
static boost::filesystem::path current_path; auto current_path = [] {
if(!current_path.empty())
return current_path;
#ifdef _WIN32 #ifdef _WIN32
boost::system::error_code ec; boost::system::error_code ec;
auto path = boost::filesystem::current_path(ec); auto path = boost::filesystem::current_path(ec);
if(!ec) { if(!ec)
current_path = std::move(path); return path;
return current_path;
}
return boost::filesystem::path(); return boost::filesystem::path();
#else #else
std::string path; std::string path;
@ -102,29 +98,32 @@ boost::filesystem::path filesystem::get_current_path() noexcept {
if(process.get_exit_status() == 0) { if(process.get_exit_status() == 0) {
if(!path.empty() && path.back() == '\n') if(!path.empty() && path.back() == '\n')
path.pop_back(); path.pop_back();
current_path = boost::filesystem::path(path); return boost::filesystem::path(path);
return current_path;
} }
return boost::filesystem::path(); return boost::filesystem::path();
#endif #endif
};
static boost::filesystem::path path = current_path();
return path;
} }
boost::filesystem::path filesystem::get_home_path() noexcept { boost::filesystem::path filesystem::get_home_path() noexcept {
static boost::filesystem::path home_path; auto home_path = [] {
if(!home_path.empty())
return home_path;
std::vector<std::string> environment_variables = {"HOME", "AppData"}; std::vector<std::string> environment_variables = {"HOME", "AppData"};
for(auto &variable : environment_variables) { for(auto &variable : environment_variables) {
if(auto ptr = std::getenv(variable.c_str())) { if(auto ptr = std::getenv(variable.c_str())) {
boost::system::error_code ec; boost::system::error_code ec;
boost::filesystem::path path(ptr); boost::filesystem::path path(ptr);
if(boost::filesystem::exists(path, ec)) { if(boost::filesystem::exists(path, ec))
home_path = std::move(path); return path;
return home_path;
}
} }
} }
return boost::filesystem::path(); return boost::filesystem::path();
};
static boost::filesystem::path path = home_path();
return path;
} }
boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept { boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept {
@ -260,9 +259,8 @@ boost::filesystem::path filesystem::get_executable(const boost::filesystem::path
// Based on https://stackoverflow.com/a/11295568 // Based on https://stackoverflow.com/a/11295568
const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() { const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() {
static std::vector<boost::filesystem::path> result; auto executable_search_paths = [] {
if(!result.empty()) std::vector<boost::filesystem::path> paths;
return result;
const std::string env = getenv("PATH"); const std::string env = getenv("PATH");
const char delimiter = ':'; const char delimiter = ':';
@ -270,12 +268,16 @@ const std::vector<boost::filesystem::path> &filesystem::get_executable_search_pa
size_t previous = 0; size_t previous = 0;
size_t pos; size_t pos;
while((pos = env.find(delimiter, previous)) != std::string::npos) { while((pos = env.find(delimiter, previous)) != std::string::npos) {
result.emplace_back(env.substr(previous, pos - previous)); paths.emplace_back(env.substr(previous, pos - previous));
previous = pos + 1; previous = pos + 1;
} }
result.emplace_back(env.substr(previous)); paths.emplace_back(env.substr(previous));
return paths;
};
return result; static std::vector<boost::filesystem::path> paths = executable_search_paths();
return paths;
} }
boost::filesystem::path filesystem::find_executable(const std::string &executable_name) { boost::filesystem::path filesystem::find_executable(const std::string &executable_name) {

24
tests/filesystem_test.cpp

@ -3,14 +3,26 @@
int main() { int main() {
{ {
auto home_path = filesystem::get_home_path(); auto path = filesystem::get_home_path();
g_assert(!home_path.empty()); g_assert(!path.empty());
g_assert(boost::filesystem::exists(path));
g_assert(boost::filesystem::is_directory(path));
} }
{ {
auto home_path = filesystem::get_current_path(); auto path = filesystem::get_current_path();
g_assert(!home_path.empty()); g_assert(!path.empty());
g_assert(boost::filesystem::exists(home_path)); g_assert(boost::filesystem::exists(path));
g_assert(boost::filesystem::is_directory(home_path)); g_assert(boost::filesystem::is_directory(path));
}
{
auto paths = filesystem::get_executable_search_paths();
g_assert(!paths.empty());
for(auto &path : paths) {
g_assert(!path.empty());
g_assert(boost::filesystem::exists(path));
g_assert(boost::filesystem::is_directory(path));
}
} }
{ {

Loading…
Cancel
Save