Module: xenomai-forge
Branch: master
Commit: 6fe91773294a9400ea2432e5f8ed579b0e86811b
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=6fe91773294a9400ea2432e5f8ed579b0e86811b

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sat Dec 15 15:32:27 2012 +0100

cobalt: fix select syscall

When a timeout occurs, the polled fd_set should be zeroed upon select return.

This fixes the bug reported by and which fix was tested by Alexandre Duch
as Debian bug #695657.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=695657

---

 kernel/cobalt/nucleus/select.c |   16 ++++++----------
 kernel/cobalt/syscall.c        |    2 +-
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/kernel/cobalt/nucleus/select.c b/kernel/cobalt/nucleus/select.c
index 22b0a34..fc11edb 100644
--- a/kernel/cobalt/nucleus/select.c
+++ b/kernel/cobalt/nucleus/select.c
@@ -249,7 +249,7 @@ fd_set_and(fd_set *result, fd_set *first, fd_set *second, 
unsigned n)
        return not_empty;
 }
 
-static void fd_set_zerofill(fd_set *set, unsigned n)
+static void fd_set_zeropad(fd_set *set, unsigned n)
 {
        unsigned i;
 
@@ -335,6 +335,10 @@ int xnselect(struct xnselector *selector,
 
        thread = xnpod_current_thread();
 
+       for (i = 0; i < XNSELECT_MAX_TYPES; i++)
+               if (out_fds[i])
+                       fd_set_zeropad(out_fds[i], nfds);
+
        xnlock_get_irqsave(&nklock, s);
        for (i = 0; i < XNSELECT_MAX_TYPES; i++)
                if (out_fds[i]
@@ -343,12 +347,8 @@ int xnselect(struct xnselector *selector,
                        not_empty = 1;
        xnlock_put_irqrestore(&nklock, s);
 
-       if (not_empty) {
-               for (i = 0; i < XNSELECT_MAX_TYPES; i++)
-                       if (out_fds[i])
-                               fd_set_zerofill(out_fds[i], nfds);
+       if (not_empty)
                return -ECHRNG;
-       }
 
        xnlock_get_irqsave(&nklock, s);
        for (i = 0; i < XNSELECT_MAX_TYPES; i++)
@@ -374,10 +374,6 @@ int xnselect(struct xnselector *selector,
        if (not_empty) {
                unsigned count;
 
-               for (i = 0; i < XNSELECT_MAX_TYPES; i++)
-                       if (out_fds[i])
-                               fd_set_zerofill(out_fds[i], nfds);
-
                for (count = 0, i = 0; i < XNSELECT_MAX_TYPES; i++)
                        if (out_fds[i])
                                count += fd_set_popcount(out_fds[i], nfds);
diff --git a/kernel/cobalt/syscall.c b/kernel/cobalt/syscall.c
index b98d37e..c4177ab 100644
--- a/kernel/cobalt/syscall.c
+++ b/kernel/cobalt/syscall.c
@@ -212,7 +212,7 @@ static int __select(int nfds,
                        return -EFAULT;
        }
 
-       if (err > 0)
+       if (err >= 0)
                for (i = 0; i < XNSELECT_MAX_TYPES; i++)
                        if (ufd_sets[i]
                            && __xn_copy_to_user((void __user *) ufd_sets[i],


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to