From: Mikko Rasa Date: Wed, 12 Nov 2014 20:10:25 +0000 (+0200) Subject: Split getcwd and chdir to platform files X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=edf916d784e503505ddac2acef6f3e9a72abb0d6;p=libs%2Fcore.git Split getcwd and chdir to platform files --- diff --git a/source/fs/dir.cpp b/source/fs/dir.cpp index df85e35..9c6a97a 100644 --- a/source/fs/dir.cpp +++ b/source/fs/dir.cpp @@ -130,12 +130,6 @@ list list_filtered(const Path &path, const string &filter) return result; } -Path getcwd() -{ - char buf[1024]; - return ::getcwd(buf, sizeof(buf)); -} - Path get_user_data_dir() { const string &name = Application::get_name(); @@ -214,12 +208,6 @@ Path get_sys_lib_dir() return get_sys_lib_dir(argv0, Application::get_name()); } -void chdir(const Path &path) -{ - if(::chdir(path.str().c_str())==-1) - throw system_error("chdir"); -} - Path path_lookup(const string &name, const list &paths) { for(list::const_iterator i=paths.begin(); i!=paths.end(); ++i) diff --git a/source/fs/dir.h b/source/fs/dir.h index cf2cdeb..e964a2d 100644 --- a/source/fs/dir.h +++ b/source/fs/dir.h @@ -37,6 +37,9 @@ std::list list_filtered(const Path &path, const std::string &filter /// Returns the current working directory Path getcwd(); +/// Changes the current working directory +void chdir(const Path &); + /// Returns the user's home directory Path get_home_dir(); @@ -64,9 +67,6 @@ Path get_sys_lib_dir(const std::string &argv0, const std::string &appname); /// Returns a directory containing system-wide architecture-specific files. Path get_sys_lib_dir(); -/// Changes the current working directory -void chdir(const Path &); - /** Looks for a file in a list of paths. Returns the absolute path to the first existing location, or an empty Path if the file is not found at all. */ Path path_lookup(const std::string &, const std::list &); diff --git a/source/fs/unix/dir.cpp b/source/fs/unix/dir.cpp index 69e926a..8169a63 100644 --- a/source/fs/unix/dir.cpp +++ b/source/fs/unix/dir.cpp @@ -21,6 +21,18 @@ void rmdir(const Path &path) throw system_error("rmdir"); } +Path getcwd() +{ + char buf[1024]; + return ::getcwd(buf, sizeof(buf)); +} + +void chdir(const Path &path) +{ + if(::chdir(path.str().c_str())==-1) + throw system_error("chdir"); +} + Path get_home_dir() { const char *home = getenv("HOME"); diff --git a/source/fs/windows/dir.cpp b/source/fs/windows/dir.cpp index 6b63b47..151cc1b 100644 --- a/source/fs/windows/dir.cpp +++ b/source/fs/windows/dir.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "dir.h" @@ -19,6 +20,43 @@ void rmdir(const Path &path) throw system_error("RemoveDirectory"); } +/* Windows documentation says Get/SetCurrentDirectory use a global buffer and +are not thread safe. */ +static Mutex &cwd_mutex() +{ + static Mutex mutex; + return mutex; +} + +Path getcwd() +{ + MutexLock lock(cwd_mutex()); + + char buf[1024]; + Path result; + DWORD len = GetCurrentDirectory(sizeof(buf), buf); + if(len>=sizeof(buf)) + { + vector buf2(len+1); + len = GetCurrentDirectory(buf2.size(), buf2.data()); + result = buf2.data(); + } + else + result = buf; + + if(!len) + throw system_error("GetCurrentDirectory"); + + return result; +} + +void chdir(const Path &path) +{ + MutexLock lock(cwd_mutex()); + if(!SetCurrentDirectory(path.c_str())) + throw system_error("SetCurrentDirectory"); +} + Path get_home_dir() { char home[MAX_PATH];