]> granicus.if.org Git - strace/commitdiff
Move dirent related parsers to a separate file
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 11 Sep 2014 22:40:37 +0000 (22:40 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 11 Sep 2014 22:40:37 +0000 (22:40 +0000)
* dirent.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* file.c (print_old_dirent, sys_readdir, sys_getdents, sys_getdents64):
Move to dirent.c.

Makefile.am
dirent.c [new file with mode: 0644]
file.c

index a30ac1c09ad5460cc2c48f74b7de5f21df3ac8c2..7dfdf2c80fe722be8cb936a284b4f117fd61df14 100644 (file)
@@ -22,6 +22,7 @@ strace_SOURCES =      \
        block.c         \
        count.c         \
        desc.c          \
+       dirent.c        \
        fanotify.c      \
        file.c          \
        inotify.c       \
diff --git a/dirent.c b/dirent.c
new file mode 100644 (file)
index 0000000..cbebdb7
--- /dev/null
+++ b/dirent.c
@@ -0,0 +1,210 @@
+#include "defs.h"
+#include <dirent.h>
+
+struct kernel_dirent {
+       unsigned long   d_ino;
+       unsigned long   d_off;
+       unsigned short  d_reclen;
+       char            d_name[1];
+};
+
+static void
+print_old_dirent(struct tcb *tcp, long addr)
+{
+#ifdef SH64
+       typedef struct kernel_dirent old_dirent_t;
+#else
+       typedef struct {
+               uint32_t        d_ino;
+               uint32_t        d_off;
+               unsigned short  d_reclen;
+               char            d_name[1];
+       } old_dirent_t;
+#endif
+       old_dirent_t d;
+
+       if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
+               tprintf("%#lx", addr);
+               return;
+       }
+
+       tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=\"",
+               (unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
+       if (d.d_reclen > 256)
+               d.d_reclen = 256;
+       printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
+       tprints("\"}");
+}
+
+int
+sys_readdir(struct tcb *tcp)
+{
+       if (entering(tcp)) {
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
+       } else {
+               if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
+                       tprintf("%#lx", tcp->u_arg[1]);
+               else
+                       print_old_dirent(tcp, tcp->u_arg[1]);
+               /* Not much point in printing this out, it is always 1. */
+               if (tcp->u_arg[2] != 1)
+                       tprintf(", %lu", tcp->u_arg[2]);
+       }
+       return 0;
+}
+
+#include "xlat/direnttypes.h"
+
+int
+sys_getdents(struct tcb *tcp)
+{
+       unsigned int i, len, dents = 0;
+       char *buf;
+
+       if (entering(tcp)) {
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
+               return 0;
+       }
+       if (syserror(tcp) || !verbose(tcp)) {
+               tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+               return 0;
+       }
+
+       /* Beware of insanely large or too small values in tcp->u_rval */
+       if (tcp->u_rval > 1024*1024)
+               len = 1024*1024;
+       else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
+               len = 0;
+       else
+               len = tcp->u_rval;
+
+       if (len) {
+               buf = malloc(len);
+               if (!buf)
+                       die_out_of_memory();
+               if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
+                       tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+                       free(buf);
+                       return 0;
+               }
+       } else {
+               buf = NULL;
+       }
+
+       if (!abbrev(tcp))
+               tprints("{");
+       for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
+               struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
+
+               if (!abbrev(tcp)) {
+                       int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
+                                 i + d->d_reclen - 1 >= len;
+                       int d_name_len = oob ? len - i : d->d_reclen;
+                       d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
+
+                       tprintf("%s{d_ino=%lu, d_off=%lu, ",
+                               i ? " " : "", d->d_ino, d->d_off);
+                       tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
+                               d->d_reclen, d_name_len, d->d_name);
+                       if (oob)
+                               tprints("?");
+                       else
+                               printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
+                       tprints("}");
+               }
+               dents++;
+               if (d->d_reclen < sizeof(struct kernel_dirent)) {
+                       tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
+                       break;
+               }
+               i += d->d_reclen;
+       }
+       if (!abbrev(tcp))
+               tprints("}");
+       else
+               tprintf("/* %u entries */", dents);
+       tprintf(", %lu", tcp->u_arg[2]);
+       free(buf);
+       return 0;
+}
+
+int
+sys_getdents64(struct tcb *tcp)
+{
+       /* the minimum size of a valid dirent64 structure */
+       const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
+
+       unsigned int i, len, dents = 0;
+       char *buf;
+
+       if (entering(tcp)) {
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
+               return 0;
+       }
+       if (syserror(tcp) || !verbose(tcp)) {
+               tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+               return 0;
+       }
+
+       /* Beware of insanely large or too small tcp->u_rval */
+       if (tcp->u_rval > 1024*1024)
+               len = 1024*1024;
+       else if (tcp->u_rval < (int) d_name_offset)
+               len = 0;
+       else
+               len = tcp->u_rval;
+
+       if (len) {
+               buf = malloc(len);
+               if (!buf)
+                       die_out_of_memory();
+               if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
+                       tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+                       free(buf);
+                       return 0;
+               }
+       } else {
+               buf = NULL;
+       }
+
+       if (!abbrev(tcp))
+               tprints("{");
+       for (i = 0; len && i <= len - d_name_offset; ) {
+               struct dirent64 *d = (struct dirent64 *) &buf[i];
+               if (!abbrev(tcp)) {
+                       int d_name_len;
+                       if (d->d_reclen >= d_name_offset
+                           && i + d->d_reclen <= len) {
+                               d_name_len = d->d_reclen - d_name_offset;
+                       } else {
+                               d_name_len = len - i - d_name_offset;
+                       }
+
+                       tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
+                               ", d_reclen=%u, d_type=",
+                               i ? " " : "",
+                               d->d_ino,
+                               d->d_off,
+                               d->d_reclen);
+                       printxval(direnttypes, d->d_type, "DT_???");
+                       tprintf(", d_name=\"%.*s\"}",
+                               d_name_len, d->d_name);
+               }
+               if (d->d_reclen < d_name_offset) {
+                       tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
+                       break;
+               }
+               i += d->d_reclen;
+               dents++;
+       }
+       if (!abbrev(tcp))
+               tprints("}");
+       else
+               tprintf("/* %u entries */", dents);
+       tprintf(", %lu", tcp->u_arg[2]);
+       free(buf);
+       return 0;
+}
diff --git a/file.c b/file.c
index 0044429911b5d12c09c174b31c89738ae3c27901..47ca2302fd49d1a6ea32c872c22a04aa39d8a58f 100644 (file)
--- a/file.c
+++ b/file.c
@@ -29,7 +29,6 @@
  */
 
 #include "defs.h"
