... 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 <a.vol...@rusbitech.ru>
---
 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

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to