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

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