[[PATCH,RFC,2] 22/63] Y2038: add function __sigtimedwait64
Commit Message
---
signal/sigtimedwait.c | 10 +++++
sysdeps/unix/sysv/linux/sigtimedwait.c | 76 ++++++++++++++++++++++++++++++++++
time/Versions | 1 +
3 files changed, 87 insertions(+)
@@ -30,3 +30,13 @@ libc_hidden_def (__sigtimedwait)
weak_alias (__sigtimedwait, sigtimedwait)
stub_warning (sigtimedwait)
+
+int
+__sigtimedwait64 (const sigset_t *set, siginfo_t *info,
+ const struct __timespec64 *timeout)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (__sigtimedwait64)
@@ -18,6 +18,9 @@
#include <errno.h>
#include <signal.h>
#include <string.h>
+//#include <stdint.h>
+
+//#include <nptl/pthreadP.h>
#include <sysdep-cancel.h>
int
@@ -39,3 +42,76 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info,
}
libc_hidden_def (__sigtimedwait)
weak_alias (__sigtimedwait, sigtimedwait)
+
+/* 64-bit time version */
+
+extern int __y2038_linux_support;
+
+int
+__sigtimedwait64 (const sigset_t *set, siginfo_t *info,
+ const struct __timespec64 *timeout)
+{
+ int result;
+ struct __timespec64 ts64;
+ struct timespec ts32;
+
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+
+ if (__y2038_linux_support)
+ {
+ if (timeout)
+ {
+ ts64.tv_sec = timeout->tv_sec;
+ ts64.tv_nsec = timeout->tv_nsec;
+ ts64.tv_pad = 0;
+ result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, &ts64, _NSIG / 8);
+ }
+ else
+ result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, NULL, _NSIG / 8);
+ }
+ else
+ {
+ if (timeout)
+ {
+ if (! timespec64_to_timespec(timeout, &ts32))
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, &ts32, _NSIG / 8);
+ }
+ else
+ result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, NULL, _NSIG / 8);
+ }
+
+ /* The kernel generates a SI_TKILL code in si_code in case tkill is
+ used. tkill is transparently used in raise(). Since having
+ SI_TKILL as a code is useful in general we fold the results
+ here. */
+ if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+ info->si_code = SI_USER;
+
+ return result;
+}
+
@@ -81,5 +81,6 @@ libc {
__timespec_get64;
__futimens64;
__utimensat64;
+ __sigtimedwait64;
}
}