]> granicus.if.org Git - strace/blobdiff - file_ioctl.c
xlat: add ability to specify a default string to print_xlat_ex
[strace] / file_ioctl.c
index b065db917557149dd0b7cb3270f78424184aea0f..fc45aa693b9676f8a0aef23854c03d77b73a36a4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016 Jeff Mahoney <jeffm@suse.com>
+ * Copyright (c) 2016-2018 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #endif
 
 #ifndef FICLONE
-# define FICLONE         _IOW(0x94, 9, int)
+# define FICLONE       _IOW(0x94, 9, int)
 #endif
 
 #ifndef FICLONERANGE
-# define FICLONERANGE    _IOW(0x94, 13, struct file_clone_range)
+# define FICLONERANGE  _IOW(0x94, 13, struct file_clone_range)
 struct file_clone_range {
        int64_t src_fd;
        uint64_t src_offset;
@@ -50,7 +51,7 @@ struct file_clone_range {
 #endif
 
 #ifndef FIDEDUPERANGE
-# define FIDEDUPERANGE   _IOWR(0x94, 54, struct file_dedupe_range)
+# define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range)
 struct file_dedupe_range_info {
        int64_t dest_fd;        /* in - destination file */
        uint64_t dest_offset;   /* in - start of extent in destination */
@@ -80,6 +81,15 @@ print_file_dedupe_range_info(struct tcb *tcp, void *elem_buf,
                             size_t elem_size, void *data)
 {
        const struct file_dedupe_range_info *info = elem_buf;
+       unsigned int *count = data;
+
+       if (count) {
+               if (*count == 0) {
+                       tprints("...");
+                       return false;
+               }
+               --*count;
+       }
 
        if (entering(tcp)) {
                tprints("{dest_fd=");
@@ -114,7 +124,8 @@ print_fiemap_extent(struct tcb *tcp, void *elem_buf, size_t elem_size, void *dat
 #endif /* HAVE_LINUX_FIEMAP_H */
 
 int
-file_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
+file_ioctl(struct tcb *const tcp, const unsigned int code,
+          const kernel_ulong_t arg)
 {
        switch (code) {
        case FICLONE:   /* W */
@@ -141,6 +152,10 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
 
        case FIDEDUPERANGE: { /* RW */
                struct file_dedupe_range args;
+               struct file_dedupe_range_info info;
+               unsigned int *limit = NULL;
+               unsigned int count = 2;
+               bool rc;
 
                if (entering(tcp))
                        tprints(", ");
@@ -162,19 +177,16 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
                                (uint16_t) args.dest_count);
                }
 
-               bool rc = false;
                tprints("info=");
-               if (abbrev(tcp)) {
-                       tprints("...");
-               } else {
-                       struct file_dedupe_range_info info;
-                       rc = print_array(tcp,
-                                        arg + offsetof(typeof(args), info),
-                                        args.dest_count,
-                                        &info, sizeof(info),
-                                        umoven_or_printaddr,
-                                        print_file_dedupe_range_info, 0);
-               }
+
+               /* Limit how many elements we print in abbrev mode. */
+               if (abbrev(tcp) && args.dest_count > count)
+                       limit = &count;
+
+               rc = print_array(tcp, arg + offsetof(typeof(args), info),
+                                args.dest_count, &info, sizeof(info),
+                                tfetch_mem,
+                                print_file_dedupe_range_info, limit);
 
                tprints("}");
                if (!rc || exiting(tcp))
@@ -213,15 +225,15 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
                             "FIEMAP_FLAG_???");
                tprintf(", fm_mapped_extents=%u",
                        args.fm_mapped_extents);
-               tprints(", fm_extents=");
                if (abbrev(tcp)) {
-                       tprints("...");
+                       tprints("...");
                } else {
                        struct fiemap_extent fe;
+                       tprints(", fm_extents=");
                        print_array(tcp,
                                    arg + offsetof(typeof(args), fm_extents),
                                    args.fm_mapped_extents, &fe, sizeof(fe),
-                                   umoven_or_printaddr,
+                                   tfetch_mem,
                                    print_fiemap_extent, 0);
                }
                tprints("}");
@@ -234,5 +246,5 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
                return RVAL_DECODED;
        };
 
-       return RVAL_DECODED | 1;
+       return RVAL_IOCTL_DECODED;
 }