From f79b535f6b303a77fd9c990118c9bc1a165a0dc1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Oct 2022 19:15:13 -0700 Subject: [PATCH] IPC: use QNativeIpcKey for QtIpcCommon::legacyPlatformSafeKey() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation only has #if now for Apple compatibility; otherwise, we're relying on the QNativeIpcKey::Type parameter, because I intend to allow Unix systems to support both POSIX realtime and System V / XSI shared memory and semaphores. Most of the uses of QtIpcCommon::isIpcSupported() will be constant expressions because they don't depend on the ipcType. Change-Id: I12a088d1ae424825abd3fffd171d38dfb6b5de74 Reviewed-by: MÃ¥rten Nordheim --- src/corelib/ipc/qtipccommon.cpp | 42 ++++++++++++++++++++------------- src/corelib/ipc/qtipccommon_p.h | 30 ++++++++++++++++++++++- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/corelib/ipc/qtipccommon.cpp b/src/corelib/ipc/qtipccommon.cpp index c29de77de4..6f4495fdd5 100644 --- a/src/corelib/ipc/qtipccommon.cpp +++ b/src/corelib/ipc/qtipccommon.cpp @@ -96,28 +96,30 @@ static QNativeIpcKey::Type stringToType(QStringView typeString) On Unix this will be a file name */ -QString QtIpcCommon::legacyPlatformSafeKey(const QString &key, QtIpcCommon::IpcType ipcType) +QString QtIpcCommon::legacyPlatformSafeKey(const QString &key, QtIpcCommon::IpcType ipcType, + QNativeIpcKey::Type type) { if (key.isEmpty()) return QString(); QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex(); -#if defined(Q_OS_DARWIN) && defined(QT_POSIX_IPC) - if (qt_apple_isSandboxed()) { - // Sandboxed applications on Apple platforms require the shared memory name - // to be in the form /. - // Since we don't know which application group identifier the user wants - // to apply, we instead document that requirement, and use the key directly. - return key; - } else { + if (type == QNativeIpcKey::Type::PosixRealtime) { +#if defined(Q_OS_DARWIN) + if (qt_apple_isSandboxed()) { + // Sandboxed applications on Apple platforms require the shared memory name + // to be in the form /. + // Since we don't know which application group identifier the user wants + // to apply, we instead document that requirement, and use the key directly. + return key; + } // The shared memory name limit on Apple platforms is very low (30 characters), // so we can't use the logic below of combining the prefix, key, and a hash, // to ensure a unique and valid name. Instead we use the first part of the // hash, which should still long enough to avoid collisions in practice. return u'/' + hex.left(SHM_NAME_MAX - 1); - } #endif + } QString result; result.reserve(1 + 18 + key.size() + 40); @@ -137,13 +139,21 @@ QString QtIpcCommon::legacyPlatformSafeKey(const QString &key, QtIpcCommon::IpcT } result.append(QLatin1StringView(hex)); -#ifdef Q_OS_WIN - return result; -#elif defined(QT_POSIX_IPC) - return u'/' + result; -#else + switch (type) { + case QNativeIpcKey::Type::Windows: + if (!isIpcSupported(ipcType, QNativeIpcKey::Type::Windows)) + return QString(); + return result; + case QNativeIpcKey::Type::PosixRealtime: + if (!isIpcSupported(ipcType, QNativeIpcKey::Type::PosixRealtime)) + return QString(); + return result.prepend(u'/'); + case QNativeIpcKey::Type::SystemV: + break; + } + if (!isIpcSupported(ipcType, QNativeIpcKey::Type::SystemV)) + return QString(); return QDir::tempPath() + u'/' + result; -#endif } /*! diff --git a/src/corelib/ipc/qtipccommon_p.h b/src/corelib/ipc/qtipccommon_p.h index 223916897a..d4a80068e9 100644 --- a/src/corelib/ipc/qtipccommon_p.h +++ b/src/corelib/ipc/qtipccommon_p.h @@ -15,7 +15,9 @@ // We mean it. // +#include "qtipccommon.h" #include +#include #if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore) @@ -32,7 +34,33 @@ enum class IpcType { SystemSemaphore }; -Q_AUTOTEST_EXPORT QString legacyPlatformSafeKey(const QString &key, IpcType ipcType); +static constexpr bool isIpcSupported(IpcType ipcType, QNativeIpcKey::Type type) +{ + switch (type) { + case QNativeIpcKey::Type::SystemV: + break; + + case QNativeIpcKey::Type::PosixRealtime: + if (ipcType == IpcType::SharedMemory) + return QT_CONFIG(posix_shm); + return QT_CONFIG(posix_sem); + + case QNativeIpcKey::Type::Windows: +#ifdef Q_OS_WIN + return true; +#else + return false; +#endif + } + + if (ipcType == IpcType::SharedMemory) + return QT_CONFIG(sysv_shm); + return QT_CONFIG(sysv_sem); +} + +Q_AUTOTEST_EXPORT QString +legacyPlatformSafeKey(const QString &key, IpcType ipcType, + QNativeIpcKey::Type type = QNativeIpcKey::legacyDefaultTypeForOs()); #ifdef Q_OS_UNIX // Convenience function to create the file if needed