From fc28666946c466212f2cb98707c41ca3a563c033 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 2 Feb 2024 13:32:56 +0100 Subject: [PATCH] Improved creating/attaching shared memory: there is a possibility of a stale shared memory under /tmp. --- src/shared_mem_buffer.cpp | 114 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/src/shared_mem_buffer.cpp b/src/shared_mem_buffer.cpp index c76b0ea..d27ed07 100644 --- a/src/shared_mem_buffer.cpp +++ b/src/shared_mem_buffer.cpp @@ -1,7 +1,13 @@ #include "shared_mem_buffer.h" #include +#include +#include +#include +#include +#include #include +#include #ifdef QT_POSIX_IPC // The POSIX backend can be explicitly selected using the -feature-ipc_posix @@ -9,33 +15,124 @@ // macro will be defined. -> we use SystemV shared memory #error "QT_POSIX_IPC defined" #else -#ifdef __linux__ +#ifdef linux +#include +#include #include // ftok #endif #endif //static bool shdMemFirstUse; +static QString read1stLineOfFile(QString fileName) { // read for instance /etc/os-release + QFile f(fileName); + if (f.exists()) { + if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&f); + in.setCodec("UTF-8"); + while(!in.atEnd()) { + return in.readLine(); + } + } + } + return "N/A"; +} + //QSharedMemory *SharedMemBuffer::getShm(std::size_t size) { QSharedMemory *SharedMem::getShm(std::size_t size) { static QSharedMemory shMem; if (size > 0) { -#ifdef __linux__ - //static const long nativeKey = ftok("/etc/os-release", 'H'); - //static const QString fkey = std::to_string(nativeKey).c_str(); - static const QString fkey = "0123456?000=7"; +#ifdef linux + static const long nativeKey = ftok("/etc/os-release", 'H'); + static const QString fkey = std::to_string(nativeKey).c_str(); + //static const QString fkey = "0123456?000=7"; #else static const QString fkey = "0123456?000=9"; #endif + qCritical() << __func__ << ":" << __LINE__ << ": size" << size; + shMem.setKey(fkey); if (!shMem.isAttached()) { if (shMem.create(size)) { + qCritical() << __func__ << ":" << __LINE__ << ": created shared memory"; + +#ifdef linux + if ((size != (std::size_t)shMem.size()) || (sizeof(SharedMem) != shMem.size())) { + qCritical() << __func__ << ":" << __LINE__ + << "size=" << size + << "shMem.size=" << shMem.size() + << "sizeof(SharedMem)=" << sizeof(SharedMem) + << "ABOUT TO REBOOT SYSTEM..."; + if (system("reboot")) { + // reboot system -> shared memory re-created + } + } + + struct SharedMem *sh = (SharedMem *)(shMem.data()); + + memset(sh->indat_HWversion, 0x00, sizeof(sh->indat_HWversion)); + memset(sh->indat_SWversion, 0x00, sizeof(sh->indat_SWversion)); + + memset(sh->os_release, 0x00, sizeof(sh->os_release)); + memset(sh->date_of_creation, 0x00, sizeof(sh->date_of_creation)); + memset(sh->creator, 0x00, sizeof(sh->creator)); + + QString const &os_release = read1stLineOfFile("/etc/os-release"); + strncpy(sh->os_release, os_release.toStdString().c_str(), + std::min((int)os_release.size(), (int)sizeof(sh->os_release)-1)); + + QString const ¤tDateTime = QDateTime::currentDateTime().toString(Qt::ISODate); + char const *current = currentDateTime.toUtf8().constData(); + strncpy(sh->date_of_creation, current, + std::min((int)strlen(current), (int)sizeof(sh->date_of_creation)-1)); + + QString const &appPid = QString("%1 (%2)").arg(QCoreApplication::applicationName()) + .arg(QCoreApplication::applicationPid()); + + strncpy(sh->creator, appPid.toStdString().c_str(), + std::min((int)strlen(appPid.toStdString().c_str()), + (int)sizeof(sh->creator)-1)); + + qCritical() << "os-release:" << sh->os_release; + qCritical() << " creator:" << sh->creator; + qCritical() << " date:" << sh->date_of_creation; + +#else + Q_ASSERT_X(size != shMem.size(), "compare sizes", "sizes different"); + Q_ASSERT_X(sizeof(SharedMem) != shMem.size(), "compare sizes", "sizes different"); +#endif return &shMem; } else { if (shMem.error() == QSharedMemory::AlreadyExists) { if (shMem.attach()) { +#ifdef linux + if ((size != (std::size_t)shMem.size()) || (sizeof(SharedMem) != shMem.size())) { + qCritical() << __func__ << ":" << __LINE__ + << "size=" << size + << "shMem.size=" << shMem.size() + << "sizeof(SharedMem)=" << sizeof(SharedMem) + << "ABOUT TO REBOOT SYSTEM..."; + if (system("reboot")) { + // reboot system -> shared memory re-created + } + } +#else + Q_ASSERT_X(size != shMem.size(), "compare sizes", "sizes different"); + Q_ASSERT_X(sizeof(SharedMem) != shMem.size(), "compare sizes", "sizes different"); +#endif + + QString const &appPid = QString("%1 (%2)").arg(QCoreApplication::applicationName()) + .arg(QCoreApplication::applicationPid()); + + qCritical() << __func__ << ":" << __LINE__ << appPid << "attached shared memory"; + + struct SharedMem const *sh = (SharedMem const *)(shMem.data()); + qCritical() << "os-release:" << sh->os_release; + qCritical() << " creator:" << sh->creator; + qCritical() << " date:" << sh->date_of_creation; + return &shMem; } } @@ -43,6 +140,13 @@ QSharedMemory *SharedMem::getShm(std::size_t size) { qCritical() << shMem.nativeKey() << shMem.key() << shMem.data() << shMem.error() << shMem.errorString(); return nullptr; + } else { + qCritical() << __func__ << ":" << __LINE__ << "shared memory already attached"; + + struct SharedMem const *sh = (SharedMem const *)(shMem.data()); + qCritical() << "os-release:" << sh->os_release; + qCritical() << " creator:" << sh->creator; + qCritical() << " date:" << sh->date_of_creation; } } return &shMem;