Add support for using time64 on big-endian machines.
[uclibc-ng.git] / libc / sysdeps / linux / common / __rt_sigtimedwait.c
blobaff5299a1e8bb648a3f5e1a3072d070e612fc94d
1 /*
2 * __rt_sigtimedwait() for uClibc
4 * Copyright (C) 2006 by Steven Hill <sjhill@realitydiluted.com>
5 * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
7 * GNU Library General Public License (LGPL) version 2 or later.
8 */
10 #include <sys/syscall.h>
12 #if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
13 # include <signal.h>
14 # include <cancel.h>
15 # ifdef __UCLIBC_HAS_THREADS_NATIVE__
16 # include <pthreadP.h> /* SIGCANCEL */
17 # endif
18 # ifdef SIGCANCEL
19 # define __need_NULL
20 # include <stddef.h>
21 # include <string.h>
22 # endif
24 #if defined(__UCLIBC_USE_TIME64__)
25 #include "internal/time64_helpers.h"
26 #endif
28 int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
29 const struct timespec *timeout)
31 # if defined SI_TKILL && defined SI_USER
32 int result;
33 # endif
34 # ifdef SIGCANCEL
35 sigset_t tmpset;
37 if (set != NULL && (unlikely (__sigismember (set, SIGCANCEL))
38 # ifdef SIGSETXID
39 || unlikely (__sigismember (set, SIGSETXID))
40 # endif
43 /* Create a temporary mask without the bit for SIGCANCEL set. */
44 // We are not copying more than we have to.
45 memcpy (&tmpset, set, _NSIG / 8);
46 __sigdelset (&tmpset, SIGCANCEL);
47 # ifdef SIGSETXID
48 __sigdelset (&tmpset, SIGSETXID);
49 # endif
50 set = &tmpset;
52 # endif
54 /* if this is enabled, enable the disabled section in sigwait.c */
55 # if defined SI_TKILL && defined SI_USER
56 /* XXX The size argument hopefully will have to be changed to the
57 real size of the user-level sigset_t. */
58 /* on uClibc we use the kernel sigset_t size */
59 # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
60 result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
61 TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
62 # else
63 result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
64 timeout, __SYSCALL_SIGSET_T_SIZE);
65 # endif
67 /* The kernel generates a SI_TKILL code in si_code in case tkill is
68 used. tkill is transparently used in raise(). Since having
69 SI_TKILL as a code is useful in general we fold the results
70 here. */
71 if (result != -1 && info != NULL && info->si_code == SI_TKILL)
72 info->si_code = SI_USER;
74 return result;
75 # else
76 /* on uClibc we use the kernel sigset_t size */
77 # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
78 return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
79 TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
80 # else
81 return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
82 timeout, __SYSCALL_SIGSET_T_SIZE);
83 # endif
84 # endif
86 CANCELLABLE_SYSCALL(int, sigtimedwait,
87 (const sigset_t *set, siginfo_t *info, const struct timespec *timeout),
88 (set, info, timeout))
89 lt_libc_hidden(sigtimedwait)
90 #endif