- do {
- if (tsp) {
- if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
- timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
- timeout += ts.tv_sec * (unsigned long)HZ;
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- } else {
- ts.tv_sec -= MAX_SELECT_SECONDS;
- timeout = MAX_SELECT_SECONDS * HZ;
- }
- }
-
- ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
-
- } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
-
- if (tsp) {
- struct compat_timespec rts;
-
- if (current->personality & STICKY_TIMEOUTS)
- goto sticky;
-
- rts.tv_sec = timeout / HZ;
- rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ);
- if (rts.tv_nsec >= NSEC_PER_SEC) {
- rts.tv_sec++;
- rts.tv_nsec -= NSEC_PER_SEC;
- }
- if (compat_timespec_compare(&rts, &ts) >= 0)
- rts = ts;
- if (copy_to_user(tsp, &rts, sizeof(rts))) {
-sticky:
- /*
- * If an application puts its timeval in read-only
- * memory, we don't want the Linux-specific update to
- * the timeval to cause a fault after the select has
- * completed successfully. However, because we're not
- * updating the timeval, we can't restart the system
- * call.
- */
- if (ret == -ERESTARTNOHAND)
- ret = -EINTR;
- }
- }
+ ret = compat_core_sys_select(n, inp, outp, exp, to);
+ ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);