diff options
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 69 | ||||
-rw-r--r-- | fs/select.c | 2 | ||||
-rw-r--r-- | include/linux/poll.h | 2 |
3 files changed, 7 insertions, 66 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 9fee37e2596f..32ca1b927307 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -981,27 +981,18 @@ asmlinkage int | |||
981 | osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, | 981 | osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, |
982 | struct timeval32 __user *tvp) | 982 | struct timeval32 __user *tvp) |
983 | { | 983 | { |
984 | fd_set_bits fds; | 984 | s64 timeout = MAX_SCHEDULE_TIMEOUT; |
985 | char *bits; | ||
986 | size_t size; | ||
987 | long timeout; | ||
988 | int ret = -EINVAL; | ||
989 | struct fdtable *fdt; | ||
990 | int max_fds; | ||
991 | |||
992 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
993 | if (tvp) { | 985 | if (tvp) { |
994 | time_t sec, usec; | 986 | time_t sec, usec; |
995 | 987 | ||
996 | if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp)) | 988 | if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp)) |
997 | || __get_user(sec, &tvp->tv_sec) | 989 | || __get_user(sec, &tvp->tv_sec) |
998 | || __get_user(usec, &tvp->tv_usec)) { | 990 | || __get_user(usec, &tvp->tv_usec)) { |
999 | ret = -EFAULT; | 991 | return -EFAULT; |
1000 | goto out_nofds; | ||
1001 | } | 992 | } |
1002 | 993 | ||
1003 | if (sec < 0 || usec < 0) | 994 | if (sec < 0 || usec < 0) |
1004 | goto out_nofds; | 995 | return -EINVAL; |
1005 | 996 | ||
1006 | if ((unsigned long) sec < MAX_SELECT_SECONDS) { | 997 | if ((unsigned long) sec < MAX_SELECT_SECONDS) { |
1007 | timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); | 998 | timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); |
@@ -1009,60 +1000,8 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, | |||
1009 | } | 1000 | } |
1010 | } | 1001 | } |
1011 | 1002 | ||
1012 | rcu_read_lock(); | ||
1013 | fdt = files_fdtable(current->files); | ||
1014 | max_fds = fdt->max_fds; | ||
1015 | rcu_read_unlock(); | ||
1016 | if (n < 0 || n > max_fds) | ||
1017 | goto out_nofds; | ||
1018 | |||
1019 | /* | ||
1020 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), | ||
1021 | * since we used fdset we need to allocate memory in units of | ||
1022 | * long-words. | ||
1023 | */ | ||
1024 | ret = -ENOMEM; | ||
1025 | size = FDS_BYTES(n); | ||
1026 | bits = kmalloc(6 * size, GFP_KERNEL); | ||
1027 | if (!bits) | ||
1028 | goto out_nofds; | ||
1029 | fds.in = (unsigned long *) bits; | ||
1030 | fds.out = (unsigned long *) (bits + size); | ||
1031 | fds.ex = (unsigned long *) (bits + 2*size); | ||
1032 | fds.res_in = (unsigned long *) (bits + 3*size); | ||
1033 | fds.res_out = (unsigned long *) (bits + 4*size); | ||
1034 | fds.res_ex = (unsigned long *) (bits + 5*size); | ||
1035 | |||
1036 | if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) || | ||
1037 | (ret = get_fd_set(n, outp->fds_bits, fds.out)) || | ||
1038 | (ret = get_fd_set(n, exp->fds_bits, fds.ex))) | ||
1039 | goto out; | ||
1040 | zero_fd_set(n, fds.res_in); | ||
1041 | zero_fd_set(n, fds.res_out); | ||
1042 | zero_fd_set(n, fds.res_ex); | ||
1043 | |||
1044 | ret = do_select(n, &fds, &timeout); | ||
1045 | |||
1046 | /* OSF does not copy back the remaining time. */ | 1003 | /* OSF does not copy back the remaining time. */ |
1047 | 1004 | return core_sys_select(n, inp, outp, exp, &timeout); | |
1048 | if (ret < 0) | ||
1049 | goto out; | ||
1050 | if (!ret) { | ||
1051 | ret = -ERESTARTNOHAND; | ||
1052 | if (signal_pending(current)) | ||
1053 | goto out; | ||
1054 | ret = 0; | ||
1055 | } | ||
1056 | |||
1057 | if (set_fd_set(n, inp->fds_bits, fds.res_in) || | ||
1058 | set_fd_set(n, outp->fds_bits, fds.res_out) || | ||
1059 | set_fd_set(n, exp->fds_bits, fds.res_ex)) | ||
1060 | ret = -EFAULT; | ||
1061 | |||
1062 | out: | ||
1063 | kfree(bits); | ||
1064 | out_nofds: | ||
1065 | return ret; | ||
1066 | } | 1005 | } |
1067 | 1006 | ||
1068 | struct rusage32 { | 1007 | struct rusage32 { |
diff --git a/fs/select.c b/fs/select.c index 2c292146e246..80d70387e790 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -298,7 +298,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) | |||
298 | #define MAX_SELECT_SECONDS \ | 298 | #define MAX_SELECT_SECONDS \ |
299 | ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) | 299 | ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) |
300 | 300 | ||
301 | static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | 301 | int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, |
302 | fd_set __user *exp, s64 *timeout) | 302 | fd_set __user *exp, s64 *timeout) |
303 | { | 303 | { |
304 | fd_set_bits fds; | 304 | fd_set_bits fds; |
diff --git a/include/linux/poll.h b/include/linux/poll.h index 16d813b364ef..ef453828877a 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h | |||
@@ -117,6 +117,8 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset) | |||
117 | extern int do_select(int n, fd_set_bits *fds, s64 *timeout); | 117 | extern int do_select(int n, fd_set_bits *fds, s64 *timeout); |
118 | extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, | 118 | extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, |
119 | s64 *timeout); | 119 | s64 *timeout); |
120 | extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | ||
121 | fd_set __user *exp, s64 *timeout); | ||
120 | 122 | ||
121 | #endif /* KERNEL */ | 123 | #endif /* KERNEL */ |
122 | 124 | ||