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