Qt 4.8
qunixsocketserver.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui 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 "qunixsocketserver_p.h"
43 
44 // #define QUNIXSOCKETSERVER_DEBUG
45 
46 #ifdef QUNIXSOCKETSERVER_DEBUG
47 #include <QDebug>
48 #endif
49 
50 #include <QtCore/qsocketnotifier.h>
51 
52 extern "C" {
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 #include <sys/un.h>
56 #include <unistd.h>
57 #include <errno.h>
58 };
59 
60 #define UNIX_PATH_MAX 108 // From unix(7)
61 
63 
65 {
67 public:
69  : QObject(), me(parent), fd(-1), maxConns(30),
71  {}
72 
74  int fd;
75  int maxConns;
79 public slots:
80  void acceptActivated();
81 };
82 
142 : QObject(parent), d(0)
143 {
144 }
145 
150 {
151  close();
152  if(d)
153  delete d;
154 }
155 
163 {
164  if(!d)
165  return;
166 
167  if(d->acceptNotifier) {
168  d->acceptNotifier->setEnabled(false);
169  delete d->acceptNotifier;
170  }
171  d->acceptNotifier = 0;
172 
173  if(-1 != d->fd) {
174 #ifdef QUNIXSOCKET_DEBUG
175  int closerv =
176 #endif
177  ::close(d->fd);
178 #ifdef QUNIXSOCKET_DEBUG
179  if(0 != closerv) {
180  qDebug() << "QUnixSocketServer: Unable to close socket ("
181  << strerror(errno) << ')';
182  }
183 #endif
184  }
185  d->fd = -1;
186  d->address = QByteArray();
187  d->error = NoError;
188 }
189 
200 {
201  if(!d)
202  return NoError;
203 
204  return d->error;
205 }
206 
214 {
215  if(!d)
216  return false;
217 
218  return (-1 != d->fd);
219 }
220 
236 {
237  if(d) {
238  close(); // Any existing server is destroyed
239  } else {
240  d = new QUnixSocketServerPrivate(this);
241  }
242 
243  if(path.isEmpty() || path.size() > UNIX_PATH_MAX) {
244  d->error = InvalidPath;
245  return false;
246  }
247  unlink( path ); // ok if this fails
248 
249  // Create the socket
250  d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0);
251  if(-1 == d->fd) {
252 #ifdef QUNIXSOCKETSERVER_DEBUG
253  qDebug() << "QUnixSocketServer: Unable to create socket ("
254  << strerror(errno) << ')';
255 #endif
256  close();
257  d->error = ResourceError;
258  return false;
259  }
260 
261  // Construct our unix address
262  struct ::sockaddr_un addr;
263  addr.sun_family = AF_UNIX;
264  ::memcpy(addr.sun_path, path.data(), path.size());
265  if(path.size() < UNIX_PATH_MAX)
266  addr.sun_path[path.size()] = '\0';
267 
268  // Attempt to bind
269  if(-1 == ::bind(d->fd, (sockaddr *)&addr, sizeof(sockaddr_un))) {
270 #ifdef QUNIXSOCKETSERVER_DEBUG
271  qDebug() << "QUnixSocketServer: Unable to bind socket ("
272  << strerror(errno) << ')';
273 #endif
274  close();
275  d->error = BindError;
276  return false;
277  }
278 
279  // Listen to socket
280  if(-1 == ::listen(d->fd, d->maxConns)) {
281 #ifdef QUNIXSOCKETSERVER_DEBUG
282  qDebug() << "QUnixSocketServer: Unable to listen socket ("
283  << strerror(errno) << ')';
284 #endif
285  close();
286  d->error = ListenError;
287  return false;
288  }
289 
290  // Success!
291  d->address = path;
293  d->acceptNotifier->setEnabled(true);
294  QObject::connect(d->acceptNotifier, SIGNAL(activated(int)),
295  d, SLOT(acceptActivated()));
296 
297  return true;
298 }
299 
305 {
306  if(!d)
307  return QByteArray();
308  return d->address;
309 }
310 
312 {
313  if (!d)
314  return -1;
315  return d->fd;
316 }
317 
318 
331 {
332  if(!d)
333  return 30;
334 
335  return d->maxConns;
336 }
337 
347 {
348  Q_ASSERT(numConnections >= 1);
349  if(!d)
350  d = new QUnixSocketServerPrivate(this);
351 
352  d->maxConns = numConnections;
353 }
354 
372 {
373  ::sockaddr_un r;
374  socklen_t len = sizeof(sockaddr_un);
375  int connsock = ::accept(fd, (sockaddr *)&r, &len);
376 #ifdef QUNIXSOCKETSERVER_DEBUG
377  qDebug() << "QUnixSocketServer: Accept connection " << connsock;
378 #endif
379  if(-1 != connsock)
380  me->incomingConnection(connsock);
381 }
382 
384 
385 #include "qunixsocketserver.moc"
QSocketNotifier * acceptNotifier
double d
Definition: qnumeric_p.h:62
virtual ~QUnixSocketServer()
Stops listening for incoming connection and destroys the Unix socket server.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
void close()
Stop listening for incoming connections and resets the Unix socket server&#39;s state.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define SLOT(a)
Definition: qobjectdefs.h:226
bool listen(const QByteArray &path)
Tells the server to listen for incoming connections on path.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QUnixSocketServerPrivate(QUnixSocketServer *parent)
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
ServerError serverError() const
Returns the last server error.
QUnixSocketServerPrivate * d
Q_CORE_EXPORT void qDebug(const char *,...)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setMaxPendingConnections(int numConnections)
Sets the maximum length the queue of pending connections may grow to numConnections.
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isListening() const
Returns true if this server is listening for incoming connections, false otherwise.
#define Q_OBJECT
Definition: qobjectdefs.h:157
QUnixSocketServer(QObject *parent=0)
Create a new Unix socket server with the given parent.
int maxPendingConnections() const
Returns the maximum length the queue of pending connections may grow to.
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setEnabled(bool)
If enable is true, the notifier is enabled; otherwise the notifier is disabled.
QUnixSocketServer::ServerError error
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
The QUnixSocketServer class provides a Unix domain socket based server.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
#define UNIX_PATH_MAX
friend class QUnixSocketServerPrivate
ServerError
The ServerError enumeration represents the errors that can occur during server establishment.
#define slots
Definition: qobjectdefs.h:68
int errno
QByteArray serverAddress() const
Returns the Unix path on which this server is listening.
int socketDescriptor() const