QSharedMemory: fix attach() -> create() for non-legacy SystemV mode

The problem with non-legacy mode is that the backend uses the same
filename for the system semaphore file and for the shared memory file.

What happens is that when we try to call attach(), a semaphore is
created. Later in attach() we set unix_key, because ftok() returns
a valid handle (it uses the file which was created for semaphore).
After that, an attempt to actually attach to a shared memory fails, but
no clean-up is done.
So, a later call to create() sees that unix_key is already valid, but
it cannot properly clean it, because it does not actually refer to
any shared memory.

Fix it by cleaning up unix_key and nativeKeyFile if shmget() call in
attach() fails.

Change-Id: Ibccc3ac307d8b2e07e1b9b24b55f97a859a03131
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit e85a3cde2f8aa15eb33f12dc8c52ef660aeb7cc0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ivan Solovev 2023-11-07 11:39:48 +01:00 committed by Qt Cherry-pick Bot
parent fd242e8cec
commit 9f6765897c
2 changed files with 2 additions and 3 deletions

View File

@ -160,6 +160,8 @@ bool QSharedMemorySystemV::attach(QSharedMemoryPrivate *self, QSharedMemory::Acc
int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0400 : 0600)); int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0400 : 0600));
if (-1 == id) { if (-1 == id) {
self->setUnixErrorString("QSharedMemory::attach (shmget)"_L1); self->setUnixErrorString("QSharedMemory::attach (shmget)"_L1);
unix_key = 0;
nativeKeyFile.clear();
return false; return false;
} }

View File

@ -575,9 +575,6 @@ void tst_QSharedMemory::attachBeforeCreate()
const qsizetype sz = 100; const qsizetype sz = 100;
QSharedMemory mem(key); QSharedMemory mem(key);
QVERIFY(!mem.attach()); QVERIFY(!mem.attach());
// Fails for all SystemV backends now
if (!legacy && (keyType < QNativeIpcKey::Type::PosixRealtime))
QEXPECT_FAIL("", "Not fixed yet", Continue);
QVERIFY(mem.create(sz)); QVERIFY(mem.create(sz));
} }