Line | Source Code | Coverage |
---|
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 FOO 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 | | - |
43 | #include "qdbusunixfiledescriptor.h" | - |
44 | | - |
45 | #ifdef Q_OS_UNIX | - |
46 | # include <private/qcore_unix_p.h> | - |
47 | #endif | - |
48 | | - |
49 | QT_BEGIN_NAMESPACE | - |
50 | | - |
51 | #ifndef QT_NO_DBUS | - |
52 | | - |
53 | /*! | - |
54 | \class QDBusUnixFileDescriptor | - |
55 | \inmodule QtDBus | - |
56 | \ingroup shared | - |
57 | \since 4.8 | - |
58 | | - |
59 | \brief The QDBusUnixFileDescriptor class holds one Unix file descriptor. | - |
60 | | - |
61 | The QDBusUnixFileDescriptor class is used to hold one Unix file | - |
62 | descriptor for use with the Qt D-Bus module. This allows applications to | - |
63 | send and receive Unix file descriptors over the D-Bus connection, mapping | - |
64 | automatically to the D-Bus type 'h'. | - |
65 | | - |
66 | Objects of type QDBusUnixFileDescriptors can be used also as parameters | - |
67 | in signals and slots that get exported to D-Bus by registering with | - |
68 | QDBusConnection::registerObject. | - |
69 | | - |
70 | QDBusUnixFileDescriptor does not take ownership of the file descriptor. | - |
71 | Instead, it will use the Unix system call \c dup(2) to make a copy of the | - |
72 | file descriptor. This file descriptor belongs to the | - |
73 | QDBusUnixFileDescriptor object and should not be stored or closed by the | - |
74 | user. Instead, you should make your own copy if you need that. | - |
75 | | - |
76 | \section2 Availability | - |
77 | | - |
78 | Unix file descriptor passing is not available in all D-Bus connections. | - |
79 | This feature is present with D-Bus library and bus daemon version 1.4 and | - |
80 | upwards on Unix systems. Qt D-Bus automatically enables the feature if such | - |
81 | a version was found at compile-time and run-time. | - |
82 | | - |
83 | To verify that your connection does support passing file descriptors, | - |
84 | check if the QDBusConnection::UnixFileDescriptorPassing capability is set | - |
85 | with QDBusConnection::connectionCapabilities(). If the flag is not | - |
86 | active, then you will not be able to make calls to methods that have | - |
87 | QDBusUnixFileDescriptor as arguments or even embed such a type in a | - |
88 | variant. You will also not receive calls containing that type. | - |
89 | | - |
90 | Note also that remote applications may not have support for Unix file | - |
91 | descriptor passing. If you make a D-Bus to a remote application that | - |
92 | cannot receive such a type, you will receive an error reply. If you try | - |
93 | to send a signal containing a D-Bus file descriptor or return one from a | - |
94 | method call, the message will be silently dropped. | - |
95 | | - |
96 | Even if the feature is not available, QDBusUnixFileDescriptor will | - |
97 | continue to operate, so code need not have compile-time checks for the | - |
98 | availability of this feature. | - |
99 | | - |
100 | On non-Unix systems, QDBusUnixFileDescriptor will always report an | - |
101 | invalid state and QDBusUnixFileDescriptor::isSupported() will return | - |
102 | false. | - |
103 | | - |
104 | \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities() | - |
105 | */ | - |
106 | | - |
107 | /*! | - |
108 | \typedef QDBusUnixFileDescriptor::Data | - |
109 | \internal | - |
110 | */ | - |
111 | | - |
112 | /*! | - |
113 | \variable QDBusUnixFileDescriptor::d | - |
114 | \internal | - |
115 | */ | - |
116 | | - |
117 | class QDBusUnixFileDescriptorPrivate : public QSharedData { | - |
118 | public: | - |
119 | QDBusUnixFileDescriptorPrivate() : fd(-1) { } | 0 |
120 | QDBusUnixFileDescriptorPrivate(const QDBusUnixFileDescriptorPrivate &other) | - |
121 | : QSharedData(other), fd(-1) | - |
122 | { } | 0 |
123 | ~QDBusUnixFileDescriptorPrivate(); | - |
124 | | - |
125 | QAtomicInt fd; | - |
126 | }; | - |
127 | | - |
128 | template<> inline | - |
129 | QExplicitlySharedDataPointer<QDBusUnixFileDescriptorPrivate>::~QExplicitlySharedDataPointer() | - |
130 | { if (d && !d->ref.deref()) delete d; } never executed: delete d; never executed: } never evaluated: d never evaluated: !d->ref.deref() | 0 |
131 | | - |
132 | /*! | - |
133 | Constructs a QDBusUnixFileDescriptor without a wrapped file descriptor. | - |
134 | This is equivalent to constructing the object with an invalid file | - |
135 | descriptor (like -1). | - |
136 | | - |
137 | \sa fileDescriptor(), isValid() | - |
138 | */ | - |
139 | QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() | - |
140 | : d(0) | - |
141 | { | - |
142 | } | 0 |
143 | | - |
144 | /*! | - |
145 | Constructs a QDBusUnixFileDescriptor object by copying the \a | - |
146 | fileDescriptor parameter. The original file descriptor is not touched and | - |
147 | must be closed by the user. | - |
148 | | - |
149 | Note that the value returned by fileDescriptor() will be different from | - |
150 | the \a fileDescriptor parameter passed. | - |
151 | | - |
152 | If the \a fileDescriptor parameter is not valid, isValid() will return | - |
153 | false and fileDescriptor() will return -1. | - |
154 | | - |
155 | \sa setFileDescriptor(), fileDescriptor() | - |
156 | */ | - |
157 | QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor) | - |
158 | : d(0) | - |
159 | { | - |
160 | if (fileDescriptor != -1) never evaluated: fileDescriptor != -1 | 0 |
161 | setFileDescriptor(fileDescriptor); never executed: setFileDescriptor(fileDescriptor); | 0 |
162 | } | 0 |
163 | | - |
164 | /*! | - |
165 | Constructs a QDBusUnixFileDescriptor object by copying \a other. | - |
166 | */ | - |
167 | QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other) | - |
168 | : d(other.d) | - |
169 | { | - |
170 | } | 0 |
171 | | - |
172 | /*! | - |
173 | Copies the Unix file descriptor from the \a other QDBusUnixFileDescriptor | - |
174 | object. If the current object contained a file descriptor, it will be | - |
175 | properly disposed of before. | - |
176 | */ | - |
177 | QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileDescriptor &other) | - |
178 | { | - |
179 | if (this != &other) never evaluated: this != &other | 0 |
180 | d.operator=(other.d); never executed: d.operator=(other.d); | 0 |
181 | return *this; never executed: return *this; | 0 |
182 | } | - |
183 | | - |
184 | /*! | - |
185 | Destroys this QDBusUnixFileDescriptor object and disposes of the Unix file descriptor that it contained. | - |
186 | */ | - |
187 | QDBusUnixFileDescriptor::~QDBusUnixFileDescriptor() | - |
188 | { | - |
189 | } | - |
190 | | - |
191 | /*! | - |
192 | \fn void QDBusUnixFileDescriptor::swap(QDBusUnixFileDescriptor &other) | - |
193 | \since 5.0 | - |
194 | | - |
195 | Swaps this file descriptor instance with \a other. This function | - |
196 | is very fast and never fails. | - |
197 | */ | - |
198 | | - |
199 | /*! | - |
200 | Returns true if this Unix file descriptor is valid. A valid Unix file | - |
201 | descriptor is not -1. | - |
202 | | - |
203 | \sa fileDescriptor() | - |
204 | */ | - |
205 | bool QDBusUnixFileDescriptor::isValid() const | - |
206 | { | - |
207 | return d ? d->fd.load() != -1 : false; never executed: return d ? d->fd.load() != -1 : false; | 0 |
208 | } | - |
209 | | - |
210 | /*! | - |
211 | Returns the Unix file descriptor contained by this | - |
212 | QDBusUnixFileDescriptor object. An invalid file descriptor is represented | - |
213 | by the value -1. | - |
214 | | - |
215 | Note that the file descriptor returned by this function is owned by the | - |
216 | QDBusUnixFileDescriptor object and must not be stored past the lifetime | - |
217 | of this object. It is ok to use it while this object is valid, but if one | - |
218 | wants to store it for longer use, the file descriptor should be cloned | - |
219 | using the Unix \c dup(2), \c dup2(2) or \c dup3(2) functions. | - |
220 | | - |
221 | \sa isValid() | - |
222 | */ | - |
223 | int QDBusUnixFileDescriptor::fileDescriptor() const | - |
224 | { | - |
225 | return d ? d->fd.load() : -1; never executed: return d ? d->fd.load() : -1; | 0 |
226 | } | - |
227 | | - |
228 | // actual implementation | - |
229 | #ifdef Q_OS_UNIX | - |
230 | | - |
231 | // qdoc documentation is generated on Unix | - |
232 | | - |
233 | /*! | - |
234 | Returns true if Unix file descriptors are supported on this platform. In | - |
235 | other words, this function returns true if this is a Unix platform. | - |
236 | | - |
237 | Note that QDBusUnixFileDescriptor continues to operate even if this | - |
238 | function returns false. The only difference is that the | - |
239 | QDBusUnixFileDescriptor objects will always be in the isValid() == false | - |
240 | state and fileDescriptor() will always return -1. The class will not | - |
241 | consume any operating system resources. | - |
242 | */ | - |
243 | bool QDBusUnixFileDescriptor::isSupported() | - |
244 | { | - |
245 | return true; never executed: return true; | 0 |
246 | } | - |
247 | | - |
248 | /*! | - |
249 | Sets the file descriptor that this QDBusUnixFileDescriptor object holds | - |
250 | to a copy of \a fileDescriptor. The original file descriptor is not | - |
251 | touched and must be closed by the user. | - |
252 | | - |
253 | Note that the value returned by fileDescriptor() will be different from | - |
254 | the \a fileDescriptor parameter passed. | - |
255 | | - |
256 | If the \a fileDescriptor parameter is not valid, isValid() will return | - |
257 | false and fileDescriptor() will return -1. | - |
258 | | - |
259 | \sa isValid(), fileDescriptor() | - |
260 | */ | - |
261 | void QDBusUnixFileDescriptor::setFileDescriptor(int fileDescriptor) | - |
262 | { | - |
263 | if (fileDescriptor != -1) never evaluated: fileDescriptor != -1 | 0 |
264 | giveFileDescriptor(qt_safe_dup(fileDescriptor)); never executed: giveFileDescriptor(qt_safe_dup(fileDescriptor)); | 0 |
265 | } | 0 |
266 | | - |
267 | /*! | - |
268 | \internal | - |
269 | Sets the Unix file descriptor to \a fileDescriptor without copying. | - |
270 | | - |
271 | \sa setFileDescriptor() | - |
272 | */ | - |
273 | void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor) | - |
274 | { | - |
275 | // if we are the sole ref, d remains unchanged | - |
276 | // if detaching happens, d->fd will be -1 | - |
277 | if (d) | 0 |
278 | d.detach(); never executed: d.detach(); | 0 |
279 | else | - |
280 | d = new QDBusUnixFileDescriptorPrivate; never executed: d = new QDBusUnixFileDescriptorPrivate; | 0 |
281 | | - |
282 | const int fdl = d->fd.load(); never executed (the execution status of this line is deduced): const int fdl = d->fd.load(); | - |
283 | if (fdl != -1) never evaluated: fdl != -1 | 0 |
284 | qt_safe_close(fdl); never executed: qt_safe_close(fdl); | 0 |
285 | | - |
286 | if (fileDescriptor != -1) never evaluated: fileDescriptor != -1 | 0 |
287 | d->fd.store(fileDescriptor); never executed: d->fd.store(fileDescriptor); | 0 |
288 | } | 0 |
289 | | - |
290 | /*! | - |
291 | \internal | - |
292 | Extracts the Unix file descriptor from the QDBusUnixFileDescriptor object | - |
293 | and transfers ownership. | - |
294 | | - |
295 | Note: since QDBusUnixFileDescriptor is implicitly shared, this function | - |
296 | is inherently racy and should be avoided. | - |
297 | */ | - |
298 | int QDBusUnixFileDescriptor::takeFileDescriptor() | - |
299 | { | - |
300 | if (!d) | 0 |
301 | return -1; never executed: return -1; | 0 |
302 | | - |
303 | return d->fd.fetchAndStoreRelaxed(-1); never executed: return d->fd.fetchAndStoreRelaxed(-1); | 0 |
304 | } | - |
305 | | - |
306 | QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() | - |
307 | { | - |
308 | const int fdl = fd.load(); never executed (the execution status of this line is deduced): const int fdl = fd.load(); | - |
309 | if (fdl != -1) never evaluated: fdl != -1 | 0 |
310 | qt_safe_close(fdl); never executed: qt_safe_close(fdl); | 0 |
311 | } | 0 |
312 | | - |
313 | #else | - |
314 | bool QDBusUnixFileDescriptor::isSupported() | - |
315 | { | - |
316 | return false; | - |
317 | } | - |
318 | | - |
319 | void QDBusUnixFileDescriptor::setFileDescriptor(int) | - |
320 | { | - |
321 | } | - |
322 | | - |
323 | void QDBusUnixFileDescriptor::giveFileDescriptor(int) | - |
324 | { | - |
325 | } | - |
326 | | - |
327 | int QDBusUnixFileDescriptor::takeFileDescriptor() | - |
328 | { | - |
329 | return -1; | - |
330 | } | - |
331 | | - |
332 | QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() | - |
333 | { | - |
334 | } | - |
335 | | - |
336 | #endif | - |
337 | | - |
338 | #endif // QT_NO_DBUS | - |
339 | | - |
340 | QT_END_NAMESPACE | - |
341 | | - |
| | |