]> granicus.if.org Git - strace/commitdiff
ioctl: simplify ioctl_decode handling, document its return value semantics
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 25 Aug 2017 22:33:55 +0000 (00:33 +0200)
committerEugene Syromyatnikov <evgsyr@gmail.com>
Mon, 28 Aug 2017 00:33:20 +0000 (02:33 +0200)
* ioctl.s (SYS_FUNC(ioctl.c)): Unconditionally unset 1, simply print arg
when (ret & RVAL_DECODED) && !(ret & 1).

ioctl.c

diff --git a/ioctl.c b/ioctl.c
index 264c7c02c71cafdd49d8b5baf189daf68d9b69ea..a10c80b8fd8f0b0717aeec5d90389ea37aa78e66 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -224,6 +224,32 @@ ioctl_decode_command_number(struct tcb *tcp)
        }
 }
 
+/**
+ * Decode arg parameter of the ioctl call.
+ *
+ * @return There are two bits of the return value important for the purposes of
+ *         processing by SYS_FUNC(ioctl):
+ *          - 1 - indicates that ioctl decoder code has printed arg parameter.
+ *          - RVAL_DECODED - indicates that decoding is done.
+ *         As a result, the following behaviour is expected:
+ *          - on entering:
+ *            - 0 - decoding should be continued on exiting;
+ *            - RVAL_DECODED - decoding on exiting is not needed and generic
+ *                             handler should print arg value;
+ *            - 1 | RVAL_DECODED - decoding on exiting is not needed and decoder
+ *                                 has printed arg value.
+ *          - on exiting:
+ *            - 0 - generic handler should print arg value.
+ *            - 1 - decoder has printed arg value.
+ *
+ *         Note that it makes no sense to return just 1 (without RVAL_DECODED)
+ *         on entering, or 1 | RVAL_DECODED on exiting, but, of course, it is
+ *         not prohibited (for example, it may be useful in cases where the
+ *         return path is common on entering and on exiting the syscall).
+ *
+ *         SYS_FUNC(ioctl) clears bit 0 and passes all other bits of
+ *         ioctl_decode return value unchanged.
+ */
 static int
 ioctl_decode(struct tcb *tcp)
 {
@@ -319,17 +345,10 @@ SYS_FUNC(ioctl)
                ret = ioctl_decode(tcp) | RVAL_DECODED;
        }
 
-       if (ret & RVAL_DECODED) {
-               ret &= ~RVAL_DECODED;
-               if (ret)
-                       --ret;
-               else
-                       tprintf(", %#" PRI_klx, tcp->u_arg[2]);
-               ret |= RVAL_DECODED;
-       } else {
-               if (ret)
-                       --ret;
-       }
+       if ((ret & RVAL_DECODED) && !(ret & 1))
+               tprintf(", %#" PRI_klx, tcp->u_arg[2]);
+
+       ret &= ~1;
 
        return ret;
 }