1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNetwork 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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qlocalserver.h"
41#include "qlocalserver_p.h"
42#include "qlocalsocket.h"
43
44#if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
45#include <QtCore/qt_windows.h>
46#endif
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \class QLocalServer
52 \since 4.4
53 \inmodule QtNetwork
54
55 \brief The QLocalServer class provides a local socket based server.
56
57 This class makes it possible to accept incoming local socket
58 connections.
59
60 Call listen() to have the server start listening
61 for incoming connections on a specified key. The
62 newConnection() signal is then emitted each time a client
63 connects to the server.
64
65 Call nextPendingConnection() to accept the pending connection
66 as a connected QLocalSocket. The function returns a pointer to a
67 QLocalSocket that can be used for communicating with the client.
68
69 If an error occurs, serverError() returns the type of error, and
70 errorString() can be called to get a human readable description
71 of what happened.
72
73 When listening for connections, the name which the server is
74 listening on is available through serverName().
75
76 Calling close() makes QLocalServer stop listening for incoming connections.
77
78 Although QLocalServer is designed for use with an event loop, it's possible
79 to use it without one. In that case, you must use waitForNewConnection(),
80 which blocks until either a connection is available or a timeout expires.
81
82 \sa QLocalSocket, QTcpServer
83*/
84
85/*!
86 \enum QLocalServer::SocketOption
87 \since 5.0
88
89 This enum describes the possible options that can be used to create the
90 socket. This changes the access permissions on platforms (Linux, Windows)
91 that support access permissions on the socket. Both GroupAccess and OtherAccess
92 may vary slightly in meanings depending on the platform.
93
94 \value NoOptions No access restrictions have been set.
95 \value UserAccessOption
96 Access is restricted to the same user as the process that created the socket.
97 \value GroupAccessOption
98 Access is restricted to the same group but not the user that created the socket on Linux.
99 Access is restricted to the primary group of the process on Windows
100 \value OtherAccessOption
101 Access is available to everyone but the user and group that created the socket on Linux.
102 Access is available to everyone on Windows.
103 \value WorldAccessOption
104 No access restrictions.
105
106 \sa socketOptions
107*/
108
109
110/*!
111 Create a new local socket server with the given \a parent.
112
113 \sa listen()
114 */
115QLocalServer::QLocalServer(QObject *parent)
116 : QObject(*new QLocalServerPrivate, parent)
117{
118 Q_D(QLocalServer);
119 d->init();
120}
121
122/*!
123 Destroys the QLocalServer object. If the server is listening for
124 connections, it is automatically closed.
125
126 Any client QLocalSockets that are still connected must either
127 disconnect or be reparented before the server is deleted.
128
129 \sa close()
130 */
131QLocalServer::~QLocalServer()
132{
133 if (isListening())
134 close();
135}
136
137/*!
138 \property QLocalServer::socketOptions
139 \since 5.0
140
141 The setSocketOptions method controls how the socket operates.
142 For example the socket may restrict access to what user ids can
143 connect to the socket.
144
145 These options must be set before listen() is called.
146
147 In some cases, such as with Unix domain sockets on Linux, the
148 access to the socket will be determined by file system permissions,
149 and are created based on the umask. Setting the access flags will
150 override this and will restrict or permit access as specified.
151
152 Other Unix-based operating systems, such as \macos, do not
153 honor file permissions for Unix domain sockets and by default
154 have WorldAccess and these permission flags will have no effect.
155
156 On Windows, UserAccessOption is sufficient to allow a non
157 elevated process to connect to a local server created by an
158 elevated process run by the same user. GroupAccessOption
159 refers to the primary group of the process (see TokenPrimaryGroup
160 in the Windows documentation). OtherAccessOption refers to
161 the well known "Everyone" group.
162
163 By default none of the flags are set, access permissions
164 are the platform default.
165
166 \sa listen()
167*/
168void QLocalServer::setSocketOptions(SocketOptions options)
169{
170 Q_D(QLocalServer);
171
172 d->socketOptions = options;
173}
174
175/*!
176 \since 5.0
177 Returns the socket options set on the socket.
178
179 \sa setSocketOptions()
180 */
181QLocalServer::SocketOptions QLocalServer::socketOptions() const
182{
183 Q_D(const QLocalServer);
184 return d->socketOptions;
185}
186
187/*!
188 \since 5.10
189 Returns the native socket descriptor the server uses to listen
190 for incoming instructions, or -1 if the server is not listening.
191
192 The type of the descriptor depends on the platform:
193 \list
194 \li On Windows, the returned value is a
195 \l{https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx}
196 {Winsock 2 Socket Handle}.
197
198 \li With WinRT and on INTEGRITY, the returned value is the
199 QTcpServer socket descriptor and the type is defined by
200 \l{QTcpServer::socketDescriptor}{socketDescriptor}.
201
202 \li On all other UNIX-like operating systems, the type is
203 a file descriptor representing a listening socket.
204 \endlist
205
206 \sa listen()
207*/
208qintptr QLocalServer::socketDescriptor() const
209{
210 Q_D(const QLocalServer);
211 if (!isListening())
212 return -1;
213#if defined(QT_LOCALSOCKET_TCP)
214 return d->tcpServer.socketDescriptor();
215#elif defined(Q_OS_WIN)
216 const auto handle = d->connectionEventNotifier->handle();
217 return handle != INVALID_HANDLE_VALUE ? qintptr(handle) : -1;
218#else
219 return d->socketNotifier->socket();
220#endif
221}
222
223/*!
224 Stop listening for incoming connections. Existing connections are not
225 affected, but any new connections will be refused.
226
227 \sa isListening(), listen()
228 */
229void QLocalServer::close()
230{
231 Q_D(QLocalServer);
232 if (!isListening())
233 return;
234 qDeleteAll(c: d->pendingConnections);
235 d->pendingConnections.clear();
236 d->closeServer();
237 d->serverName.clear();
238 d->fullServerName.clear();
239 d->errorString.clear();
240 d->error = QAbstractSocket::UnknownSocketError;
241}
242
243/*!
244 Returns the human-readable message appropriate to the current error
245 reported by serverError(). If no suitable string is available, an empty
246 string is returned.
247
248 \sa serverError()
249 */
250QString QLocalServer::errorString() const
251{
252 Q_D(const QLocalServer);
253 return d->errorString;
254}
255
256/*!
257 Returns \c true if the server has a pending connection; otherwise
258 returns \c false.
259
260 \sa nextPendingConnection(), setMaxPendingConnections()
261 */
262bool QLocalServer::hasPendingConnections() const
263{
264 Q_D(const QLocalServer);
265 return !(d->pendingConnections.isEmpty());
266}
267
268/*!
269 This virtual function is called by QLocalServer when a new connection
270 is available. \a socketDescriptor is the native socket descriptor for
271 the accepted connection.
272
273 The base implementation creates a QLocalSocket, sets the socket descriptor
274 and then stores the QLocalSocket in an internal list of pending
275 connections. Finally newConnection() is emitted.
276
277 Reimplement this function to alter the server's behavior
278 when a connection is available.
279
280 \sa newConnection(), nextPendingConnection(),
281 QLocalSocket::setSocketDescriptor()
282 */
283void QLocalServer::incomingConnection(quintptr socketDescriptor)
284{
285 Q_D(QLocalServer);
286 QLocalSocket *socket = new QLocalSocket(this);
287 socket->setSocketDescriptor(socketDescriptor);
288 d->pendingConnections.enqueue(t: socket);
289 emit newConnection();
290}
291
292/*!
293 Returns \c true if the server is listening for incoming connections
294 otherwise false.
295
296 \sa listen(), close()
297 */
298bool QLocalServer::isListening() const
299{
300 Q_D(const QLocalServer);
301 return !(d->serverName.isEmpty());
302}
303
304/*!
305 Tells the server to listen for incoming connections on \a name.
306 If the server is currently listening then it will return false.
307 Return true on success otherwise false.
308
309 \a name can be a single name and QLocalServer will determine
310 the correct platform specific path. serverName() will return
311 the name that is passed into listen.
312
313 Usually you would just pass in a name like "foo", but on Unix this
314 could also be a path such as "/tmp/foo" and on Windows this could
315 be a pipe path such as "\\\\.\\pipe\\foo"
316
317 \note On Unix if the server crashes without closing listen will fail
318 with AddressInUseError. To create a new server the file should be removed.
319 On Windows two local servers can listen to the same pipe at the same
320 time, but any connections will go to one of the server.
321
322 \sa serverName(), isListening(), close()
323 */
324bool QLocalServer::listen(const QString &name)
325{
326 Q_D(QLocalServer);
327 if (isListening()) {
328 qWarning(msg: "QLocalServer::listen() called when already listening");
329 return false;
330 }
331
332 if (name.isEmpty()) {
333 d->error = QAbstractSocket::HostNotFoundError;
334 QString function = QLatin1String("QLocalServer::listen");
335 d->errorString = tr(s: "%1: Name error").arg(a: function);
336 return false;
337 }
338
339 if (!d->listen(name)) {
340 d->serverName.clear();
341 d->fullServerName.clear();
342 return false;
343 }
344
345 d->serverName = name;
346 return true;
347}
348
349/*!
350 \since 5.0
351
352 Instructs the server to listen for incoming connections on
353 \a socketDescriptor. The property returns \c false if the server is
354 currently listening. It returns \c true on success; otherwise,
355 it returns \c false. The socket must be ready to accept
356 new connections with no extra platform-specific functions
357 called. The socket is set into non-blocking mode.
358
359 serverName(), fullServerName() may return a string with
360 a name if this option is supported by the platform;
361 otherwise, they return an empty QString.
362
363 \sa isListening(), close()
364 */
365bool QLocalServer::listen(qintptr socketDescriptor)
366{
367 Q_D(QLocalServer);
368 if (isListening()) {
369 qWarning(msg: "QLocalServer::listen() called when already listening");
370 return false;
371 }
372
373 d->serverName.clear();
374 d->fullServerName.clear();
375
376 if (!d->listen(socketDescriptor)) {
377 return false;
378 }
379
380 return true;
381}
382
383/*!
384 Returns the maximum number of pending accepted connections.
385 The default is 30.
386
387 \sa setMaxPendingConnections(), hasPendingConnections()
388 */
389int QLocalServer::maxPendingConnections() const
390{
391 Q_D(const QLocalServer);
392 return d->maxPendingConnections;
393}
394
395/*!
396 \fn void QLocalServer::newConnection()
397
398 This signal is emitted every time a new connection is available.
399
400 \sa hasPendingConnections(), nextPendingConnection()
401*/
402
403/*!
404 Returns the next pending connection as a connected QLocalSocket object.
405
406 The socket is created as a child of the server, which means that it is
407 automatically deleted when the QLocalServer object is destroyed. It is
408 still a good idea to delete the object explicitly when you are done with
409 it, to avoid wasting memory.
410
411 \nullptr is returned if this function is called when there are no pending
412 connections.
413
414 \sa hasPendingConnections(), newConnection(), incomingConnection()
415 */
416QLocalSocket *QLocalServer::nextPendingConnection()
417{
418 Q_D(QLocalServer);
419 if (d->pendingConnections.isEmpty())
420 return nullptr;
421 QLocalSocket *nextSocket = d->pendingConnections.dequeue();
422#ifndef QT_LOCALSOCKET_TCP
423 if (d->pendingConnections.size() <= d->maxPendingConnections)
424#ifndef Q_OS_WIN
425 d->socketNotifier->setEnabled(true);
426#else
427 d->connectionEventNotifier->setEnabled(true);
428#endif
429#endif
430 return nextSocket;
431}
432
433/*!
434 \since 4.5
435
436 Removes any server instance that might cause a call to listen() to fail
437 and returns \c true if successful; otherwise returns \c false.
438 This function is meant to recover from a crash, when the previous server
439 instance has not been cleaned up.
440
441 On Windows, this function does nothing; on Unix, it removes the socket file
442 given by \a name.
443
444 \warning Be careful to avoid removing sockets of running instances.
445*/
446bool QLocalServer::removeServer(const QString &name)
447{
448 return QLocalServerPrivate::removeServer(name);
449}
450
451/*!
452 Returns the server name if the server is listening for connections;
453 otherwise returns QString()
454
455 \sa listen(), fullServerName()
456 */
457QString QLocalServer::serverName() const
458{
459 Q_D(const QLocalServer);
460 return d->serverName;
461}
462
463/*!
464 Returns the full path that the server is listening on.
465
466 Note: This is platform specific
467
468 \sa listen(), serverName()
469 */
470QString QLocalServer::fullServerName() const
471{
472 Q_D(const QLocalServer);
473 return d->fullServerName;
474}
475
476/*!
477 Returns the type of error that occurred last or NoError.
478
479 \sa errorString()
480 */
481QAbstractSocket::SocketError QLocalServer::serverError() const
482{
483 Q_D(const QLocalServer);
484 return d->error;
485}
486
487/*!
488 Sets the maximum number of pending accepted connections to
489 \a numConnections. QLocalServer will accept no more than
490 \a numConnections incoming connections before nextPendingConnection()
491 is called.
492
493 Note: Even though QLocalServer will stop accepting new connections
494 after it has reached its maximum number of pending connections,
495 the operating system may still keep them in queue which will result
496 in clients signaling that it is connected.
497
498 \sa maxPendingConnections(), hasPendingConnections()
499 */
500void QLocalServer::setMaxPendingConnections(int numConnections)
501{
502 Q_D(QLocalServer);
503 d->maxPendingConnections = numConnections;
504}
505
506/*!
507 Waits for at most \a msec milliseconds or until an incoming connection
508 is available. Returns \c true if a connection is available; otherwise
509 returns \c false. If the operation timed out and \a timedOut is not
510 \nullptr, *timedOut will be set to true.
511
512 This is a blocking function call. Its use is ill-advised in a
513 single-threaded GUI application, since the whole application will stop
514 responding until the function returns. waitForNewConnection() is mostly
515 useful when there is no event loop available.
516
517 The non-blocking alternative is to connect to the newConnection() signal.
518
519 If msec is -1, this function will not time out.
520
521 \sa hasPendingConnections(), nextPendingConnection()
522 */
523bool QLocalServer::waitForNewConnection(int msec, bool *timedOut)
524{
525 Q_D(QLocalServer);
526 if (timedOut)
527 *timedOut = false;
528
529 if (!isListening())
530 return false;
531
532 d->waitForNewConnection(msec, timedOut);
533
534 return !d->pendingConnections.isEmpty();
535}
536
537QT_END_NAMESPACE
538
539#include "moc_qlocalserver.cpp"
540
541

source code of qtbase/src/network/socket/qlocalserver.cpp