Browse Source

wayland: Add a sigtimedwait() implementation for OpenBSD

sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it. Add a replacement implementation based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation

(backported from commit 1049426a765cc38e94f65a839b156852d86e3b57)
Frank Praznik 1 week ago
parent
commit
d31d98d436
6 changed files with 54 additions and 4 deletions
  1. 1 0
      CMakeLists.txt
  2. 6 1
      configure
  3. 1 2
      configure.ac
  4. 1 0
      include/SDL_config.h.cmake
  5. 2 0
      include/SDL_config.h.in
  6. 43 1
      src/video/wayland/SDL_waylanddatamanager.c

+ 1 - 0
CMakeLists.txt

@@ -1099,6 +1099,7 @@ if(SDL_LIBC)
     endforeach()
 
     check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
+    check_symbol_exists(sigtimedwait "signal.h" HAVE_SIGTIMEDWAIT)
     check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP)
     check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP)
     check_symbol_exists(sysconf "unistd.h" HAVE_SYSCONF)

+ 6 - 1
configure

@@ -19755,6 +19755,12 @@ if test "x$ac_cv_func_sigaction" = xyes
 then :
   printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "sigtimedwait" "ac_cv_func_sigtimedwait"
+if test "x$ac_cv_func_sigtimedwait" = xyes
+then :
+  printf "%s\n" "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h
+
 fi
 ac_fn_c_check_func "$LINENO" "setjmp" "ac_cv_func_setjmp"
 if test "x$ac_cv_func_setjmp" = xyes
@@ -22422,7 +22428,6 @@ printf %s "checking for NAS audio support... " >&6; }
             have_nas=yes
             NAS_CFLAGS="-I/usr/X11R6/include/"
             NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt"
-
         fi
 
         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_nas" >&5

+ 1 - 2
configure.ac

@@ -359,7 +359,7 @@ dnl Checks for library functions.
         AC_DEFINE(HAVE_MPROTECT, 1, [ ])
         ],[]),
     )
-    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcmp memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtod strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll memfd_create posix_fallocate _Exit)
+    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcmp memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtod strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction sigtimedwait setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll memfd_create posix_fallocate _Exit)
 
     AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
     AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf trunc truncf fmod fmodf log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt sqrtf tan tanf)
@@ -1247,7 +1247,6 @@ CheckNAS()
             have_nas=yes
             NAS_CFLAGS="-I/usr/X11R6/include/"
             NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt"
-
         fi
 
         AC_MSG_RESULT($have_nas)

+ 1 - 0
include/SDL_config.h.cmake

@@ -193,6 +193,7 @@
 #cmakedefine HAVE_MEMFD_CREATE 1
 #cmakedefine HAVE_POSIX_FALLOCATE 1
 #cmakedefine HAVE_SIGACTION 1
+#cmakedefine HAVE_SIGTIMEDWAIT 1
 #cmakedefine HAVE_SA_SIGACTION 1
 #cmakedefine HAVE_SETJMP 1
 #cmakedefine HAVE_NANOSLEEP 1

+ 2 - 0
include/SDL_config.h.in

@@ -195,6 +195,7 @@
 #undef HAVE_FSEEKO
 #undef HAVE_FSEEKO64
 #undef HAVE_SIGACTION
+#undef HAVE_SIGTIMEDWAIT
 #undef HAVE_SA_SIGACTION
 #undef HAVE_SETJMP
 #undef HAVE_NANOSLEEP
@@ -216,6 +217,7 @@
 #undef HAVE__EXIT
 
 #else
+
 #define HAVE_STDARG_H 1
 #define HAVE_STDDEF_H 1
 #define HAVE_STDINT_H 1

+ 43 - 1
src/video/wayland/SDL_waylanddatamanager.c

@@ -40,6 +40,48 @@
  */
 #define PIPE_MS_TIMEOUT 14
 
+/* sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it.
+ * Based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation
+ */
+#ifndef HAVE_SIGTIMEDWAIT
+#include <errno.h>
+#include <time.h>
+static int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
+{
+    struct timespec elapsed = { 0 }, rem = { 0 };
+    sigset_t pending;
+    int signo;
+    do {
+        /* Check the pending signals, and call sigwait if there is at least one of interest in the set. */
+        sigpending(&pending);
+        for (signo = 1; signo < NSIG; ++signo) {
+            if (sigismember(set, signo) && sigismember(&pending, signo)) {
+                if (!sigwait(set, &signo)) {
+                    if (info) {
+                        SDL_memset(info, 0, sizeof *info);
+                        info->si_signo = signo;
+                    }
+                    return signo;
+                } else {
+                    return -1;
+                }
+            }
+        }
+
+        if (timeout->tv_sec || timeout->tv_nsec) {
+            long ns = 20000000L; // 2/100ths of a second
+            nanosleep(&(struct timespec){ 0, ns }, &rem);
+            ns -= rem.tv_nsec;
+            elapsed.tv_sec += (elapsed.tv_nsec + ns) / 1000000000L;
+            elapsed.tv_nsec = (elapsed.tv_nsec + ns) % 1000000000L;
+        }
+    } while (elapsed.tv_sec < timeout->tv_sec || (elapsed.tv_sec == timeout->tv_sec && elapsed.tv_nsec < timeout->tv_nsec));
+
+    errno = EAGAIN;
+    return -1;
+}
+#endif
+
 static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos)
 {
     int ready = 0;
@@ -75,7 +117,7 @@ static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_
         }
     }
 
-    sigtimedwait(&sig_set, 0, &zerotime);
+    sigtimedwait(&sig_set, NULL, &zerotime);
 
 #ifdef SDL_THREADS_DISABLED
     sigprocmask(SIG_SETMASK, &old_sig_set, NULL);