1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2022 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#ifndef QSYSTEMSEMAPHORE_P_H
7#define QSYSTEMSEMAPHORE_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include "qsystemsemaphore.h"
21
22#if QT_CONFIG(systemsemaphore)
23
24#include "qcoreapplication.h"
25#include "qtipccommon_p.h"
26#include "private/qtcore-config_p.h"
27
28#include <sys/types.h>
29#if QT_CONFIG(posix_sem)
30# include <semaphore.h>
31#endif
32#ifndef SEM_FAILED
33# define SEM_FAILED nullptr
34struct sem_t;
35#endif
36#if QT_CONFIG(sysv_sem)
37# include <sys/sem.h>
38#endif
39
40QT_BEGIN_NAMESPACE
41
42class QSystemSemaphorePrivate;
43
44struct QSystemSemaphorePosix
45{
46 static constexpr bool Enabled = QT_CONFIG(posix_sem);
47 static bool supports(QNativeIpcKey::Type type)
48 { return type == QNativeIpcKey::Type::PosixRealtime; }
49 static bool runtimeSupportCheck();
50
51 bool handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
52 void cleanHandle(QSystemSemaphorePrivate *self);
53 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
54
55 sem_t *semaphore = SEM_FAILED;
56 bool createdSemaphore = false;
57};
58
59struct QSystemSemaphoreSystemV
60{
61 static constexpr bool Enabled = QT_CONFIG(sysv_sem);
62 static bool supports(QNativeIpcKey::Type type)
63 { return quint16(type) <= 0xff; }
64 static bool runtimeSupportCheck();
65
66#if QT_CONFIG(sysv_sem)
67 key_t handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
68 void cleanHandle(QSystemSemaphorePrivate *self);
69 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
70
71 QByteArray nativeKeyFile;
72 key_t unix_key = -1;
73 int semaphore = -1;
74 bool createdFile = false;
75 bool createdSemaphore = false;
76#endif
77};
78
79struct QSystemSemaphoreWin32
80{
81#ifdef Q_OS_WIN32
82 static constexpr bool Enabled = true;
83#else
84 static constexpr bool Enabled = false;
85#endif
86 static bool supports(QNativeIpcKey::Type type)
87 { return type == QNativeIpcKey::Type::Windows; }
88 static bool runtimeSupportCheck() { return Enabled; }
89
90 // we can declare the members without the #if
91 Qt::HANDLE handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
92 void cleanHandle(QSystemSemaphorePrivate *self);
93 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
94
95 Qt::HANDLE semaphore = nullptr;
96};
97
98class QSystemSemaphorePrivate
99{
100public:
101 QSystemSemaphorePrivate(QNativeIpcKey::Type type) : nativeKey(type)
102 { constructBackend(); }
103 ~QSystemSemaphorePrivate() { destructBackend(); }
104
105 void setWindowsErrorString(QLatin1StringView function); // Windows only
106 void setUnixErrorString(QLatin1StringView function);
107 inline void setError(QSystemSemaphore::SystemSemaphoreError e, const QString &message)
108 { error = e; errorString = message; }
109 inline void clearError()
110 { setError(e: QSystemSemaphore::NoError, message: QString()); }
111
112 QNativeIpcKey nativeKey;
113 QString errorString;
114 int initialValue;
115 QSystemSemaphore::SystemSemaphoreError error = QSystemSemaphore::NoError;
116
117 union Backend {
118 Backend() {}
119 ~Backend() {}
120 QSystemSemaphorePosix posix;
121 QSystemSemaphoreSystemV sysv;
122 QSystemSemaphoreWin32 win32;
123 };
124 QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend;
125
126 void constructBackend();
127 void destructBackend();
128
129 template <typename Lambda> auto visit(const Lambda &lambda)
130 {
131 return backend.visit(nativeKey.type(), lambda);
132 }
133
134 void handle(QSystemSemaphore::AccessMode mode)
135 {
136 visit(lambda: [&](auto p) { p->handle(this, mode); });
137 }
138 void cleanHandle()
139 {
140 visit(lambda: [&](auto p) { p->cleanHandle(this); });
141 }
142 bool modifySemaphore(int count)
143 {
144 return visit(lambda: [&](auto p) { return p->modifySemaphore(this, count); });
145 }
146};
147
148QT_END_NAMESPACE
149
150#endif // QT_CONFIG(systemsemaphore)
151
152#endif // QSYSTEMSEMAPHORE_P_H
153
154

source code of qtbase/src/corelib/ipc/qsystemsemaphore_p.h