]> granicus.if.org Git - strace/commitdiff
printfd: print character/block device number in -yy mode
authorEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 25 Jan 2018 16:53:23 +0000 (17:53 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 1 Mar 2018 01:00:24 +0000 (01:00 +0000)
* util.c: Include <sys/stat.h>, <sys/sysmacros.h>,
and "largefile_wrappers.h".
(printsocket, printdev): New functions.
(printfd): Move socket matching/printing logic to printsocket.  Check
also for printdev.  Escape opening angle bracket in addition to closing angle
bracket as it can show up as a separator in printdev.
* tests/fsync-y.c: Update expected output.
* strace.1.in: Mention this.
* NEWS: Likewise.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
NEWS
strace.1.in
tests/fsync-y.c
util.c

diff --git a/NEWS b/NEWS
index cd85c097c9f186b0c7a92e42ffa6e2c13227ccdf..c0874912b55ec717b4e2381a55a23ff3422c637c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,7 @@ Noteworthy changes in release ?.?? (????-??-??)
   * The mailing list was moved to strace-devel@lists.strace.io.
 
 * Changes in behaviour
-  * Closing angle bracket is now printed as an octal number escape sequence
+  * Angle brackets are now printed as octal number escape sequences
     in the output of paths associated with file descriptors.
 
 * Improvements
@@ -14,6 +14,7 @@ Noteworthy changes in release ?.?? (????-??-??)
   * Enhanced NETLINK_ROUTE protocol decoding.
   * Updated lists of signal codes.
   * Updated lists of INET_DIAG_BC_*, POLL*, RWF_*, and SCHED_FLAG_* constants.
+  * Implemented block/character device number printing in -yy mode.
 
 * Bug fixes
   * Fixed build on m68k.
index d05d16508d446385b76d66e81b5de6d95145bc3c..3443b3b9482b2febf0d9d25343a0f5c074e66c8f 100644 (file)
@@ -318,7 +318,8 @@ Print all strings in hexadecimal string format.
 Print paths associated with file descriptor arguments.
 .TP
 .B \-yy
-Print protocol specific information associated with socket file descriptors.
+Print protocol specific information associated with socket file descriptors,
+and block/character device number associated with device file descriptors.
 .SS Statistics
 .TP 12
 .B \-c
index df4b1088f7fd1e3bf8ea01edcad25f0e42144597..34267b9c14bafe5c27b235a050bb9f964d2092d8 100644 (file)
@@ -46,7 +46,7 @@ main(void)
        } checks[] = {
                { ARG_STR("\1\0020\v\0047\f\58\t\79\n\10\0171\r\0167\218\37 \\\'\"<<0::0>>1~\177\200\377"),
                        "\\1\\0020\\v\\0047\\f\\58\\t\\79\\n\\10\\0171\\r\\0167"
-                       "\\218\\37 \\\\\'\\\"<<0::0\\76\\0761~\\177\\200\\377" },
+                       "\\218\\37 \\\\\'\\\"\\74\\0740::0\\76\\0761~\\177\\200\\377" },
        };
 
        if (!getcwd(dir, sizeof(dir)))
@@ -60,7 +60,7 @@ main(void)
                int rc = fsync(fd);
 
                printf("fsync(%ld<", fd);
-               print_quoted_string_ex(dir, false, ">");
+               print_quoted_string_ex(dir, false, ">:");
                printf("/%s>) = %s\n", checks[i].fdstr, sprintrc(rc));
 
                close(fd);
diff --git a/util.c b/util.c
index 78aad90b268330172cf2dd8093fb8d366a18e916..38458658b45b8404a140ef6e2fcb8117b7b77519 100644 (file)
--- a/util.c
+++ b/util.c
 #include <limits.h>
 #include <fcntl.h>
 #include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
 #ifdef HAVE_SYS_XATTR_H
 # include <sys/xattr.h>
 #endif
 #include <sys/uio.h>
+
+#include "largefile_wrappers.h"
 #include "xstring.h"
 
 int
@@ -418,24 +422,59 @@ getfdinode(struct tcb *tcp, int fd)
        return 0;
 }
 
+static bool
+printsocket(struct tcb *tcp, int fd, const char *path)
+{
+       const char *str = STR_STRIP_PREFIX(path, "socket:[");
+       size_t len;
+       unsigned long inode;
+
+       return (str != path)
+               && (len = strlen(str))
+               && (str[len - 1] == ']')
+               && (inode = strtoul(str, NULL, 10))
+               && print_sockaddr_by_inode(tcp, fd, inode);
+}
+
+static bool
+printdev(struct tcb *tcp, int fd, const char *path)
+{
+       struct_stat st;
+
+       if (path[0] != '/')
+               return false;
+
+       if (stat_file(path, &st)) {
+               debug_func_perror_msg("stat(\"%s\")", path);
+               return false;
+       }
+
+       switch (st.st_mode & S_IFMT) {
+       case S_IFBLK:
+       case S_IFCHR:
+               print_quoted_string_ex(path, strlen(path),
+                                      QUOTE_OMIT_LEADING_TRAILING_QUOTES,
+                                      "<>");
+               tprintf("<%s %u:%u>",
+                       S_ISBLK(st.st_mode)? "block" : "char",
+                       major(st.st_rdev), minor(st.st_rdev));
+               return true;
+       }
+
+       return false;
+}
+
 void
 printfd(struct tcb *tcp, int fd)
 {
        char path[PATH_MAX + 1];
        if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
-               const char *str;
-               size_t len;
-               unsigned long inode;
-
                tprintf("%d<", fd);
                if (show_fd_path <= 1
-                   || (str = STR_STRIP_PREFIX(path, "socket:[")) == path
-                   || !(len = strlen(str))
-                   || str[len - 1] != ']'
-                   || !(inode = strtoul(str, NULL, 10))
-                   || !print_sockaddr_by_inode(tcp, fd, inode)) {
+                   || (!printsocket(tcp, fd, path)
+                        && !printdev(tcp, fd, path))) {
                        print_quoted_string_ex(path, strlen(path),
-                               QUOTE_OMIT_LEADING_TRAILING_QUOTES, ">");
+                               QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
                }
                tprints(">");
        } else