QWaylandShmBuffer: use QTemporaryFile
Instead of using mkstemp. Even current glibc versions do not open the file with O_CLOEXEC, so this code is not thread-safe. QTemporaryFile is. And since Qt 5.10, it will also use O_TMPFILE on Linux, so the file will not actually exists on disk. Take this opportunity to use the runtime directory instead of /tmp. There's no guarantee that the /tmp filesystem can support mmap'ing, while XDG_RUNTIME_DIR has that guarantee. It's also usually a tmpfs, so no data will be leaked to disk. Change-Id: I8d96dea9955d4c749b99fffd14cd5335d1114cef Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com>
This commit is contained in:
parent
636ce8d733
commit
516c3b7fe9
@ -44,6 +44,8 @@
|
|||||||
#include "qwaylandabstractdecoration_p.h"
|
#include "qwaylandabstractdecoration_p.h"
|
||||||
|
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qstandardpaths.h>
|
||||||
|
#include <QtCore/qtemporaryfile.h>
|
||||||
#include <QtGui/QPainter>
|
#include <QtGui/QPainter>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
@ -52,10 +54,7 @@
|
|||||||
#include <wayland-client-protocol.h>
|
#include <wayland-client-protocol.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace QtWaylandClient {
|
namespace QtWaylandClient {
|
||||||
@ -72,28 +71,22 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
|
|||||||
{
|
{
|
||||||
int stride = size.width() * 4;
|
int stride = size.width() * 4;
|
||||||
int alloc = stride * size.height();
|
int alloc = stride * size.height();
|
||||||
char filename[] = "/tmp/wayland-shm-XXXXXX";
|
int fd;
|
||||||
int fd = mkstemp(filename);
|
|
||||||
if (fd < 0) {
|
|
||||||
qWarning("mkstemp %s failed: %s", filename, strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int flags = fcntl(fd, F_GETFD);
|
|
||||||
if (flags != -1)
|
|
||||||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
|
||||||
|
|
||||||
if (ftruncate(fd, alloc) < 0) {
|
QTemporaryFile tmp(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) +
|
||||||
qWarning("ftruncate failed: %s", strerror(errno));
|
QLatin1String("/wayland-shm-XXXXXX"));
|
||||||
close(fd);
|
if (!tmp.open() || !tmp.resize(alloc)) {
|
||||||
|
qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(tmp.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fd = tmp.handle();
|
||||||
|
|
||||||
|
// map ourselves: QFile::map() will unmap when the object is destroyed,
|
||||||
|
// but we want this mapping to persist (unmapping in destructor)
|
||||||
uchar *data = (uchar *)
|
uchar *data = (uchar *)
|
||||||
mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
unlink(filename);
|
|
||||||
|
|
||||||
if (data == (uchar *) MAP_FAILED) {
|
if (data == (uchar *) MAP_FAILED) {
|
||||||
qWarning("mmap /dev/zero failed: %s", strerror(errno));
|
qErrnoWarning("QWaylandShmBuffer: mmap failed");
|
||||||
close(fd);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +98,6 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
|
|||||||
mShmPool = wl_shm_create_pool(shm->object(), fd, alloc);
|
mShmPool = wl_shm_create_pool(shm->object(), fd, alloc);
|
||||||
init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(),
|
init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(),
|
||||||
stride, wl_format));
|
stride, wl_format));
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandShmBuffer::~QWaylandShmBuffer(void)
|
QWaylandShmBuffer::~QWaylandShmBuffer(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user