From 29d00da7418afdd738ecb5c64ea8d27df7f6dc41 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 7 May 2021 11:22:31 +0300 Subject: [PATCH] Port klipper away from select() to poll() select() is not safe, it can corrupt stack if the polled fd is greater than FD_SETSIZE. poll() is a much safer alternative. Unlike 20 or so years ago, many unix systems support poll() nowadays, so we can safely use it. --- klipper/systemclipboard/waylandclipboard.cpp | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/klipper/systemclipboard/waylandclipboard.cpp b/klipper/systemclipboard/waylandclipboard.cpp index a331614ff..53e56c46e 100644 --- a/klipper/systemclipboard/waylandclipboard.cpp +++ b/klipper/systemclipboard/waylandclipboard.cpp @@ -29,12 +29,13 @@ #include +#include +#include +#include #include #include "qwayland-wlr-data-control-unstable-v1.h" -#include - class DataControlDeviceManager : public QWaylandClientExtensionTemplate, public QtWayland::zwlr_data_control_manager_v1 { Q_OBJECT @@ -130,18 +131,17 @@ QVariant DataControlOffer::retrieveData(const QString &mimeType, QVariant::Type // true if data is read successfully bool DataControlOffer::readData(int fd, QByteArray &data) { - fd_set readset; - FD_ZERO(&readset); - FD_SET(fd, &readset); - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - - Q_FOREVER { - int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout); + pollfd pfds[1]; + pfds[0].fd = fd; + pfds[0].events = POLLIN; + + while (true) { + const int ready = poll(pfds, 1, 1000); if (ready < 0) { - qWarning() << "DataControlOffer: select() failed"; - return false; + if (errno != EINTR) { + qWarning("DataControlOffer: poll() failed: %s", strerror(errno)); + return false; + } } else if (ready == 0) { qWarning("DataControlOffer: timeout reading from pipe"); return false;