diff --git a/src/common.hpp b/src/common.hpp index c562fad..0d900f0 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -42,6 +42,7 @@ extern zwlr_layer_shell_v1* wlrLayerShell; void spawn(Monitor&, const Arg& arg); void setCloexec(int fd); [[noreturn]] void die(const char* why); +[[noreturn]] void diesys(const char* why); // wayland smart pointers template diff --git a/src/main.cpp b/src/main.cpp index 693af5c..0aeadb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,7 +62,6 @@ static void onGlobalRemove(void*, wl_registry* registry, uint32_t name); static void requireGlobal(const void* p, const char* name); static void waylandFlush(); static void cleanup(); -[[noreturn]] static void diesys(const char* why); wl_display* display; wl_compositor* compositor; diff --git a/src/shm_buffer.cpp b/src/shm_buffer.cpp index 6e7592a..18a28f3 100644 --- a/src/shm_buffer.cpp +++ b/src/shm_buffer.cpp @@ -1,11 +1,14 @@ // somebar - dwl bar // See LICENSE file for copyright and license details. +#include #include +#include #include #include "shm_buffer.hpp" #include "common.hpp" +static int createAnonShm(); constexpr int n = 2; ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) @@ -15,8 +18,13 @@ ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) { auto oneSize = stride*size_t(h); auto totalSize = oneSize * n; - auto fd = memfd_create("wl_shm", MFD_CLOEXEC); - ftruncate(fd, totalSize); + auto fd = createAnonShm(); + if (fd < 0) { + diesys("memfd_create"); + } + if (ftruncate(fd, totalSize) < 0) { + diesys("ftruncate"); + } auto pool = wl_shm_create_pool(shm, fd, totalSize); auto ptr = reinterpret_cast(mmap(nullptr, totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); _mapping = MemoryMapping {ptr, totalSize}; @@ -34,3 +42,30 @@ ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) uint8_t* ShmBuffer::data() { return _buffers[_current].data; } wl_buffer* ShmBuffer::buffer() { return _buffers[_current].buffer.get(); } void ShmBuffer::flip() { _current = 1-_current; } + +#if defined(__linux__) +static int createAnonShm() { + return memfd_create("wl_shm", MFD_CLOEXEC); +} +#elif defined(__FreeBSD__) +static int createAnonShm() { + auto fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0600); + setCloexec(fd); + return fd; +} +#elif defined(__OpenBSD__) +static int createAnonShm() { + char name[] = "/wl_shm-XXXXXX"; + auto fd = shm_mkstemp(name); + if (fd >= 0) { + auto res = shm_unlink(name); + if (res < 0) { + return res; + } + } + setCloexec(fd); + return fd; +} +#else +#error "your system has no sane method of creating an anonymous shared memory object. no, calling shm_open in a loop is not sane." +#endif