diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-01-29 12:58:59 +0100 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-07-31 16:13:31 +0000 |
commit | aac987b2a18041997634f2cb1e7c827e380041ad (patch) | |
tree | 8e885f61351f24a9a5224d52abe552ff5e483c8e | |
parent | e459125d971d1a0c548a63a1286cb839936a8772 (diff) | |
download | qtwayland-aac987b2a18041997634f2cb1e7c827e380041ad.tar.gz |
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>
-rw-r--r-- | src/client/qwaylandshmbackingstore.cpp | 32 |
1 files changed, 12 insertions, 20 deletions
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp index 045748a1..4c7c53b2 100644 --- a/src/client/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -44,6 +44,8 @@ #include "qwaylandabstractdecoration_p.h" #include <QtCore/qdebug.h> +#include <QtCore/qstandardpaths.h> +#include <QtCore/qtemporaryfile.h> #include <QtGui/QPainter> #include <QMutexLocker> #include <QLoggingCategory> @@ -52,10 +54,7 @@ #include <wayland-client-protocol.h> #include <unistd.h> -#include <fcntl.h> -#include <errno.h> #include <sys/mman.h> - QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -72,28 +71,22 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, { int stride = size.width() * 4; int alloc = stride * size.height(); - char filename[] = "/tmp/wayland-shm-XXXXXX"; - 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); + int fd; - if (ftruncate(fd, alloc) < 0) { - qWarning("ftruncate failed: %s", strerror(errno)); - close(fd); + QTemporaryFile tmp(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + + QLatin1String("/wayland-shm-XXXXXX")); + if (!tmp.open() || !tmp.resize(alloc)) { + qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(tmp.errorString())); 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 *) mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - unlink(filename); - if (data == (uchar *) MAP_FAILED) { - qWarning("mmap /dev/zero failed: %s", strerror(errno)); - close(fd); + qErrnoWarning("QWaylandShmBuffer: mmap failed"); return; } @@ -105,7 +98,6 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, mShmPool = wl_shm_create_pool(shm->object(), fd, alloc); init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(), stride, wl_format)); - close(fd); } QWaylandShmBuffer::~QWaylandShmBuffer(void) |