Skip to content

Commit

Permalink
IPC: use QNativeIpcKey for QtIpcCommon::legacyPlatformSafeKey()
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
thiagomacieira committed Jan 22, 2023
1 parent 7a37083 commit f79b535
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 17 deletions.
42 changes: 26 additions & 16 deletions src/corelib/ipc/qtipccommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <application group identifier>/<custom identifier>.
// 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 <application group identifier>/<custom identifier>.
// 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);
Expand All @@ -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
}

/*!
Expand Down
30 changes: 29 additions & 1 deletion src/corelib/ipc/qtipccommon_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
// We mean it.
//

#include "qtipccommon.h"
#include <private/qglobal_p.h>
#include <private/qtcore-config_p.h>

#if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)

Expand All @@ -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
Expand Down

0 comments on commit f79b535

Please sign in to comment.