Split getcwd and chdir to platform files
authorMikko Rasa <tdb@tdb.fi>
Wed, 12 Nov 2014 20:10:25 +0000 (22:10 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 12 Nov 2014 20:16:28 +0000 (22:16 +0200)
source/fs/dir.cpp
source/fs/dir.h
source/fs/unix/dir.cpp
source/fs/windows/dir.cpp

index df85e352ee78c05874b40ac6d406c421db816a04..9c6a97a8318ceaccb77c2d708f7ae65a45f3d951 100644 (file)
@@ -130,12 +130,6 @@ list<string> 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<Path> &paths)
 {
        for(list<Path>::const_iterator i=paths.begin(); i!=paths.end(); ++i)
index cf2cdeb79c97437f86a7e8ffb4f5bc158aa2c8e8..e964a2d848ae93fd5875711544898608911a58f3 100644 (file)
@@ -37,6 +37,9 @@ std::list<std::string> 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<Path> &);
index 69e926adf189e7087f3772b546248ad80079bd2a..8169a63fffbe9809af24012ed4ae28101ac881e3 100644 (file)
@@ -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");
index 6b63b471d5bc939fe11a78ccbc668cdb02573c8c..151cc1b0944c4b455655c1f426da09c0ee81f89f 100644 (file)
@@ -1,4 +1,5 @@
 #include <shlobj.h>
+#include <msp/core/mutex.h>
 #include <msp/core/systemerror.h>
 #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<char> 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];