do_poll: return -EINTR when signalled
Oleg Nesterov [Wed, 17 Oct 2007 06:26:18 +0000 (23:26 -0700)]
do_poll() checks signal_pending() but returns 0 when interrupted.  This means
the caller has to check signal_pending() again.

Change it to return -EINTR when signal_pending() and count == 0.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Andi Kleen <ak@suse.de>
Cc: Davide Libenzi <davidel@xmailserver.org>
Cc: Vadim Lobanov <vlobanov@speakeasy.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

fs/select.c

index 41c3571..e2fd58f 100644 (file)
@@ -586,7 +586,7 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
        /* Optimise the no-wait case */
        if (!(*timeout))
                pt = NULL;
+
        for (;;) {
                struct poll_list *walk;
                long __timeout;
@@ -616,10 +616,12 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
                 * a poll_table to them on the next loop iteration.
                 */
                pt = NULL;
-               if (count || !*timeout || signal_pending(current))
-                       break;
-               count = wait->error;
-               if (count)
+               if (!count) {
+                       count = wait->error;
+                       if (signal_pending(current))
+                               count = -EINTR;
+               }
+               if (count || !*timeout)
                        break;
 
                if (*timeout < 0) {
@@ -689,8 +691,6 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
 
        poll_initwait(&table);
        fdcount = do_poll(nfds, head, &table, timeout);
-       if (!fdcount && signal_pending(current))
-               fdcount = -EINTR;
        poll_freewait(&table);
 
        for (walk = head; walk; walk = walk->next) {