diff options
author | Ray Strode <rstrode@redhat.com> | 2016-05-12 15:52:12 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2016-06-16 12:02:51 -0400 |
commit | 2f3cb31e55d698fe6ddcc8126b9d1342268a1a98 (patch) | |
tree | 05b704dfb2d1f14dd43589cb84fb462f5905545b /gdk/wayland/gdkdisplay-wayland.c | |
parent | bb2ca3b94d53c009c78d0f364c41ae0220ea2c9e (diff) | |
download | gtk+-2f3cb31e55d698fe6ddcc8126b9d1342268a1a98.tar.gz |
wayland: fall back to shm_open if memfd unavailable
Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.
This commit adds shm_open fall back code for that case
(for now).
https://bugzilla.gnome.org/show_bug.cgi?id=766341
Diffstat (limited to 'gdk/wayland/gdkdisplay-wayland.c')
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 9f78f29802..d8b71b7999 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -22,7 +22,11 @@ #include <errno.h> #include <unistd.h> #include <fcntl.h> + +#ifdef HAVE_LINUX_MEMFD_H #include <linux/memfd.h> +#endif + #include <sys/mman.h> #include <sys/syscall.h> @@ -1107,16 +1111,47 @@ typedef struct _GdkWaylandCairoSurfaceData { static int open_shared_memory (void) { - int ret; + static gboolean force_shm_open = FALSE; + int ret = -1; + +#if !defined (__NR_memfd_create) + force_shm_open = TRUE; +#endif do { - ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC); +#if defined (__NR_memfd_create) + if (!force_shm_open) + { + ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC); + + /* fall back to shm_open until debian stops shipping 3.16 kernel + * See bug 766341 + */ + if (ret < 0 && errno == ENOSYS) + force_shm_open = TRUE; + } +#endif + + if (force_shm_open) + { + char name[NAME_MAX - 1] = ""; + + sprintf (name, "/gdk-wayland-%x", g_random_int ()); + + ret = shm_open (name, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600); + + if (ret >= 0) + shm_unlink (name); + else if (errno == EEXIST) + continue; + } } while (ret < 0 && errno == EINTR); if (ret < 0) - g_critical (G_STRLOC ": creating shared memory file failed: %m"); + g_critical (G_STRLOC ": creating shared memory file (using %s) failed: %m", + force_shm_open? "shm_open" : "memfd_create"); return ret; } |