]> granicus.if.org Git - strace/commitdiff
tests: check verbose decoding of 32-bit and 64-bit struct stat
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 7 Jan 2015 19:30:37 +0000 (19:30 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 8 Jan 2015 00:59:42 +0000 (00:59 +0000)
* tests/stat.c: New file.
* tests/stat32.c: Likewise.
* tests/stat32-v.test: New file.
* tests/stat64-v.test: Likewise.
* tests/Makefile.am (check_PROGRAMS): Add stat and stat32.
(stat_CFLAGS): Define.
(TESTS): Add stat32-v.test and stat64-v.test.
* tests/.gitignore: Add stat and stat32.

tests/.gitignore
tests/Makefile.am
tests/stat.c [new file with mode: 0644]
tests/stat32-v.test [new file with mode: 0755]
tests/stat32.c [new file with mode: 0644]
tests/stat64-v.test [new file with mode: 0755]

index b53ef6ad0aeccd83c56db89bb4661ca8962f1a97..af463d08544dfded4f8df93c69b91c98d13b37ab 100644 (file)
@@ -8,6 +8,8 @@ scm_rights
 set_ptracer_any
 sigaction
 stack-fcall
+stat
+stat32
 statfs
 uid
 uid16
index e307c577b468819623bd2797699d6e2b475fdde9..b88ed55e45e18be90fdb1b75ef331f90bf2712c2 100644 (file)
@@ -13,12 +13,15 @@ check_PROGRAMS = \
        set_ptracer_any \
        sigaction \
        stack-fcall \
+       stat \
+       stat32 \
        statfs \
        uid \
        uid16 \
        uid32 \
        uio
 
+stat_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
 statfs_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
 uio_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
 stack_fcall_SOURCES = stack-fcall.c \
@@ -33,6 +36,8 @@ TESTS = \
        scm_rights-fd.test \
        sigaction.test \
        stat.test \
+       stat32-v.test \
+       stat64-v.test \
        statfs.test \
        mmsg.test \
        net.test \
diff --git a/tests/stat.c b/tests/stat.c
new file mode 100644 (file)
index 0000000..21e37fb
--- /dev/null
@@ -0,0 +1,171 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h>
+
+#if defined MAJOR_IN_SYSMACROS
+# include <sys/sysmacros.h>
+#elif defined MAJOR_IN_MKDEV
+# include <sys/mkdev.h>
+#else
+# include <sys/types.h>
+#endif
+
+#undef STAT_FNAME
+#undef NR_stat
+
+#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
+# include <sys/stat.h>
+# define STAT_FNAME "stat(64)?"
+#else
+# include <sys/syscall.h>
+# if defined __NR_stat
+#  define NR_stat __NR_stat
+#  define STAT_FNAME "stat"
+# elif defined __NR_newstat
+#  define NR_stat __NR_newstat
+#  define STAT_FNAME "newstat"
+# endif
+# ifdef STAT_FNAME
+/* for S_IFMT */
+#  define stat libc_stat
+#  define stat64 libc_stat64
+#  include <sys/stat.h>
+#  undef stat
+#  undef stat64
+#  undef st_atime
+#  undef st_mtime
+#  undef st_ctime
+
+#  undef dev_t
+#  undef ino_t
+#  undef mode_t
+#  undef nlink_t
+#  undef uid_t
+#  undef gid_t
+#  undef off_t
+#  undef loff_t
+#  define dev_t __kernel_dev_t
+#  define ino_t __kernel_ino_t
+#  define mode_t __kernel_mode_t
+#  define nlink_t __kernel_nlink_t
+#  define uid_t __kernel_uid_t
+#  define gid_t __kernel_gid_t
+#  define off_t __kernel_off_t
+#  define loff_t __kernel_loff_t
+#  include <asm/stat.h>
+#  endif /* STAT_FNAME */
+#endif /* _FILE_OFFSET_BITS */
+
+#ifdef STAT_FNAME
+
+static void
+print_ftype(unsigned int mode)
+{
+       if (S_ISREG(mode))
+               printf("S_IFREG");
+       else if (S_ISDIR(mode))
+               printf("S_IFDIR");
+       else if (S_ISCHR(mode))
+               printf("S_IFCHR");
+       else if (S_ISBLK(mode))
+               printf("S_IFBLK");
+       else
+               printf("%#o", mode & S_IFMT);
+}
+
+static void
+print_perms(unsigned int mode)
+{
+       printf("%#o", mode & ~S_IFMT);
+}
+
+static void
+print_time(time_t t)
+{
+       if (!t) {
+               printf("0");
+               return;
+       }
+
+       struct tm *p = localtime(&t);
+
+       if (p)
+               printf("%02d/%02d/%02d-%02d:%02d:%02d",
+                      p->tm_year + 1900, p->tm_mon + 1, p->tm_mday,
+                      p->tm_hour, p->tm_min, p->tm_sec);
+       else
+               printf("%llu", (unsigned long long) t);
+}
+
+int
+main(int ac, const char **av)
+{
+       assert(ac == 2);
+       struct stat stb;
+
+#ifdef NR_stat
+       if (sizeof(stb.st_size) > 4)
+               return 77;
+       assert(syscall(NR_stat, av[1], &stb) == 0);
+#else
+       assert(stat(av[1], &stb) == 0);
+#endif
+
+       printf(STAT_FNAME "\\(\"%s\", \\{", av[1]);
+       printf("st_dev=makedev\\(%u, %u\\)",
+              (unsigned int) major(stb.st_dev),
+              (unsigned int) minor(stb.st_dev));
+       printf(", st_ino=%llu", (unsigned long long) stb.st_ino);
+       printf(", st_mode=");
+               print_ftype(stb.st_mode);
+               printf("\\|");
+               print_perms(stb.st_mode);
+       printf(", st_nlink=%u", (unsigned int) stb.st_nlink);
+       printf(", st_uid=%u", (unsigned int) stb.st_uid);
+       printf(", st_gid=%u", (unsigned int) stb.st_gid);
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+       printf(", st_blksize=%u", (unsigned int) stb.st_blksize);
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+       printf(", st_blocks=%u", (unsigned int) stb.st_blocks);
+#endif
+
+       switch (stb.st_mode & S_IFMT) {
+       case S_IFCHR: case S_IFBLK:
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+               printf(", st_rdev=makedev\\(%u, %u\\)",
+                      (unsigned int) major(stb.st_rdev),
+                      (unsigned int) minor(stb.st_rdev));
+#else
+               printf(", st_size=makedev\\(%u, %u\\)",
+                      (unsigned int) major(stb.st_size),
+                      (unsigned int) minor(stb.st_size));
+#endif
+               break;
+       default:
+               printf(", st_size=%llu", (unsigned long long) stb.st_size);
+       }
+
+       printf(", st_atime=");
+               print_time(stb.st_atime);
+       printf(", st_mtime=");
+               print_time(stb.st_mtime);
+       printf(", st_ctime=");
+               print_time(stb.st_ctime);
+       printf("(, st_flags=[0-9]+)?");
+       printf("(, st_fstype=[^,]*)?");
+       printf("(, st_gen=[0-9]+)?");
+       printf("\\}\\) += 0\n");
+       return 0;
+}
+
+#else /* !STAT_FNAME */
+int main(void)
+{
+       return 77;
+}
+#endif
diff --git a/tests/stat32-v.test b/tests/stat32-v.test
new file mode 100755 (executable)
index 0000000..74373c3
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# Check verbose decoding of 32-bit stat syscall.
+
+. "${srcdir=.}/init.sh"
+
+check_prog dd
+check_prog grep
+check_prog touch
+
+OUT="$LOG.out"
+size=233811181
+sample=stat32_sample
+
+umask 022
+truncate_cmd="dd seek=$size obs=1 count=0 if=/dev/null of=$sample"
+$truncate_cmd > "$OUT" 2>&1 || {
+       cat "$OUT"
+       framework_skip_ 'failed to create a large sparse file'
+}
+
+./stat32 $sample > /dev/null || {
+       if [ $? -eq 77 ]; then
+               framework_skip_ '32-bit stat syscall is not available'
+       else
+               fail_ 'stat32 failed'
+       fi
+}
+
+touch -t 0102030405 $sample
+
+for f in $sample . /dev/null; do
+       args="-v -efile ./stat32 $f"
+       $STRACE -o "$LOG" $args > "$OUT" &&
+       LC_ALL=C grep -E -x -f "$OUT" "$LOG" > /dev/null || {
+               cat "$OUT" "$LOG"
+               fail_ "$STRACE $args output mismatch"
+       }
+done
+
+rm -f $sample "$OUT"
+
+exit 0
diff --git a/tests/stat32.c b/tests/stat32.c
new file mode 100644 (file)
index 0000000..a074251
--- /dev/null
@@ -0,0 +1 @@
+#include "stat.c"
diff --git a/tests/stat64-v.test b/tests/stat64-v.test
new file mode 100755 (executable)
index 0000000..7e08e25
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Check verbose decoding of 64-bit stat syscall.
+
+. "${srcdir=.}/init.sh"
+
+check_prog dd
+check_prog grep
+check_prog touch
+
+OUT="$LOG.out"
+size=46118400000
+sample=stat64_sample
+
+umask 022
+truncate_cmd="dd seek=$size obs=1 count=0 if=/dev/null of=$sample"
+$truncate_cmd > "$OUT" 2>&1 || {
+       cat "$OUT"
+       framework_skip_ 'failed to create a large sparse file'
+}
+
+./stat $sample > /dev/null ||
+       fail_ 'stat failed'
+
+touch -t 0102030405 $sample
+
+for f in $sample . /dev/null; do
+       args="-v -efile ./stat $f"
+       $STRACE -o "$LOG" $args > "$OUT" &&
+       LC_ALL=C grep -E -x -f "$OUT" "$LOG" > /dev/null || {
+               cat "$OUT" "$LOG"
+               fail_ "$STRACE $args output mismatch"
+       }
+done
+
+rm -f $sample "$OUT"
+
+exit 0