--- linux-2.6.14/fs/select.c.org +++ linux-2.6.14/fs/select.c @@ -25,6 +25,7 @@ #include #include +#include #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) #define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) @@ -464,7 +465,7 @@ static int do_poll(unsigned int nfds, s return count; } -asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long timeout) +asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, int timeout_msecs) { struct poll_wqueues table; int fdcount, err; @@ -473,6 +474,8 @@ asmlinkage long sys_poll(struct pollfd _ struct poll_list *walk; struct fdtable *fdt; int max_fdset; + long timeout; + int64_t lltimeout; /* Do a sanity check on nfds ... */ rcu_read_lock(); @@ -482,13 +485,20 @@ asmlinkage long sys_poll(struct pollfd _ if (nfds > max_fdset && nfds > OPEN_MAX) return -EINVAL; - if (timeout) { - /* Careful about overflow in the intermediate values */ - if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ) - timeout = (unsigned long)(timeout*HZ+999)/1000+1; - else /* Negative or overflow */ + if (timeout_msecs) { + if (timeout_msecs < 0) timeout = MAX_SCHEDULE_TIMEOUT; - } + else { + lltimeout = (int64_t)timeout_msecs * HZ + 999; + do_div(lltimeout, 1000); + lltimeout++; + if (lltimeout > MAX_SCHEDULE_TIMEOUT) + timeout = MAX_SCHEDULE_TIMEOUT; + else + timeout = (long)lltimeout; + } + } else + timeout = 0; poll_initwait(&table); --- linux-2.6.14/include/linux/syscalls.h.org +++ linux-2.6.14/include/linux/syscalls.h @@ -420,7 +420,7 @@ asmlinkage long sys_socketpair(int, int, asmlinkage long sys_socketcall(int call, unsigned long __user *args); asmlinkage long sys_listen(int, int); asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, - long timeout); + int timeout_msecs); asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp); asmlinkage long sys_epoll_create(int size);