From 24ff42d79aab60651113d60b5a8e9081c15acd82 Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Thu, 14 Dec 2017 17:05:55 -0800 Subject: [PATCH] Cygwin: Implement sigtimedwait Abstract out common code from sigwait/sigwaitinfo/sigtimedwait to implement the latter. --- winsup/cygwin/common.din | 1 + winsup/cygwin/include/cygwin/version.h | 3 ++- winsup/cygwin/signal.cc | 36 ++++++++++++++++++++++++-- winsup/cygwin/thread.cc | 2 +- winsup/doc/posix.xml | 2 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 14b9c2c18..91f2915bf 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1326,6 +1326,7 @@ sigrelse SIGFE sigset SIGFE sigsetjmp NOSIGFE sigsuspend SIGFE +sigtimedwait SIGFE sigwait SIGFE sigwaitinfo SIGFE sin NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 0fee73c1d..aa7c14ec3 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -492,12 +492,13 @@ details. */ 321: Export wmempcpy. 322: [w]scanf %m modifier. 323: scanf %l[ conversion. + 324: Export sigtimedwait. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 323 +#define CYGWIN_VERSION_API_MINOR 324 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 69c5e2aad..16210b571 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -575,6 +575,29 @@ siginterrupt (int sig, int flag) return res; } +static int sigwait_common (const sigset_t *, siginfo_t *, PLARGE_INTEGER); + +extern "C" int +sigtimedwait (const sigset_t *set, siginfo_t *info, const timespec *timeout) +{ + LARGE_INTEGER waittime; + + if (timeout) + { + if (timeout->tv_sec < 0 + || timeout->tv_nsec < 0 || timeout->tv_nsec > (NSPERSEC * 100LL)) + { + set_errno (EINVAL); + return -1; + } + /* convert timespec to 100ns units */ + waittime.QuadPart = (LONGLONG) timeout->tv_sec * NSPERSEC + + ((LONGLONG) timeout->tv_nsec + 99LL) / 100LL; + } + + return sigwait_common (set, info, timeout ? &waittime : cw_infinite); +} + extern "C" int sigwait (const sigset_t *set, int *sig_ptr) { @@ -582,7 +605,7 @@ sigwait (const sigset_t *set, int *sig_ptr) do { - sig = sigwaitinfo (set, NULL); + sig = sigwait_common (set, NULL, cw_infinite); } while (sig == -1 && get_errno () == EINTR); if (sig > 0) @@ -592,6 +615,12 @@ sigwait (const sigset_t *set, int *sig_ptr) extern "C" int sigwaitinfo (const sigset_t *set, siginfo_t *info) +{ + return sigwait_common (set, info, cw_infinite); +} + +static int +sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) { int res = -1; @@ -602,7 +631,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) set_signal_mask (_my_tls.sigwait_mask, *set); sig_dispatch_pending (true); - switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self)) + switch (cygwait (NULL, waittime, cw_sig_eintr | cw_cancel | cw_cancel_self)) { case WAIT_SIGNALED: if (!sigismember (set, _my_tls.infodata.si_signo)) @@ -619,6 +648,9 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) _my_tls.unlock (); } break; + case WAIT_TIMEOUT: + set_errno (EAGAIN); + break; default: __seterrno (); break; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index b9b2c7aaa..f3c709a15 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -708,7 +708,7 @@ pthread::cancel () * sendto () * sigpause () * sigsuspend () - o sigtimedwait () + * sigtimedwait () * sigwait () * sigwaitinfo () * sleep () diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index ab574300f..2664159e1 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -888,6 +888,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). sigset sigsetjmp sigsuspend + sigtimedwait sigwait sigwaitinfo sin @@ -1582,7 +1583,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). pthread_mutex_consistent putmsg setnetent - sigtimedwait timer_getoverrun ulimit waitid