From ea5bad90316b21b7ba577b6f5f9fb6551e11149c Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Thu, 6 Oct 2022 19:46:56 +0200 Subject: [PATCH] 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 Pick-to: 6.4 6.2 5.15 Change-Id: Ieb446da9fdfbaaa55100f573b396ee449cadc463 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/wayland/qwaylanddatasource.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylanddatasource.cpp b/src/plugins/platforms/wayland/qwaylanddatasource.cpp index ef1d14d397a..093c40f2fd5 100644 --- a/src/plugins/platforms/wayland/qwaylanddatasource.cpp +++ b/src/plugins/platforms/wayland/qwaylanddatasource.cpp @@ -13,6 +13,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -57,6 +58,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);