kernel/qsharedmemory_unix.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qplatformdefs.h" -
43 -
44#include "qsharedmemory.h" -
45#include "qsharedmemory_p.h" -
46#include "qsystemsemaphore.h" -
47#include <qdir.h> -
48#include <qdebug.h> -
49 -
50#include <errno.h> -
51 -
52#ifndef QT_NO_SHAREDMEMORY -
53#include <sys/types.h> -
54#include <sys/ipc.h> -
55#include <sys/shm.h> -
56#include <sys/stat.h> -
57#include <fcntl.h> -
58#include <unistd.h> -
59#endif //QT_NO_SHAREDMEMORY -
60 -
61#include "private/qcore_unix_p.h" -
62 -
63#ifndef QT_NO_SHAREDMEMORY -
64QT_BEGIN_NAMESPACE -
65 -
66QSharedMemoryPrivate::QSharedMemoryPrivate() -
67 : QObjectPrivate(), memory(0), size(0), error(QSharedMemory::NoError), -
68#ifndef QT_NO_SYSTEMSEMAPHORE -
69 systemSemaphore(QString()), lockedByMe(false), -
70#endif -
71 unix_key(0) -
72{ -
73}
executed: }
Execution Count:1
1
74 -
75void QSharedMemoryPrivate::setErrorString(const QString &function) -
76{ -
77 // EINVAL is handled in functions so they can give better error strings -
78 switch (errno) { -
79 case EACCES: -
80 errorString = QSharedMemory::tr("%1: permission denied").arg(function);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: permission denied").arg(function);
-
81 error = QSharedMemory::PermissionDenied;
never executed (the execution status of this line is deduced): error = QSharedMemory::PermissionDenied;
-
82 break;
never executed: break;
0
83 case EEXIST: -
84 errorString = QSharedMemory::tr("%1: already exists").arg(function);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: already exists").arg(function);
-
85 error = QSharedMemory::AlreadyExists;
never executed (the execution status of this line is deduced): error = QSharedMemory::AlreadyExists;
-
86 break;
never executed: break;
0
87 case ENOENT: -
88 errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
-
89 error = QSharedMemory::NotFound;
never executed (the execution status of this line is deduced): error = QSharedMemory::NotFound;
-
90 break;
never executed: break;
0
91 case EMFILE: -
92 case ENOMEM: -
93 case ENOSPC: -
94 errorString = QSharedMemory::tr("%1: out of resources").arg(function);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: out of resources").arg(function);
-
95 error = QSharedMemory::OutOfResources;
never executed (the execution status of this line is deduced): error = QSharedMemory::OutOfResources;
-
96 break;
never executed: break;
0
97 default: -
98 errorString = QSharedMemory::tr("%1: unknown error %2").arg(function).arg(errno);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: unknown error %2").arg(function).arg((*__errno_location ()));
-
99 error = QSharedMemory::UnknownError;
never executed (the execution status of this line is deduced): error = QSharedMemory::UnknownError;
-
100#if defined QSHAREDMEMORY_DEBUG -
101 qDebug() << errorString << "key" << key << "errno" << errno << EINVAL; -
102#endif -
103 }
never executed: }
0
104}
never executed: }
0
105 -
106/*! -
107 \internal -
108 -
109 If not already made create the handle used for accessing the shared memory. -
110*/ -
111key_t QSharedMemoryPrivate::handle() -
112{ -
113 // already made -
114 if (unix_key)
never evaluated: unix_key
0
115 return unix_key;
never executed: return unix_key;
0
116 -
117 // don't allow making handles on empty keys -
118 if (nativeKey.isEmpty()) {
never evaluated: nativeKey.isEmpty()
0
119 errorString = QSharedMemory::tr("%1: key is empty").arg(QLatin1String("QSharedMemory::handle:"));
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: key is empty").arg(QLatin1String("QSharedMemory::handle:"));
-
120 error = QSharedMemory::KeyError;
never executed (the execution status of this line is deduced): error = QSharedMemory::KeyError;
-
121 return 0;
never executed: return 0;
0
122 } -
123 -
124 // ftok requires that an actual file exists somewhere -
125 if (!QFile::exists(nativeKey)) {
never evaluated: !QFile::exists(nativeKey)
0
126 errorString = QSharedMemory::tr("%1: UNIX key file doesn't exist").arg(QLatin1String("QSharedMemory::handle:"));
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: UNIX key file doesn't exist").arg(QLatin1String("QSharedMemory::handle:"));
-
127 error = QSharedMemory::NotFound;
never executed (the execution status of this line is deduced): error = QSharedMemory::NotFound;
-
128 return 0;
never executed: return 0;
0
129 } -
130 -
131 unix_key = ftok(QFile::encodeName(nativeKey).constData(), 'Q');
never executed (the execution status of this line is deduced): unix_key = ftok(QFile::encodeName(nativeKey).constData(), 'Q');
-
132 if (-1 == unix_key) {
never evaluated: -1 == unix_key
0
133 errorString = QSharedMemory::tr("%1: ftok failed").arg(QLatin1String("QSharedMemory::handle:"));
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: ftok failed").arg(QLatin1String("QSharedMemory::handle:"));
-
134 error = QSharedMemory::KeyError;
never executed (the execution status of this line is deduced): error = QSharedMemory::KeyError;
-
135 unix_key = 0;
never executed (the execution status of this line is deduced): unix_key = 0;
-
136 }
never executed: }
0
137 return unix_key;
never executed: return unix_key;
0
138} -
139 -
140#endif // QT_NO_SHAREDMEMORY -
141 -
142#if !(defined(QT_NO_SHAREDMEMORY) && defined(QT_NO_SYSTEMSEMAPHORE)) -
143/*! -
144 \internal -
145 Creates the unix file if needed. -
146 returns true if the unix file was created. -
147 -
148 -1 error -
149 0 already existed -
150 1 created -
151 */ -
152int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) -
153{ -
154 if (QFile::exists(fileName))
partially evaluated: QFile::exists(fileName)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:46
0-46
155 return 0;
never executed: return 0;
0
156 -
157 int fd = qt_safe_open(QFile::encodeName(fileName).constData(),
executed (the execution status of this line is deduced): int fd = qt_safe_open(QFile::encodeName(fileName).constData(),
-
158 O_EXCL | O_CREAT | O_RDWR, 0640);
executed (the execution status of this line is deduced): 0200 | 0100 | 02, 0640);
-
159 if (-1 == fd) {
partially evaluated: -1 == fd
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:46
0-46
160 if (errno == EEXIST)
never evaluated: (*__errno_location ()) == 17
0
161 return 0;
never executed: return 0;
0
162 return -1;
never executed: return -1;
0
163 } else { -
164 close(fd);
executed (the execution status of this line is deduced): close(fd);
-
165 }
executed: }
Execution Count:46
46
166 return 1;
executed: return 1;
Execution Count:46
46
167} -
168#endif // QT_NO_SHAREDMEMORY && QT_NO_SYSTEMSEMAPHORE -
169 -
170#ifndef QT_NO_SHAREDMEMORY -
171 -
172bool QSharedMemoryPrivate::cleanHandle() -
173{ -
174 unix_key = 0;
never executed (the execution status of this line is deduced): unix_key = 0;
-
175 return true;
never executed: return true;
0
176} -
177 -
178bool QSharedMemoryPrivate::create(int size) -
179{ -
180 // build file if needed -
181 bool createdFile = false;
never executed (the execution status of this line is deduced): bool createdFile = false;
-
182 int built = createUnixKeyFile(nativeKey);
never executed (the execution status of this line is deduced): int built = createUnixKeyFile(nativeKey);
-
183 if (built == -1) {
never evaluated: built == -1
0
184 errorString = QSharedMemory::tr("%1: unable to make key").arg(QLatin1String("QSharedMemory::handle:"));
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: unable to make key").arg(QLatin1String("QSharedMemory::handle:"));
-
185 error = QSharedMemory::KeyError;
never executed (the execution status of this line is deduced): error = QSharedMemory::KeyError;
-
186 return false;
never executed: return false;
0
187 } -
188 if (built == 1) {
never evaluated: built == 1
0
189 createdFile = true;
never executed (the execution status of this line is deduced): createdFile = true;
-
190 }
never executed: }
0
191 -
192 // get handle -
193 if (!handle()) {
never evaluated: !handle()
0
194 if (createdFile)
never evaluated: createdFile
0
195 QFile::remove(nativeKey);
never executed: QFile::remove(nativeKey);
0
196 return false;
never executed: return false;
0
197 } -
198 -
199 // create -
200 if (-1 == shmget(unix_key, size, 0600 | IPC_CREAT | IPC_EXCL)) {
never evaluated: -1 == shmget(unix_key, size, 0600 | 01000 | 02000)
0
201 QString function = QLatin1String("QSharedMemory::create");
never executed (the execution status of this line is deduced): QString function = QLatin1String("QSharedMemory::create");
-
202 switch (errno) { -
203 case EINVAL: -
204 errorString = QSharedMemory::tr("%1: system-imposed size restrictions").arg(QLatin1String("QSharedMemory::handle"));
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: system-imposed size restrictions").arg(QLatin1String("QSharedMemory::handle"));
-
205 error = QSharedMemory::InvalidSize;
never executed (the execution status of this line is deduced): error = QSharedMemory::InvalidSize;
-
206 break;
never executed: break;
0
207 default: -
208 setErrorString(function);
never executed (the execution status of this line is deduced): setErrorString(function);
-
209 }
never executed: }
0
210 if (createdFile && error != QSharedMemory::AlreadyExists)
never evaluated: createdFile
never evaluated: error != QSharedMemory::AlreadyExists
0
211 QFile::remove(nativeKey);
never executed: QFile::remove(nativeKey);
0
212 return false;
never executed: return false;
0
213 } -
214 -
215 return true;
never executed: return true;
0
216} -
217 -
218bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) -
219{ -
220 // grab the shared memory segment id -
221 int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0400 : 0600));
never executed (the execution status of this line is deduced): int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0400 : 0600));
-
222 if (-1 == id) {
never evaluated: -1 == id
0
223 setErrorString(QLatin1String("QSharedMemory::attach (shmget)"));
never executed (the execution status of this line is deduced): setErrorString(QLatin1String("QSharedMemory::attach (shmget)"));
-
224 return false;
never executed: return false;
0
225 } -
226 -
227 // grab the memory -
228 memory = shmat(id, 0, (mode == QSharedMemory::ReadOnly ? SHM_RDONLY : 0));
never executed (the execution status of this line is deduced): memory = shmat(id, 0, (mode == QSharedMemory::ReadOnly ? 010000 : 0));
-
229 if ((void*) - 1 == memory) {
never evaluated: (void*) - 1 == memory
0
230 memory = 0;
never executed (the execution status of this line is deduced): memory = 0;
-
231 setErrorString(QLatin1String("QSharedMemory::attach (shmat)"));
never executed (the execution status of this line is deduced): setErrorString(QLatin1String("QSharedMemory::attach (shmat)"));
-
232 return false;
never executed: return false;
0
233 } -
234 -
235 // grab the size -
236 shmid_ds shmid_ds;
never executed (the execution status of this line is deduced): shmid_ds shmid_ds;
-
237 if (!shmctl(id, IPC_STAT, &shmid_ds)) {
never evaluated: !shmctl(id, 2, &shmid_ds)
0
238 size = (int)shmid_ds.shm_segsz;
never executed (the execution status of this line is deduced): size = (int)shmid_ds.shm_segsz;
-
239 } else {
never executed: }
0
240 setErrorString(QLatin1String("QSharedMemory::attach (shmctl)"));
never executed (the execution status of this line is deduced): setErrorString(QLatin1String("QSharedMemory::attach (shmctl)"));
-
241 return false;
never executed: return false;
0
242 } -
243 -
244 return true;
never executed: return true;
0
245} -
246 -
247bool QSharedMemoryPrivate::detach() -
248{ -
249 // detach from the memory segment -
250 if (-1 == shmdt(memory)) {
never evaluated: -1 == shmdt(memory)
0
251 QString function = QLatin1String("QSharedMemory::detach");
never executed (the execution status of this line is deduced): QString function = QLatin1String("QSharedMemory::detach");
-
252 switch (errno) { -
253 case EINVAL: -
254 errorString = QSharedMemory::tr("%1: not attached").arg(function);
never executed (the execution status of this line is deduced): errorString = QSharedMemory::tr("%1: not attached").arg(function);
-
255 error = QSharedMemory::NotFound;
never executed (the execution status of this line is deduced): error = QSharedMemory::NotFound;
-
256 break;
never executed: break;
0
257 default: -
258 setErrorString(function);
never executed (the execution status of this line is deduced): setErrorString(function);
-
259 }
never executed: }
0
260 return false;
never executed: return false;
0
261 } -
262 memory = 0;
never executed (the execution status of this line is deduced): memory = 0;
-
263 size = 0;
never executed (the execution status of this line is deduced): size = 0;
-
264 -
265 // Get the number of current attachments -
266 int id = shmget(unix_key, 0, 0400);
never executed (the execution status of this line is deduced): int id = shmget(unix_key, 0, 0400);
-
267 cleanHandle();
never executed (the execution status of this line is deduced): cleanHandle();
-
268 -
269 struct shmid_ds shmid_ds;
never executed (the execution status of this line is deduced): struct shmid_ds shmid_ds;
-
270 if (0 != shmctl(id, IPC_STAT, &shmid_ds)) {
never evaluated: 0 != shmctl(id, 2, &shmid_ds)
0
271 switch (errno) { -
272 case EINVAL: -
273 return true;
never executed: return true;
0
274 default: -
275 return false;
never executed: return false;
0
276 } -
277 }
never executed: }
0
278 // If there are no attachments then remove it. -
279 if (shmid_ds.shm_nattch == 0) {
never evaluated: shmid_ds.shm_nattch == 0
0
280 // mark for removal -
281 if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) {
never evaluated: -1 == shmctl(id, 0, &shmid_ds)
0
282 setErrorString(QLatin1String("QSharedMemory::remove"));
never executed (the execution status of this line is deduced): setErrorString(QLatin1String("QSharedMemory::remove"));
-
283 switch (errno) { -
284 case EINVAL: -
285 return true;
never executed: return true;
0
286 default: -
287 return false;
never executed: return false;
0
288 } -
289 }
never executed: }
0
290 -
291 // remove file -
292 if (!QFile::remove(nativeKey))
never evaluated: !QFile::remove(nativeKey)
0
293 return false;
never executed: return false;
0
294 }
never executed: }
0
295 return true;
never executed: return true;
0
296} -
297 -
298 -
299QT_END_NAMESPACE -
300 -
301#endif // QT_NO_SHAREDMEMORY -
302 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial