aboutsummaryrefslogtreecommitdiffstats
path: root/fs/eventpoll.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-02-24 14:52:17 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-03-03 22:58:49 -0500
commit35280bd4a3fa841897e2638437607fdec6c34f31 (patch)
tree03c7cb65bcb2cc94c1613944798f780645e64edd /fs/eventpoll.c
parent19f4fc3aee180000fe45952691bbe69dde1d9e95 (diff)
switch epoll_pwait to COMPAT_SYSCALL_DEFINE
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/eventpoll.c')
-rw-r--r--fs/eventpoll.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 9fec1836057a..495d15558f42 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -40,6 +40,7 @@
40#include <linux/atomic.h> 40#include <linux/atomic.h>
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/compat.h>
43 44
44/* 45/*
45 * LOCKING: 46 * LOCKING:
@@ -1940,6 +1941,52 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
1940 return error; 1941 return error;
1941} 1942}
1942 1943
1944#ifdef CONFIG_COMPAT
1945COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
1946 struct epoll_event __user *, events,
1947 int, maxevents, int, timeout,
1948 const compat_sigset_t __user *, sigmask,
1949 compat_size_t, sigsetsize)
1950{
1951 long err;
1952 compat_sigset_t csigmask;
1953 sigset_t ksigmask, sigsaved;
1954
1955 /*
1956 * If the caller wants a certain signal mask to be set during the wait,
1957 * we apply it here.
1958 */
1959 if (sigmask) {
1960 if (sigsetsize != sizeof(compat_sigset_t))
1961 return -EINVAL;
1962 if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
1963 return -EFAULT;
1964 sigset_from_compat(&ksigmask, &csigmask);
1965 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
1966 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1967 }
1968
1969 err = sys_epoll_wait(epfd, events, maxevents, timeout);
1970
1971 /*
1972 * If we changed the signal mask, we need to restore the original one.
1973 * In case we've got a signal while waiting, we do not restore the
1974 * signal mask yet, and we allow do_signal() to deliver the signal on
1975 * the way back to userspace, before the signal mask is restored.
1976 */
1977 if (sigmask) {
1978 if (err == -EINTR) {
1979 memcpy(&current->saved_sigmask, &sigsaved,
1980 sizeof(sigsaved));
1981 set_restore_sigmask();
1982 } else
1983 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1984 }
1985
1986 return err;
1987}
1988#endif
1989
1943static int __init eventpoll_init(void) 1990static int __init eventpoll_init(void)
1944{ 1991{
1945 struct sysinfo si; 1992 struct sysinfo si;