... which then can be mapped with mmap(). It is intended to be used in conjunction with xcb_shm_attach_fd() to access the created shared memory from a client and the X server.
Signed-off-by: Alexander Volkov <[email protected]> --- configure.ac | 47 +++++++++++++++++++++++++++++ src/xcb_aux.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/xcb_aux.h | 3 ++ 3 files changed, 133 insertions(+) diff --git a/configure.ac b/configure.ac index 1fe1561..81e1f6b 100644 --- a/configure.ac +++ b/configure.ac @@ -7,10 +7,57 @@ AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AC_USE_SYSTEM_EXTENSIONS + XCB_UTIL_COMMON([1.4], [1.6]) AC_CHECK_FUNCS_ONCE(vasprintf) +AC_CHECK_FUNCS(memfd_create mkostemp) + +AC_CHECK_DECLS([__NR_memfd_create], [], [], [[#include <asm/unistd.h>]]) + +AC_CHECK_HEADERS([sys/memfd.h], [AC_DEFINE([HAVE_MEMFD_H], 1, [Has sys/memfd.h header])]) + +AC_ARG_WITH(shared-memory-dir, AS_HELP_STRING([--with-shared-memory-dir=PATH], [Path to directory in a world-writable temporary directory for anonymous shared memory (default: auto)]), +[], +[with_shared_memory_dir=yes]) + +shmdirs="/run/shm /dev/shm /var/tmp /tmp" + +case x"$with_shared_memory_dir" in +xyes) + for dir in $shmdirs; do + case x"$with_shared_memory_dir" in + xyes) + echo Checking temp dir "$dir" + if test -d "$dir"; then + with_shared_memory_dir="$dir" + fi + ;; + esac + done + ;; +x/*) + ;; +xno) + ;; +*) + AC_MSG_ERROR([Invalid directory specified for --with-shared-memory-dir: $with_shared_memory_dir]) + ;; +esac + +case x"$with_shared_memory_dir" in +xyes) + AC_MSG_ERROR([No directory found for shared memory temp files.]) + ;; +xno) + ;; +*) + AC_DEFINE_UNQUOTED(SHMDIR, ["$with_shared_memory_dir"], [Directory for shared memory temp files]) + ;; +esac + AC_CONFIG_FILES([Makefile src/Makefile xcb-atom.pc diff --git a/src/xcb_aux.c b/src/xcb_aux.c index b6f64f8..e8f7ba9 100644 --- a/src/xcb_aux.c +++ b/src/xcb_aux.c @@ -33,9 +33,39 @@ #include "config.h" #endif +#if !HAVE_MEMFD_CREATE +#if HAVE_DECL___NR_MEMFD_CREATE +#include <unistd.h> +#include <sys/syscall.h> +static int memfd_create(const char *name, + unsigned int flags) +{ + return syscall(__NR_memfd_create, name, flags); +} +#define HAVE_MEMFD_CREATE 1 +#endif +#endif + +#if HAVE_MEMFD_CREATE + +/* Get defines for the memfd_create syscall, using the + * header if available, or just defining the constants otherwise + */ + +#if HAVE_MEMFD_H +#include <sys/memfd.h> +#else +/* flags for memfd_create(2) (unsigned int) */ +#define MFD_CLOEXEC 0x0001U +#define MFD_ALLOW_SEALING 0x0002U +#endif + +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <fcntl.h> #include <xcb/xcb.h> #include "xcb_aux.h" @@ -376,3 +406,56 @@ xcb_aux_clear_window(xcb_connection_t * dpy, { return xcb_clear_area(dpy, 0, w, 0, 0, 0, 0); } + +/* SHM related functions */ + +/** + * xcb_aux_alloc_shm: + * + * Creates an anonymous file of the required size in RAM. + * This function is intended for use in conjunction with + * xcb_shm_attach_fd(). + * + * Return value: the file descriptor, or -1 on failure + * (in which case, errno will be set as appropriate). + **/ +int +xcb_aux_alloc_shm(size_t size) +{ + char template[] = SHMDIR "/shmfd-XXXXXX"; + int fd; + +#if HAVE_MEMFD_CREATE + fd = memfd_create("xcb_aux", MFD_CLOEXEC|MFD_ALLOW_SEALING); + if (fd < 0) +#endif + { +#ifdef O_TMPFILE + fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); + if (fd < 0) +#endif + { +#ifndef HAVE_MKOSTEMP + int flags; + fd = mkstemp(template); +#else + fd = mkostemp(template, O_CLOEXEC); +#endif + if (fd < 0) + return fd; + unlink(template); +#ifndef HAVE_MKOSTEMP + flags = fcntl(fd, F_GETFD); + if (flags != -1) { + flags |= FD_CLOEXEC; + (void) fcntl(fd, F_SETFD, &flags); + } +#endif + } + } + if (ftruncate(fd, size) < 0) { + close(fd); + return -1; + } + return fd; +} diff --git a/src/xcb_aux.h b/src/xcb_aux.h index da4fb85..75b6e66 100644 --- a/src/xcb_aux.h +++ b/src/xcb_aux.h @@ -206,6 +206,9 @@ xcb_void_cookie_t xcb_aux_clear_window(xcb_connection_t * dpy, xcb_window_t w); +int +xcb_aux_alloc_shm(size_t size); + #ifdef __cplusplus } #endif -- 2.17.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
