qdbusunixfiledescriptor.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 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 -
49QT_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 -
117class QDBusUnixFileDescriptorPrivate : public QSharedData { -
118public: -
119 QDBusUnixFileDescriptorPrivate() : fd(-1) { }
never executed: }
0
120 QDBusUnixFileDescriptorPrivate(const QDBusUnixFileDescriptorPrivate &other) -
121 : QSharedData(other), fd(-1) -
122 { }
never executed: }
0
123 ~QDBusUnixFileDescriptorPrivate(); -
124 -
125 QAtomicInt fd; -
126}; -
127 -
128template<> inline -
129QExplicitlySharedDataPointer<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*/ -
139QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() -
140 : d(0) -
141{ -
142}
never executed: }
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*/ -
157QDBusUnixFileDescriptor::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}
never executed: }
0
163 -
164/*! -
165 Constructs a QDBusUnixFileDescriptor object by copying \a other. -
166*/ -
167QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other) -
168 : d(other.d) -
169{ -
170}
never executed: }
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*/ -
177QDBusUnixFileDescriptor &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*/ -
187QDBusUnixFileDescriptor::~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*/ -
205bool 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*/ -
223int 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*/ -
243bool 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*/ -
261void 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}
never executed: }
0
266 -
267/*! -
268 \internal -
269 Sets the Unix file descriptor to \a fileDescriptor without copying. -
270 -
271 \sa setFileDescriptor() -
272*/ -
273void 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)
never evaluated: 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}
never executed: }
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*/ -
298int QDBusUnixFileDescriptor::takeFileDescriptor() -
299{ -
300 if (!d)
never evaluated: !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 -
306QDBusUnixFileDescriptorPrivate::~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}
never executed: }
0
312 -
313#else -
314bool QDBusUnixFileDescriptor::isSupported() -
315{ -
316 return false; -
317} -
318 -
319void QDBusUnixFileDescriptor::setFileDescriptor(int) -
320{ -
321} -
322 -
323void QDBusUnixFileDescriptor::giveFileDescriptor(int) -
324{ -
325} -
326 -
327int QDBusUnixFileDescriptor::takeFileDescriptor() -
328{ -
329 return -1; -
330} -
331 -
332QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate() -
333{ -
334} -
335 -
336#endif -
337 -
338#endif // QT_NO_DBUS -
339 -
340QT_END_NAMESPACE -
341 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial