1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the FOO module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qdbusunixfiledescriptor.h"
44 #include <QSharedData>
47 # include <private/qcore_unix_p.h>
55 \class QDBusUnixFileDescriptor
59 \brief The QDBusUnixFileDescriptor class holds one Unix file descriptor.
61 The QDBusUnixFileDescriptor class is used to hold one Unix file
62 descriptor for use with the QtDBus 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'.
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.
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.
76 \section2 Availability
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. QtDBus automatically enables the feature if such
81 a version was found at compile-time and run-time.
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.
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.
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.
100 On non-Unix systems, QDBusUnixFileDescriptor will always report an
101 invalid state and QDBusUnixFileDescriptor::isSupported() will return
104 \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities()
108 \typedef QDBusUnixFileDescriptor::Data
113 \variable QDBusUnixFileDescriptor::d
117 class QDBusUnixFileDescriptorPrivate : public QSharedData {
119 QDBusUnixFileDescriptorPrivate() : fd(-1) { }
120 QDBusUnixFileDescriptorPrivate(const QDBusUnixFileDescriptorPrivate &other)
121 : QSharedData(other), fd(-1)
123 ~QDBusUnixFileDescriptorPrivate();
129 QExplicitlySharedDataPointer<QDBusUnixFileDescriptorPrivate>::~QExplicitlySharedDataPointer()
130 { if (d && !d->ref.deref()) delete d; }
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).
137 \sa fileDescriptor(), isValid()
139 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor()
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.
149 Note that the value returned by fileDescriptor() will be different from
150 the \a fileDescriptor parameter passed.
152 If the \a fileDescriptor parameter is not valid, isValid() will return
153 false and fileDescriptor() will return -1.
155 \sa setFileDescriptor(), fileDescriptor()
157 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor)
160 if (fileDescriptor != -1)
161 setFileDescriptor(fileDescriptor);
165 Constructs a QDBusUnixFileDescriptor object by copying \a other.
167 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other)
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.
177 QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileDescriptor &other)
180 d.operator=(other.d);
185 Destroys this QDBusUnixFileDescriptor object and disposes of the Unix file descriptor that it contained.
187 QDBusUnixFileDescriptor::~QDBusUnixFileDescriptor()
192 \fn void QDBusUnixFileDescriptor::swap(QDBusUnixFileDescriptor &other)
195 Swaps this file descriptor instance with \a other. This function
196 is very fast and never fails.
200 Returns true if this Unix file descriptor is valid. A valid Unix file
201 descriptor is not -1.
205 bool QDBusUnixFileDescriptor::isValid() const
207 return d ? d->fd.load() != -1 : false;
211 Returns the Unix file descriptor contained by this
212 QDBusUnixFileDescriptor object. An invalid file descriptor is represented
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.
223 int QDBusUnixFileDescriptor::fileDescriptor() const
225 return d ? d->fd.load() : -1;
228 // actual implementation
231 // qdoc documentation is generated on Unix
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.
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.
243 bool QDBusUnixFileDescriptor::isSupported()
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.
253 Note that the value returned by fileDescriptor() will be different from
254 the \a fileDescriptor parameter passed.
256 If the \a fileDescriptor parameter is not valid, isValid() will return
257 false and fileDescriptor() will return -1.
259 \sa isValid(), fileDescriptor()
261 void QDBusUnixFileDescriptor::setFileDescriptor(int fileDescriptor)
263 if (fileDescriptor != -1)
264 giveFileDescriptor(qt_safe_dup(fileDescriptor));
269 Sets the Unix file descriptor to \a fileDescriptor without copying.
271 \sa setFileDescriptor()
273 void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor)
275 // if we are the sole ref, d remains unchanged
276 // if detaching happens, d->fd will be -1
280 d = new QDBusUnixFileDescriptorPrivate;
282 const int fdl = d->fd.load();
286 if (fileDescriptor != -1)
287 d->fd.store(fileDescriptor);
292 Extracts the Unix file descriptor from the QDBusUnixFileDescriptor object
293 and transfers ownership.
295 Note: since QDBusUnixFileDescriptor is implicitly shared, this function
296 is inherently racy and should be avoided.
298 int QDBusUnixFileDescriptor::takeFileDescriptor()
303 return d->fd.fetchAndStoreRelaxed(-1);
306 QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate()
308 const int fdl = fd.load();
314 bool QDBusUnixFileDescriptor::isSupported()
319 void QDBusUnixFileDescriptor::setFileDescriptor(int)
323 void QDBusUnixFileDescriptor::giveFileDescriptor(int)
327 int QDBusUnixFileDescriptor::takeFileDescriptor()
332 QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate()