]> granicus.if.org Git - strace/blobdiff - block.c
travis: add x86 musl
[strace] / block.c
diff --git a/block.c b/block.c
index 599e5840ec0d45cec55f6401e3659497435fecf5..3c007464e0ac984c5d6edbe0984e931ff61e731e 100644 (file)
--- a/block.c
+++ b/block.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
+ * Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include "defs.h"
-#include <stdint.h>
-#include <inttypes.h>
+
+#include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
+#include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
+#include DEF_MPERS_TYPE(struct_blkpg_partition)
+
 #include <linux/blkpg.h>
 #include <linux/fs.h>
-#include <linux/hdreg.h>
-
-/* ioctls <= 114 are present in Linux 2.4. The following ones have been
- * added since then and headers containing them may not be available on
- * every system. */
 
 #define BLKTRACE_BDEV_SIZE      32
-struct blk_user_trace_setup {
+typedef struct blk_user_trace_setup {
        char name[BLKTRACE_BDEV_SIZE];  /* output */
        uint16_t act_mask;              /* input */
        uint32_t buf_size;              /* input */
@@ -45,101 +44,102 @@ struct blk_user_trace_setup {
        uint64_t start_lba;
        uint64_t end_lba;
        uint32_t pid;
-};
+} struct_blk_user_trace_setup;
+
+typedef struct blkpg_ioctl_arg struct_blkpg_ioctl_arg;
+typedef struct blkpg_partition struct_blkpg_partition;
+
+#include MPERS_DEFS
+
+/*
+ * ioctl numbers <= 114 are present in Linux 2.4.  The following ones have been
+ * added since then and headers containing them may not be available on every
+ * system.
+ */
 
 #ifndef BLKTRACESETUP
-#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
+# define BLKTRACESETUP _IOWR(0x12, 115, struct_blk_user_trace_setup)
 #endif
 #ifndef BLKTRACESTART
-#define BLKTRACESTART _IO(0x12,116)
+# define BLKTRACESTART _IO(0x12,116)
 #endif
 #ifndef BLKTRACESTOP
-#define BLKTRACESTOP _IO(0x12,117)
+# define BLKTRACESTOP _IO(0x12,117)
 #endif
 #ifndef BLKTRACETEARDOWN
-#define BLKTRACETEARDOWN _IO(0x12,118)
+# define BLKTRACETEARDOWN _IO(0x12,118)
 #endif
 #ifndef BLKDISCARD
-#define BLKDISCARD _IO(0x12,119)
+# define BLKDISCARD _IO(0x12,119)
 #endif
 #ifndef BLKIOMIN
-#define BLKIOMIN _IO(0x12,120)
+# define BLKIOMIN _IO(0x12,120)
 #endif
 #ifndef BLKIOOPT
-#define BLKIOOPT _IO(0x12,121)
+# define BLKIOOPT _IO(0x12,121)
 #endif
 #ifndef BLKALIGNOFF
-#define BLKALIGNOFF _IO(0x12,122)
+# define BLKALIGNOFF _IO(0x12,122)
 #endif
 #ifndef BLKPBSZGET
-#define BLKPBSZGET _IO(0x12,123)
+# define BLKPBSZGET _IO(0x12,123)
 #endif
 #ifndef BLKDISCARDZEROES
-#define BLKDISCARDZEROES _IO(0x12,124)
+# define BLKDISCARDZEROES _IO(0x12,124)
 #endif
 #ifndef BLKSECDISCARD
-#define BLKSECDISCARD _IO(0x12,125)
+# define BLKSECDISCARD _IO(0x12,125)
+#endif
+#ifndef BLKROTATIONAL
+# define BLKROTATIONAL _IO(0x12,126)
+#endif
+#ifndef BLKZEROOUT
+# define BLKZEROOUT _IO(0x12,127)
 #endif
 
-static const struct xlat blkpg_ops[] = {
-       { BLKPG_ADD_PARTITION,  "BLKPG_ADD_PARTITION", },
-       { BLKPG_DEL_PARTITION,  "BLKPG_DEL_PARTITION", },
-       { 0,                    NULL },
-};
+#include "xlat/blkpg_ops.h"
 
 static void
-print_blkpg_req(struct tcb *tcp, struct blkpg_ioctl_arg *blkpg)
+print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
 {
-       struct blkpg_partition p;
+       struct_blkpg_partition p;
 
        tprints("{");
        printxval(blkpg_ops, blkpg->op, "BLKPG_???");
 
-       tprintf(", flags=%d, datalen=%d, ",
+       tprintf(", flags=%d, datalen=%d, data=",
                blkpg->flags, blkpg->datalen);
 
-       if (umove(tcp, (long) blkpg->data, &p) < 0)
-               tprintf("%#lx}", (long) blkpg->data);
-       else
-               tprintf("{start=%lld, length=%lld, pno=%d, "
-                       "devname=\"%.*s\", volname=\"%.*s\"}}",
-                       p.start, p.length, p.pno,
-                       (int) sizeof(p.devname), p.devname,
-                       (int) sizeof(p.volname), p.volname);
+       if (!umove_or_printaddr(tcp, (long) blkpg->data, &p)) {
+               tprintf("{start=%lld, length=%lld, pno=%d, devname=",
+                       (long long) p.start, (long long) p.length, p.pno);
+               print_quoted_string(p.devname, sizeof(p.devname),
+                                   QUOTE_0_TERMINATED);
+               tprints(", volname=");
+               print_quoted_string(p.volname, sizeof(p.volname),
+                                   QUOTE_0_TERMINATED);
+               tprints("}");
+       }
+       tprints("}");
 }
 
-int
-block_ioctl(struct tcb *tcp, long code, long arg)
+MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *tcp,
+                  const unsigned int code, const long arg)
 {
        switch (code) {
        /* take arg as a value, not as a pointer */
        case BLKRASET:
        case BLKFRASET:
-               if (entering(tcp))
-                       tprintf(", %ld", arg);
-               break;
-
-       /* take a signed int */
-       case BLKROSET:
-       case BLKBSZSET:
-               if (entering(tcp)) {
-                       int val;
-                       if (umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %d", val);
-               }
+               tprintf(", %lu", arg);
                break;
 
-       /* returns an unsigned short */
+       /* return an unsigned short */
        case BLKSECTGET:
-               if (exiting(tcp)) {
-                       unsigned short val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %hu", val);
-               }
+       case BLKROTATIONAL:
+               if (entering(tcp))
+                       return 0;
+               tprints(", ");
+               printnum_short(tcp, arg, "%hu");
                break;
 
        /* return a signed int */
@@ -147,13 +147,14 @@ block_ioctl(struct tcb *tcp, long code, long arg)
        case BLKBSZGET:
        case BLKSSZGET:
        case BLKALIGNOFF:
-               if (exiting(tcp)) {
-                       int val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %d", val);
-               }
+               if (entering(tcp))
+                       return 0;
+               /* fall through */
+       /* take a signed int */
+       case BLKROSET:
+       case BLKBSZSET:
+               tprints(", ");
+               printnum_int(tcp, arg, "%d");
                break;
 
        /* return an unsigned int */
@@ -161,123 +162,93 @@ block_ioctl(struct tcb *tcp, long code, long arg)
        case BLKIOMIN:
        case BLKIOOPT:
        case BLKDISCARDZEROES:
-               if (exiting(tcp)) {
-                       unsigned int val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %u", val);
-               }
+               if (entering(tcp))
+                       return 0;
+               tprints(", ");
+               printnum_int(tcp, arg, "%u");
                break;
 
        /* return a signed long */
        case BLKRAGET:
        case BLKFRAGET:
-               if (exiting(tcp)) {
-                       long val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %ld", val);
-               }
+               if (entering(tcp))
+                       return 0;
+               tprints(", ");
+               printnum_slong(tcp, arg);
                break;
 
        /* returns an unsigned long */
        case BLKGETSIZE:
-               if (exiting(tcp)) {
-                       unsigned long val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %lu", val);
-                       }
+               if (entering(tcp))
+                       return 0;
+               tprints(", ");
+               printnum_ulong(tcp, arg);
                break;
 
 #ifdef HAVE_BLKGETSIZE64
-       /* return an uint64_t */
+       /* returns an uint64_t */
        case BLKGETSIZE64:
-               if (exiting(tcp)) {
-                       uint64_t val;
-                       if (syserror(tcp) || umove(tcp, arg, &val) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", %" PRIu64, val);
-               }
+               if (entering(tcp))
+                       return 0;
+               tprints(", ");
+               printnum_int64(tcp, arg, "%" PRIu64);
                break;
 #endif
 
-       /* More complex types */
+       /* takes a pair of uint64_t */
        case BLKDISCARD:
        case BLKSECDISCARD:
-               if (entering(tcp)) {
-                       uint64_t range[2];
-                       if (umove(tcp, arg, range) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", {%" PRIx64 ", %" PRIx64 "}",
-                                       range[0], range[1]);
-               }
+       case BLKZEROOUT:
+               tprints(", ");
+               printpair_int64(tcp, arg, "%" PRIu64);
                break;
 
-       case HDIO_GETGEO:
-               if (exiting(tcp)) {
-                       struct hd_geometry geo;
-                       if (syserror(tcp) || umove(tcp, arg, &geo) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", {heads=%hhu, sectors=%hhu, "
-                                       "cylinders=%hu, start=%lu}",
-                                       geo.heads, geo.sectors,
-                                       geo.cylinders, geo.start);
-               }
-               break;
+       /* More complex types */
+       case BLKPG: {
+               struct_blkpg_ioctl_arg blkpg;
 
-       case BLKPG:
-               if (entering(tcp)) {
-                       struct blkpg_ioctl_arg blkpg;
-                       if (umove(tcp, arg, &blkpg) < 0)
-                               tprintf(", %#lx", arg);
-                       else {
-                               tprints(", ");
-                               print_blkpg_req(tcp, &blkpg);
-                       }
-               }
+               tprints(", ");
+               if (!umove_or_printaddr(tcp, arg, &blkpg))
+                       print_blkpg_req(tcp, &blkpg);
                break;
+       }
 
        case BLKTRACESETUP:
                if (entering(tcp)) {
-                       struct blk_user_trace_setup buts;
-                       if (umove(tcp, arg, &buts) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", {act_mask=%hu, buf_size=%u, "
-                                       "buf_nr=%u, start_lba=%" PRIu64 ", "
-                                       "end_lba=%" PRIu64 ", pid=%u}",
-                                       buts.act_mask, buts.buf_size,
-                                       buts.buf_nr, buts.start_lba,
-                                       buts.end_lba, buts.pid);
-               }
-               if (exiting(tcp)) {
-                       struct blk_user_trace_setup buts;
-                       if (syserror(tcp) || umove(tcp, arg, &buts) < 0)
-                               tprintf(", %#lx", arg);
-                       else
-                               tprintf(", {name=\"%.*s\"}",
-                                       (int) sizeof(buts.name), buts.name);
+                       struct_blk_user_trace_setup buts;
+
+                       tprints(", ");
+                       if (umove_or_printaddr(tcp, arg, &buts))
+                               break;
+                       tprintf("{act_mask=%u, buf_size=%u, "
+                               "buf_nr=%u, start_lba=%" PRIu64 ", "
+                               "end_lba=%" PRIu64 ", pid=%u",
+                               (unsigned)buts.act_mask, buts.buf_size,
+                               buts.buf_nr, buts.start_lba,
+                               buts.end_lba, buts.pid);
+                       return 1;
+               } else {
+                       struct_blk_user_trace_setup buts;
+
+                       if (!syserror(tcp) && !umove(tcp, arg, &buts)) {
+                               tprints(", name=");
+                               print_quoted_string(buts.name, sizeof(buts.name),
+                                                   QUOTE_0_TERMINATED);
+                       }
+                       tprints("}");
+                       break;
                }
-               break;
 
-       /* No arguments or unhandled */
+       /* No arguments */
+       case BLKRRPART:
+       case BLKFLSBUF:
        case BLKTRACESTART:
        case BLKTRACESTOP:
        case BLKTRACETEARDOWN:
-       case BLKFLSBUF: /* Requires driver knowlege */
-       case BLKRRPART: /* No args */
-       default:
-               if (entering(tcp))
-                       tprintf(", %#lx", arg);
                break;
+       default:
+               return RVAL_DECODED;
+       }
 
-       };
-       return 1;
+       return RVAL_DECODED | 1;
 }