From: Eugene Syromyatnikov Date: Fri, 25 Aug 2017 22:33:55 +0000 (+0200) Subject: ioctl: simplify ioctl_decode handling, document its return value semantics X-Git-Tag: v4.19~51 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e4aead09e44e3604244216edc435ca706a89792;p=strace ioctl: simplify ioctl_decode handling, document its return value semantics * ioctl.s (SYS_FUNC(ioctl.c)): Unconditionally unset 1, simply print arg when (ret & RVAL_DECODED) && !(ret & 1). --- diff --git a/ioctl.c b/ioctl.c index 264c7c02..a10c80b8 100644 --- 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; }