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
This commit is contained in:
Frank Praznik
2025-08-29 13:12:05 -04:00
parent dc7a3a1219
commit 1049426a76
3 changed files with 45 additions and 1 deletions

View File

@@ -1126,6 +1126,7 @@ if(SDL_LIBC)
check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME)
check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE)
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(gmtime_r "time.h" HAVE_GMTIME_R)

View File

@@ -180,6 +180,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_ST_MTIM 1
#cmakedefine HAVE_SETJMP 1

View File

@@ -42,6 +42,48 @@
*/
#define PIPE_TIMEOUT_NS SDL_MS_TO_NS(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;
do {
// Check the pending signals, and call sigwait if there is at least one of interest in the set.
sigpending(&pending);
for (int 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;
@@ -77,7 +119,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);