// Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QTIPCCOMMON_P_H #define QTIPCCOMMON_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qtipccommon.h" #include #include #if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore) #if defined(Q_OS_UNIX) # include # include #endif QT_BEGIN_NAMESPACE class QNativeIpcKeyPrivate { public: QString legacyKey_; static QString legacyKey(const QNativeIpcKey &key) { if (key.isSlowPath()) return key.d->legacyKey_; return QString(); } static void setLegacyKey(QNativeIpcKey &key, const QString &legacyKey) { QNativeIpcKeyPrivate::makeExtended(key)->legacyKey_ = legacyKey; } static void setNativeAndLegacyKeys(QNativeIpcKey &key, const QString &nativeKey, const QString &legacyKey) { key.setNativeKey(nativeKey); setLegacyKey(key, legacyKey); } private: static QNativeIpcKeyPrivate *makeExtended(QNativeIpcKey &key) { if (!key.isSlowPath()) key.d = new QNativeIpcKeyPrivate; return key.d; } }; namespace QtIpcCommon { enum class IpcType { SharedMemory, SystemSemaphore }; 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); } template class IpcStorageVariant { template static C extractClass(T C::*); template static T extractObject(T C::*); template static constexpr bool IsEnabled = decltype(extractObject(M))::Enabled; static_assert(std::is_member_object_pointer_v); using StorageType = decltype(extractClass(Member1)); StorageType d; public: template static auto visit_internal(StorageType &storage, QNativeIpcKey::Type keyType, const Lambda &lambda) { if constexpr ((IsEnabled || ... || IsEnabled)) { if constexpr (IsEnabled) { using MemberType1 = decltype(extractObject(Member1)); if (MemberType1::supports(keyType)) return lambda(&(storage.*Member1)); } if constexpr ((... || IsEnabled)) return IpcStorageVariant::visit_internal(storage, keyType, lambda); Q_UNREACHABLE(); } else { // no backends enabled, but we can't return void return false; } } template auto visit(QNativeIpcKey::Type keyType, const Lambda &lambda) { return visit_internal(d, keyType, lambda); } template static auto staticVisit(QNativeIpcKey::Type keyType, const Lambda &lambda) { if constexpr ((IsEnabled || ... || IsEnabled)) { if constexpr (IsEnabled) { using MemberType1 = decltype(extractObject(Member1)); if (MemberType1::supports(keyType)) return lambda(static_cast(nullptr)); } if constexpr ((... || IsEnabled)) return IpcStorageVariant::staticVisit(keyType, lambda); Q_UNREACHABLE(); } else { // no backends enabled, but we can't return void return false; } } }; QNativeIpcKey legacyPlatformSafeKey(const QString &key, IpcType ipcType, QNativeIpcKey::Type type); QNativeIpcKey platformSafeKey(const QString &key, IpcType ipcType, QNativeIpcKey::Type type); #ifdef Q_OS_UNIX // Convenience function to create the file if needed inline int createUnixKeyFile(const QByteArray &fileName) { int fd = qt_safe_open(fileName.constData(), O_EXCL | O_CREAT | O_RDWR, 0640); if (fd < 0) { if (errno == EEXIST) return 0; return -1; } else { close(fd); } return 1; } #endif // Q_OS_UNIX } // namespace QtIpcCommon QT_END_NAMESPACE #endif // QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore) #endif // QTIPCCOMMON_P_H