|
40 | 40 | */ |
41 | 41 | #define PIPE_MS_TIMEOUT 14 |
42 | 42 |
|
| 43 | +/* sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it. |
| 44 | + * Based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation |
| 45 | + */ |
| 46 | +#ifndef HAVE_SIGTIMEDWAIT |
| 47 | +#include <errno.h> |
| 48 | +#include <time.h> |
| 49 | +static int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) |
| 50 | +{ |
| 51 | + struct timespec elapsed = { 0 }, rem = { 0 }; |
| 52 | + sigset_t pending; |
| 53 | + int signo; |
| 54 | + do { |
| 55 | + /* Check the pending signals, and call sigwait if there is at least one of interest in the set. */ |
| 56 | + sigpending(&pending); |
| 57 | + for (signo = 1; signo < NSIG; ++signo) { |
| 58 | + if (sigismember(set, signo) && sigismember(&pending, signo)) { |
| 59 | + if (!sigwait(set, &signo)) { |
| 60 | + if (info) { |
| 61 | + SDL_memset(info, 0, sizeof *info); |
| 62 | + info->si_signo = signo; |
| 63 | + } |
| 64 | + return signo; |
| 65 | + } else { |
| 66 | + return -1; |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + if (timeout->tv_sec || timeout->tv_nsec) { |
| 72 | + long ns = 20000000L; // 2/100ths of a second |
| 73 | + nanosleep(&(struct timespec){ 0, ns }, &rem); |
| 74 | + ns -= rem.tv_nsec; |
| 75 | + elapsed.tv_sec += (elapsed.tv_nsec + ns) / 1000000000L; |
| 76 | + elapsed.tv_nsec = (elapsed.tv_nsec + ns) % 1000000000L; |
| 77 | + } |
| 78 | + } while (elapsed.tv_sec < timeout->tv_sec || (elapsed.tv_sec == timeout->tv_sec && elapsed.tv_nsec < timeout->tv_nsec)); |
| 79 | + |
| 80 | + errno = EAGAIN; |
| 81 | + return -1; |
| 82 | +} |
| 83 | +#endif |
| 84 | + |
43 | 85 | static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos) |
44 | 86 | { |
45 | 87 | int ready = 0; |
@@ -75,7 +117,7 @@ static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_ |
75 | 117 | } |
76 | 118 | } |
77 | 119 |
|
78 | | - sigtimedwait(&sig_set, 0, &zerotime); |
| 120 | + sigtimedwait(&sig_set, NULL, &zerotime); |
79 | 121 |
|
80 | 122 | #ifdef SDL_THREADS_DISABLED |
81 | 123 | sigprocmask(SIG_SETMASK, &old_sig_set, NULL); |
|
0 commit comments