1/* Copyright (C) 2006-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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/>. */
17
18#include <sys/select.h>
19#include <sysdep-cancel.h>
20
21static int
22pselect64_syscall (int nfds, fd_set *readfds, fd_set *writefds,
23 fd_set *exceptfds, const struct __timespec64 *timeout,
24 const sigset_t *sigmask)
25{
26#ifndef __NR_pselect6_time64
27# define __NR_pselect6_time64 __NR_pselect6
28#endif
29 /* NB: This is required by ARGIFY used in x32 internal_syscallN. */
30 __syscall_ulong_t data[2] =
31 {
32 (uintptr_t) sigmask, __NSIG_BYTES
33 };
34 return SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
35 timeout, data);
36}
37
38int
39__pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
40 const struct __timespec64 *timeout, const sigset_t *sigmask)
41{
42 /* The Linux kernel can in some situations update the timeout value.
43 We do not want that so use a local variable. */
44 struct __timespec64 tval;
45 if (timeout != NULL)
46 {
47 tval = *timeout;
48 timeout = &tval;
49 }
50
51 /* Note: the system call expects 7 values but on most architectures
52 we can only pass in 6 directly. If there is an architecture with
53 support for more parameters a new version of this file needs to
54 be created. */
55#ifdef __ASSUME_TIME64_SYSCALLS
56 return pselect64_syscall (nfds, readfds, writefds, exceptfds, timeout,
57 sigmask);
58#else
59 bool need_time64 = timeout != NULL && !in_time_t_range (timeout->tv_sec);
60 if (need_time64)
61 {
62 int r = pselect64_syscall (nfds, readfds, writefds, exceptfds, timeout,
63 sigmask);
64 if (r == 0 || errno != ENOSYS)
65 return r;
66 __set_errno (EOVERFLOW);
67 return -1;
68 }
69
70 return __pselect32 (nfds, readfds, writefds, exceptfds, timeout, sigmask);
71#endif
72}
73
74#if __TIMESIZE != 64
75libc_hidden_def (__pselect64)
76
77int
78__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
79 const struct timespec *timeout, const sigset_t *sigmask)
80{
81 struct __timespec64 ts64, *pts64 = NULL;
82 if (timeout != NULL)
83 {
84 ts64 = valid_timespec_to_timespec64 (*timeout);
85 pts64 = &ts64;
86 }
87 return __pselect64 (nfds, readfds, writefds, exceptfds, pts64, sigmask);
88}
89#endif
90
91#ifndef __pselect
92weak_alias (__pselect, pselect)
93#endif
94

source code of glibc/sysdeps/unix/sysv/linux/pselect.c