SDL: Add utility function to detect if SDL is inside a sandbox

From e8cb4da71f6b23fdb0714b891ef3a31b94f0424c Mon Sep 17 00:00:00 2001
From: Ludovico de Nittis <[EMAIL REDACTED]>
Date: Fri, 26 Aug 2022 12:28:33 +0200
Subject: [PATCH] Add utility function to detect if SDL is inside a sandbox

Refactor the previous sandbox check in a standalone function that also
includes Snap support.

Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
---
 CMakeLists.txt                           |  1 +
 configure                                |  1 +
 configure.ac                             |  1 +
 src/core/linux/SDL_sandbox.c             | 50 ++++++++++++++++++++++++
 src/core/linux/SDL_sandbox.h             | 39 ++++++++++++++++++
 src/hidapi/SDL_hidapi.c                  |  7 +---
 src/joystick/hidapi/SDL_hidapijoystick.c |  9 ++---
 src/joystick/linux/SDL_sysjoystick.c     |  8 +---
 8 files changed, 100 insertions(+), 16 deletions(-)
 create mode 100644 src/core/linux/SDL_sandbox.c
 create mode 100644 src/core/linux/SDL_sandbox.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7541b34396..45f0fc9d083 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1509,6 +1509,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
     # Always compiled for Linux, unconditionally:
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c")
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c")
+    list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_sandbox.c")
 
     # src/core/unix/*.c is included in a generic if(UNIX) section, elsewhere.
   endif()
diff --git a/configure b/configure
index edd52dd1240..f1937782134 100755
--- a/configure
+++ b/configure
@@ -28590,6 +28590,7 @@ printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h
         # Set up other core UNIX files
         SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c"
         SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c"
+        SOURCES="$SOURCES $srcdir/src/core/linux/SDL_sandbox.c"
         SOURCES="$SOURCES $srcdir/src/core/unix/*.c"
         ;;
     *-*-cygwin* | *-*-mingw*)
diff --git a/configure.ac b/configure.ac
index 4d2249f5407..b539f614823 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3955,6 +3955,7 @@ case "$host" in
         # Set up other core UNIX files
         SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c"
         SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c"
+        SOURCES="$SOURCES $srcdir/src/core/linux/SDL_sandbox.c"
         SOURCES="$SOURCES $srcdir/src/core/unix/*.c"
         ;;
     *-*-cygwin* | *-*-mingw*)
diff --git a/src/core/linux/SDL_sandbox.c b/src/core/linux/SDL_sandbox.c
new file mode 100644
index 00000000000..e266e5e5ca8
--- /dev/null
+++ b/src/core/linux/SDL_sandbox.c
@@ -0,0 +1,50 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 2022 Collabora Ltd.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "../../SDL_internal.h"
+#include "SDL_sandbox.h"
+
+#include <unistd.h>
+
+SDL_Sandbox SDL_DetectSandbox(void)
+{
+    if (access("/.flatpak-info", F_OK) == 0) {
+        return SDL_SANDBOX_FLATPAK;
+    }
+
+    /* For Snap, we check multiple variables because they might be set for
+     * unrelated reasons. This is the same thing WebKitGTK does. */
+    if (SDL_getenv("SNAP") != NULL
+        && SDL_getenv("SNAP_NAME") != NULL
+        && SDL_getenv("SNAP_REVISION") != NULL) {
+        return SDL_SANDBOX_SNAP;
+    }
+
+    if (access("/run/host/container-runtime", F_OK) == 0) {
+        return SDL_SANDBOX_UNKNOWN_CONTAINER;
+    }
+
+    return SDL_SANDBOX_NONE;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/core/linux/SDL_sandbox.h b/src/core/linux/SDL_sandbox.h
new file mode 100644
index 00000000000..22be6902579
--- /dev/null
+++ b/src/core/linux/SDL_sandbox.h
@@ -0,0 +1,39 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 2022 Collabora Ltd.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_SANDBOX_H
+#define SDL_SANDBOX_H
+
+typedef enum
+{
+    SDL_SANDBOX_NONE = 0,
+    SDL_SANDBOX_UNKNOWN_CONTAINER,
+    SDL_SANDBOX_FLATPAK,
+    SDL_SANDBOX_SNAP,
+} SDL_Sandbox;
+
+/* Return the sandbox type currently in use, if any */
+SDL_Sandbox SDL_DetectSandbox(void);
+
+#endif /* SDL_SANDBOX_H */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index 718e5c192d6..82abcbd2982 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -53,6 +53,7 @@
 #ifdef SDL_USE_LIBUDEV
 #include <poll.h>
 #include <unistd.h>
+#include "../core/linux/SDL_sandbox.h"
 #endif
 
 #ifdef HAVE_INOTIFY
@@ -1018,11 +1019,7 @@ int SDL_hid_init(void)
         SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                      "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV");
         linux_enumeration_method = ENUMERATION_FALLBACK;
-    } else if (access("/.flatpak-info", F_OK) == 0
-               || access("/run/host/container-manager", F_OK) == 0) {
-        /* Explicitly check `/.flatpak-info` because, for old versions of
-         * Flatpak, this was the only available way to tell if we were in
-         * a Flatpak container. */
+    } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
         SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                      "Container detected, disabling HIDAPI udev integration");
         linux_enumeration_method = ENUMERATION_FALLBACK;
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index 35068714993..275db1734f7 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -36,6 +36,9 @@
 #include "../windows/SDL_rawinputjoystick_c.h"
 #endif
 
+#ifdef SDL_USE_LIBUDEV
+#include "../../core/linux/SDL_sandbox.h"
+#endif
 
 struct joystick_hwdata
 {
@@ -398,11 +401,7 @@ HIDAPI_JoystickInit(void)
             SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                          "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV");
             linux_enumeration_method = ENUMERATION_FALLBACK;
-        } else if (access("/.flatpak-info", F_OK) == 0
-                   || access("/run/host/container-manager", F_OK) == 0) {
-            /* Explicitly check `/.flatpak-info` because, for old versions of
-             * Flatpak, this was the only available way to tell if we were in
-             * a Flatpak container. */
+        } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
             SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                          "Container detected, disabling HIDAPI udev integration");
             linux_enumeration_method = ENUMERATION_FALLBACK;
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index e96e5b0aa29..4e3da5dde66 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -77,6 +77,7 @@
 
 #include "../../core/linux/SDL_evdev_capabilities.h"
 #include "../../core/linux/SDL_udev.h"
+#include "../../core/linux/SDL_sandbox.h"
 
 #if 0
 #define DEBUG_INPUT_EVENTS 1
@@ -756,12 +757,7 @@ LINUX_JoystickInit(void)
             SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                          "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
             enumeration_method = ENUMERATION_FALLBACK;
-
-        } else if (access("/.flatpak-info", F_OK) == 0
-                 || access("/run/host/container-manager", F_OK) == 0) {
-            /* Explicitly check `/.flatpak-info` because, for old versions of
-             * Flatpak, this was the only available way to tell if we were in
-             * a Flatpak container. */
+        } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
             SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                          "Container detected, disabling udev integration");
             enumeration_method = ENUMERATION_FALLBACK;