]> granicus.if.org Git - strace/commitdiff
Fix decoding of statfs family syscalls
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 26 Apr 2016 00:21:26 +0000 (00:21 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 26 Apr 2016 01:35:31 +0000 (01:35 +0000)
Fix decoders of fstatfs, fstatfs64, statfs, and statfs64 syscalls
by rewriting them using mpers infrastructure.

* fetch_struct_statfs.c: New file.
* fstatfs.c: Likewise.
* fstatfs64.c: Likewise.
* print_statfs.c: Likewise.
* statfs.h: Likewise.
* statfs64.c: Likewise.
* statfs.c: Remove everything except SYS_FUNC(statfs).
* configure.ac: Remove the check for struct statfs64 in <sys/vfs.h>.
Add checks for struct statfs and struct statfs64 in <asm/statfs.h>.
Add checks for f_frsize and f_flags members of these structures.
* defs.h (struct strace_statfs): New forward declaration.
(print_struct_statfs, print_struct_statfs64): New prototypes.
* Makefile.am (libstrace_a_SOURCES): Add fstatfs.c, fstatfs64.c,
statfs.c, and statfs64.c.
(strace_SOURCES): Add fetch_struct_statfs.c, print_statfs.c,
and statfs.h.
* NEWS: Mention this fix.
* tests/fstatfs.c: New file.
* tests/fstatfs64.c: Likewise.
* tests/statfs64.c: Likewise.
* tests/xstatfs.c: Likewise.
* tests/xstatfs64.c: Likewise.
* tests/xstatfsx.c: Likewise.
* tests/fstatfs.test: New test.
* tests/fstatfs64.test: Likewise.
* tests/statfs64.test: Likewise.
* tests/statfs.c: Rewrite using xstatfs.c.
* tests/statfs.test: Update.
* tests/.gitignore: Add fstatfs, fstatfs64, and statfs64.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(DECODER_TESTS): Add  fstatfs.test, fstatfs64.test, and statfs64.test.
(EXTRA_DIST): Add xstatfs.c, xstatfs64.c, and xstatfsx.c.

24 files changed:
Makefile.am
NEWS
configure.ac
defs.h
fetch_struct_statfs.c [new file with mode: 0644]
fstatfs.c [new file with mode: 0644]
fstatfs64.c [new file with mode: 0644]
print_statfs.c [new file with mode: 0644]
statfs.c
statfs.h [new file with mode: 0644]
statfs64.c [new file with mode: 0644]
tests/.gitignore
tests/Makefile.am
tests/fstatfs.c [new file with mode: 0644]
tests/fstatfs.test [new file with mode: 0755]
tests/fstatfs64.c [new file with mode: 0644]
tests/fstatfs64.test [new file with mode: 0755]
tests/statfs.c
tests/statfs.test
tests/statfs64.c [new file with mode: 0644]
tests/statfs64.test [new file with mode: 0755]
tests/xstatfs.c [new file with mode: 0644]
tests/xstatfs64.c [new file with mode: 0644]
tests/xstatfsx.c [new file with mode: 0644]

index f02a42113a3b80ab5a7fcd5abf8e81d555849115..96146dd00657dfff21eb7350b7c6b4b40a4bd24f 100644 (file)
@@ -64,6 +64,10 @@ noinst_LIBRARIES = libstrace.a
 libstrace_a_CPPFLAGS = $(strace_CPPFLAGS)
 libstrace_a_CFLAGS = $(strace_CFLAGS)
 libstrace_a_SOURCES =  \
+       fstatfs.c \
+       fstatfs64.c \
+       statfs.c \
+       statfs64.c \
        sync_file_range.c \
        sync_file_range2.c \
        upeek.c         \
@@ -103,6 +107,7 @@ strace_SOURCES =    \
        fcntl.c         \
        fetch_seccomp_fprog.c \
        fetch_struct_flock.c \
+       fetch_struct_statfs.c \
        file.c          \
        file_handle.c   \
        flock.c         \
@@ -157,6 +162,7 @@ strace_SOURCES =    \
        print_mq_attr.c \
        print_msgbuf.c  \
        print_sigevent.c \
+       print_statfs.c  \
        print_time.c    \
        print_timex.c   \
        printmode.c     \
@@ -190,6 +196,7 @@ strace_SOURCES =    \
        socketutils.c   \
        sram_alloc.c    \
        statfs.c        \
+       statfs.h        \
        strace.c        \
        swapon.c        \
        syscall.c       \
diff --git a/NEWS b/NEWS
index 4cd5677b790ef2b4eaa70c6c7c5e2da96b4248f2..08e23093c64b4b734efb48f7f0c517f6b7d44d85 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,7 @@ Noteworthy changes in release ?.?? (????-??-??)
   * Implemented simultaneous use of -p option and tracing of a command.
     (addresses Debian bug #549942).
   * Enhanced decoding of personality, sched_getaffinity,
-    and sched_setaffinity syscalls.
+    sched_setaffinity, statfs, statfs64, fstatfs, and fstatfs64 syscalls.
   * Enhanced decoding of getxpid, getxuid, and getxgid syscalls on alpha.
   * Added decoding of bind, listen, and setsockopt direct syscalls on sparc.
   * Implemented caching of netlink conversations to reduce amount of time
index 2b29c945e53da0194485e1c97abdbed7b4e9dbc6..8a776d2e4b321823a079bc3dcf4dd401f13f30ed 100644 (file)
@@ -304,8 +304,6 @@ AC_CHECK_TYPES([struct stat64, struct __old_kernel_stat],,,
 [#include <sys/types.h>
 #include <asm/stat.h>])
 
-AC_CHECK_TYPES([struct statfs64],,, [#include <sys/vfs.h>])
-
 AC_CHECK_TYPES(m4_normalize([
        struct pt_all_user_regs,
        struct ia64_fpreg,
@@ -393,7 +391,6 @@ AC_CHECK_HEADERS(m4_normalize([
        sys/sem.h
        sys/shm.h
        sys/signalfd.h
-       sys/vfs.h
        sys/xattr.h
 ]))
 
@@ -434,6 +431,30 @@ AC_CHECK_HEADERS([linux/bpf.h], [
        fi
 ])
 
+AC_CHECK_TYPES([struct statfs], [
+       AC_CHECK_MEMBERS([struct statfs.f_frsize],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs.f_flags],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs.f_fsid.val],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs.f_fsid.__val],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+],, [#include <linux/types.h>
+#include <asm/statfs.h>])
+
+AC_CHECK_TYPES([struct statfs64], [
+       AC_CHECK_MEMBERS([struct statfs64.f_frsize],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs64.f_flags],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs64.f_fsid.val],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+       AC_CHECK_MEMBERS([struct statfs64.f_fsid.__val],,, [#include <linux/types.h>
+#include <asm/statfs.h>])
+],, [#include <linux/types.h>
+#include <asm/statfs.h>])
+
 AC_CHECK_DECLS([sys_errlist])
 AC_CHECK_DECLS(m4_normalize([
        PTRACE_PEEKUSER,
diff --git a/defs.h b/defs.h
index e345fd948a7126a5a01e70d653b7b458f9ab2be9..ef579ebef86ab8b3df96bfbb892bb9b1b89eca4c 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -634,6 +634,10 @@ extern void tprint_open_modes(int);
 extern const char *sprint_open_modes(int);
 extern void print_seccomp_filter(struct tcb *tcp, unsigned long);
 
+struct strace_statfs;
+extern void print_struct_statfs(struct tcb *tcp, long);
+extern void print_struct_statfs64(struct tcb *tcp, long, unsigned long);
+
 extern int block_ioctl(struct tcb *, const unsigned int, long);
 extern int evdev_ioctl(struct tcb *, const unsigned int, long);
 extern int loop_ioctl(struct tcb *, const unsigned int, long);
diff --git a/fetch_struct_statfs.c b/fetch_struct_statfs.c
new file mode 100644 (file)
index 0000000..7c8b088
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include DEF_MPERS_TYPE(struct_statfs)
+#include DEF_MPERS_TYPE(struct_statfs64)
+
+#include <linux/types.h>
+#include <asm/statfs.h>
+typedef struct statfs struct_statfs;
+typedef struct statfs64 struct_statfs64;
+
+#include MPERS_DEFS
+
+#include "statfs.h"
+
+#define ASSIGN_NUMBER(dst, src)                                \
+       if (sizeof(src) == sizeof(int))                 \
+               dst = (unsigned int) (src);             \
+       else if (sizeof(src) == sizeof(long))           \
+               dst = (unsigned long) (src);            \
+       else                                            \
+               dst = (unsigned long long) (src)
+
+MPERS_PRINTER_DECL(bool, fetch_struct_statfs)(struct tcb *tcp, const long addr, struct strace_statfs *p)
+{
+       struct_statfs b;
+
+       if (umove_or_printaddr(tcp, addr, &b))
+               return false;
+
+       ASSIGN_NUMBER(p->f_type, b.f_type);
+       ASSIGN_NUMBER(p->f_bsize, b.f_bsize);
+       ASSIGN_NUMBER(p->f_blocks, b.f_blocks);
+       ASSIGN_NUMBER(p->f_bfree, b.f_bfree);
+       ASSIGN_NUMBER(p->f_bavail, b.f_bavail);
+       ASSIGN_NUMBER(p->f_files, b.f_files);
+       ASSIGN_NUMBER(p->f_ffree, b.f_ffree);
+#if defined HAVE_STRUCT_STATFS_F_FSID_VAL
+       ASSIGN_NUMBER(p->f_fsid[0], b.f_fsid.val[0]);
+       ASSIGN_NUMBER(p->f_fsid[1], b.f_fsid.val[1]);
+#elif defined HAVE_STRUCT_STATFS_F_FSID___VAL
+       ASSIGN_NUMBER(p->f_fsid[0], b.f_fsid.__val[0]);
+       ASSIGN_NUMBER(p->f_fsid[1], b.f_fsid.__val[1]);
+#endif
+       ASSIGN_NUMBER(p->f_namelen, b.f_namelen);
+#ifdef HAVE_STRUCT_STATFS_F_FRSIZE
+       ASSIGN_NUMBER(p->f_frsize, b.f_frsize);
+#endif
+#ifdef HAVE_STRUCT_STATFS_F_FLAGS
+       ASSIGN_NUMBER(p->f_flags, b.f_flags);
+#endif
+
+       return true;
+}
+
+#if defined ARM || (defined AARCH64 && defined IN_MPERS)
+/* See arch/arm/kernel/sys_oabi-compat.c for details. */
+# define COMPAT_STATFS64_PADDED_SIZE (sizeof(struct_statfs64) + 4)
+#endif
+
+MPERS_PRINTER_DECL(bool, fetch_struct_statfs64)(struct tcb *tcp, const long addr, const unsigned long size, struct strace_statfs *p)
+{
+       struct_statfs64 b;
+
+        if (sizeof(b) != size
+#ifdef COMPAT_STATFS64_PADDED_SIZE
+           && sizeof(b) != COMPAT_STATFS64_PADDED_SIZE
+#endif
+          ) {
+               printaddr(addr);
+               return false;
+       }
+
+       if (umove_or_printaddr(tcp, addr, &b))
+               return false;
+
+       ASSIGN_NUMBER(p->f_type, b.f_type);
+       ASSIGN_NUMBER(p->f_bsize, b.f_bsize);
+       ASSIGN_NUMBER(p->f_blocks, b.f_blocks);
+       ASSIGN_NUMBER(p->f_bfree, b.f_bfree);
+       ASSIGN_NUMBER(p->f_bavail, b.f_bavail);
+       ASSIGN_NUMBER(p->f_files, b.f_files);
+       ASSIGN_NUMBER(p->f_ffree, b.f_ffree);
+#if defined HAVE_STRUCT_STATFS64_F_FSID_VAL
+       ASSIGN_NUMBER(p->f_fsid[0], b.f_fsid.val[0]);
+       ASSIGN_NUMBER(p->f_fsid[1], b.f_fsid.val[1]);
+#elif defined HAVE_STRUCT_STATFS64_F_FSID___VAL
+       ASSIGN_NUMBER(p->f_fsid[0], b.f_fsid.__val[0]);
+       ASSIGN_NUMBER(p->f_fsid[1], b.f_fsid.__val[1]);
+#endif
+       ASSIGN_NUMBER(p->f_namelen, b.f_namelen);
+#ifdef HAVE_STRUCT_STATFS64_F_FRSIZE
+       ASSIGN_NUMBER(p->f_frsize, b.f_frsize);
+#endif
+#ifdef HAVE_STRUCT_STATFS64_F_FLAGS
+       ASSIGN_NUMBER(p->f_flags, b.f_flags);
+#endif
+
+       return true;
+}
diff --git a/fstatfs.c b/fstatfs.c
new file mode 100644 (file)
index 0000000..1f35824
--- /dev/null
+++ b/fstatfs.c
@@ -0,0 +1,12 @@
+#include "defs.h"
+
+SYS_FUNC(fstatfs)
+{
+       if (entering(tcp)) {
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
+       } else {
+               print_struct_statfs(tcp, tcp->u_arg[1]);
+       }
+       return 0;
+}
diff --git a/fstatfs64.c b/fstatfs64.c
new file mode 100644 (file)
index 0000000..63eb3df
--- /dev/null
@@ -0,0 +1,14 @@
+#include "defs.h"
+
+SYS_FUNC(fstatfs64)
+{
+       const unsigned long size = tcp->u_arg[1];
+
+       if (entering(tcp)) {
+               printfd(tcp, tcp->u_arg[0]);
+               tprintf(", %lu, ", size);
+       } else {
+               print_struct_statfs64(tcp, tcp->u_arg[2], size);
+       }
+       return 0;
+}
diff --git a/print_statfs.c b/print_statfs.c
new file mode 100644 (file)
index 0000000..17f4c6f
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include "statfs.h"
+#include "xlat/fsmagic.h"
+#include "xlat/statfs_flags.h"
+
+static void
+print_statfs_type(const char *const prefix, const unsigned long long magic)
+{
+       tprints(prefix);
+       const char *s = xlat_search(fsmagic, ARRAY_SIZE(fsmagic), magic);
+       if (s)
+               tprints(s);
+       else
+               tprintf("%#llx", magic);
+}
+
+static void
+print_statfs_flags(const char *const prefix, const unsigned long long flags)
+{
+       if (flags & ST_VALID) {
+               tprints(prefix);
+               printflags(statfs_flags, flags, "ST_???");
+       }
+}
+
+static void
+print_statfs_number(const char *const prefix, const unsigned long long number)
+{
+       tprints(prefix);
+       tprintf("%llu",  number);
+}
+
+void
+print_struct_statfs(struct tcb *tcp, const long addr)
+{
+#ifdef HAVE_STRUCT_STATFS
+       struct strace_statfs b;
+
+       if (!fetch_struct_statfs(tcp, addr, &b))
+               return;
+
+       print_statfs_type("{f_type=", b.f_type);
+       print_statfs_number(", f_bsize=", b.f_bsize);
+       print_statfs_number(", f_blocks=", b.f_blocks);
+       print_statfs_number(", f_bfree=", b.f_bfree);
+       print_statfs_number(", f_bavail=", b.f_bavail);
+       print_statfs_number(", f_files=", b.f_files);
+       print_statfs_number(", f_ffree=", b.f_ffree);
+# if defined HAVE_STRUCT_STATFS_F_FSID_VAL \
+  || defined HAVE_STRUCT_STATFS_F_FSID___VAL
+       print_statfs_number(", f_fsid={", b.f_fsid[0]);
+       print_statfs_number(", ", b.f_fsid[1]);
+       tprints("}");
+# endif
+       print_statfs_number(", f_namelen=", b.f_namelen);
+# ifdef HAVE_STRUCT_STATFS_F_FRSIZE
+       print_statfs_number(", f_frsize=", b.f_frsize);
+# endif
+# ifdef HAVE_STRUCT_STATFS_F_FLAGS
+       print_statfs_flags(", f_flags=", b.f_flags);
+# endif
+       tprints("}");
+#else
+       printaddr(addr);
+#endif
+}
+
+void
+print_struct_statfs64(struct tcb *tcp, const long addr, const unsigned long size)
+{
+#ifdef HAVE_STRUCT_STATFS64
+       struct strace_statfs b;
+
+       if (!fetch_struct_statfs64(tcp, addr, size, &b))
+               return;
+
+       print_statfs_type("{f_type=", b.f_type);
+       print_statfs_number(", f_bsize=", b.f_bsize);
+       print_statfs_number(", f_blocks=", b.f_blocks);
+       print_statfs_number(", f_bfree=", b.f_bfree);
+       print_statfs_number(", f_bavail=", b.f_bavail);
+       print_statfs_number(", f_files=", b.f_files);
+       print_statfs_number(", f_ffree=", b.f_ffree);
+# if defined HAVE_STRUCT_STATFS64_F_FSID_VAL \
+  || defined HAVE_STRUCT_STATFS64_F_FSID___VAL
+       print_statfs_number(", f_fsid={", b.f_fsid[0]);
+       print_statfs_number(", ", b.f_fsid[1]);
+       tprints("}");
+# endif
+       print_statfs_number(", f_namelen=", b.f_namelen);
+# ifdef HAVE_STRUCT_STATFS64_F_FRSIZE
+       print_statfs_number(", f_frsize=", b.f_frsize);
+# endif
+# ifdef HAVE_STRUCT_STATFS64_F_FLAGS
+       print_statfs_flags(", f_flags=", b.f_flags);
+# endif
+       tprints("}");
+#else
+       printaddr(addr);
+#endif
+}
index bcbb73d2546bd4df19ec6d9d40359dffe166012a..00dd04c4e49165570879bd4e5b2f1a72b4358750 100644 (file)
--- a/statfs.c
+++ b/statfs.c
@@ -1,91 +1,4 @@
-/*
- * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
- * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
- * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
- * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
- * Copyright (c) 2003 Ulrich Drepper <drepper@redhat.com>
- * Copyright (c) 2012 Andreas Schwab <schwab@linux-m68k.org>
- * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
 #include "defs.h"
-#ifdef HAVE_SYS_VFS_H
-# include <sys/vfs.h>
-#endif
-#include "xlat/fsmagic.h"
-#include "xlat/statfs_flags.h"
-
-static const char *
-sprintfstype(const unsigned int magic)
-{
-       static char buf[32];
-       const char *s;
-
-       s = xlat_search(fsmagic, ARRAY_SIZE(fsmagic), magic);
-       if (s)
-               return s;
-       sprintf(buf, "%#x", magic);
-       return buf;
-}
-
-static void
-print_statfs_flags(const char *const prefix, const unsigned int flags)
-{
-       if (flags & ST_VALID) {
-               tprints(prefix);
-               printflags(statfs_flags, flags, "ST_???");
-       }
-}
-
-static void
-printstatfs(struct tcb *tcp, const long addr)
-{
-       struct statfs statbuf;
-
-       if (umove_or_printaddr(tcp, addr, &statbuf))
-               return;
-       tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
-               sprintfstype(statbuf.f_type),
-               (unsigned long)statbuf.f_bsize,
-               (unsigned long)statbuf.f_blocks,
-               (unsigned long)statbuf.f_bfree);
-       tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
-               (unsigned long)statbuf.f_bavail,
-               (unsigned long)statbuf.f_files,
-               (unsigned long)statbuf.f_ffree,
-               statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
-       tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
-#ifdef _STATFS_F_FRSIZE
-       tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
-#endif
-#ifdef _STATFS_F_FLAGS
-       print_statfs_flags(", f_flags=", statbuf.f_flags);
-#endif
-       tprints("}");
-}
 
 SYS_FUNC(statfs)
 {
@@ -93,127 +6,7 @@ SYS_FUNC(statfs)
                printpath(tcp, tcp->u_arg[0]);
                tprints(", ");
        } else {
-               printstatfs(tcp, tcp->u_arg[1]);
+               print_struct_statfs(tcp, tcp->u_arg[1]);
        }
        return 0;
 }
-
-SYS_FUNC(fstatfs)
-{
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-       } else {
-               printstatfs(tcp, tcp->u_arg[1]);
-       }
-       return 0;
-}
-
-#ifdef HAVE_STRUCT_STATFS64
-static void
-printstatfs64(struct tcb *tcp, long addr)
-{
-       struct statfs64 statbuf;
-
-       if (umove_or_printaddr(tcp, addr, &statbuf))
-               return;
-       tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
-               sprintfstype(statbuf.f_type),
-               (unsigned long long)statbuf.f_bsize,
-               (unsigned long long)statbuf.f_blocks,
-               (unsigned long long)statbuf.f_bfree);
-       tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
-               (unsigned long long)statbuf.f_bavail,
-               (unsigned long long)statbuf.f_files,
-               (unsigned long long)statbuf.f_ffree,
-               statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
-       tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
-#ifdef _STATFS_F_FRSIZE
-       tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
-#endif
-#ifdef _STATFS_F_FLAGS
-       print_statfs_flags(", f_flags=", statbuf.f_flags);
-#endif
-       tprints("}");
-}
-
-struct compat_statfs64 {
-       uint32_t f_type;
-       uint32_t f_bsize;
-       uint64_t f_blocks;
-       uint64_t f_bfree;
-       uint64_t f_bavail;
-       uint64_t f_files;
-       uint64_t f_ffree;
-       fsid_t f_fsid;
-       uint32_t f_namelen;
-       uint32_t f_frsize;
-       uint32_t f_flags;
-       uint32_t f_spare[4];
-}
-#if defined AARCH64 || defined X86_64 || defined X32 || defined IA64
-  ATTRIBUTE_PACKED ATTRIBUTE_ALIGNED(4)
-#endif
-;
-#if defined AARCH64 || defined ARM
-/* See arch/arm/kernel/sys_oabi-compat.c for details. */
-# define COMPAT_STATFS64_PADDED_SIZE (sizeof(struct compat_statfs64) + 4)
-#endif
-
-static void
-printcompat_statfs64(struct tcb *tcp, const long addr)
-{
-       struct compat_statfs64 statbuf;
-
-       if (umove_or_printaddr(tcp, addr, &statbuf))
-               return;
-       tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%llu, f_bfree=%llu, ",
-               sprintfstype(statbuf.f_type),
-               (unsigned long)statbuf.f_bsize,
-               (unsigned long long)statbuf.f_blocks,
-               (unsigned long long)statbuf.f_bfree);
-       tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
-               (unsigned long long)statbuf.f_bavail,
-               (unsigned long long)statbuf.f_files,
-               (unsigned long long)statbuf.f_ffree,
-               statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
-       tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
-       tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
-       print_statfs_flags(", f_flags=", statbuf.f_flags);
-       tprints("}");
-}
-
-static int
-do_statfs64_fstatfs64(struct tcb *tcp)
-{
-       if (entering(tcp)) {
-               tprintf(", %lu, ", tcp->u_arg[1]);
-       } else {
-               if (tcp->u_arg[1] == sizeof(struct statfs64))
-                       printstatfs64(tcp, tcp->u_arg[2]);
-               else if (tcp->u_arg[1] == sizeof(struct compat_statfs64)
-#ifdef COMPAT_STATFS64_PADDED_SIZE
-                        || tcp->u_arg[1] == COMPAT_STATFS64_PADDED_SIZE
-#endif
-                                                                       )
-                       printcompat_statfs64(tcp, tcp->u_arg[2]);
-               else
-                       tprints("{???}");
-       }
-       return 0;
-}
-
-SYS_FUNC(statfs64)
-{
-       if (entering(tcp))
-               printpath(tcp, tcp->u_arg[0]);
-       return do_statfs64_fstatfs64(tcp);
-}
-
-SYS_FUNC(fstatfs64)
-{
-       if (entering(tcp))
-               printfd(tcp, tcp->u_arg[0]);
-       return do_statfs64_fstatfs64(tcp);
-}
-#endif /* HAVE_STRUCT_STATFS64 */
diff --git a/statfs.h b/statfs.h
new file mode 100644 (file)
index 0000000..9341687
--- /dev/null
+++ b/statfs.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRACE_STATFS_H
+#define STRACE_STATFS_H
+
+struct strace_statfs {
+       unsigned long long f_type;
+       unsigned long long f_bsize;
+       unsigned long long f_blocks;
+       unsigned long long f_bfree;
+       unsigned long long f_bavail;
+       unsigned long long f_files;
+       unsigned long long f_ffree;
+       unsigned long f_fsid[2];
+       unsigned long long f_namelen;
+       unsigned long long f_frsize;
+       unsigned long long f_flags;
+};
+
+#endif /* STRACE_STATFS_H */
diff --git a/statfs64.c b/statfs64.c
new file mode 100644 (file)
index 0000000..f459831
--- /dev/null
@@ -0,0 +1,14 @@
+#include "defs.h"
+
+SYS_FUNC(statfs64)
+{
+       const unsigned long size = tcp->u_arg[1];
+
+       if (entering(tcp)) {
+               printpath(tcp, tcp->u_arg[0]);
+               tprintf(", %lu, ", size);
+       } else {
+               print_struct_statfs64(tcp, tcp->u_arg[2], size);
+       }
+       return 0;
+}
index ef39fe2016124e9425f0640857c4aaec84ef5b5e..9cac19d7746b059dcf8ce4ee619bd06d9cffd16c 100644 (file)
@@ -56,6 +56,8 @@ fork-f
 fstat
 fstat64
 fstatat64
+fstatfs
+fstatfs64
 fsync
 ftruncate
 ftruncate64
@@ -198,6 +200,7 @@ stack-fcall
 stat
 stat64
 statfs
+statfs64
 swap
 symlink
 symlinkat
index bd170fddd9a360bec9c159e7c0cbccb78f78ca19..6aa5d0e56e758168046833189263506a643a7e85 100644 (file)
@@ -110,6 +110,8 @@ check_PROGRAMS = \
        fstat \
        fstat64 \
        fstatat64 \
+       fstatfs \
+       fstatfs64 \
        fsync \
        ftruncate \
        ftruncate64 \
@@ -250,6 +252,7 @@ check_PROGRAMS = \
        stat \
        stat64 \
        statfs \
+       statfs64 \
        swap \
        symlink \
        symlinkat \
@@ -366,6 +369,8 @@ DECODER_TESTS = \
        fstat.test \
        fstat64.test \
        fstatat64.test \
+       fstatfs.test \
+       fstatfs64.test \
        fsync.test \
        ftruncate.test \
        ftruncate64.test \
@@ -498,6 +503,7 @@ DECODER_TESTS = \
        stat.test \
        stat64.test \
        statfs.test \
+       statfs64.test \
        sun_path.test \
        swap.test \
        symlink.test \
@@ -614,6 +620,9 @@ EXTRA_DIST = init.sh run.sh match.awk \
             xattr.expected \
             xchownx.c \
             xselect.c \
+            xstatfs.c \
+            xstatfs64.c \
+            xstatfsx.c \
             xstatx.c \
             $(TESTS)
 
diff --git a/tests/fstatfs.c b/tests/fstatfs.c
new file mode 100644 (file)
index 0000000..7ff39dc
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <sys/syscall.h>
+
+#ifdef __NR_fstatfs
+
+# define SYSCALL_ARG_FMT               "%d"
+# define SYSCALL_ARG(file, desc)       (desc)
+# define SYSCALL_NR                    __NR_fstatfs
+# define SYSCALL_NAME                  "fstatfs"
+# include "xstatfs.c"
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fstatfs")
+
+#endif
diff --git a/tests/fstatfs.test b/tests/fstatfs.test
new file mode 100755 (executable)
index 0000000..646e66f
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Check fstatfs syscall decoding.
+
+. "${srcdir=.}/statfs.test"
diff --git a/tests/fstatfs64.c b/tests/fstatfs64.c
new file mode 100644 (file)
index 0000000..6c59974
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <sys/syscall.h>
+
+#ifdef __NR_fstatfs64
+
+# define SYSCALL_ARG_FMT               "%d"
+# define SYSCALL_ARG(file, desc)       (desc)
+# define SYSCALL_NR                    __NR_fstatfs64
+# define SYSCALL_NAME                  "fstatfs64"
+# include "xstatfs64.c"
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fstatfs64")
+
+#endif
diff --git a/tests/fstatfs64.test b/tests/fstatfs64.test
new file mode 100755 (executable)
index 0000000..179ff1b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Check fstatfs64 syscall decoding.
+
+. "${srcdir=.}/statfs.test"
index 9b6ba55a804ff82d9bd5fbfd8629b29696f7b8ef..5a87afc16a498469b221eac90c46d7525bc23efa 100644 (file)
  */
 
 #include "tests.h"
-#include <sys/statfs.h>
+#include <sys/syscall.h>
 
-int
-main(void)
-{
-       struct statfs stb;
-       if (statfs("/proc/self/status", &stb))
-               perror_msg_and_fail("statfs");
-       return 0;
-}
+#ifdef __NR_statfs
+
+# define SYSCALL_ARG_FMT               "\"%s\""
+# define SYSCALL_ARG(file, desc)       (file)
+# define SYSCALL_NR                    __NR_statfs
+# define SYSCALL_NAME                  "statfs"
+# include "xstatfs.c"
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_statfs")
+
+#endif
index 214d52108a9f8aa2d1a8a47adbe907999555b03e..6075576f87d09d0ec6815966b2f8686a1a221eeb 100755 (executable)
@@ -1,15 +1,11 @@
 #!/bin/sh
 
-# Check how statfs/statfs64 syscalls are traced.
+# Check statfs syscall decoding.
 
 . "${srcdir=.}/init.sh"
 
 # this test probes /proc/self/status
 [ -f /proc/self/status ] ||
-        framework_skip_ '/proc/self/status is not available'
+       framework_skip_ '/proc/self/status is not available'
 
-run_prog
-run_strace -efile $args
-match_grep
-
-exit 0
+run_strace_match_diff -a17
diff --git a/tests/statfs64.c b/tests/statfs64.c
new file mode 100644 (file)
index 0000000..b85dce2
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <sys/syscall.h>
+
+#ifdef __NR_statfs64
+
+# define SYSCALL_ARG_FMT               "\"%s\""
+# define SYSCALL_ARG(file, desc)       (file)
+# define SYSCALL_NR                    __NR_statfs64
+# define SYSCALL_NAME                  "statfs64"
+# include "xstatfs64.c"
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_statfs64")
+
+#endif
diff --git a/tests/statfs64.test b/tests/statfs64.test
new file mode 100755 (executable)
index 0000000..9c0aa27
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Check statfs64 syscall decoding.
+
+. "${srcdir=.}/statfs.test"
diff --git a/tests/xstatfs.c b/tests/xstatfs.c
new file mode 100644 (file)
index 0000000..26c43de
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define SYSCALL_INVOKE(file, desc, ptr, size) \
+       syscall(SYSCALL_NR, SYSCALL_ARG(file, desc), ptr)
+#define PRINT_SYSCALL_HEADER(file, desc, size) \
+       printf("%s(" SYSCALL_ARG_FMT ", ", SYSCALL_NAME, SYSCALL_ARG(file, desc))
+
+#define STRUCT_STATFS  struct statfs
+#ifdef HAVE_STRUCT_STATFS_F_FRSIZE
+# define PRINT_F_FRSIZE
+#endif
+#ifdef HAVE_STRUCT_STATFS_F_FLAGS
+# define PRINT_F_FLAGS
+#endif
+#if defined HAVE_STRUCT_STATFS_F_FSID_VAL
+# define PRINT_F_FSID  f_fsid.val
+#elif defined HAVE_STRUCT_STATFS_F_FSID___VAL
+# define PRINT_F_FSID  f_fsid.__val
+#endif
+
+#include "xstatfsx.c"
diff --git a/tests/xstatfs64.c b/tests/xstatfs64.c
new file mode 100644 (file)
index 0000000..8f50de2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define SYSCALL_INVOKE(file, desc, ptr, size) \
+       syscall(SYSCALL_NR, SYSCALL_ARG(file, desc), size, ptr)
+#define PRINT_SYSCALL_HEADER(file, desc, size) \
+       printf("%s(" SYSCALL_ARG_FMT ", %u, ", SYSCALL_NAME, \
+              SYSCALL_ARG(file, desc), (unsigned) size)
+
+#define STRUCT_STATFS  struct statfs64
+#ifdef HAVE_STRUCT_STATFS64_F_FRSIZE
+# define PRINT_F_FRSIZE
+#endif
+#ifdef HAVE_STRUCT_STATFS64_F_FLAGS
+# define PRINT_F_FLAGS
+#endif
+#if defined HAVE_STRUCT_STATFS64_F_FSID_VAL
+# define PRINT_F_FSID  f_fsid.val
+#elif defined HAVE_STRUCT_STATFS64_F_FSID___VAL
+# define PRINT_F_FSID  f_fsid.__val
+#endif
+#define CHECK_ODD_SIZE
+
+#include "xstatfsx.c"
diff --git a/tests/xstatfsx.c b/tests/xstatfsx.c
new file mode 100644 (file)
index 0000000..8e54fce
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <linux/types.h>
+#include <asm/statfs.h>
+
+#include "xlat.h"
+#include "xlat/fsmagic.h"
+#include "xlat/statfs_flags.h"
+
+#define PRINT_NUM(arg)                                                 \
+       if (sizeof(b->arg) == sizeof(int))                              \
+               printf(", %s=%u", #arg, (unsigned int) b->arg);         \
+       else if (sizeof(b->arg) == sizeof(long))                                \
+               printf(", %s=%lu", #arg, (unsigned long) b->arg);       \
+       else                                                            \
+               printf(", %s=%llu", #arg, (unsigned long long) b->arg)
+
+static void
+print_statfs_type(const char *const prefix, const unsigned int magic)
+{
+       fputs(prefix, stdout);
+       unsigned int i;
+       for (i = 0; i < ARRAY_SIZE(fsmagic); ++i)
+               if (magic == fsmagic[i].val) {
+                       fputs(fsmagic[i].str, stdout);
+                       return;
+               }
+       printf("%#x", magic);
+}
+
+static void
+print_statfs(const char *const sample, const char *magic_str)
+{
+       int fd = open(sample, O_RDONLY);
+       if (fd < 0)
+               perror_msg_and_fail("open: %s", sample);
+
+       STRUCT_STATFS *const b = tail_alloc(sizeof(*b));
+       long rc = SYSCALL_INVOKE(sample, fd, b, sizeof(*b));
+       if (rc)
+               perror_msg_and_skip(SYSCALL_NAME);
+
+       PRINT_SYSCALL_HEADER(sample, fd, sizeof(*b));
+       if (magic_str)
+               printf("{f_type=%s", magic_str);
+       else
+               print_statfs_type("{f_type=", b->f_type);
+       PRINT_NUM(f_bsize);
+       PRINT_NUM(f_blocks);
+       PRINT_NUM(f_bfree);
+       PRINT_NUM(f_bavail);
+       PRINT_NUM(f_files);
+       PRINT_NUM(f_ffree);
+#ifdef PRINT_F_FSID
+       printf(", f_fsid={%u, %u}", b->PRINT_F_FSID[0], b->PRINT_F_FSID[1]);
+#endif
+       PRINT_NUM(f_namelen);
+#ifdef PRINT_F_FRSIZE
+       PRINT_NUM(f_frsize);
+#endif
+#ifdef PRINT_F_FLAGS
+       if (b->f_flags & ST_VALID) {
+               printf(", f_flags=");
+               printflags(statfs_flags, b->f_flags, "ST_???");
+       }
+#endif
+       printf("}) = 0\n");
+}
+
+int
+main(void)
+{
+       print_statfs("/proc/self/status", "PROC_SUPER_MAGIC");
+
+       print_statfs(".", NULL);
+
+       long rc = SYSCALL_INVOKE("", -1, 0, sizeof(STRUCT_STATFS));
+       PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS));
+       printf("NULL) = %ld %s (%m)\n", rc, errno2name());
+
+#ifdef CHECK_ODD_SIZE
+       const unsigned long addr = (unsigned long) 0xfacefeeddeadbeef;
+       rc = SYSCALL_INVOKE("", -1, addr, sizeof(STRUCT_STATFS) + 1);
+       PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS) + 1);
+       printf("%#lx) = %ld %s (%m)\n", addr, rc, errno2name());
+#endif
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}