]> granicus.if.org Git - strace/blobdiff - ioctl.c
io.c: use printaddr and umove_or_printaddr
[strace] / ioctl.c
diff --git a/ioctl.c b/ioctl.c
index 9b6ea166a2552648b6bf0efa8ec9193cdd67cc55..284828a5a468db2e042a19957e8adc28e190c5ee 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -182,8 +182,10 @@ hiddev_decode_number(const unsigned int code)
 }
 
 static int
-ioctl_decode_command_number(const unsigned int code)
+ioctl_decode_command_number(struct tcb *tcp)
 {
+       const unsigned int code = tcp->u_arg[1];
+
        switch (_IOC_TYPE(code)) {
                case 'E':
                        return evdev_decode_number(code);
@@ -222,8 +224,11 @@ ioctl_decode_command_number(const unsigned int code)
 }
 
 static int
-ioctl_decode(struct tcb *tcp, unsigned int code, long arg)
+ioctl_decode(struct tcb *tcp)
 {
+       const unsigned int code = tcp->u_arg[1];
+       const long arg = tcp->u_arg[2];
+
        switch (_IOC_TYPE(code)) {
 #if defined(ALPHA) || defined(POWERPC)
        case 'f': case 't': case 'T':
@@ -267,11 +272,12 @@ ioctl_decode(struct tcb *tcp, unsigned int code, long arg)
 SYS_FUNC(ioctl)
 {
        const struct_ioctlent *iop;
+       int ret;
 
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
-               if (!ioctl_decode_command_number(tcp->u_arg[1])) {
+               if (!ioctl_decode_command_number(tcp)) {
                        iop = ioctl_lookup(tcp->u_arg[1]);
                        if (iop) {
                                tprints(iop->symbol);
@@ -281,14 +287,22 @@ SYS_FUNC(ioctl)
                                ioctl_print_code(tcp->u_arg[1]);
                        }
                }
-               ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+               ret = ioctl_decode(tcp);
+       } else {
+               ret = ioctl_decode(tcp) | RVAL_DECODED;
        }
-       else {
-               int ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
-               if (!ret)
-                       tprintf(", %#lx", tcp->u_arg[2]);
+
+       if (ret & RVAL_DECODED) {
+               ret &= ~RVAL_DECODED;
+               if (ret)
+                       --ret;
                else
-                       return ret - 1;
+                       tprintf(", %#lx", tcp->u_arg[2]);
+               ret |= RVAL_DECODED;
+       } else {
+               if (ret)
+                       --ret;
        }
-       return 0;
+
+       return ret;
 }