]> granicus.if.org Git - strace/blobdiff - file.c
io.c: move sendfile parsers to a separate file
[strace] / file.c
diff --git a/file.c b/file.c
index 92ebcd6c0cbd97b8664dec71854c37918c6bcdee..78d86f2d8913ade225aec8ca8a32abd7e7812d0a 100644 (file)
--- a/file.c
+++ b/file.c
 
 #include "printstat.h"
 
+/* all locally defined structures provide these fields */
+#undef HAVE_STRUCT_STAT_ST_ATIME_NSEC
+#define HAVE_STRUCT_STAT_ST_ATIME_NSEC 1
+#undef HAVE_STRUCT_STAT_ST_CTIME_NSEC
+#define HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
+#undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+
 #undef STAT32_PERSONALITY
 #if SUPPORTED_PERSONALITIES > 1
 # if defined AARCH64 || defined X86_64 || defined X32
@@ -174,19 +182,6 @@ struct stat32 {
 # undef HAVE_STRUCT_STAT_ST_FSTYPE
 # undef HAVE_STRUCT_STAT_ST_GEN
 # include "printstat.h"
-
-static void
-printstat32(struct tcb *tcp, long addr)
-{
-       struct stat32 statbuf;
-
-       if (umove(tcp, addr, &statbuf) < 0) {
-               tprints("{...}");
-               return;
-       }
-
-       do_printstat32(tcp, &statbuf);
-}
 #endif /* STAT32_PERSONALITY */
 
 #if defined(SPARC) || defined(SPARC64)
@@ -223,20 +218,6 @@ struct solstat {
 # undef HAVE_STRUCT_STAT_ST_FSTYPE
 # undef HAVE_STRUCT_STAT_ST_GEN
 # include "printstat.h"
-
-static void
-printstatsol(struct tcb *tcp, long addr)
-{
-       struct solstat statbuf;
-
-       if (umove(tcp, addr, &statbuf) < 0) {
-               tprints("{...}");
-               return;
-       }
-
-       do_printstat_sol(tcp, &statbuf);
-}
-
 #endif /* SPARC || SPARC64 */
 
 static void
@@ -244,39 +225,31 @@ printstat(struct tcb *tcp, long addr)
 {
        struct stat statbuf;
 
-       if (!addr) {
-               tprints("NULL");
-               return;
-       }
-       if (syserror(tcp) || !verbose(tcp)) {
-               tprintf("%#lx", addr);
-               return;
-       }
-
 #ifdef STAT32_PERSONALITY
        if (current_personality == STAT32_PERSONALITY) {
-               printstat32(tcp, addr);
+               struct stat32 statbuf;
+
+               if (!umove_or_printaddr(tcp, addr, &statbuf))
+                       do_printstat32(tcp, &statbuf);
                return;
        }
 #endif
 
 #if defined(SPARC) || defined(SPARC64)
        if (current_personality == 1) {
-               printstatsol(tcp, addr);
-               return;
-       }
-#endif /* SPARC || SPARC64 */
+               struct solstat statbuf;
 
-       if (umove(tcp, addr, &statbuf) < 0) {
-               tprints("{...}");
+               if (!umove_or_printaddr(tcp, addr, &statbuf))
+                       do_printstat_sol(tcp, &statbuf);
                return;
        }
+#endif /* SPARC || SPARC64 */
 
-       do_printstat(tcp, &statbuf);
+       if (!umove_or_printaddr(tcp, addr, &statbuf))
+               do_printstat(tcp, &statbuf);
 }
 
-int
-sys_stat(struct tcb *tcp)
+SYS_FUNC(stat)
 {
        if (entering(tcp)) {
                printpath(tcp, tcp->u_arg[0]);
@@ -287,8 +260,7 @@ sys_stat(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_fstat(struct tcb *tcp)
+SYS_FUNC(fstat)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -299,13 +271,12 @@ sys_fstat(struct tcb *tcp)
        return 0;
 }
 
-#if defined STAT32_PERSONALITY && !defined HAVE_STAT64
+#if defined STAT32_PERSONALITY && !defined HAVE_STRUCT_STAT64
 # if defined AARCH64 || defined X86_64 || defined X32
 /*
  * Linux x86_64 and x32 have unified `struct stat' but their i386 personality
  * needs `struct stat64'.
  * linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
- * __GNUC__ is needed for the required __attribute__ below.
  *
  * Similarly, aarch64 has a unified `struct stat' but its arm personality
  * needs `struct stat64' (unlike x86, it shouldn't be packed).
@@ -332,19 +303,19 @@ struct stat64 {
        unsigned long long      st_ino;
 }
 #  if defined X86_64 || defined X32
-  __attribute__((packed))
+  ATTRIBUTE_PACKED
 #   define STAT64_SIZE 96
 #  else
 #   define STAT64_SIZE 104
 #  endif
 ;
-#  define HAVE_STAT64  1
+#  define HAVE_STRUCT_STAT64   1
 # else /* !(AARCH64 || X86_64 || X32) */
 #  warning FIXME: check whether struct stat64 definition is needed for this architecture!
 # endif
-#endif /* STAT32_PERSONALITY && !HAVE_STAT64 */
+#endif /* STAT32_PERSONALITY && !HAVE_STRUCT_STAT64 */
 
-#ifdef HAVE_STAT64
+#ifdef HAVE_STRUCT_STAT64
 
 # define DO_PRINTSTAT do_printstat64
 # define STRUCT_STAT struct stat64
@@ -362,15 +333,6 @@ printstat64(struct tcb *tcp, long addr)
        (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
 # endif
 
-       if (!addr) {
-               tprints("NULL");
-               return;
-       }
-       if (syserror(tcp) || !verbose(tcp)) {
-               tprintf("%#lx", addr);
-               return;
-       }
-
 # ifdef STAT32_PERSONALITY
        if (current_personality != STAT32_PERSONALITY) {
                printstat(tcp, addr);
@@ -378,16 +340,11 @@ printstat64(struct tcb *tcp, long addr)
        }
 # endif /* STAT32_PERSONALITY */
 
-       if (umove(tcp, addr, &statbuf) < 0) {
-               tprints("{...}");
-               return;
-       }
-
-       do_printstat64(tcp, &statbuf);
+       if (!umove_or_printaddr(tcp, addr, &statbuf))
+               do_printstat64(tcp, &statbuf);
 }
 
-int
-sys_stat64(struct tcb *tcp)
+SYS_FUNC(stat64)
 {
        if (entering(tcp)) {
                printpath(tcp, tcp->u_arg[0]);
@@ -398,8 +355,7 @@ sys_stat64(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_fstat64(struct tcb *tcp)
+SYS_FUNC(fstat64)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -412,22 +368,19 @@ sys_fstat64(struct tcb *tcp)
 
 #else
 
-int
-sys_stat64(struct tcb *tcp)
+SYS_FUNC(stat64)
 {
        return sys_stat(tcp);
 }
 
-int
-sys_fstat64(struct tcb *tcp)
+SYS_FUNC(fstat64)
 {
        return sys_fstat(tcp);
 }
 
-#endif /* HAVE_STAT64 */
+#endif /* HAVE_STRUCT_STAT64 */
 
-int
-sys_newfstatat(struct tcb *tcp)
+SYS_FUNC(newfstatat)
 {
        if (entering(tcp)) {
                print_dirfd(tcp, tcp->u_arg[0]);
@@ -439,11 +392,11 @@ sys_newfstatat(struct tcb *tcp)
                        printstat64(tcp, tcp->u_arg[2]);
                else
                        printstat(tcp, tcp->u_arg[2]);
-#elif defined HAVE_STAT64
+#elif defined HAVE_STRUCT_STAT64
                printstat64(tcp, tcp->u_arg[2]);
 #else
                printstat(tcp, tcp->u_arg[2]);
-#endif /* STAT32_PERSONALITY || HAVE_STAT64 */
+#endif /* STAT32_PERSONALITY || HAVE_STRUCT_STAT64 */
                tprints(", ");
                printflags(at_flags, tcp->u_arg[3], "AT_???");
        }
@@ -475,33 +428,23 @@ printoldstat(struct tcb *tcp, long addr)
        struct __old_kernel_stat statbuf;
        struct stat newstatbuf;
 
-       if (!addr) {
-               tprints("NULL");
-               return;
-       }
-       if (syserror(tcp) || !verbose(tcp)) {
-               tprintf("%#lx", addr);
-               return;
-       }
-
 # if defined(SPARC) || defined(SPARC64)
        if (current_personality == 1) {
-               printstatsol(tcp, addr);
+               struct solstat statbuf;
+
+               if (!umove_or_printaddr(tcp, addr, &statbuf))
+                       do_printstat_sol(tcp, &statbuf);
                return;
        }
 # endif
 
-       if (umove(tcp, addr, &statbuf) < 0) {
-               tprints("{...}");
-               return;
+       if (!umove_or_printaddr(tcp, addr, &statbuf)) {
+               convertoldstat(&statbuf, &newstatbuf);
+               do_printstat(tcp, &newstatbuf);
        }
-
-       convertoldstat(&statbuf, &newstatbuf);
-       do_printstat(tcp, &newstatbuf);
 }
 
-int
-sys_oldstat(struct tcb *tcp)
+SYS_FUNC(oldstat)
 {
        if (entering(tcp)) {
                printpath(tcp, tcp->u_arg[0]);
@@ -512,8 +455,7 @@ sys_oldstat(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_oldfstat(struct tcb *tcp)
+SYS_FUNC(oldfstat)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -528,8 +470,7 @@ sys_oldfstat(struct tcb *tcp)
 
 #if defined(SPARC) || defined(SPARC64)
 
-int
-sys_xstat(struct tcb *tcp)
+SYS_FUNC(xstat)
 {
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
@@ -541,8 +482,7 @@ sys_xstat(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_fxstat(struct tcb *tcp)
+SYS_FUNC(fxstat)
 {
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);