From 2fc5ad143a89acad80e4b1cf99ceeb9d1461c58d Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:04:42 +1300 Subject: [PATCH 01/11] Added USE_IOS(i) and IOS_OR_POSIX(i, p) convenience macros. --- include/mega/types.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/mega/types.h b/include/mega/types.h index 4b9bda1aef..009c9593f1 100644 --- a/include/mega/types.h +++ b/include/mega/types.h @@ -1480,4 +1480,17 @@ class CheckableMutex using detail::CheckableMutex; +// For convenience. +#ifdef USE_IOS + +#define IOS_ONLY(i) i +#define IOS_OR_POSIX(i, p) i + +#else // USE_IOS + +#define IOS_ONLY(i) +#define IOS_OR_POSIX(i, p) p + +#endif // ! USE_IOS + #endif From a5dad74aa200be5919478974429c4e054ab305e9 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:14:07 +1300 Subject: [PATCH 02/11] Added LocalPath::rawValue() accessor function. Present only to reduce the expanding necessity of friend declarations. --- include/mega/filesystem.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/mega/filesystem.h b/include/mega/filesystem.h index ee500d43ba..2a08174954 100644 --- a/include/mega/filesystem.h +++ b/include/mega/filesystem.h @@ -338,6 +338,16 @@ class MEGA_API LocalPath bool operator==(const LocalPath& p) const { return localpath == p.localpath; } bool operator!=(const LocalPath& p) const { return localpath != p.localpath; } bool operator<(const LocalPath& p) const { return localpath < p.localpath; } + + // Try to avoid using this function as much as you can. + // + // It's present for efficiency reasons and is really only meant for + // specific cases when we are using a LocalPath instance in a system + // call. + const string_type& rawValue() const + { + return localpath; + } }; inline std::ostream& operator<<(std::ostream& os, const LocalPath& p) From b6417c27e8063fde4a730108380a6e60657f263e Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:40:33 +1300 Subject: [PATCH 03/11] Added new AdjustBasePath(...) function. --- include/mega/posix/megafs.h | 8 +++ src/posix/fs.cpp | 119 ++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 33 deletions(-) diff --git a/include/mega/posix/megafs.h b/include/mega/posix/megafs.h index 03441f09f6..e8960cba20 100644 --- a/include/mega/posix/megafs.h +++ b/include/mega/posix/megafs.h @@ -44,6 +44,14 @@ #define DEBRISFOLDER ".debris" namespace mega { + +namespace detail { + +auto AdjustBasePath(const LocalPath& path) + -> IOS_OR_POSIX(std::string, const std::string&); + +} // detail + struct MEGA_API PosixDirAccess : public DirAccess { DIR* dp; diff --git a/src/posix/fs.cpp b/src/posix/fs.cpp index 152220d51e..faa8c8a22a 100644 --- a/src/posix/fs.cpp +++ b/src/posix/fs.cpp @@ -110,8 +110,61 @@ extern JavaVM *MEGAjvm; #endif /* __APPLE__ || USE_IOS */ namespace mega { + +namespace detail { + +#ifdef USE_IOS + +static std::string GetBasePath() +{ + static std::string basePath; + static std::once_flag onceOnly; + + // Compute base path as necessary. + std::call_once(onceOnly, []() { + ios_appbasepath(&basePath); + }); + + // Return base path to caller. + return basePath; +} + +auto AdjustBasePath(const LocalPath& path) -> std::string +{ + // Get our hands on the app's base path. + auto basePath = GetBasePath(); + + // No base path. + if (basePath.empty()) + return path.rawValue(); + + // Path is absolute. + if (path.beginsWithSeparator()) + return path.rawValue(); + + // Compute absolute path. + basePath.append(path.rawValue()); + + // Return absolute path to caller. + return basePath; +} + +#else // USE_IOS + +auto AdjustBasePath(const LocalPath& path) -> const std::string& +{ + return path.rawValue(); +} + +#endif // ! USE_IOS + +} // detail + using namespace std; +// Make AdjustBasePath visible in current scope. +using detail::AdjustBasePath; + bool PosixFileAccess::mFoundASymlink = false; void FileSystemAccess::setMinimumDirectoryPermissions(int permissions) @@ -231,10 +284,10 @@ PosixFileAccess::~PosixFileAccess() bool PosixFileAccess::sysstat(m_time_t* mtime, m_off_t* size, FSLogging) { #ifdef USE_IOS - const string nameStr = adjustBasePath(nonblocking_localname); + const string nameStr = AdjustBasePath(nonblocking_localname); #else // use the existing string if it's not iOS, no need for a copy - const string& nameStr = adjustBasePath(nonblocking_localname); + const string& nameStr = AdjustBasePath(nonblocking_localname); #endif struct stat statbuf; @@ -285,13 +338,13 @@ bool PosixFileAccess::sysopen(bool, FSLogging fsl) // this is ok: this is not called with mFollowSymLinks = false, but from transfers doio. // When fully supporting symlinks, this might need to be reassessed - fd = open(adjustBasePath(nonblocking_localname).c_str(), O_RDONLY); + fd = open(AdjustBasePath(nonblocking_localname).c_str(), O_RDONLY); if (fd < 0) { errorcode = errno; if (fsl.doLog(errorcode)) { - LOG_err << "Failed to open('" << adjustBasePath(nonblocking_localname) << "'): error " << errorcode << ": " << PosixFileSystemAccess::getErrorMessage(errorcode); + LOG_err << "Failed to open('" << AdjustBasePath(nonblocking_localname) << "'): error " << errorcode << ": " << PosixFileSystemAccess::getErrorMessage(errorcode); } } @@ -553,10 +606,10 @@ bool PosixFileAccess::fopen(const LocalPath& f, bool read, bool write, FSLogging } #ifdef USE_IOS - const string fstr = adjustBasePath(f); + const string fstr = AdjustBasePath(f); #else // use the existing string if it's not iOS, no need for a copy - const string& fstr = adjustBasePath(f); + const string& fstr = AdjustBasePath(f); #endif @@ -979,12 +1032,12 @@ bool PosixFileSystemAccess::getsname(const LocalPath&, LocalPath&) const bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPath& newname, bool override) { #ifdef USE_IOS - const string oldnamestr = adjustBasePath(oldname); - const string newnamestr = adjustBasePath(newname); + const string oldnamestr = AdjustBasePath(oldname); + const string newnamestr = AdjustBasePath(newname); #else // use the existing string if it's not iOS, no need for a copy - const string& oldnamestr = adjustBasePath(oldname); - const string& newnamestr = adjustBasePath(newname); + const string& oldnamestr = AdjustBasePath(oldname); + const string& newnamestr = AdjustBasePath(newname); #endif bool existingandcare = !override && (0 == access(newnamestr.c_str(), F_OK)); @@ -1009,12 +1062,12 @@ bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPat bool PosixFileSystemAccess::copylocal(const LocalPath& oldname, const LocalPath& newname, m_time_t mtime) { #ifdef USE_IOS - const string oldnamestr = adjustBasePath(oldname); - const string newnamestr = adjustBasePath(newname); + const string oldnamestr = AdjustBasePath(oldname); + const string newnamestr = AdjustBasePath(newname); #else // use the existing string if it's not iOS, no need for a copy - const string& oldnamestr = adjustBasePath(oldname); - const string& newnamestr = adjustBasePath(newname); + const string& oldnamestr = AdjustBasePath(oldname); + const string& newnamestr = AdjustBasePath(newname); #endif int sfd, tfd; @@ -1078,7 +1131,7 @@ bool PosixFileSystemAccess::copylocal(const LocalPath& oldname, const LocalPath& bool PosixFileSystemAccess::unlinklocal(const LocalPath& name) { - if (!unlink(adjustBasePath(name).c_str())) + if (!unlink(AdjustBasePath(name).c_str())) { return true; } @@ -1099,9 +1152,9 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base int removed; struct stat statbuf; #ifdef USE_IOS - const string namestr = adjustBasePath(name); + const string namestr = AdjustBasePath(name); #else - const string& namestr = adjustBasePath(name); + const string& namestr = AdjustBasePath(name); #endif if (!basedev) @@ -1133,10 +1186,10 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base name.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); #ifdef USE_IOS - const string nameStr = adjustBasePath(name); + const string nameStr = AdjustBasePath(name); #else // use the existing string if it's not iOS, no need for a copy - const string& nameStr = adjustBasePath(name); + const string& nameStr = AdjustBasePath(name); #endif if (!lstat(nameStr.c_str(), &statbuf)) { @@ -1195,7 +1248,7 @@ bool PosixFileSystemAccess::rmdirlocal(const LocalPath& name) { emptydirlocal(name); - if (!rmdir(adjustBasePath(name).c_str())) + if (!rmdir(AdjustBasePath(name).c_str())) { return true; } @@ -1208,10 +1261,10 @@ bool PosixFileSystemAccess::rmdirlocal(const LocalPath& name) bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlreadyExistsError) { #ifdef USE_IOS - const string nameStr = adjustBasePath(name); + const string nameStr = AdjustBasePath(name); #else // use the existing string if it's not iOS, no need for a copy - const string& nameStr = adjustBasePath(name); + const string& nameStr = AdjustBasePath(name); #endif mode_t mode = umask(0); @@ -1243,10 +1296,10 @@ bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlre bool PosixFileSystemAccess::setmtimelocal(const LocalPath& name, m_time_t mtime) { #ifdef USE_IOS - const string nameStr = adjustBasePath(name); + const string nameStr = AdjustBasePath(name); #else // use the existing string if it's not iOS, no need for a copy - const string& nameStr = adjustBasePath(name); + const string& nameStr = AdjustBasePath(name); #endif struct utimbuf times = { (time_t)mtime, (time_t)mtime }; @@ -1263,7 +1316,7 @@ bool PosixFileSystemAccess::setmtimelocal(const LocalPath& name, m_time_t mtime) bool PosixFileSystemAccess::chdirlocal(LocalPath& name) const { - return !chdir(adjustBasePath(name).c_str()); + return !chdir(AdjustBasePath(name).c_str()); } // return lowercased ASCII file extension, including the . separator @@ -2296,10 +2349,10 @@ bool PosixFileSystemAccess::fsStableIDs(const LocalPath& path) const bool PosixFileSystemAccess::hardLink(const LocalPath& source, const LocalPath& target) { - using StringType = decltype(adjustBasePath(source)); + using StringType = decltype(AdjustBasePath(source)); - StringType sourcePath = adjustBasePath(source); - StringType targetPath = adjustBasePath(target); + StringType sourcePath = AdjustBasePath(source); + StringType targetPath = AdjustBasePath(target); if (link(sourcePath.c_str(), targetPath.c_str())) { @@ -2448,7 +2501,7 @@ bool PosixDirAccess::dopen(LocalPath* path, FileAccess* f, bool doglob) { if (doglob) { - if (glob(adjustBasePath(*path).c_str(), GLOB_NOSORT, NULL, &globbuf)) + if (glob(AdjustBasePath(*path).c_str(), GLOB_NOSORT, NULL, &globbuf)) { return false; } @@ -2470,7 +2523,7 @@ bool PosixDirAccess::dopen(LocalPath* path, FileAccess* f, bool doglob) } else { - dp = opendir(adjustBasePath(*path).c_str()); + dp = opendir(AdjustBasePath(*path).c_str()); } return dp != NULL; @@ -2514,10 +2567,10 @@ bool PosixDirAccess::dnext(LocalPath& path, LocalPath& name, bool followsymlinks path.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); #ifdef USE_IOS - const string pathStr = adjustBasePath(path); + const string pathStr = AdjustBasePath(path); #else // use the existing string if it's not iOS, no need for a copy - const string& pathStr = adjustBasePath(path); + const string& pathStr = AdjustBasePath(path); #endif bool statOk = !lstat(pathStr.c_str(), &statbuf); @@ -2581,7 +2634,7 @@ m_off_t PosixFileSystemAccess::availableDiskSpace(const LocalPath& drivePath) struct statfs buffer; m_off_t constexpr maximumBytes = std::numeric_limits::max(); - if (statfs(adjustBasePath(drivePath).c_str(), &buffer) < 0) + if (statfs(AdjustBasePath(drivePath).c_str(), &buffer) < 0) { auto result = errno; From d170fda5ad0b5d2ecbb1d0b756ad59c57ad5edd0 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:46:56 +1300 Subject: [PATCH 04/11] Simplify use of AdjustBasePath(...). --- include/mega/posix/megafs.h | 6 ++- src/posix/fs.cpp | 81 ++++++++----------------------------- 2 files changed, 21 insertions(+), 66 deletions(-) diff --git a/include/mega/posix/megafs.h b/include/mega/posix/megafs.h index e8960cba20..76af35d9d0 100644 --- a/include/mega/posix/megafs.h +++ b/include/mega/posix/megafs.h @@ -47,8 +47,10 @@ namespace mega { namespace detail { -auto AdjustBasePath(const LocalPath& path) - -> IOS_OR_POSIX(std::string, const std::string&); +using AdjustBasePathResult = + IOS_OR_POSIX(std::string, const std::string&); + +AdjustBasePathResult AdjustBasePath(const LocalPath& path); } // detail diff --git a/src/posix/fs.cpp b/src/posix/fs.cpp index faa8c8a22a..a7b9daa42d 100644 --- a/src/posix/fs.cpp +++ b/src/posix/fs.cpp @@ -129,7 +129,7 @@ static std::string GetBasePath() return basePath; } -auto AdjustBasePath(const LocalPath& path) -> std::string +AdjustBasePathResult AdjustBasePath(const LocalPath& path) { // Get our hands on the app's base path. auto basePath = GetBasePath(); @@ -151,7 +151,7 @@ auto AdjustBasePath(const LocalPath& path) -> std::string #else // USE_IOS -auto AdjustBasePath(const LocalPath& path) -> const std::string& +AdjustBasePathResult AdjustBasePath(const LocalPath& path) { return path.rawValue(); } @@ -164,6 +164,7 @@ using namespace std; // Make AdjustBasePath visible in current scope. using detail::AdjustBasePath; +using detail::AdjustBasePathResult; bool PosixFileAccess::mFoundASymlink = false; @@ -283,12 +284,7 @@ PosixFileAccess::~PosixFileAccess() bool PosixFileAccess::sysstat(m_time_t* mtime, m_off_t* size, FSLogging) { -#ifdef USE_IOS - const string nameStr = AdjustBasePath(nonblocking_localname); -#else - // use the existing string if it's not iOS, no need for a copy - const string& nameStr = AdjustBasePath(nonblocking_localname); -#endif + AdjustBasePathResult nameStr = AdjustBasePath(nonblocking_localname); struct stat statbuf; retry = false; @@ -605,13 +601,7 @@ bool PosixFileAccess::fopen(const LocalPath& f, bool read, bool write, FSLogging statok = true; } -#ifdef USE_IOS - const string fstr = AdjustBasePath(f); -#else - // use the existing string if it's not iOS, no need for a copy - const string& fstr = AdjustBasePath(f); -#endif - + AdjustBasePathResult fstr = AdjustBasePath(f); #ifdef __MACH__ if (!write) @@ -1031,14 +1021,8 @@ bool PosixFileSystemAccess::getsname(const LocalPath&, LocalPath&) const bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPath& newname, bool override) { -#ifdef USE_IOS - const string oldnamestr = AdjustBasePath(oldname); - const string newnamestr = AdjustBasePath(newname); -#else - // use the existing string if it's not iOS, no need for a copy - const string& oldnamestr = AdjustBasePath(oldname); - const string& newnamestr = AdjustBasePath(newname); -#endif + AdjustBasePathResult oldnamestr = AdjustBasePath(oldname); + AdjustBasePathResult newnamestr = AdjustBasePath(newname); bool existingandcare = !override && (0 == access(newnamestr.c_str(), F_OK)); if (!existingandcare && !rename(oldnamestr.c_str(), newnamestr.c_str())) @@ -1061,14 +1045,8 @@ bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPat bool PosixFileSystemAccess::copylocal(const LocalPath& oldname, const LocalPath& newname, m_time_t mtime) { -#ifdef USE_IOS - const string oldnamestr = AdjustBasePath(oldname); - const string newnamestr = AdjustBasePath(newname); -#else - // use the existing string if it's not iOS, no need for a copy - const string& oldnamestr = AdjustBasePath(oldname); - const string& newnamestr = AdjustBasePath(newname); -#endif + AdjustBasePathResult oldnamestr = AdjustBasePath(oldname); + AdjustBasePathResult newnamestr = AdjustBasePath(newname); int sfd, tfd; ssize_t t = -1; @@ -1151,11 +1129,7 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base dirent* d; int removed; struct stat statbuf; -#ifdef USE_IOS - const string namestr = AdjustBasePath(name); -#else - const string& namestr = AdjustBasePath(name); -#endif + AdjustBasePathResult namestr = AdjustBasePath(name); if (!basedev) { @@ -1185,12 +1159,8 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base name.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); -#ifdef USE_IOS - const string nameStr = AdjustBasePath(name); -#else - // use the existing string if it's not iOS, no need for a copy - const string& nameStr = AdjustBasePath(name); -#endif + AdjustBasePathResult nameStr = AdjustBasePath(name); + if (!lstat(nameStr.c_str(), &statbuf)) { if (!S_ISLNK(statbuf.st_mode) && S_ISDIR(statbuf.st_mode) && statbuf.st_dev == basedev) @@ -1260,12 +1230,7 @@ bool PosixFileSystemAccess::rmdirlocal(const LocalPath& name) bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlreadyExistsError) { -#ifdef USE_IOS - const string nameStr = AdjustBasePath(name); -#else - // use the existing string if it's not iOS, no need for a copy - const string& nameStr = AdjustBasePath(name); -#endif + AdjustBasePathResult nameStr = AdjustBasePath(name); mode_t mode = umask(0); bool r = !mkdir(nameStr.c_str(), defaultfolderpermissions); @@ -1295,12 +1260,7 @@ bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlre bool PosixFileSystemAccess::setmtimelocal(const LocalPath& name, m_time_t mtime) { -#ifdef USE_IOS - const string nameStr = AdjustBasePath(name); -#else - // use the existing string if it's not iOS, no need for a copy - const string& nameStr = AdjustBasePath(name); -#endif + AdjustBasePathResult nameStr = AdjustBasePath(name); struct utimbuf times = { (time_t)mtime, (time_t)mtime }; @@ -2349,10 +2309,8 @@ bool PosixFileSystemAccess::fsStableIDs(const LocalPath& path) const bool PosixFileSystemAccess::hardLink(const LocalPath& source, const LocalPath& target) { - using StringType = decltype(AdjustBasePath(source)); - - StringType sourcePath = AdjustBasePath(source); - StringType targetPath = AdjustBasePath(target); + AdjustBasePathResult sourcePath = AdjustBasePath(source); + AdjustBasePathResult targetPath = AdjustBasePath(target); if (link(sourcePath.c_str(), targetPath.c_str())) { @@ -2566,12 +2524,7 @@ bool PosixDirAccess::dnext(LocalPath& path, LocalPath& name, bool followsymlinks { path.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); -#ifdef USE_IOS - const string pathStr = AdjustBasePath(path); -#else - // use the existing string if it's not iOS, no need for a copy - const string& pathStr = AdjustBasePath(path); -#endif + AdjustBasePathResult pathStr = AdjustBasePath(path); bool statOk = !lstat(pathStr.c_str(), &statbuf); if (followsymlinks && statOk && S_ISLNK(statbuf.st_mode)) From fc1b2cde811f79a982027513aebfc45b66091c57 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:48:12 +1300 Subject: [PATCH 05/11] Remove old adjustBasePath(...) code. --- include/mega/posix/megafs.h | 4 ---- src/posix/fs.cpp | 41 ------------------------------------- 2 files changed, 45 deletions(-) diff --git a/include/mega/posix/megafs.h b/include/mega/posix/megafs.h index 76af35d9d0..d55e57c755 100644 --- a/include/mega/posix/megafs.h +++ b/include/mega/posix/megafs.h @@ -76,10 +76,6 @@ class MEGA_API PosixFileSystemAccess : public FileSystemAccess public: using FileSystemAccess::getlocalfstype; -#ifdef USE_IOS - static char *appbasepath; -#endif - int defaultfilepermissions; int defaultfolderpermissions; diff --git a/src/posix/fs.cpp b/src/posix/fs.cpp index a7b9daa42d..99a84d217b 100644 --- a/src/posix/fs.cpp +++ b/src/posix/fs.cpp @@ -178,34 +178,6 @@ void FileSystemAccess::setMinimumFilePermissions(int permissions) mMinimumFilePermissions = permissions & 07777; } -#ifdef USE_IOS - -const string adjustBasePath(const LocalPath& name) -{ - // return a temporary variable that the caller can optionally use c_str on (in that expression) - if (PosixFileSystemAccess::appbasepath) - { - if (!name.beginsWithSeparator()) - { - string absolutename = PosixFileSystemAccess::appbasepath; - absolutename.append(name.localpath); - return absolutename; - } - } - return name.localpath; -} - -char* PosixFileSystemAccess::appbasepath = nullptr; - -#else /* USE_IOS */ - -const string& adjustBasePath(const LocalPath& name) -{ - return name.localpath; -} - -#endif /* ! USE_IOS */ - int platformCompareUtf(const string& p1, bool unescape1, const string& p2, bool unescape2) { return compareUtf(p1, unescape1, p2, unescape2, false); @@ -801,19 +773,6 @@ PosixFileSystemAccess::PosixFileSystemAccess() defaultfilepermissions = 0600; defaultfolderpermissions = 0700; - -#ifdef USE_IOS - if (!appbasepath) - { - string basepath; - ios_appbasepath(&basepath); - if (basepath.size()) - { - basepath.append("/"); - appbasepath = strdup(basepath.c_str()); - } - } -#endif } #ifdef __linux__ From fb1939211561b94d1c4190a444cfad9fa1d9c3f6 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 09:55:16 +1300 Subject: [PATCH 06/11] Don't use Disk Arbitration on iOS. --- src/osx/fs.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/osx/fs.cpp b/src/osx/fs.cpp index 87ce781646..50eac835b0 100644 --- a/src/osx/fs.cpp +++ b/src/osx/fs.cpp @@ -1,7 +1,10 @@ #include #include -#include +// Disk Arbitration is not available on iOS. +#ifndef USE_IOS +# include +#endif // ! USE_IOS #include #include @@ -117,6 +120,8 @@ static DeviceOfResult deviceOf(const std::string& path) return result; } +#ifndef USE_IOS + static std::string uuidOf(const std::string& device) { // Convenience. @@ -230,21 +235,33 @@ static std::string uuidOf(const std::string& device) return std::string(); } +#endif // ! USE_IOS + fsfp_t FileSystemAccess::fsFingerprint(const LocalPath& path) const { - auto device = deviceOf(path.localpath); + // Convenience. + using detail::AdjustBasePath; + + // What device contains path? + auto device = deviceOf(AdjustBasePath(path)); // Couldn't determine which device contains path. if (device.first.empty()) return fsfp_t(); + std::string uuid; + +#ifndef USE_IOS + // Try and determine the device's UUID. - auto uuid = uuidOf(device.first); + uuid = uuidOf(device.first); // Couldn't determine UUID. if (uuid.empty()) return fsfp_t(); +#endif // ! USE_IOS + // Return fingerprint to caller. return fsfp_t(device.second, std::move(uuid)); } From fd19485dc616f65ad40221da9563808ad98ae917 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 12:34:15 +1300 Subject: [PATCH 07/11] Fix iOS compilation failure. --- src/osx/fs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/osx/fs.cpp b/src/osx/fs.cpp index 50eac835b0..a024be09cf 100644 --- a/src/osx/fs.cpp +++ b/src/osx/fs.cpp @@ -1,16 +1,16 @@ #include #include -// Disk Arbitration is not available on iOS. -#ifndef USE_IOS -# include -#endif // ! USE_IOS - #include #include #include "mega.h" +// Disk Arbitration is not available on iOS. +#ifndef USE_IOS +# include +#endif // ! USE_IOS + namespace mega { // Convenience. From f8569fbe31fc62285e8c22f672b25ffedccb0bfe Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 12:34:55 +1300 Subject: [PATCH 08/11] adjustBasePath(...) no longer needs to be friends with LocalPath. --- include/mega/filesystem.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/mega/filesystem.h b/include/mega/filesystem.h index 2a08174954..0948162b86 100644 --- a/include/mega/filesystem.h +++ b/include/mega/filesystem.h @@ -198,11 +198,7 @@ class MEGA_API LocalPath friend void AddHiddenFileAttribute(LocalPath& path); friend class GfxProviderFreeImage; friend struct FileSystemAccess; -#ifdef USE_IOS - friend const string adjustBasePath(const LocalPath& name); -#else - friend const string& adjustBasePath(const LocalPath& name); -#endif + friend int compareUtf(const string&, bool unescaping1, const string&, bool unescaping2, bool caseInsensitive); friend int compareUtf(const string&, bool unescaping1, const LocalPath&, bool unescaping2, bool caseInsensitive); friend int compareUtf(const LocalPath&, bool unescaping1, const string&, bool unescaping2, bool caseInsensitive); From bb4a98a995322a325e66d50ef957edd7f52f33aa Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 12:38:10 +1300 Subject: [PATCH 09/11] Rename AdjustBasePath -> adjustBasePath. --- include/mega/posix/megafs.h | 2 +- src/osx/fs.cpp | 4 ++-- src/posix/fs.cpp | 48 ++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/mega/posix/megafs.h b/include/mega/posix/megafs.h index d55e57c755..6241a835f3 100644 --- a/include/mega/posix/megafs.h +++ b/include/mega/posix/megafs.h @@ -50,7 +50,7 @@ namespace detail { using AdjustBasePathResult = IOS_OR_POSIX(std::string, const std::string&); -AdjustBasePathResult AdjustBasePath(const LocalPath& path); +AdjustBasePathResult adjustBasePath(const LocalPath& path); } // detail diff --git a/src/osx/fs.cpp b/src/osx/fs.cpp index a024be09cf..a2d88ce8c9 100644 --- a/src/osx/fs.cpp +++ b/src/osx/fs.cpp @@ -240,10 +240,10 @@ static std::string uuidOf(const std::string& device) fsfp_t FileSystemAccess::fsFingerprint(const LocalPath& path) const { // Convenience. - using detail::AdjustBasePath; + using detail::adjustBasePath; // What device contains path? - auto device = deviceOf(AdjustBasePath(path)); + auto device = deviceOf(adjustBasePath(path)); // Couldn't determine which device contains path. if (device.first.empty()) diff --git a/src/posix/fs.cpp b/src/posix/fs.cpp index 99a84d217b..2a574e91f7 100644 --- a/src/posix/fs.cpp +++ b/src/posix/fs.cpp @@ -129,7 +129,7 @@ static std::string GetBasePath() return basePath; } -AdjustBasePathResult AdjustBasePath(const LocalPath& path) +AdjustBasePathResult adjustBasePath(const LocalPath& path) { // Get our hands on the app's base path. auto basePath = GetBasePath(); @@ -151,7 +151,7 @@ AdjustBasePathResult AdjustBasePath(const LocalPath& path) #else // USE_IOS -AdjustBasePathResult AdjustBasePath(const LocalPath& path) +AdjustBasePathResult adjustBasePath(const LocalPath& path) { return path.rawValue(); } @@ -163,7 +163,7 @@ AdjustBasePathResult AdjustBasePath(const LocalPath& path) using namespace std; // Make AdjustBasePath visible in current scope. -using detail::AdjustBasePath; +using detail::adjustBasePath; using detail::AdjustBasePathResult; bool PosixFileAccess::mFoundASymlink = false; @@ -256,7 +256,7 @@ PosixFileAccess::~PosixFileAccess() bool PosixFileAccess::sysstat(m_time_t* mtime, m_off_t* size, FSLogging) { - AdjustBasePathResult nameStr = AdjustBasePath(nonblocking_localname); + AdjustBasePathResult nameStr = adjustBasePath(nonblocking_localname); struct stat statbuf; retry = false; @@ -306,13 +306,13 @@ bool PosixFileAccess::sysopen(bool, FSLogging fsl) // this is ok: this is not called with mFollowSymLinks = false, but from transfers doio. // When fully supporting symlinks, this might need to be reassessed - fd = open(AdjustBasePath(nonblocking_localname).c_str(), O_RDONLY); + fd = open(adjustBasePath(nonblocking_localname).c_str(), O_RDONLY); if (fd < 0) { errorcode = errno; if (fsl.doLog(errorcode)) { - LOG_err << "Failed to open('" << AdjustBasePath(nonblocking_localname) << "'): error " << errorcode << ": " << PosixFileSystemAccess::getErrorMessage(errorcode); + LOG_err << "Failed to open('" << adjustBasePath(nonblocking_localname) << "'): error " << errorcode << ": " << PosixFileSystemAccess::getErrorMessage(errorcode); } } @@ -573,7 +573,7 @@ bool PosixFileAccess::fopen(const LocalPath& f, bool read, bool write, FSLogging statok = true; } - AdjustBasePathResult fstr = AdjustBasePath(f); + AdjustBasePathResult fstr = adjustBasePath(f); #ifdef __MACH__ if (!write) @@ -980,8 +980,8 @@ bool PosixFileSystemAccess::getsname(const LocalPath&, LocalPath&) const bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPath& newname, bool override) { - AdjustBasePathResult oldnamestr = AdjustBasePath(oldname); - AdjustBasePathResult newnamestr = AdjustBasePath(newname); + AdjustBasePathResult oldnamestr = adjustBasePath(oldname); + AdjustBasePathResult newnamestr = adjustBasePath(newname); bool existingandcare = !override && (0 == access(newnamestr.c_str(), F_OK)); if (!existingandcare && !rename(oldnamestr.c_str(), newnamestr.c_str())) @@ -1004,8 +1004,8 @@ bool PosixFileSystemAccess::renamelocal(const LocalPath& oldname, const LocalPat bool PosixFileSystemAccess::copylocal(const LocalPath& oldname, const LocalPath& newname, m_time_t mtime) { - AdjustBasePathResult oldnamestr = AdjustBasePath(oldname); - AdjustBasePathResult newnamestr = AdjustBasePath(newname); + AdjustBasePathResult oldnamestr = adjustBasePath(oldname); + AdjustBasePathResult newnamestr = adjustBasePath(newname); int sfd, tfd; ssize_t t = -1; @@ -1068,7 +1068,7 @@ bool PosixFileSystemAccess::copylocal(const LocalPath& oldname, const LocalPath& bool PosixFileSystemAccess::unlinklocal(const LocalPath& name) { - if (!unlink(AdjustBasePath(name).c_str())) + if (!unlink(adjustBasePath(name).c_str())) { return true; } @@ -1088,7 +1088,7 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base dirent* d; int removed; struct stat statbuf; - AdjustBasePathResult namestr = AdjustBasePath(name); + AdjustBasePathResult namestr = adjustBasePath(name); if (!basedev) { @@ -1118,7 +1118,7 @@ void PosixFileSystemAccess::emptydirlocal(const LocalPath& nameParam, dev_t base name.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); - AdjustBasePathResult nameStr = AdjustBasePath(name); + AdjustBasePathResult nameStr = adjustBasePath(name); if (!lstat(nameStr.c_str(), &statbuf)) { @@ -1177,7 +1177,7 @@ bool PosixFileSystemAccess::rmdirlocal(const LocalPath& name) { emptydirlocal(name); - if (!rmdir(AdjustBasePath(name).c_str())) + if (!rmdir(adjustBasePath(name).c_str())) { return true; } @@ -1189,7 +1189,7 @@ bool PosixFileSystemAccess::rmdirlocal(const LocalPath& name) bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlreadyExistsError) { - AdjustBasePathResult nameStr = AdjustBasePath(name); + AdjustBasePathResult nameStr = adjustBasePath(name); mode_t mode = umask(0); bool r = !mkdir(nameStr.c_str(), defaultfolderpermissions); @@ -1219,7 +1219,7 @@ bool PosixFileSystemAccess::mkdirlocal(const LocalPath& name, bool, bool logAlre bool PosixFileSystemAccess::setmtimelocal(const LocalPath& name, m_time_t mtime) { - AdjustBasePathResult nameStr = AdjustBasePath(name); + AdjustBasePathResult nameStr = adjustBasePath(name); struct utimbuf times = { (time_t)mtime, (time_t)mtime }; @@ -1235,7 +1235,7 @@ bool PosixFileSystemAccess::setmtimelocal(const LocalPath& name, m_time_t mtime) bool PosixFileSystemAccess::chdirlocal(LocalPath& name) const { - return !chdir(AdjustBasePath(name).c_str()); + return !chdir(adjustBasePath(name).c_str()); } // return lowercased ASCII file extension, including the . separator @@ -2268,8 +2268,8 @@ bool PosixFileSystemAccess::fsStableIDs(const LocalPath& path) const bool PosixFileSystemAccess::hardLink(const LocalPath& source, const LocalPath& target) { - AdjustBasePathResult sourcePath = AdjustBasePath(source); - AdjustBasePathResult targetPath = AdjustBasePath(target); + AdjustBasePathResult sourcePath = adjustBasePath(source); + AdjustBasePathResult targetPath = adjustBasePath(target); if (link(sourcePath.c_str(), targetPath.c_str())) { @@ -2418,7 +2418,7 @@ bool PosixDirAccess::dopen(LocalPath* path, FileAccess* f, bool doglob) { if (doglob) { - if (glob(AdjustBasePath(*path).c_str(), GLOB_NOSORT, NULL, &globbuf)) + if (glob(adjustBasePath(*path).c_str(), GLOB_NOSORT, NULL, &globbuf)) { return false; } @@ -2440,7 +2440,7 @@ bool PosixDirAccess::dopen(LocalPath* path, FileAccess* f, bool doglob) } else { - dp = opendir(AdjustBasePath(*path).c_str()); + dp = opendir(adjustBasePath(*path).c_str()); } return dp != NULL; @@ -2483,7 +2483,7 @@ bool PosixDirAccess::dnext(LocalPath& path, LocalPath& name, bool followsymlinks { path.appendWithSeparator(LocalPath::fromPlatformEncodedRelative(d->d_name), true); - AdjustBasePathResult pathStr = AdjustBasePath(path); + AdjustBasePathResult pathStr = adjustBasePath(path); bool statOk = !lstat(pathStr.c_str(), &statbuf); if (followsymlinks && statOk && S_ISLNK(statbuf.st_mode)) @@ -2546,7 +2546,7 @@ m_off_t PosixFileSystemAccess::availableDiskSpace(const LocalPath& drivePath) struct statfs buffer; m_off_t constexpr maximumBytes = std::numeric_limits::max(); - if (statfs(AdjustBasePath(drivePath).c_str(), &buffer) < 0) + if (statfs(adjustBasePath(drivePath).c_str(), &buffer) < 0) { auto result = errno; From b13342e4317eb9b8c091065cd0758aaea980f80c Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 12:45:46 +1300 Subject: [PATCH 10/11] Add uuidOf(...) stub for iOS. --- src/osx/fs.cpp | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/osx/fs.cpp b/src/osx/fs.cpp index a2d88ce8c9..ea2b634303 100644 --- a/src/osx/fs.cpp +++ b/src/osx/fs.cpp @@ -120,9 +120,13 @@ static DeviceOfResult deviceOf(const std::string& path) return result; } +// Convenience. +using UUIDOfResult = + std::pair; + #ifndef USE_IOS -static std::string uuidOf(const std::string& device) +static UUIDOfResult uuidOf(const std::string& device) { // Convenience. using DictionaryPtr = CFPtr; @@ -137,7 +141,7 @@ static std::string uuidOf(const std::string& device) // Couldn't establish DA session. if (!session) - return std::string(); + return UUIDOfResult("", false); // Try and get a reference to the specified device. DiskPtr disk(DADiskCreateFromBSDName(allocator, @@ -146,14 +150,14 @@ static std::string uuidOf(const std::string& device) // Couldn't get a reference to the device. if (!disk) - return std::string(); + return UUIDOfResult("", false); // Try and get the device's description. DictionaryPtr info(DADiskCopyDescription(disk.get())); // Couldn't get device's description. if (!info) - return std::string(); + return UUIDOfResult("", false); // What UUIDs do we want to retrieve? static const std::vector names = { @@ -177,7 +181,7 @@ static std::string uuidOf(const std::string& device) // Couldn't create key. if (!key) - return std::string(); + return UUIDOfResult("", false); // Try and retrieve UUID associated with key. auto uuid = ([&]() { @@ -201,7 +205,7 @@ static std::string uuidOf(const std::string& device) // Try and retrieve the string's raw value. if (auto* value = CFStringGetCStringPtr(string.get(), encoding)) - return value; + return UUIDOfResult(value, true); // Compute necessary buffer length. auto required = @@ -228,14 +232,21 @@ static std::string uuidOf(const std::string& device) buffer.resize(static_cast(required)); // Return UUID to caller. - return buffer; + return UUIDOfResult(std::move(buffer), true); } // Couldn't retrieve UUID. - return std::string(); + return UUIDOfResult("", false); } -#endif // ! USE_IOS +#else // ! USE_IOS + +static UUIDOfResult uuidOf(const std::string&) +{ + return UUIDOfResult("", true); +} + +#endif // USE_IOS fsfp_t FileSystemAccess::fsFingerprint(const LocalPath& path) const { @@ -249,21 +260,15 @@ fsfp_t FileSystemAccess::fsFingerprint(const LocalPath& path) const if (device.first.empty()) return fsfp_t(); - std::string uuid; - -#ifndef USE_IOS - // Try and determine the device's UUID. - uuid = uuidOf(device.first); + auto uuid = uuidOf(device.first); // Couldn't determine UUID. - if (uuid.empty()) + if (!uuid.second) return fsfp_t(); -#endif // ! USE_IOS - // Return fingerprint to caller. - return fsfp_t(device.second, std::move(uuid)); + return fsfp_t(device.second, std::move(uuid.first)); } MacFileSystemAccess::MacFileSystemAccess() From 5a66f2a7ca2ce9d72d3032ddbb51d2098c232a40 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 23 Nov 2023 13:01:15 +1300 Subject: [PATCH 11/11] CG GFXProc now uses adjustBasePath(...). --- src/gfx/GfxProcCG.mm | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/gfx/GfxProcCG.mm b/src/gfx/GfxProcCG.mm index a6ba9fcca2..e901ae06bd 100644 --- a/src/gfx/GfxProcCG.mm +++ b/src/gfx/GfxProcCG.mm @@ -55,17 +55,20 @@ return NULL; } -bool GfxProviderCG::readbitmap(FileSystemAccess* fa, const LocalPath& name, int size) { - string absolutename; - NSString *sourcePath; - if (PosixFileSystemAccess::appbasepath && !name.beginsWithSeparator()) { - absolutename = PosixFileSystemAccess::appbasepath; - absolutename.append(name.platformEncoded()); - sourcePath = [NSString stringWithCString:absolutename.c_str() encoding:[NSString defaultCStringEncoding]]; - } else { - sourcePath = [NSString stringWithCString:name.platformEncoded().c_str() encoding:[NSString defaultCStringEncoding]]; - } - +bool GfxProviderCG::readbitmap(FileSystemAccess* fa, const LocalPath& path, int size) { + // Convenience. + using mega::detail::AdjustBasePathResult; + using mega::detail::adjustBasePath; + + // Ensure provided path is absolute. + AdjustBasePathResult absolutePath = adjustBasePath(path); + + // Make absolute path usable to Cocoa. + NSString* sourcePath = + [NSString stringWithCString: absolutePath.c_str() + encoding: [NSString defaultCStringEncoding]]; + + // Couldn't create a Cocoa-friendly path. if (sourcePath == nil) { return false; }