diff options
author | Inho Lee <inho.lee@qt.io> | 2022-10-06 19:46:56 +0200 |
---|---|---|
committer | Inho Lee <inho.lee@qt.io> | 2022-11-24 08:36:22 +0100 |
commit | 4cc3ce4a20fb46ed70094bd1c9a4c735eb37cc60 (patch) | |
tree | fecc978d70a7dc3d8d499b01c9a5bc75b7d61ae1 | |
parent | 4f3490008c1fb90f4c6a21d1908c69f5548eb972 (diff) |
Always use blocking write for data_source.send
QtWaylandClient assumes that data_source's fd is BLOCKING,
but some compositors (e.g. mutter) pass an fd with
O_NONBLOCK set. In this case, 'write' is not guaranteed to
process all of the passed data in one call. Instead of
dealing with such partial writes, remove O_NONBLOCK.
Fixes: QTBUG-107076
Change-Id: Ieb446da9fdfbaaa55100f573b396ee449cadc463
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 5025ac15088d1b85007b3d3439c14bdc3e4979a1)
Reviewed-by: Liang Qi <liang.qi@qt.io>
-rw-r--r-- | src/client/qwaylanddatasource.cpp | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp index a0635de20..c71ce0fd2 100644 --- a/src/client/qwaylanddatasource.cpp +++ b/src/client/qwaylanddatasource.cpp @@ -49,6 +49,7 @@ #include <unistd.h> #include <signal.h> +#include <fcntl.h> QT_BEGIN_NAMESPACE @@ -93,6 +94,13 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) action.sa_flags = 0; sigaction(SIGPIPE, &action, &oldAction); + // Some compositors (e.g., mutter) make fd with O_NONBLOCK. + // Since wl_data_source.send describes that fd is closed here, + // it should be done in a loop and don't have any advantage. + // Blocking operation will be used. + // According to fcntl(2), FSETFL ignores O_WRONLY. So this + // call will just remove O_NONBLOCK. + fcntl(fd, F_SETFL, O_WRONLY); ssize_t unused = write(fd, content.constData(), content.size()); Q_UNUSED(unused); sigaction(SIGPIPE, &oldAction, nullptr); |