Commit b6e63625c8bb40423e306814568788caafec35f6

Ozkan Sezer 2020-12-13T15:32:24

fix bug #5395: handle old systems where inotify_init1 is not available

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f28958..e6268f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1222,6 +1222,12 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
     endif()
 
     check_include_file("libudev.h" HAVE_LIBUDEV_H)
+    check_include_file("sys/inotify.h" HAVE_SYS_INOTIFY_H)
+    check_symbol_exists(inotify_init "sys/inotify.h" HAVE_INOTIFY_INIT)
+    check_symbol_exists(inotify_init1 "sys/inotify.h" HAVE_INOTIFY_INIT1)
+    if(HAVE_SYS_INOTIFY_H AND HAVE_INOTIFY_INIT)
+      set(HAVE_INOTIFY 1)
+    endif()
 
     if(PKG_CONFIG_FOUND)
       pkg_search_module(DBUS dbus-1 dbus)
diff --git a/configure b/configure
index 9d95014..f3c87a3 100755
--- a/configure
+++ b/configure
@@ -22984,15 +22984,48 @@ $as_echo "#define SDL_USE_IME 1" >>confdefs.h
 
 CheckInotify()
 {
-    ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
+    save_LIBS="$LIBS"
+    case "$host" in
+     *-*-freebsd*) LIBS="$LIBS -linotify"
+      ;;
+    esac
+    for ac_header in sys/inotify.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
 if test "x$ac_cv_header_sys_inotify_h" = xyes; then :
-  have_inotify_inotify_h_hdr=yes
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_INOTIFY_H 1
+_ACEOF
+ have_inotify_inotify_h_hdr=yes
 fi
 
+done
+
+    for ac_func in inotify_init
+do :
+  ac_fn_c_check_func "$LINENO" "inotify_init" "ac_cv_func_inotify_init"
+if test "x$ac_cv_func_inotify_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_INOTIFY_INIT 1
+_ACEOF
+ have_inotify=yes
+fi
+done
+
+    for ac_func in inotify_init1
+do :
+  ac_fn_c_check_func "$LINENO" "inotify_init1" "ac_cv_func_inotify_init1"
+if test "x$ac_cv_func_inotify_init1" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_INOTIFY_INIT1 1
+_ACEOF
+
+fi
+done
 
-    if test x$have_inotify_inotify_h_hdr = xyes; then
+    if test x$have_inotify_inotify_h_hdr = xyes -a x$have_inotify = xyes; then
 
-$as_echo "#define HAVE_INOTIFY_H 1" >>confdefs.h
+$as_echo "#define HAVE_INOTIFY 1" >>confdefs.h
 
         case "$host" in
             *-*-freebsd*)
@@ -23000,6 +23033,7 @@ $as_echo "#define HAVE_INOTIFY_H 1" >>confdefs.h
                 ;;
         esac
     fi
+    LIBS="save_$LIBS"
 }
 
 CheckIBus()
diff --git a/configure.ac b/configure.ac
index 6337e12..172e7db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2725,15 +2725,23 @@ AS_HELP_STRING([--enable-ime], [enable IME support [[default=yes]]]),
 dnl Check inotify presense
 CheckInotify()
 {
-    AC_CHECK_HEADER(sys/inotify.h, have_inotify_inotify_h_hdr=yes)
-    if test x$have_inotify_inotify_h_hdr = xyes; then
-        AC_DEFINE(HAVE_INOTIFY_H, 1, [ ])
+    save_LIBS="$LIBS"
+    case "$host" in
+     *-*-freebsd*) LIBS="$LIBS -linotify"
+      ;;
+    esac
+    AC_CHECK_HEADERS(sys/inotify.h, [have_inotify_inotify_h_hdr=yes])
+    AC_CHECK_FUNCS(inotify_init, [have_inotify=yes])
+    AC_CHECK_FUNCS(inotify_init1)
+    if test x$have_inotify_inotify_h_hdr = xyes -a x$have_inotify = xyes; then
+        AC_DEFINE(HAVE_INOTIFY, 1, [ ])
         case "$host" in
             *-*-freebsd*)
                 EXTRA_LDFLAGS="$EXTRA_LDFLAGS -linotify"
                 ;;
         esac
     fi
+    LIBS="save_$LIBS"
 }
 
 dnl See if the platform has libibus IME support.
diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake
index eef38f2..0f8a662 100644
--- a/include/SDL_config.h.cmake
+++ b/include/SDL_config.h.cmake
@@ -211,9 +211,13 @@
 #cmakedefine HAVE_DBUS_DBUS_H 1
 #cmakedefine HAVE_FCITX 1
 #cmakedefine HAVE_IBUS_IBUS_H 1
+#cmakedefine HAVE_SYS_INOTIFY_H 1
+#cmakedefine HAVE_INOTIFY_INIT 1
+#cmakedefine HAVE_INOTIFY_INIT1 1
+#cmakedefine HAVE_INOTIFY 1
 #cmakedefine HAVE_IMMINTRIN_H 1
-#cmakedefine HAVE_LIBSAMPLERATE_H 1
 #cmakedefine HAVE_LIBUDEV_H 1
+#cmakedefine HAVE_LIBSAMPLERATE_H 1
 
 #cmakedefine HAVE_D3D_H @HAVE_D3D_H@
 #cmakedefine HAVE_D3D11_H @HAVE_D3D11_H@
diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in
index ee9b434..b4f338b 100644
--- a/include/SDL_config.h.in
+++ b/include/SDL_config.h.in
@@ -211,11 +211,14 @@
 #undef HAVE_ALTIVEC_H
 #undef HAVE_DBUS_DBUS_H
 #undef HAVE_FCITX
-#undef HAVE_INOTIFY_H
+#undef HAVE_SYS_INOTIFY_H
+#undef HAVE_INOTIFY_INIT
+#undef HAVE_INOTIFY_INIT1
+#undef HAVE_INOTIFY
 #undef HAVE_IBUS_IBUS_H
 #undef HAVE_IMMINTRIN_H
-#undef HAVE_LIBSAMPLERATE_H
 #undef HAVE_LIBUDEV_H
+#undef HAVE_LIBSAMPLERATE_H
 
 #undef HAVE_DDRAW_H
 #undef HAVE_DINPUT_H
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index eefe381..10cebb0 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -32,7 +32,7 @@
 #include <errno.h>              /* errno, strerror */
 #include <fcntl.h>
 #include <limits.h>             /* For the definition of PATH_MAX */
-#ifdef HAVE_INOTIFY_H
+#ifdef HAVE_INOTIFY
 #include <sys/inotify.h>
 #endif
 #include <sys/ioctl.h>
@@ -499,7 +499,21 @@ static void SteamControllerDisconnectedCallback(int device_instance)
     }
 }
 
-#ifdef HAVE_INOTIFY_H
+#ifdef HAVE_INOTIFY
+#ifdef HAVE_INOTIFY_INIT1
+static int SDL_inotify_init1(void) {
+    return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+}
+#else
+static int SDL_inotify_init1(void) {
+    int fd = inotify_init();
+    if (fd  < 0) return -1;
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+    fcntl(fd, F_SETFD, FD_CLOEXEC);
+    return fd;
+}
+#endif
+
 static int
 StrHasPrefix(const char *string, const char *prefix)
 {
@@ -568,7 +582,7 @@ LINUX_InotifyJoystickDetect(void)
         }
     }
 }
-#endif /* HAVE_INOTIFY_H */
+#endif /* HAVE_INOTIFY */
 
 /* Detect devices by reading /dev/input. In the inotify code path we
  * have to do this the first time, to detect devices that already existed
@@ -618,7 +632,7 @@ LINUX_JoystickDetect(void)
     }
     else
 #endif
-#ifdef HAVE_INOTIFY_H
+#ifdef HAVE_INOTIFY
     if (inotify_fd >= 0 && last_joy_detect_time != 0) {
         LINUX_InotifyJoystickDetect();
     }
@@ -698,8 +712,8 @@ LINUX_JoystickInit(void)
     else
 #endif
     {
-#ifdef HAVE_INOTIFY_H
-        inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+#if defined(HAVE_INOTIFY)
+        inotify_fd = SDL_inotify_init1();
 
         if (inotify_fd < 0) {
             SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
@@ -720,7 +734,7 @@ LINUX_JoystickInit(void)
                             strerror (errno));
             }
         }
-#endif /* HAVE_INOTIFY_H */
+#endif /* HAVE_INOTIFY */
 
         /* Report all devices currently present */
         LINUX_JoystickDetect();