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>
53 \class QDBusUnixFileDescriptor
57 \brief The QDBusUnixFileDescriptor class holds one Unix file descriptor.
59 The QDBusUnixFileDescriptor class is used to hold one Unix file
60 descriptor for use with the QtDBus module. This allows applications to
61 send and receive Unix file descriptors over the D-Bus connection, mapping
62 automatically to the D-Bus type 'h'.
64 Objects of type QDBusUnixFileDescriptors can be used also as parameters
65 in signals and slots that get exported to D-Bus by registering with
66 QDBusConnection::registerObject.
68 QDBusUnixFileDescriptor does not take ownership of the file descriptor.
69 Instead, it will use the Unix system call \c dup(2) to make a copy of the
70 file descriptor. This file descriptor belongs to the
71 QDBusUnixFileDescriptor object and should not be stored or closed by the
72 user. Instead, you should make your own copy if you need that.
74 \section2 Availability
76 Unix file descriptor passing is not available in all D-Bus connections.
77 This feature is present with D-Bus library and bus daemon version 1.4 and
78 upwards on Unix systems. QtDBus automatically enables the feature if such
79 a version was found at compile-time and run-time.
81 To verify that your connection does support passing file descriptors,
82 check if the QDBusConnection::UnixFileDescriptorPassing capability is set
83 with QDBusConnection::connectionCapabilities(). If the flag is not
84 active, then you will not be able to make calls to methods that have
85 QDBusUnixFileDescriptor as arguments or even embed such a type in a
86 variant. You will also not receive calls containing that type.
88 Note also that remote applications may not have support for Unix file
89 descriptor passing. If you make a D-Bus to a remote application that
90 cannot receive such a type, you will receive an error reply. If you try
91 to send a signal containing a D-Bus file descriptor or return one from a
92 method call, the message will be silently dropped.
94 Even if the feature is not available, QDBusUnixFileDescriptor will
95 continue to operate, so code need not have compile-time checks for the
96 availability of this feature.
98 On non-Unix systems, QDBusUnixFileDescriptor will always report an
99 invalid state and QDBusUnixFileDescriptor::isSupported() will return
102 \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities()
106 \typedef QDBusUnixFileDescriptor::Data
111 \variable QDBusUnixFileDescriptor::d
115 class QDBusUnixFileDescriptorPrivate : public QSharedData {
117 QDBusUnixFileDescriptorPrivate() : fd(-1) { }
118 QDBusUnixFileDescriptorPrivate(const QDBusUnixFileDescriptorPrivate &other)
119 : QSharedData(other), fd(-1)
121 ~QDBusUnixFileDescriptorPrivate();
127 QExplicitlySharedDataPointer<QDBusUnixFileDescriptorPrivate>::~QExplicitlySharedDataPointer()
128 { if (d && !d->ref.deref()) delete d; }
131 Constructs a QDBusUnixFileDescriptor without a wrapped file descriptor.
132 This is equivalent to constructing the object with an invalid file
133 descriptor (like -1).
135 \sa fileDescriptor(), isValid()
137 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor()
143 Constructs a QDBusUnixFileDescriptor object by copying the \a
144 fileDescriptor parameter. The original file descriptor is not touched and
145 must be closed by the user.
147 Note that the value returned by fileDescriptor() will be different from
148 the \a fileDescriptor parameter passed.
150 If the \a fileDescriptor parameter is not valid, isValid() will return
151 false and fileDescriptor() will return -1.
153 \sa setFileDescriptor(), fileDescriptor()
155 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor)
158 if (fileDescriptor != -1)
159 setFileDescriptor(fileDescriptor);
163 Constructs a QDBusUnixFileDescriptor object by copying \a other.
165 QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other)
171 Copies the Unix file descriptor from the \a other QDBusUnixFileDescriptor
172 object. If the current object contained a file descriptor, it will be
173 properly disposed of before.
175 QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileDescriptor &other)
178 d.operator=(other.d);
183 Destroys this QDBusUnixFileDescriptor object and disposes of the Unix file descriptor that it contained.
185 QDBusUnixFileDescriptor::~QDBusUnixFileDescriptor()
190 Returns true if this Unix file descriptor is valid. A valid Unix file
191 descriptor is not -1.
195 bool QDBusUnixFileDescriptor::isValid() const
197 return d ? d->fd.load() != -1 : false;
201 Returns the Unix file descriptor contained by this
202 QDBusUnixFileDescriptor object. An invalid file descriptor is represented
205 Note that the file descriptor returned by this function is owned by the
206 QDBusUnixFileDescriptor object and must not be stored past the lifetime
207 of this object. It is ok to use it while this object is valid, but if one
208 wants to store it for longer use, the file descriptor should be cloned
209 using the Unix \c dup(2), \c dup2(2) or \c dup3(2) functions.
213 int QDBusUnixFileDescriptor::fileDescriptor() const
215 return d ? d->fd.load() : -1;
218 // actual implementation
221 // qdoc documentation is generated on Unix
224 Returns true if Unix file descriptors are supported on this platform. In
225 other words, this function returns true if this is a Unix platform.
227 Note that QDBusUnixFileDescriptor continues to operate even if this
228 function returns false. The only difference is that the
229 QDBusUnixFileDescriptor objects will always be in the isValid() == false
230 state and fileDescriptor() will always return -1. The class will not
231 consume any operating system resources.
233 bool QDBusUnixFileDescriptor::isSupported()
239 Sets the file descriptor that this QDBusUnixFileDescriptor object holds
240 to a copy of \a fileDescriptor. The original file descriptor is not
241 touched and must be closed by the user.
243 Note that the value returned by fileDescriptor() will be different from
244 the \a fileDescriptor parameter passed.
246 If the \a fileDescriptor parameter is not valid, isValid() will return
247 false and fileDescriptor() will return -1.
249 \sa isValid(), fileDescriptor()
251 void QDBusUnixFileDescriptor::setFileDescriptor(int fileDescriptor)
253 if (fileDescriptor != -1)
254 giveFileDescriptor(qt_safe_dup(fileDescriptor));
259 Sets the Unix file descriptor to \a fileDescriptor without copying.
261 \sa setFileDescriptor()
263 void QDBusUnixFileDescriptor::giveFileDescriptor(int fileDescriptor)
265 // if we are the sole ref, d remains unchanged
266 // if detaching happens, d->fd will be -1
270 d = new QDBusUnixFileDescriptorPrivate;
272 const int fdl = d->fd.load();
276 if (fileDescriptor != -1)
277 d->fd.store(fileDescriptor);
282 Extracts the Unix file descriptor from the QDBusUnixFileDescriptor object
283 and transfers ownership.
285 Note: since QDBusUnixFileDescriptor is implicitly shared, this function
286 is inherently racy and should be avoided.
288 int QDBusUnixFileDescriptor::takeFileDescriptor()
293 return d->fd.fetchAndStoreRelaxed(-1);
296 QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate()
298 const int fdl = fd.load();
304 bool QDBusUnixFileDescriptor::isSupported()
309 void QDBusUnixFileDescriptor::setFileDescriptor(int)
313 void QDBusUnixFileDescriptor::giveFileDescriptor(int)
317 int QDBusUnixFileDescriptor::takeFileDescriptor()
322 QDBusUnixFileDescriptorPrivate::~QDBusUnixFileDescriptorPrivate()