From 020ed5b7caaba5cf877cdb9ebaa575db1d15b7f0 Mon Sep 17 00:00:00 2001
From: Joerg Bornemann <joerg.bornemann@trolltech.com>
Date: Thu, 9 Jul 2009 18:09:12 +0200
Subject: QLocalSocket WriteOnly mode fixed on Windows

Write only local sockets silently disconnected after some time.
Reason: we cannot call PeekNamedPipe on a write only pipe.

Task-number: 257714
Reviewed-by: ossi
Autotest: tst_QLocalSocket::writeOnlySocket
---
 src/network/socket/qlocalsocket_win.cpp      | 10 ++++++----
 tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 17 +++++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 1a971f0..794b2b7 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -168,7 +168,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
 
     // we have a valid handle
     d->serverName = name;
-    if (setSocketDescriptor((quintptr)localSocket), openMode) {
+    if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) {
         d->handle = localSocket;
         emit connected();
     }
@@ -299,8 +299,6 @@ void QLocalSocket::abort()
 DWORD QLocalSocketPrivate::bytesAvailable()
 {
     Q_Q(QLocalSocket);
-    if (q->state() != QLocalSocket::ConnectedState)
-        return 0;
     DWORD bytes;
     if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) {
         return bytes;
@@ -410,7 +408,7 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor,
     d->handle = (int*)socketDescriptor;
     d->state = socketState;
     emit stateChanged(d->state);
-    if (d->state == ConnectedState) {
+    if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) {
         d->startAsyncRead();
         d->checkReadyRead();
     }
@@ -471,6 +469,10 @@ bool QLocalSocket::waitForDisconnected(int msecs)
     Q_D(QLocalSocket);
     if (state() == UnconnectedState)
         return false;
+    if (!openMode().testFlag(QIODevice::ReadOnly)) {
+        qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes.");
+        return false;
+    }
     QIncrementalSleepTimer timer(msecs);
     forever {
         d->bytesAvailable();    // to check if PeekNamedPipe fails
diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
index 0f636a4..a41eecd 100644
--- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
@@ -104,6 +104,7 @@ private slots:
     void recycleServer();
 
     void multiConnect();
+    void writeOnlySocket();
 
     void debug();
 
@@ -906,6 +907,22 @@ void tst_QLocalSocket::multiConnect()
     QVERIFY(server.nextPendingConnection() != 0);
 }
 
+void tst_QLocalSocket::writeOnlySocket()
+{
+    QLocalServer server;
+    QVERIFY(server.listen("writeOnlySocket"));
+
+    QLocalSocket client;
+    client.connectToServer("writeOnlySocket", QIODevice::WriteOnly);
+    QVERIFY(client.waitForConnected());
+
+    QVERIFY(server.waitForNewConnection());
+    QLocalSocket* serverSocket = server.nextPendingConnection();
+
+    QCOMPARE(client.bytesAvailable(), qint64(0));
+    QCOMPARE(client.state(), QLocalSocket::ConnectedState);
+}
+
 void tst_QLocalSocket::debug()
 {
     // Make sure this compiles
-- 
cgit v0.12