Fixed creating and setting the write directory on some sandboxed operating systems

This commit is contained in:
Alex Szpakowski
2014-05-05 00:27:42 -03:00
parent 9d293af176
commit e25cdfc71c
3 changed files with 36 additions and 16 deletions
+32 -12
View File
@@ -176,16 +176,36 @@ bool Filesystem::setupWriteDirectory()
if (save_identity.empty() || save_path_full.empty() || save_path_relative.empty()) if (save_identity.empty() || save_path_full.empty() || save_path_relative.empty())
return false; return false;
// Set the appdata folder as writable directory. // We need to make sure the write directory is created. To do that, we also
// need to make sure all its parent directories are also created.
std::string temp_writedir = getDriveRoot(save_path_full);
std::string temp_createdir = skipDriveRoot(save_path_full);
// On some sandboxed platforms, physfs will break when its write directory
// is the root of the drive and it tries to create a folder (even if the
// folder's path is in a writable location.) If the user's home folder is
// in the save path, we'll try starting from there instead.
if (save_path_full.find(getUserDirectory()) == 0)
{
temp_writedir = getUserDirectory();
temp_createdir = save_path_full.substr(getUserDirectory().length());
// Strip leading '/' characters from the path we want to create.
size_t startpos = temp_createdir.find_first_not_of('/');
if (startpos != std::string::npos)
temp_createdir = temp_createdir.substr(startpos);
}
// Set either '/' or the user's home as a writable directory.
// (We must create the save folder before mounting it). // (We must create the save folder before mounting it).
if (!PHYSFS_setWriteDir(getDriveRoot(save_path_full).c_str())) if (!PHYSFS_setWriteDir(temp_writedir.c_str()))
return false; return false;
// Create the save folder. (We're now "at" %APPDATA%). // Create the save folder. (We're now "at" either '/' or the user's home).
if (!createDirectory(skipDriveRoot(save_path_full).c_str())) if (!createDirectory(temp_createdir.c_str()))
{ {
// Clear the write directory in case of error. // Clear the write directory in case of error.
PHYSFS_setWriteDir(0); PHYSFS_setWriteDir(nullptr);
return false; return false;
} }
@@ -196,7 +216,7 @@ bool Filesystem::setupWriteDirectory()
// Add the directory. (Will not be readded if already present). // Add the directory. (Will not be readded if already present).
if (!PHYSFS_addToSearchPath(save_path_full.c_str(), 0)) if (!PHYSFS_addToSearchPath(save_path_full.c_str(), 0))
{ {
PHYSFS_setWriteDir(0); // Clear the write directory in case of error. PHYSFS_setWriteDir(nullptr); // Clear the write directory in case of error.
return false; return false;
} }
@@ -332,12 +352,12 @@ const char *Filesystem::getWorkingDirectory()
return cwd.c_str(); return cwd.c_str();
} }
const char *Filesystem::getUserDirectory() std::string Filesystem::getUserDirectory()
{ {
return PHYSFS_getUserDir(); return std::string(PHYSFS_getUserDir());
} }
const char *Filesystem::getAppdataDirectory() std::string Filesystem::getAppdataDirectory()
{ {
#ifdef LOVE_WINDOWS #ifdef LOVE_WINDOWS
if (appdata.empty()) if (appdata.empty())
@@ -346,7 +366,7 @@ const char *Filesystem::getAppdataDirectory()
appdata = to_utf8(w_appdata); appdata = to_utf8(w_appdata);
replace_char(appdata, '\\', '/'); replace_char(appdata, '\\', '/');
} }
return appdata.c_str(); return appdata;
#elif defined(LOVE_MACOSX) #elif defined(LOVE_MACOSX)
if (appdata.empty()) if (appdata.empty())
{ {
@@ -354,7 +374,7 @@ const char *Filesystem::getAppdataDirectory()
udir.append("/Library/Application Support"); udir.append("/Library/Application Support");
appdata = udir; appdata = udir;
} }
return appdata.c_str(); return appdata;
#elif defined(LOVE_LINUX) #elif defined(LOVE_LINUX)
if (appdata.empty()) if (appdata.empty())
{ {
@@ -364,7 +384,7 @@ const char *Filesystem::getAppdataDirectory()
else else
appdata = xdgdatahome; appdata = xdgdatahome;
} }
return appdata.c_str(); return appdata;
#else #else
return getUserDirectory(); return getUserDirectory();
#endif #endif
+2 -2
View File
@@ -145,14 +145,14 @@ public:
/** /**
* Gets the user home directory. * Gets the user home directory.
**/ **/
const char *getUserDirectory(); std::string getUserDirectory();
/** /**
* Gets the APPDATA directory. On Windows, this is the folder * Gets the APPDATA directory. On Windows, this is the folder
* in the %APPDATA% enviroment variable. On Linux, this is the * in the %APPDATA% enviroment variable. On Linux, this is the
* user home folder. * user home folder.
**/ **/
const char *getAppdataDirectory(); std::string getAppdataDirectory();
/** /**
* Gets the full path of the save folder. * Gets the full path of the save folder.
@@ -211,13 +211,13 @@ int w_getWorkingDirectory(lua_State *L)
int w_getUserDirectory(lua_State *L) int w_getUserDirectory(lua_State *L)
{ {
lua_pushstring(L, instance->getUserDirectory()); luax_pushstring(L, instance->getUserDirectory());
return 1; return 1;
} }
int w_getAppdataDirectory(lua_State *L) int w_getAppdataDirectory(lua_State *L)
{ {
lua_pushstring(L, instance->getAppdataDirectory()); luax_pushstring(L, instance->getAppdataDirectory());
return 1; return 1;
} }