summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edmundson <davidedmundson@kde.org>2019-07-23 01:40:36 +0200
committerDavid Edmundson <davidedmundson@kde.org>2019-08-17 11:50:23 +0200
commit3e96fa1df8d2bc0ec8ab66abae1f20439b786b40 (patch)
treebff5e5d27f8499954724e517462fd955ff011a9c
parent2838c7f33a0b2f40b026d00b3e00139f94c358e7 (diff)
downloadqtwayland-3e96fa1df8d2bc0ec8ab66abae1f20439b786b40.tar.gz
Client: Fix large clipboard pasting
With the non-blocking file opening, when no data was available in the pipe, read could return 0 even though we were not at the end of the file. This resulted in truncated data when pasting the clipboard. This patch uses select to block until a file is available, removing the polling sleep. This means the file can be safely opened in blocking mode whilst keeping the timeout feature allowing read to work as intended. Change-Id: I936aa85e9f25197e7abe6fb3fa729b618c00924d Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Johan Helsing <johan.helsing@qt.io>
-rw-r--r--src/client/qwaylanddataoffer.cpp41
1 files changed, 25 insertions, 16 deletions
diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp
index 0c732c02..3da16ed0 100644
--- a/src/client/qwaylanddataoffer.cpp
+++ b/src/client/qwaylanddataoffer.cpp
@@ -135,7 +135,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
}
int pipefd[2];
- if (qt_safe_pipe(pipefd, O_NONBLOCK) == -1) {
+ if (qt_safe_pipe(pipefd) == -1) {
qWarning("QWaylandMimeData: pipe2() failed");
return QVariant();
}
@@ -158,23 +158,32 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
int QWaylandMimeData::readData(int fd, QByteArray &data) const
{
- char buf[4096];
- int retryCount = 0;
- int n;
- while (true) {
- n = QT_READ(fd, buf, sizeof buf);
- if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) && ++retryCount < 1000)
- usleep(1000);
- else
- break;
- }
- if (retryCount >= 1000)
+ fd_set readset;
+ FD_ZERO(&readset);
+ FD_SET(fd, &readset);
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout);
+ if (ready < 0) {
+ qWarning() << "QWaylandDataOffer: select() failed";
+ return -1;
+ } else if (ready == 0) {
qWarning("QWaylandDataOffer: timeout reading from pipe");
- if (n > 0) {
- data.append(buf, n);
- n = readData(fd, data);
+ return -1;
+ } else {
+ char buf[4096];
+ int n = QT_READ(fd, buf, sizeof buf);
+
+ if (n > 0) {
+ data.append(buf, n);
+ n = readData(fd, data);
+ } else if (n < 0) {
+ qWarning("QWaylandDataOffer: read() failed");
+ }
+ return n;
}
- return n;
}
}