[Xcb] [PATCH] Introduce xcb_aux_alloc_shm() to create anonymous files in RAM
Uli Schlachter
psychon at znc.in
Fri Apr 13 06:47:53 UTC 2018
On 10.04.2018 13:38, Alexander Volkov wrote:
> ... 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.volkov at 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)]),
Default is yes, not auto. See next two lines.
> +[],
> +[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)
How many shells are there that do not like "break"? :-/
(And does autoconf provide some way to make this loop nicer?)
> + 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
So, if I do --with-shared-memory-dir=/foobar, configure will tell me
that I specified an invalid directory? Why?? And why does this flag
exist at all, i.e. what would be uses for it?
Also, why does the existence of a directory at compile time have any
significance at run time? What about cross compiling? Building a distro
package with /run/shm existing and then running it on another system
that does not have /run/shm?
I really think that this compile time check is plain wrong.
Also, is it really worth it to have all these different cases?
- Linux with updated glibc that provides a memfd_create() wrapper
- Linux with older glibc where this code provides its own wrapper
- Older Linux with memfd_create() (-> mkostemp())
- Anything else (-> mkstemp())
How about dropping the second one (own syscall wrapper if glibc does not
provide one). Oh and how about making sys/memfd.h required instead of
providing the defines here instead, if needed.
What would be the downside of this? How many people would complain?
> 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
This looks quite linux-specific. Is it worth adding a linux-specific #if
in here in case any other platform ever implements this API as well and
assigns flags differently?
Also, why MFD_ALLOW_SEALING?
[...]
> +int
> +xcb_aux_alloc_shm(size_t size)
Should the documentation mention anything about sealing? close-on-exec?
> +{
> + char template[] = SHMDIR "/shmfd-XXXXXX";
This uses shmfd, but...
> + int fd;
> +
> +#if HAVE_MEMFD_CREATE
> + fd = memfd_create("xcb_aux", MFD_CLOEXEC|MFD_ALLOW_SEALING);
[...]
...this uses xcb_aux.
Shouldn't they best use the same template name?
Cheers,
Uli
--
Happiness can't be found -- it finds you.
- Majic
More information about the xorg-devel
mailing list