]> granicus.if.org Git - strace/commitdiff
evdev.c: reorder ioctl command checks
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 27 May 2016 00:40:10 +0000 (00:40 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 28 May 2016 00:37:05 +0000 (00:37 +0000)
Change the order of ioctl command cheks to match the kernel:
1st, check for fixed-number fixed-length commands,
2nd, check for fixed-number variable-length commands,
3rd, check for multi-number fixed-length commands,
4thm check for multi-number variable-length commands.

* evdev.c (evdev_read_ioctl, evdev_write_ioctl): Reorder
ioctl command checks.

evdev.c

diff --git a/evdev.c b/evdev.c
index dd068a86d017436974dc41ba098a403292d24bd6..dda8f54e9b1bd5522619e2cfca7f116237d77d02 100644 (file)
--- a/evdev.c
+++ b/evdev.c
@@ -308,59 +308,12 @@ repeat_ioctl(struct tcb *tcp, long arg)
 # endif /* EVIOCGREP || EVIOCSREP */
 
 static int
-evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg)
+evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
 {
        if (syserror(tcp))
                return 0;
 
-       if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) {
-               switch (_IOC_NR(code) - 0x20) {
-                       case EV_SYN:
-                               return decode_bitset(tcp, arg, evdev_sync,
-                                               SYN_MAX, "SYN_???");
-                       case EV_KEY:
-                               return decode_bitset(tcp, arg, evdev_keycode,
-                                               KEY_MAX, "KEY_???");
-                       case EV_REL:
-                               return decode_bitset(tcp, arg, evdev_relative_axes,
-                                               REL_MAX, "REL_???");
-                       case EV_ABS:
-                               return decode_bitset(tcp, arg,
-                                               evdev_abs, ABS_MAX, "ABS_???");
-                       case EV_MSC:
-                               return decode_bitset(tcp, arg,
-                                               evdev_misc, MSC_MAX, "MSC_???");
-# ifdef EV_SW
-                       case EV_SW:
-                               return decode_bitset(tcp, arg,
-                                               evdev_switch, SW_MAX, "SW_???");
-# endif
-                       case EV_LED:
-                               return decode_bitset(tcp, arg,
-                                               evdev_leds, LED_MAX, "LED_???");
-                       case EV_SND:
-                               return decode_bitset(tcp, arg,
-                                               evdev_snd, SND_MAX, "SND_???");
-                       case EV_REP:
-                               return decode_bitset(tcp, arg, evdev_autorepeat,
-                                               REP_MAX, "REP_???");
-                       case EV_FF:
-                               return decode_bitset(tcp, arg, evdev_ff_types,
-                                               FF_MAX, "FF_???");
-                       case EV_PWR:
-                               printnum_int(tcp, arg, "%d");
-                               return 1;
-                       case EV_FF_STATUS:
-                               return decode_bitset(tcp, arg, evdev_ff_status,
-                                               FF_STATUS_MAX, "FF_STATUS_???");
-                       default:
-                               return 0;
-               }
-       }
-
-       if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
-               return abs_ioctl(tcp, arg);
-
+       /* fixed-number fixed-length commands */
        switch (code) {
                case EVIOCGVERSION:
                        tprints(", ");
@@ -384,6 +337,7 @@ evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 # endif
        }
 
+       /* fixed-number variable-length commands */
        switch (_IOC_NR(code)) {
 # ifdef EVIOCGMTSLOTS
                case _IOC_NR(EVIOCGMTSLOTS(0)):
@@ -414,17 +368,65 @@ evdev_read_ioctl(struct tcb *tcp, const unsigned int code, long arg)
                case _IOC_NR(EVIOCGLED(0)):
                        return decode_bitset(tcp, arg,
                                        evdev_leds, LED_MAX, "LED_???");
-               default:
-                       return 0;
        }
+
+       /* multi-number fixed-length commands */
+       if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
+               return abs_ioctl(tcp, arg);
+
+       /* multi-number variable-length commands */
+       if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) {
+               switch (_IOC_NR(code) - 0x20) {
+                       case EV_SYN:
+                               return decode_bitset(tcp, arg, evdev_sync,
+                                               SYN_MAX, "SYN_???");
+                       case EV_KEY:
+                               return decode_bitset(tcp, arg, evdev_keycode,
+                                               KEY_MAX, "KEY_???");
+                       case EV_REL:
+                               return decode_bitset(tcp, arg, evdev_relative_axes,
+                                               REL_MAX, "REL_???");
+                       case EV_ABS:
+                               return decode_bitset(tcp, arg,
+                                               evdev_abs, ABS_MAX, "ABS_???");
+                       case EV_MSC:
+                               return decode_bitset(tcp, arg,
+                                               evdev_misc, MSC_MAX, "MSC_???");
+# ifdef EV_SW
+                       case EV_SW:
+                               return decode_bitset(tcp, arg,
+                                               evdev_switch, SW_MAX, "SW_???");
+# endif
+                       case EV_LED:
+                               return decode_bitset(tcp, arg,
+                                               evdev_leds, LED_MAX, "LED_???");
+                       case EV_SND:
+                               return decode_bitset(tcp, arg,
+                                               evdev_snd, SND_MAX, "SND_???");
+                       case EV_REP:
+                               return decode_bitset(tcp, arg, evdev_autorepeat,
+                                               REP_MAX, "REP_???");
+                       case EV_FF:
+                               return decode_bitset(tcp, arg, evdev_ff_types,
+                                               FF_MAX, "FF_???");
+                       case EV_PWR:
+                               printnum_int(tcp, arg, "%d");
+                               return 1;
+                       case EV_FF_STATUS:
+                               return decode_bitset(tcp, arg, evdev_ff_status,
+                                               FF_STATUS_MAX, "FF_STATUS_???");
+                       default:
+                               return 0;
+               }
+       }
+
+       return 0;
 }
 
 static int
-evdev_write_ioctl(struct tcb *tcp, const unsigned int code, long arg)
+evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
 {
-       if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
-               return abs_ioctl(tcp, arg);
-
+       /* fixed-number fixed-length commands */
        switch (code) {
 # ifdef EVIOCSREP
                case EVIOCSREP:
@@ -449,9 +451,13 @@ evdev_write_ioctl(struct tcb *tcp, const unsigned int code, long arg)
                        tprints(", ");
                        printnum_int(tcp, arg, "%u");
                        return 1;
-               default:
-                       return 0;
        }
+
+       /* multi-number fixed-length commands */
+       if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
+               return abs_ioctl(tcp, arg);
+
+       return 0;
 }
 
 int