10#include <qcoreapplication.h>
12#if QT_CONFIG(sysv_sem)
20#if defined(Q_OS_DARWIN)
21#include "private/qcore_mac_p.h"
24#include "private/qcore_unix_p.h"
28#if defined(Q_OS_OPENBSD) && !defined(EIDRM)
34using namespace Qt::StringLiterals;
36bool QSystemSemaphoreSystemV::runtimeSupportCheck()
38#if defined(Q_OS_DARWIN)
39 if (qt_apple_isSandboxed())
42 static const bool result = []() {
43 (
void)semget(IPC_PRIVATE, -1, 0);
44 return errno != ENOSYS;
50
51
52
53
54key_t QSystemSemaphoreSystemV::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode)
59#if defined(Q_OS_DARWIN)
60 if (qt_apple_isSandboxed()) {
62 self->setError(QSystemSemaphore::PermissionDenied,
63 QSystemSemaphore::tr(
"%1: System V semaphores are not available for "
64 "sandboxed applications. Please build Qt with "
66 .arg(
"QSystemSemaphore::handle:"_L1));
71 nativeKeyFile = QFile::encodeName(self->nativeKey.nativeKey());
72 if (nativeKeyFile.isEmpty()) {
73 self->setError(QSystemSemaphore::KeyError,
74 QSystemSemaphore::tr(
"%1: key is empty")
75 .arg(
"QSystemSemaphore::handle:"_L1));
80 int built = QtIpcCommon::createUnixKeyFile(nativeKeyFile);
82 self->setError(QSystemSemaphore::KeyError,
83 QSystemSemaphore::tr(
"%1: unable to make key")
84 .arg(
"QSystemSemaphore::handle:"_L1));
88 createdFile = (1 == built);
91 unix_key = ftok(nativeKeyFile,
int(self->nativeKey.type()));
93 self->setError(QSystemSemaphore::KeyError,
94 QSystemSemaphore::tr(
"%1: ftok failed")
95 .arg(
"QSystemSemaphore::handle:"_L1));
100 semaphore = semget(unix_key, 1, 0600 | IPC_CREAT | IPC_EXCL);
101 if (-1 == semaphore) {
103 semaphore = semget(unix_key, 1, 0600 | IPC_CREAT);
104 if (-1 == semaphore) {
105 self->setUnixErrorString(
"QSystemSemaphore::handle"_L1);
110 createdSemaphore =
true;
115 if (mode == QSystemSemaphore::Create) {
116 createdSemaphore =
true;
121 if (createdSemaphore && self->initialValue >= 0) {
123 init_op.val = self->initialValue;
124 if (-1 == semctl(semaphore, 0, SETVAL, init_op)) {
125 self->setUnixErrorString(
"QSystemSemaphore::handle"_L1);
135
136
137
138
139void QSystemSemaphoreSystemV::cleanHandle(QSystemSemaphorePrivate *self)
145 unlink(nativeKeyFile.constData());
149 if (createdSemaphore) {
150 if (-1 != semaphore) {
151 if (-1 == semctl(semaphore, 0, IPC_RMID, 0)) {
152 self->setUnixErrorString(
"QSystemSemaphore::cleanHandle"_L1);
153#if defined QSYSTEMSEMAPHORE_DEBUG
154 qDebug(
"QSystemSemaphoreSystemV::cleanHandle semctl failed.");
159 createdSemaphore =
false;
164
165
166bool QSystemSemaphoreSystemV::modifySemaphore(QSystemSemaphorePrivate *self,
int count)
168 if (handle(self, QSystemSemaphore::Open) == -1)
171 struct sembuf operation;
172 operation.sem_num = 0;
173 operation.sem_op = count;
174 operation.sem_flg = SEM_UNDO;
177 QT_EINTR_LOOP(res, semop(semaphore, &operation, 1));
180 if (errno == EINVAL || errno == EIDRM) {
183 handle(self, QSystemSemaphore::Open);
184 return modifySemaphore(self, count);
186 self->setUnixErrorString(
"QSystemSemaphore::modifySemaphore"_L1);
187#if defined QSYSTEMSEMAPHORE_DEBUG
188 qDebug(
"QSystemSemaphoreSystemV::modify failed %d %d %d %d %d",
189 count,
int(semctl(semaphore, 0, GETVAL)),
int(errno),
int(EIDRM),
int(EINVAL);