11#include <qcoreapplication.h>
13#if QT_CONFIG(sysv_sem)
21#if defined(Q_OS_DARWIN)
22#include "private/qcore_mac_p.h"
25#include "private/qcore_unix_p.h"
29#if defined(Q_OS_OPENBSD) && !defined(EIDRM)
35using namespace Qt::StringLiterals;
37bool QSystemSemaphoreSystemV::runtimeSupportCheck()
39#if defined(Q_OS_DARWIN)
40 if (qt_apple_isSandboxed())
43 static const bool result = []() {
44 (
void)semget(IPC_PRIVATE, -1, 0);
45 return errno != ENOSYS;
51
52
53
54
55key_t QSystemSemaphoreSystemV::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode)
60#if defined(Q_OS_DARWIN)
61 if (qt_apple_isSandboxed()) {
63 self->setError(QSystemSemaphore::PermissionDenied,
64 QSystemSemaphore::tr(
"%1: System V semaphores are not available for "
65 "sandboxed applications. Please build Qt with "
67 .arg(
"QSystemSemaphore::handle:"_L1));
72 nativeKeyFile = QFile::encodeName(self->nativeKey.nativeKey());
73 if (nativeKeyFile.isEmpty()) {
74 self->setError(QSystemSemaphore::KeyError,
75 QSystemSemaphore::tr(
"%1: key is empty")
76 .arg(
"QSystemSemaphore::handle:"_L1));
81 int built = QtIpcCommon::createUnixKeyFile(nativeKeyFile);
83 self->setError(QSystemSemaphore::KeyError,
84 QSystemSemaphore::tr(
"%1: unable to make key")
85 .arg(
"QSystemSemaphore::handle:"_L1));
89 createdFile = (1 == built);
92 unix_key = ftok(nativeKeyFile,
int(self->nativeKey.type()));
94 self->setError(QSystemSemaphore::KeyError,
95 QSystemSemaphore::tr(
"%1: ftok failed")
96 .arg(
"QSystemSemaphore::handle:"_L1));
101 semaphore = semget(unix_key, 1, 0600 | IPC_CREAT | IPC_EXCL);
102 if (-1 == semaphore) {
104 semaphore = semget(unix_key, 1, 0600 | IPC_CREAT);
105 if (-1 == semaphore) {
106 self->setUnixErrorString(
"QSystemSemaphore::handle"_L1);
111 createdSemaphore =
true;
116 if (mode == QSystemSemaphore::Create) {
117 createdSemaphore =
true;
122 if (createdSemaphore && self->initialValue >= 0) {
124 init_op.val = self->initialValue;
125 if (-1 == semctl(semaphore, 0, SETVAL, init_op)) {
126 self->setUnixErrorString(
"QSystemSemaphore::handle"_L1);
136
137
138
139
140void QSystemSemaphoreSystemV::cleanHandle(QSystemSemaphorePrivate *self)
146 unlink(nativeKeyFile.constData());
150 if (createdSemaphore) {
151 if (-1 != semaphore) {
152 if (-1 == semctl(semaphore, 0, IPC_RMID, 0)) {
153 self->setUnixErrorString(
"QSystemSemaphore::cleanHandle"_L1);
154#if defined QSYSTEMSEMAPHORE_DEBUG
155 qDebug(
"QSystemSemaphoreSystemV::cleanHandle semctl failed.");
160 createdSemaphore =
false;
165
166
167bool QSystemSemaphoreSystemV::modifySemaphore(QSystemSemaphorePrivate *self,
int count)
169 if (handle(self, QSystemSemaphore::Open) == -1)
172 struct sembuf operation;
173 operation.sem_num = 0;
174 operation.sem_op = count;
175 operation.sem_flg = SEM_UNDO;
178 QT_EINTR_LOOP(res, semop(semaphore, &operation, 1));
181 if (errno == EINVAL || errno == EIDRM) {
184 handle(self, QSystemSemaphore::Open);
185 return modifySemaphore(self, count);
187 self->setUnixErrorString(
"QSystemSemaphore::modifySemaphore"_L1);
188#if defined QSYSTEMSEMAPHORE_DEBUG
189 qDebug(
"QSystemSemaphoreSystemV::modify failed %d %d %d %d %d",
190 count,
int(semctl(semaphore, 0, GETVAL)),
int(errno),
int(EIDRM),
int(EINVAL);