-#include <dirent.h>
 #include <sys/swap.h>
 
 #if defined(SPARC) || defined(SPARC64)
@@ -204,13 +203,6 @@ struct __old_kernel_stat {
 # include <sys/asynch.h>
 #endif
 
-struct kernel_dirent {
-       unsigned long   d_ino;
-       unsigned long   d_off;
-       unsigned short  d_reclen;
-       char            d_name[1];
-};
-
 #ifdef O_LARGEFILE
 # if O_LARGEFILE == 0          /* biarch platforms in 64-bit mode */
 #  undef O_LARGEFILE
@@ -2009,207 +2001,6 @@ sys_mknodat(struct tcb *tcp)
        return decode_mknod(tcp, 1);
 }
 
-static void
-print_old_dirent(struct tcb *tcp, long addr)
-{
-#ifdef SH64
-       typedef struct kernel_dirent old_dirent_t;
-#else
-       typedef struct {
-               uint32_t        d_ino;
-               uint32_t        d_off;
-               unsigned short  d_reclen;
-               char            d_name[1];
-       } old_dirent_t;
-#endif
-       old_dirent_t d;
-
-       if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
-               tprintf("%#lx", addr);
-               return;
-       }
-
-       tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=\"",
-               (unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
-       if (d.d_reclen > 256)
-               d.d_reclen = 256;
-       printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
-       tprints("\"}");
-}
-
-int
-sys_readdir(struct tcb *tcp)
-{
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-       } else {
-               if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
-                       tprintf("%#lx", tcp->u_arg[1]);
-               else
-                       print_old_dirent(tcp, tcp->u_arg[1]);
-               /* Not much point in printing this out, it is always 1. */
-               if (tcp->u_arg[2] != 1)
-                       tprintf(", %lu", tcp->u_arg[2]);
-       }
-       return 0;
-}
-
-#include "xlat/direnttypes.h"
-
-int
-sys_getdents(struct tcb *tcp)
-{
-       unsigned int i, len, dents = 0;
-       char *buf;
-
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-               return 0;
-       }
-       if (syserror(tcp) || !verbose(tcp)) {
-               tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-               return 0;
-       }
-
-       /* Beware of insanely large or too small values in tcp->u_rval */
-       if (tcp->u_rval > 1024*1024)
-               len = 1024*1024;
-       else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
-               len = 0;
-       else
-               len = tcp->u_rval;
-
-       if (len) {
-               buf = malloc(len);
-               if (!buf)
-                       die_out_of_memory();
-               if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
-                       tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-                       free(buf);
-                       return 0;
-               }
-       } else {
-               buf = NULL;
-       }
-
-       if (!abbrev(tcp))
-               tprints("{");
-       for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
-               struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
-
-               if (!abbrev(tcp)) {
-                       int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
-                                 i + d->d_reclen - 1 >= len;
-                       int d_name_len = oob ? len - i : d->d_reclen;
-                       d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
-
-                       tprintf("%s{d_ino=%lu, d_off=%lu, ",
-                               i ? " " : "", d->d_ino, d->d_off);
-                       tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
-                               d->d_reclen, d_name_len, d->d_name);
-                       if (oob)
-                               tprints("?");
-                       else
-                               printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
-                       tprints("}");
-               }
-               dents++;
-               if (d->d_reclen < sizeof(struct kernel_dirent)) {
-                       tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
-                       break;
-               }
-               i += d->d_reclen;
-       }
-       if (!abbrev(tcp))
-               tprints("}");
-       else
-               tprintf("/* %u entries */", dents);
-       tprintf(", %lu", tcp->u_arg[2]);
-       free(buf);
-       return 0;
-}
-
-int
-sys_getdents64(struct tcb *tcp)
-{
-       /* the minimum size of a valid dirent64 structure */
-       const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
-
-       unsigned int i, len, dents = 0;
-       char *buf;
-
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-               return 0;
-       }
-       if (syserror(tcp) || !verbose(tcp)) {
-               tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-               return 0;
-       }
-
-       /* Beware of insanely large or too small tcp->u_rval */
-       if (tcp->u_rval > 1024*1024)
-               len = 1024*1024;
-       else if (tcp->u_rval < (int) d_name_offset)
-               len = 0;
-       else
-               len = tcp->u_rval;
-
-       if (len) {
-               buf = malloc(len);
-               if (!buf)
-                       die_out_of_memory();
-               if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
-                       tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-                       free(buf);
-                       return 0;
-               }
-       } else {
-               buf = NULL;
-       }
-
-       if (!abbrev(tcp))
-               tprints("{");
-       for (i = 0; len && i <= len - d_name_offset; ) {
-               struct dirent64 *d = (struct dirent64 *) &buf[i];
-               if (!abbrev(tcp)) {
-                       int d_name_len;
-                       if (d->d_reclen >= d_name_offset
-                           && i + d->d_reclen <= len) {
-                               d_name_len = d->d_reclen - d_name_offset;
-                       } else {
-                               d_name_len = len - i - d_name_offset;
-                       }
-
-                       tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
-                               ", d_reclen=%u, d_type=",
-                               i ? " " : "",
-                               d->d_ino,
-                               d->d_off,
-                               d->d_reclen);
-                       printxval(direnttypes, d->d_type, "DT_???");
-                       tprintf(", d_name=\"%.*s\"}",
-                               d_name_len, d->d_name);
-               }
-               if (d->d_reclen < d_name_offset) {
-                       tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
-                       break;
-               }
-               i += d->d_reclen;
-               dents++;
-       }
-       if (!abbrev(tcp))
-               tprints("}");
-       else
-               tprintf("/* %u entries */", dents);
-       tprintf(", %lu", tcp->u_arg[2]);
-       free(buf);
-       return 0;
-}
-
 int
 sys_getcwd(struct tcb *tcp)
 {