Skip to content

Commit

Permalink
Wayland: Use memfd_create() and seals if available
Browse files Browse the repository at this point in the history
This allows the compositor to avoid having to setup and teardown a
SIGBUS signal handler whenever it needs to read from this surface, as it
knows we won’t be able to shrink the file and so doesn’t have to protect
against that.

This codepath will only be used on Linux ≥ 3.17 with glibc ≥ 2.27, and
possibly other kernels and libc.  The former code will continue to be
used as a fallback, either if memfd_create() fails or if it isn’t
available.
  • Loading branch information
linkmauve committed Oct 1, 2018
1 parent ab16fcc commit 3e884ae
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ if (_GLFW_WAYLAND)
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")

include(CheckIncludeFiles)
include(CheckFunctionExists)
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
check_function_exists(memfd_create HAVE_MEMFD_CREATE)

if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
find_package(EpollShim)
Expand Down
2 changes: 2 additions & 0 deletions src/glfw_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@

// Define this to 1 if xkbcommon supports the compose key
#cmakedefine HAVE_XKBCOMMON_COMPOSE_H
// Define this to 1 if the libc supports memfd_create()
#cmakedefine HAVE_MEMFD_CREATE

38 changes: 26 additions & 12 deletions src/wl_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,37 @@ static int createAnonymousFile(off_t size)
int fd;
int ret;

path = getenv("XDG_RUNTIME_DIR");
if (!path)
#ifdef HAVE_MEMFD_CREATE
fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd >= 0)
{
errno = ENOENT;
return -1;
// We can add this seal before calling posix_fallocate(), as the file
// is currently zero-sized anyway.
//
// There is also no need to check for the return value, we couldn’t do
// anything with it anyway.
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
}
else
#endif
{
path = getenv("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}

name = calloc(strlen(path) + sizeof(template), 1);
strcpy(name, path);
strcat(name, template);

fd = createTmpfileCloexec(name);
name = calloc(strlen(path) + sizeof(template), 1);
strcpy(name, path);
strcat(name, template);

free(name);
fd = createTmpfileCloexec(name);
free(name);
if (fd < 0)
return -1;
}

if (fd < 0)
return -1;
ret = posix_fallocate(fd, 0, size);
if (ret != 0)
{
Expand Down

0 comments on commit 3e884ae

Please sign in to comment.