diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/socket/qlocalserver.cpp | 34 | ||||
-rw-r--r-- | src/network/socket/qlocalserver.h | 1 | ||||
-rw-r--r-- | src/network/socket/qlocalserver_p.h | 1 | ||||
-rw-r--r-- | src/network/socket/qlocalserver_tcp.cpp | 7 | ||||
-rw-r--r-- | src/network/socket/qlocalserver_unix.cpp | 42 | ||||
-rw-r--r-- | src/network/socket/qlocalserver_win.cpp | 6 |
6 files changed, 91 insertions, 0 deletions
diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index 97f5920171..05f26883d3 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -299,6 +299,40 @@ bool QLocalServer::listen(const QString &name) } /*! + \since 5.0 + + Instructs the server to listen for incoming connections on + \a socketDescriptor. The property returns \c false if the server is + currently listening. It returns \c true on success; otherwise, + it returns \c false. The socket must be ready to accept + new connections with no extra platform-specific functions + called. The socket is set into non-blocking mode. + + serverName(), fullServerName() may return a string with + a name if this option is supported by the platform; + otherwise, they return an empty QString. + + \sa isListening(), close() + */ +bool QLocalServer::listen(qintptr socketDescriptor) +{ + Q_D(QLocalServer); + if (isListening()) { + qWarning("QLocalServer::listen() called when already listening"); + return false; + } + + d->serverName.clear(); + d->fullServerName.clear(); + + if (!d->listen(socketDescriptor)) { + return false; + } + + return true; +} + +/*! Returns the maximum number of pending accepted connections. The default is 30. diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h index 6f883adc24..291122e10d 100644 --- a/src/network/socket/qlocalserver.h +++ b/src/network/socket/qlocalserver.h @@ -82,6 +82,7 @@ public: virtual bool hasPendingConnections() const; bool isListening() const; bool listen(const QString &name); + bool listen(qintptr socketDescriptor); int maxPendingConnections() const; virtual QLocalSocket *nextPendingConnection(); QString serverName() const; diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h index 03c06a42e3..84081159c7 100644 --- a/src/network/socket/qlocalserver_p.h +++ b/src/network/socket/qlocalserver_p.h @@ -87,6 +87,7 @@ public: void init(); bool listen(const QString &name); + bool listen(qintptr socketDescriptor); static bool removeServer(const QString &name); void closeServer(); void waitForNewConnection(int msec, bool *timedOut); diff --git a/src/network/socket/qlocalserver_tcp.cpp b/src/network/socket/qlocalserver_tcp.cpp index d6c6a1af92..9ac1bfaf0e 100644 --- a/src/network/socket/qlocalserver_tcp.cpp +++ b/src/network/socket/qlocalserver_tcp.cpp @@ -78,6 +78,13 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) return true; } +bool QLocalServerPrivate::listen(qintptr socketDescriptor) +{ + Q_Q(QLocalServer); + + return tcpServer.setSocketDescriptor(socketDescriptor); +} + void QLocalServerPrivate::closeServer() { QSettings settings(QLatin1String("Trolltech"), QLatin1String("Qt")); diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index ce0c283f0b..0c2edef578 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -203,6 +203,48 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) return true; } +bool QLocalServerPrivate::listen(qintptr socketDescriptor) +{ + Q_Q(QLocalServer); + + // Attach to the localsocket + listenSocket = socketDescriptor; + + ::fcntl(listenSocket, F_SETFD, FD_CLOEXEC); + ::fcntl(listenSocket, F_SETFL, ::fcntl(listenSocket, F_GETFL) | O_NONBLOCK); + +#ifdef Q_OS_LINUX + struct ::sockaddr_un addr; + socklen_t len; + memset(&addr, 0, sizeof(addr)); + if (0 == ::getsockname(listenSocket, (sockaddr *)&addr, &len)) { + // check for absract sockets + if (addr.sun_family == PF_UNIX && addr.sun_path[0] == 0) { + addr.sun_path[0] = '@'; + } + QString name = QString::fromLatin1(addr.sun_path); + if (!name.isEmpty()) { + fullServerName = name; + serverName = fullServerName.mid(fullServerName.lastIndexOf(QLatin1String("/"))+1); + if (serverName.isEmpty()) { + serverName = fullServerName; + } + } + } +#else + serverName.clear(); + fullServerName.clear(); +#endif + + Q_ASSERT(!socketNotifier); + socketNotifier = new QSocketNotifier(listenSocket, + QSocketNotifier::Read, q); + q->connect(socketNotifier, SIGNAL(activated(int)), + q, SLOT(_q_onNewConnection())); + socketNotifier->setEnabled(maxPendingConnections > 0); + return true; +} + /*! \internal diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 67e319cdbb..07357e5789 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -144,6 +144,12 @@ bool QLocalServerPrivate::listen(const QString &name) return true; } +bool QLocalServerPrivate::listen(qintptr) +{ + qWarning("QLocalServer::listen(qintptr) is not supported on Windows QTBUG-24230"); + return false; +} + void QLocalServerPrivate::_q_onNewConnection() { Q_Q(QLocalServer); |