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.
wilder-5.24
Vlad Zahorodnii 5 years ago
parent fffa1bad46
commit 29d00da741
  1. 26
      klipper/systemclipboard/waylandclipboard.cpp

@ -29,12 +29,13 @@
#include <qpa/qplatformnativeinterface.h>
#include <errno.h>
#include <poll.h>
#include <string.h>
#include <unistd.h>
#include "qwayland-wlr-data-control-unstable-v1.h"
#include <sys/select.h>
class DataControlDeviceManager : public QWaylandClientExtensionTemplate<DataControlDeviceManager>, 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;

Loading…
Cancel
Save