#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/sched/rt.h>
#include <linux/syscalls.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/personality.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/fs.h>
#include <linux/rcupdate.h>
#include <linux/hrtimer.h>
#include <linux/freezer.h>
#include <net/busy_poll.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#define MAX_SLACK …
static long __estimate_accuracy(struct timespec64 *tv)
{ … }
u64 select_estimate_accuracy(struct timespec64 *tv)
{ … }
struct poll_table_page { … };
#define POLL_TABLE_FULL(table) …
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
poll_table *p);
void poll_initwait(struct poll_wqueues *pwq)
{ … }
EXPORT_SYMBOL(…);
static void free_poll_entry(struct poll_table_entry *entry)
{ … }
void poll_freewait(struct poll_wqueues *pwq)
{ … }
EXPORT_SYMBOL(…);
static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p)
{ … }
static int __pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
{ … }
static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
{ … }
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
poll_table *p)
{ … }
static int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
ktime_t *expires, unsigned long slack)
{ … }
int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec)
{ … }
enum poll_time_type { … };
static int poll_select_finish(struct timespec64 *end_time,
void __user *p,
enum poll_time_type pt_type, int ret)
{ … }
fd_set_bits;
#define FDS_BITPERLONG …
#define FDS_LONGS(nr) …
#define FDS_BYTES(nr) …
static inline
int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
{ … }
static inline unsigned long __must_check
set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
{ … }
static inline
void zero_fd_set(unsigned long nr, unsigned long *fdset)
{ … }
#define FDS_IN(fds, n) …
#define FDS_OUT(fds, n) …
#define FDS_EX(fds, n) …
#define BITS(fds, n) …
static int max_select_fd(unsigned long n, fd_set_bits *fds)
{ … }
#define POLLIN_SET …
#define POLLOUT_SET …
#define POLLEX_SET …
static inline void wait_key_set(poll_table *wait, unsigned long in,
unsigned long out, unsigned long bit,
__poll_t ll_flag)
{ … }
static noinline_for_stack int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
{ … }
int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
fd_set __user *exp, struct timespec64 *end_time)
{ … }
static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
fd_set __user *exp, struct __kernel_old_timeval __user *tvp)
{ … }
SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp)
{ … }
static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
fd_set __user *exp, void __user *tsp,
const sigset_t __user *sigmask, size_t sigsetsize,
enum poll_time_type type)
{ … }
struct sigset_argpack { … };
static inline int get_sigset_argpack(struct sigset_argpack *to,
struct sigset_argpack __user *from)
{ … }
SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
fd_set __user *, exp, struct __kernel_timespec __user *, tsp,
void __user *, sig)
{ … }
#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, outp,
fd_set __user *, exp, struct old_timespec32 __user *, tsp,
void __user *, sig)
{
struct sigset_argpack x = {NULL, 0};
if (get_sigset_argpack(&x, sig))
return -EFAULT;
return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_OLD_TIMESPEC);
}
#endif
#ifdef __ARCH_WANT_SYS_OLD_SELECT
struct sel_arg_struct {
unsigned long n;
fd_set __user *inp, *outp, *exp;
struct __kernel_old_timeval __user *tvp;
};
SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
{
struct sel_arg_struct a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
return kern_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
#endif
struct poll_list { … };
#define POLLFD_PER_PAGE …
static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
bool *can_busy_poll,
__poll_t busy_flag)
{ … }
static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
struct timespec64 *end_time)
{ … }
#define N_STACK_PPS …
static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
struct timespec64 *end_time)
{ … }
static long do_restart_poll(struct restart_block *restart_block)
{ … }
SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
int, timeout_msecs)
{ … }
SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
size_t, sigsetsize)
{ … }
#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
size_t, sigsetsize)
{
struct timespec64 ts, end_time, *to = NULL;
int ret;
if (tsp) {
if (get_old_timespec32(&ts, tsp))
return -EFAULT;
to = &end_time;
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
return -EINVAL;
}
ret = set_user_sigmask(sigmask, sigsetsize);
if (ret)
return ret;
ret = do_sys_poll(ufds, nfds, to);
return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
}
#endif
#ifdef CONFIG_COMPAT
#define __COMPAT_NFDBITS …
static
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{ … }
static
int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{ … }
static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
struct timespec64 *end_time)
{ … }
static int do_compat_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
struct old_timeval32 __user *tvp)
{ … }
COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
struct old_timeval32 __user *, tvp)
{ … }
struct compat_sel_arg_struct { … };
COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
{ … }
static long do_compat_pselect(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
void __user *tsp, compat_sigset_t __user *sigmask,
compat_size_t sigsetsize, enum poll_time_type type)
{ … }
struct compat_sigset_argpack { … };
static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
struct compat_sigset_argpack __user *from)
{ … }
COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
struct __kernel_timespec __user *, tsp, void __user *, sig)
{ … }
#if defined(CONFIG_COMPAT_32BIT_TIME)
COMPAT_SYSCALL_DEFINE6(pselect6_time32, int, n, compat_ulong_t __user *, inp,
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
struct old_timespec32 __user *, tsp, void __user *, sig)
{ … }
#endif
#if defined(CONFIG_COMPAT_32BIT_TIME)
COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
unsigned int, nfds, struct old_timespec32 __user *, tsp,
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
{ … }
#endif
COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
unsigned int, nfds, struct __kernel_timespec __user *, tsp,
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
{ … }
#endif