GLIBC-SA-2024-0004: add commit for 2.31 branch
[glibc.git] / sysdeps / unix / sysv / linux / sigtimedwait.c
blob3da4e8ef283432b2aedc335173634709d7644e5e
1 /* Copyright (C) 1997-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <signal.h>
19 #include <sysdep.h>
21 int
22 __sigtimedwait64 (const sigset_t *set, siginfo_t *info,
23 const struct __timespec64 *timeout)
25 #ifndef __NR_rt_sigtimedwait_time64
26 # define __NR_rt_sigtimedwait_time64 __NR_rt_sigtimedwait
27 #endif
29 int result;
30 #ifdef __ASSUME_TIME64_SYSCALLS
31 result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
32 __NSIG_BYTES);
33 #else
34 bool need_time64 = timeout != NULL && !in_int32_t_range (timeout->tv_sec);
35 if (need_time64)
37 result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
38 __NSIG_BYTES);
39 if (result == 0 || errno != ENOSYS)
40 return result;
41 __set_errno (EOVERFLOW);
42 return -1;
44 else
46 struct timespec ts32, *pts32 = NULL;
47 if (timeout != NULL)
49 ts32 = valid_timespec64_to_timespec (*timeout);
50 pts32 = &ts32;
52 result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, pts32,
53 __NSIG_BYTES);
55 #endif
57 /* The kernel generates a SI_TKILL code in si_code in case tkill is
58 used. tkill is transparently used in raise(). Since having
59 SI_TKILL as a code is useful in general we fold the results
60 here. */
61 if (result != -1 && info != NULL && info->si_code == SI_TKILL)
62 info->si_code = SI_USER;
64 return result;
66 #if __TIMESIZE != 64
67 libc_hidden_def (__sigtimedwait64)
69 int
70 __sigtimedwait (const sigset_t *set, siginfo_t *info,
71 const struct timespec *timeout)
73 struct __timespec64 ts64, *pts64 = NULL;
74 if (timeout != NULL)
76 ts64 = valid_timespec_to_timespec64 (*timeout);
77 pts64 = &ts64;
79 return __sigtimedwait64 (set, info, pts64);
81 #endif
82 libc_hidden_def (__sigtimedwait)
83 weak_alias (__sigtimedwait, sigtimedwait)