From 629fc1c581d6bff49b5c4b31d83f53887feff63c Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Sat, 27 Apr 2024 12:38:30 +0800 Subject: [PATCH] Android: Use mode a+rwx for directories and a+rw for files in external storage path. Issue love2d/love-android#269. --- src/common/android.cpp | 26 +++++++++++++++----- src/common/android.h | 2 +- src/modules/filesystem/Filesystem.cpp | 16 +++++++++++- src/modules/filesystem/physfs/File.cpp | 2 +- src/modules/filesystem/physfs/Filesystem.cpp | 2 +- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/common/android.cpp b/src/common/android.cpp index e659f592d..9022e5234 100644 --- a/src/common/android.cpp +++ b/src/common/android.cpp @@ -175,10 +175,24 @@ bool directoryExists(const char *path) bool mkdir(const char *path) { - int err = ::mkdir(path, 0770); + int err = ::mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID); if (err == -1) { - SDL_Log("Error: Could not create directory %s", path); + const char *error = strerror(errno); + SDL_Log("Error: Could not create directory '%s': %s", path, error); + return false; + } + + return true; +} + +bool chmod(const char *path, int mode) +{ + int err = ::chmod(path, mode); + if (err == -1) + { + const char *error = strerror(errno); + SDL_Log("Error: Could not change mode '%s': %s", path, error); return false; } @@ -216,11 +230,11 @@ bool createStorageDirectories() return true; } -void fixupPermissionSingleFile(const std::string &savedir, const std::string &path) +void fixupPermissionSingleFile(const std::string &savedir, const std::string &path, int mode) { std::string fixedSavedir = savedir.back() == '/' ? savedir : (savedir + "/"); std::string target = fixedSavedir + path; - ::chmod(target.c_str(), 0660); + ::chmod(target.c_str(), mode); } void fixupExternalStoragePermission(const std::string &savedir, const std::string &path) @@ -242,7 +256,7 @@ void fixupExternalStoragePermission(const std::string &savedir, const std::strin } std::string fixedSavedir = savedir.back() == '/' ? savedir : (savedir + "/"); - ::chmod(savedir.c_str(), 0770); + chmod(savedir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID); for (const std::string &dir: pathsToFix) { @@ -250,7 +264,7 @@ void fixupExternalStoragePermission(const std::string &savedir, const std::strin if (!dir.empty() && strcmp(realPath, savedir.c_str()) == 0) { std::string target = fixedSavedir + dir; - ::chmod(target.c_str(), 0770); + chmod(target.c_str(), S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID); } } } diff --git a/src/common/android.h b/src/common/android.h index ef597908c..606327f29 100644 --- a/src/common/android.h +++ b/src/common/android.h @@ -65,7 +65,7 @@ bool mkdir(const char *path); bool createStorageDirectories(); -void fixupPermissionSingleFile(const std::string &savedir, const std::string &path); +void fixupPermissionSingleFile(const std::string &savedir, const std::string &path, int mode = 0666); void fixupExternalStoragePermission(const std::string &savedir, const std::string &path); diff --git a/src/modules/filesystem/Filesystem.cpp b/src/modules/filesystem/Filesystem.cpp index 026209c41..233e95a24 100644 --- a/src/modules/filesystem/Filesystem.cpp +++ b/src/modules/filesystem/Filesystem.cpp @@ -133,7 +133,21 @@ static bool createDirectoryRaw(const std::string &path) std::wstring wpath = to_widestr(path); return CreateDirectoryW(wpath.c_str(), nullptr) != 0; #else - return mkdir(path.c_str(), S_IRWXU) == 0; + int mode = S_IRWXU; + +#ifdef LOVE_ANDROID + // Need to create save directory with ugo+rwx and setgid bit if + // t.externalstorage is set and it's for save directory. + auto fs = Module::getInstance(Module::M_FILESYSTEM); + if (fs != nullptr && fs->isAndroidSaveExternal()) + { + const std::string &savedir = fs->getFullCommonPath(Filesystem::COMMONPATH_APP_SAVEDIR); + if (path.rfind(savedir, 0) == 0) + mode |= S_IRWXG | S_IRWXO | S_ISGID; + } +#endif + + return mkdir(path.c_str(), mode) == 0; #endif } diff --git a/src/modules/filesystem/physfs/File.cpp b/src/modules/filesystem/physfs/File.cpp index 373c7f0d7..a656287c3 100644 --- a/src/modules/filesystem/physfs/File.cpp +++ b/src/modules/filesystem/physfs/File.cpp @@ -57,7 +57,7 @@ File::File(const std::string &filename, Mode mode) #ifdef LOVE_ANDROID // In Android with t.externalstorage = true, make sure the file opened or - // created in the save directory has permissions of ug+rw (0660) so that + // created in the save directory has permissions of ugo+rw (0666) so that // it's accessible through MTP. auto fs = Module::getInstance(Module::M_FILESYSTEM); if (fs != nullptr && fs->isAndroidSaveExternal()) diff --git a/src/modules/filesystem/physfs/Filesystem.cpp b/src/modules/filesystem/physfs/Filesystem.cpp index 230b64104..99a1beb55 100644 --- a/src/modules/filesystem/physfs/Filesystem.cpp +++ b/src/modules/filesystem/physfs/Filesystem.cpp @@ -803,7 +803,7 @@ bool Filesystem::createDirectory(const char *dir) #ifdef LOVE_ANDROID // In Android with t.externalstorage = true, make sure the directory - // created in the save directory has permissions of ug+rwx (0770) so that + // created in the save directory has permissions of ugo+rwx (0777) so that // it's accessible through MTP. if (isAndroidSaveExternal()) love::android::fixupExternalStoragePermission(