1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
/*
* __rt_sigtimedwait() for uClibc
*
* Copyright (C) 2006 by Steven Hill <sjhill@realitydiluted.com>
* Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
*
* GNU Library General Public License (LGPL) version 2 or later.
*/
#include <sys/syscall.h>
#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
# include <signal.h>
# include <cancel.h>
# ifdef __UCLIBC_HAS_THREADS_NATIVE__
# include <pthreadP.h> /* SIGCANCEL */
# endif
# ifdef SIGCANCEL
# define __need_NULL
# include <stddef.h>
# include <string.h>
# endif
#if defined(__UCLIBC_USE_TIME64__)
#include "internal/time64_helpers.h"
#endif
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout)
{
# if defined SI_TKILL && defined SI_USER
int result;
# endif
# ifdef SIGCANCEL
sigset_t tmpset;
if (set != NULL && (unlikely (__sigismember (set, SIGCANCEL))
# ifdef SIGSETXID
|| unlikely (__sigismember (set, SIGSETXID))
# 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
/* if this is enabled, enable the disabled section in sigwait.c */
# if defined SI_TKILL && defined SI_USER
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
# else
result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
# endif
/* 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;
# else
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
# else
return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
# endif
# endif
}
CANCELLABLE_SYSCALL(int, sigtimedwait,
(const sigset_t *set, siginfo_t *info, const struct timespec *timeout),
(set, info, timeout))
lt_libc_hidden(sigtimedwait)
#endif
|