14#if QT_CONFIG(sharedmemory)
15#if QT_CONFIG(posix_shm)
22#include "private/qcore_unix_p.h"
26using namespace Qt::StringLiterals;
27using namespace QtIpcCommon;
29bool QSharedMemoryPosix::runtimeSupportCheck()
31 static const bool result = []() {
32 (
void)shm_open(
"", 0, 0);
33 return errno != ENOSYS;
38bool QSharedMemoryPosix::handle(QSharedMemoryPrivate *self)
41 if (self->nativeKey.isEmpty()) {
42 self->setError(QSharedMemory::KeyError,
43 QSharedMemory::tr(
"%1: key is empty").arg(
"QSharedMemory::handle"_L1));
50bool QSharedMemoryPosix::cleanHandle(QSharedMemoryPrivate *)
59bool QSharedMemoryPosix::create(QSharedMemoryPrivate *self, qsizetype size)
64 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
67 QT_EINTR_LOOP(fd, ::shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL, 0600));
69 const int errorNumber = errno;
70 const auto function =
"QSharedMemory::attach (shm_open)"_L1;
71 switch (errorNumber) {
73 self->setError(QSharedMemory::KeyError,
74 QSharedMemory::tr(
"%1: bad name").arg(function));
77 self->setUnixErrorString(function);
84 QT_EINTR_LOOP(ret, QT_FTRUNCATE(fd, size));
86 self->setUnixErrorString(
"QSharedMemory::create (ftruncate)"_L1);
96bool QSharedMemoryPosix::attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode)
98 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
100 const int oflag = (mode == QSharedMemory::ReadOnly ? O_RDONLY : O_RDWR);
101 const mode_t omode = (mode == QSharedMemory::ReadOnly ? 0400 : 0600);
103 QT_EINTR_LOOP(hand, ::shm_open(shmName.constData(), oflag, omode));
105 const int errorNumber = errno;
106 const auto function =
"QSharedMemory::attach (shm_open)"_L1;
107 switch (errorNumber) {
109 self->setError(QSharedMemory::KeyError,
110 QSharedMemory::tr(
"%1: bad name").arg(function));
113 self->setUnixErrorString(function);
121 if (QT_FSTAT(hand, &st) == -1) {
122 self->setUnixErrorString(
"QSharedMemory::attach (fstat)"_L1);
126 self->size = qsizetype(st.st_size);
129 const int mprot = (mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_READ | PROT_WRITE);
130 self->memory = QT_MMAP(0, size_t(self->size), mprot, MAP_SHARED, hand, 0);
131 if (self->memory == MAP_FAILED || !self->memory) {
132 self->setUnixErrorString(
"QSharedMemory::attach (mmap)"_L1);
143 fcntl(hand, F_ADD_SEALS, F_SEAL_SHRINK);
149bool QSharedMemoryPosix::detach(QSharedMemoryPrivate *self)
152 if (::munmap(self->memory, size_t(self->size)) == -1) {
153 self->setUnixErrorString(
"QSharedMemory::detach (munmap)"_L1);
168 if (QT_FSTAT(hand, &st) == 0) {
170 shm_nattch = st.st_nlink - 2;
176 if (shm_nattch == 0) {
177 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
178 if (::shm_unlink(shmName.constData()) == -1 && errno != ENOENT)
179 self->setUnixErrorString(
"QSharedMemory::detach (shm_unlink)"_L1);