memcpy instead of invidual bittoggle
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 29 Aug 2013 05:52:54 +0000 (15:52 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Fri, 30 Aug 2013 23:40:17 +0000 (09:40 +1000)
The ioctls return the number of bytes copied into the destination, so just
copy them into the device state instead of individually flipping bits.

For easier review: rc is the return value of the EVIOCG* ioctl, which is
the number of bytes copied.

state variables must be initialized to 0 now, in case the kernel's FOO_MAX
is smaller than libevdev's FOO_MAX. If not initialized to 0, the bytes
between the two max values is undefined and we may end up generating bogus
events.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
libevdev/libevdev.c

index 73405bc..36160f6 100644 (file)
@@ -306,7 +306,7 @@ sync_key_state(struct libevdev *dev)
 {
        int rc;
        int i;
-       unsigned long keystate[NLONGS(KEY_CNT)];
+       unsigned long keystate[NLONGS(KEY_CNT)] = {0};
 
        rc = ioctl(dev->fd, EVIOCGKEY(sizeof(keystate)), keystate);
        if (rc < 0)
@@ -320,9 +320,10 @@ sync_key_state(struct libevdev *dev)
                        struct input_event *ev = queue_push(dev);
                        init_event(dev, ev, EV_KEY, i, new ? 1 : 0);
                }
-               set_bit_state(dev->key_values, i, new);
        }
 
+       memcpy(dev->key_values, keystate, rc);
+
        rc = 0;
 out:
        return rc ? -errno : 0;
@@ -333,7 +334,7 @@ sync_sw_state(struct libevdev *dev)
 {
        int rc;
        int i;
-       unsigned long swstate[NLONGS(SW_CNT)];
+       unsigned long swstate[NLONGS(SW_CNT)] = {0};
 
        rc = ioctl(dev->fd, EVIOCGSW(sizeof(swstate)), swstate);
        if (rc < 0)
@@ -347,9 +348,10 @@ sync_sw_state(struct libevdev *dev)
                        struct input_event *ev = queue_push(dev);
                        init_event(dev, ev, EV_SW, i, new ? 1 : 0);
                }
-               set_bit_state(dev->sw_values, i, new);
        }
 
+       memcpy(dev->sw_values, swstate, rc);
+
        rc = 0;
 out:
        return rc ? -errno : 0;
@@ -360,7 +362,7 @@ sync_led_state(struct libevdev *dev)
 {
        int rc;
        int i;
-       unsigned long ledstate[NLONGS(LED_CNT)];
+       unsigned long ledstate[NLONGS(LED_CNT)] = {0};
 
        rc = ioctl(dev->fd, EVIOCGLED(sizeof(ledstate)), ledstate);
        if (rc < 0)
@@ -374,9 +376,10 @@ sync_led_state(struct libevdev *dev)
                        struct input_event *ev = queue_push(dev);
                        init_event(dev, ev, EV_LED, i, new ? 1 : 0);
                }
-               set_bit_state(dev->led_values, i, new);
        }
 
+       memcpy(dev->led_values, ledstate, rc);
+
        rc = 0;
 out:
        return rc ? -errno : 0;