]> granicus.if.org Git - strace/blobdiff - ioctl.c
CREDITS.in: use UTF-8 consistently
[strace] / ioctl.c
diff --git a/ioctl.c b/ioctl.c
index 2ed22cf97964ce440ce76589285c5c13f686bf63..b61a5be5c464cd28a38e744dabce8235cb2c5a91 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -3,6 +3,7 @@
  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  * Copyright (c) 1996-2001 Wichert Akkerman <wichert@cistron.nl>
+ * Copyright (c) 1999-2017 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -79,7 +80,7 @@ ioctl_print_code(const unsigned int code)
 {
        tprints("_IOC(");
        printflags(ioctl_dirs, _IOC_DIR(code), "_IOC_???");
-       tprintf(", 0x%02x, 0x%02x, 0x%02x)",
+       tprintf(", %#x, %#x, %#x)",
                _IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
 }
 
@@ -223,6 +224,33 @@ ioctl_decode_command_number(struct tcb *tcp)
        }
 }
 
+/**
+ * Decode arg parameter of the ioctl call.
+ *
+ * @return There are two flags of the return value important for the purposes of
+ *         processing by SYS_FUNC(ioctl):
+ *          - RVAL_IOCTL_DECODED: 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_IOCTL_DECODED: decoding on exiting is not needed
+ *                                  and decoder has printed arg value;
+ *            - RVAL_DECODED: decoding on exiting is not needed
+ *                            and generic handler should print arg value.
+ *          - on exiting:
+ *            - 0: generic handler should print arg value;
+ *            - RVAL_IOCTL_DECODED: decoder has printed arg value.
+ *
+ *         Note that it makes no sense to return just 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) converts RVAL_IOCTL_DECODED flag to RVAL_DECODED,
+ *         and passes all other bits of ioctl_decode return value unchanged.
+ */
 static int
 ioctl_decode(struct tcb *tcp)
 {
@@ -255,10 +283,8 @@ ioctl_decode(struct tcb *tcp)
                return block_ioctl(tcp, code, arg);
        case 'X':
                return fs_x_ioctl(tcp, code, arg);
-#ifdef HAVE_SCSI_SG_H
        case 0x22:
                return scsi_ioctl(tcp, code, arg);
-#endif
        case 'L':
                return loop_ioctl(tcp, code, arg);
        case 'M':
@@ -282,6 +308,8 @@ ioctl_decode(struct tcb *tcp)
        case 0x94:
                return btrfs_ioctl(tcp, code, arg);
 #endif
+       case 0xb7:
+               return nsfs_ioctl(tcp, code, arg);
 #ifdef HAVE_LINUX_DM_IOCTL_H
        case 0xfd:
                return dm_ioctl(tcp, code, arg);
@@ -318,16 +346,11 @@ SYS_FUNC(ioctl)
                ret = ioctl_decode(tcp) | RVAL_DECODED;
        }
 
-       if (ret & RVAL_DECODED) {
-               ret &= ~RVAL_DECODED;
-               if (ret)
-                       --ret;
-               else
-                       tprintf(", %#" PRI_krx, tcp->u_arg[2]);
+       if (ret & RVAL_IOCTL_DECODED) {
+               ret &= ~RVAL_IOCTL_DECODED;
                ret |= RVAL_DECODED;
-       } else {
-               if (ret)
-                       --ret;
+       } else if (ret & RVAL_DECODED) {
+               tprintf(", %#" PRI_klx, tcp->u_arg[2]);
        }
 
        return ret;