summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorAndrew Stanley-Jones <andrew.stanley-jones@nokia.com>2012-02-09 15:51:22 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-15 02:36:02 +0100
commit980947122307797e1d8da03f768d8f14a360d20b (patch)
tree309b9a526c1563def2018d649dc536c82b926cdb /src/network/socket
parentfc8f92106d6743d4165de7d8a440b7e5dbd14391 (diff)
Allow the QLocalServer to listen to a native descriptor
QLocalServer could only listen to sockets it created. Thi is not always possible as sockets may be passed by socketpair() or have to be created locally by other means. This adds a similar feature to QLocalSocket where a native descriptor maybe used. Change-Id: I43b0af179b3b868dd164d4e1fd312ff4546cf9ff Reviewed-by: Michalina Ziemba <michalina.ziemba@nokia.com> Reviewed-by: Tapani Mikola <tapani.mikola@nokia.com> Reviewed-by: Harald Fernengel <harald.fernengel@nokia.com>
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qlocalserver.cpp34
-rw-r--r--src/network/socket/qlocalserver.h1
-rw-r--r--src/network/socket/qlocalserver_p.h1
-rw-r--r--src/network/socket/qlocalserver_tcp.cpp7
-rw-r--r--src/network/socket/qlocalserver_unix.cpp42
-rw-r--r--src/network/socket/qlocalserver_win.cpp6
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);