14#if QT_CONFIG(sharedmemory)
15#if QT_CONFIG(posix_shm)
22#include "private/qcore_unix_p.h"
30using namespace Qt::StringLiterals;
31using namespace QtIpcCommon;
33bool QSharedMemoryPosix::runtimeSupportCheck()
35 static const bool result = []() {
36 (
void)shm_open(
"", 0, 0);
37 return errno != ENOSYS;
42bool QSharedMemoryPosix::handle(QSharedMemoryPrivate *self)
45 if (self->nativeKey.isEmpty()) {
46 self->setError(QSharedMemory::KeyError,
47 QSharedMemory::tr(
"%1: key is empty").arg(
"QSharedMemory::handle"_L1));
54bool QSharedMemoryPosix::cleanHandle(QSharedMemoryPrivate *)
63bool QSharedMemoryPosix::create(QSharedMemoryPrivate *self, qsizetype size)
68 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
71 QT_EINTR_LOOP(fd, ::shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0600));
73 const int errorNumber = errno;
74 const auto function =
"QSharedMemory::attach (shm_open)"_L1;
75 switch (errorNumber) {
77 self->setError(QSharedMemory::KeyError,
78 QSharedMemory::tr(
"%1: bad name").arg(function));
81 self->setUnixErrorString(function);
88 QT_EINTR_LOOP(ret, QT_FTRUNCATE(fd, size));
90 self->setUnixErrorString(
"QSharedMemory::create (ftruncate)"_L1);
100bool QSharedMemoryPosix::attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode)
102 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
104 const int oflag = (mode == QSharedMemory::ReadOnly ? O_RDONLY : O_RDWR);
105 const mode_t omode = (mode == QSharedMemory::ReadOnly ? 0400 : 0600);
107 QT_EINTR_LOOP(hand, ::shm_open(shmName.constData(), oflag | O_CLOEXEC, omode));
109 const int errorNumber = errno;
110 const auto function =
"QSharedMemory::attach (shm_open)"_L1;
111 switch (errorNumber) {
113 self->setError(QSharedMemory::KeyError,
114 QSharedMemory::tr(
"%1: bad name").arg(function));
117 self->setUnixErrorString(function);
125 if (QT_FSTAT(hand, &st) == -1) {
126 self->setUnixErrorString(
"QSharedMemory::attach (fstat)"_L1);
130 self->size = qsizetype(st.st_size);
133 const int mprot = (mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_READ | PROT_WRITE);
134 self->memory = QT_MMAP(0, size_t(self->size), mprot, MAP_SHARED, hand, 0);
135 if (self->memory == MAP_FAILED || !self->memory) {
136 self->setUnixErrorString(
"QSharedMemory::attach (mmap)"_L1);
147 fcntl(hand, F_ADD_SEALS, F_SEAL_SHRINK);
153bool QSharedMemoryPosix::detach(QSharedMemoryPrivate *self)
156 if (::munmap(self->memory, size_t(self->size)) == -1) {
157 self->setUnixErrorString(
"QSharedMemory::detach (munmap)"_L1);
172 if (QT_FSTAT(hand, &st) == 0) {
174 shm_nattch = st.st_nlink - 2;
180 if (shm_nattch == 0) {
181 const QByteArray shmName = QFile::encodeName(self->nativeKey.nativeKey());
182 if (::shm_unlink(shmName.constData()) == -1 && errno != ENOENT)
183 self->setUnixErrorString(
"QSharedMemory::detach (shm_unlink)"_L1);