* linux/i386/syscallent.h [383]: Add statx entry. * linux/x32/syscallent.h [332]: Likewise. * linux/x86_64/syscallent.h [332]: Likewise. * pathtrace.c (pathtrace_match): Handle SEN_statx. * statx.c: New file. * statx.h: Likewise. * Makefile.am (strace_SOURCES): Add them. * tests/.gitignore: Add statx. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add statx.test. * tests/statx.c: New file. * tests/statx.test: Likewise. * tests/xstatx.c: Modify to support statx. * xlat/at_statx_sync_types.in: New file. * xlat/statx_attrs.in: Likewise. * xlat/statx_masks.in: Likewise. * NEWS: Mention this change. --- Makefile.am | 2 + NEWS | 1 + linux/i386/syscallent.h | 1 + linux/x32/syscallent.h | 3 +- linux/x86_64/syscallent.h | 1 + pathtrace.c | 1 + statx.c | 111 ++++++++++++++++++++++++++ statx.h | 69 ++++++++++++++++ tests/.gitignore | 1 + tests/Makefile.am | 2 + tests/statx.c | 70 +++++++++++++++++ tests/statx.test | 5 ++ tests/xstatx.c | 188 ++++++++++++++++++++++++++++++++++++++++---- xlat/at_statx_sync_types.in | 5 ++ xlat/statx_attrs.in | 6 ++ xlat/statx_masks.in | 15 ++++ 16 files changed, 465 insertions(+), 16 deletions(-) create mode 100644 statx.c create mode 100644 statx.h create mode 100644 tests/statx.c create mode 100755 tests/statx.test create mode 100644 xlat/at_statx_sync_types.in create mode 100644 xlat/statx_attrs.in create mode 100644 xlat/statx_masks.in
diff --git a/Makefile.am b/Makefile.am index 7e837b3..65177a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -232,6 +232,8 @@ strace_SOURCES = \ stat64.c \ statfs.c \ statfs.h \ + statx.c \ + statx.h \ strace.c \ swapon.c \ syscall.c \ diff --git a/NEWS b/NEWS index 77b6678..b2bb644 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ Noteworthy changes in release ?.?? (????-??-??) * Improvements * Enhanced decoding of sched_setattr syscall. * Added -e trace=%sched option for tracing sched_* syscalls. + * Implemented decoding of statx syscall. * Bug fixes * Fixed decoding of flags argument of preadv2 and pwritev2 syscalls on x32. diff --git a/linux/i386/syscallent.h b/linux/i386/syscallent.h index 8ef1b1c..84c5bde 100644 --- a/linux/i386/syscallent.h +++ b/linux/i386/syscallent.h @@ -408,6 +408,7 @@ [380] = { 4, TM|SI, SEN(pkey_mprotect), "pkey_mprotect" }, [381] = { 2, 0, SEN(pkey_alloc), "pkey_alloc" }, [382] = { 1, 0, SEN(pkey_free), "pkey_free" }, +[383] = { 5, TD|TF, SEN(statx), "statx" }, #define SYS_socket_subcall 400 #include "subcall.h" diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h index 2699bc0..7f4e45b 100644 --- a/linux/x32/syscallent.h +++ b/linux/x32/syscallent.h @@ -330,7 +330,8 @@ [329] = { 4, TM|SI, SEN(pkey_mprotect), "pkey_mprotect" }, [330] = { 2, 0, SEN(pkey_alloc), "pkey_alloc" }, [331] = { 1, 0, SEN(pkey_free), "pkey_free" }, -[332 ... 511] = { }, +[332] = { 5, TD|TF, SEN(statx), "statx" }, +[333 ... 511] = { }, /* * x32-specific system call numbers start at 512 to avoid cache impact * for native 64-bit operation. diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h index a1a268e..2624947 100644 --- a/linux/x86_64/syscallent.h +++ b/linux/x86_64/syscallent.h @@ -330,3 +330,4 @@ [329] = { 4, TM|SI, SEN(pkey_mprotect), "pkey_mprotect" }, [330] = { 2, 0, SEN(pkey_alloc), "pkey_alloc" }, [331] = { 1, 0, SEN(pkey_free), "pkey_free" }, +[332] = { 5, TD|TF, SEN(statx), "statx" }, diff --git a/pathtrace.c b/pathtrace.c index d991aed..90974f4 100644 --- a/pathtrace.c +++ b/pathtrace.c @@ -183,6 +183,7 @@ pathtrace_match(struct tcb *tcp) case SEN_newfstatat: case SEN_openat: case SEN_readlinkat: + case SEN_statx: case SEN_unlinkat: case SEN_utimensat: /* fd, path */ diff --git a/statx.c b/statx.c new file mode 100644 index 0000000..86f27d1 --- /dev/null +++ b/statx.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 The strace developers. + * 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 "statx.h" + +#include <sys/stat.h> + +#include "xlat/statx_masks.h" +#include "xlat/statx_attrs.h" +#include "xlat/at_statx_sync_types.h" + +SYS_FUNC(statx) +{ + if (entering(tcp)) { + print_dirfd(tcp, tcp->u_arg[0]); + printpath(tcp, tcp->u_arg[1]); + tprints(", "); + if (printflags(at_flags, tcp->u_arg[2] & ~AT_STATX_SYNC_TYPE, + NULL)) + { + tprints("|"); + } + printxval(at_statx_sync_types, + tcp->u_arg[2] & AT_STATX_SYNC_TYPE, "AT_STATX_???"); + tprints(", "); + printflags(statx_masks, tcp->u_arg[3], "STATX_???"); + tprints(", "); + } else { +#define PRINT_FIELD_U(field) \ + tprintf(", %s=%llu", #field, (unsigned long long) stx.field) + +#define PRINT_FIELD_TIME(field) \ + do { \ + tprints(", " #field "="); \ + tprints(sprinttime(stx.field.sec)); \ + if (stx.field.nsec) \ + tprintf(".%09" PRId32, stx.field.nsec); \ + } while (0) + + struct_statx stx; + if (umove_or_printaddr(tcp, tcp->u_arg[4], &stx)) { + return 0; + } + + tprints("{stx_mask="); + printflags(statx_masks, stx.stx_mask, "STATX_???"); + + if (!abbrev(tcp)) { + PRINT_FIELD_U(stx_blksize); + } + + tprints(", stx_attributes="); + printflags(statx_attrs, stx.stx_attributes, "STATX_ATTR_???"); + + if (!abbrev(tcp)) { + PRINT_FIELD_U(stx_nlink); + printuid(", stx_uid=", stx.stx_uid); + printuid(", stx_gid=", stx.stx_gid); + } + + tprints(", stx_mode="); + print_symbolic_mode_t(stx.stx_mode); + + if (!abbrev(tcp)) { + PRINT_FIELD_U(stx_ino); + } + + PRINT_FIELD_U(stx_size); + + if (!abbrev(tcp)) { + PRINT_FIELD_U(stx_blocks); + PRINT_FIELD_TIME(stx_atime); + PRINT_FIELD_TIME(stx_btime); + PRINT_FIELD_TIME(stx_ctime); + PRINT_FIELD_TIME(stx_mtime); + PRINT_FIELD_U(stx_rdev_major); + PRINT_FIELD_U(stx_rdev_minor); + PRINT_FIELD_U(stx_dev_major); + PRINT_FIELD_U(stx_dev_minor); + } else { + tprints(", ..."); + } + tprints("}"); + } + return 0; +} diff --git a/statx.h b/statx.h new file mode 100644 index 0000000..d946291 --- /dev/null +++ b/statx.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017 The strace developers. + * 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_STATX_H +#define STRACE_STATX_H + +#include <stdint.h> + +typedef struct { + int64_t sec; + int32_t nsec; + int32_t reserved; +} struct_statx_timestamp; + +typedef struct { + uint32_t stx_mask; /* What results were written [uncond] */ + uint32_t stx_blksize; /* Preferred general I/O size [uncond] */ + uint64_t stx_attributes; /* Flags conveying information about the file + [uncond] */ + + uint32_t stx_nlink; /* Number of hard links */ + uint32_t stx_uid; /* User ID of owner */ + uint32_t stx_gid; /* Group ID of owner */ + uint16_t stx_mode; /* File mode */ + uint16_t reserved0[1]; + + uint64_t stx_ino; /* Inode number */ + uint64_t stx_size; /* File size */ + uint64_t stx_blocks; /* Number of 512-byte blocks allocated */ + uint64_t reserved1[1]; + + struct_statx_timestamp stx_atime; /* Last access time */ + struct_statx_timestamp stx_btime; /* File creation time */ + struct_statx_timestamp stx_ctime; /* Last attribute change time */ + struct_statx_timestamp stx_mtime; /* Last data modification time */ + + uint32_t stx_rdev_major; /* Device ID of special file [if bdev/cdev] */ + uint32_t stx_rdev_minor; + uint32_t stx_dev_major; /* ID of device containing file [uncond] */ + uint32_t stx_dev_minor; + + uint64_t reserved2[14]; /* Spare space for future expansion */ +} struct_statx; + +#endif /* !STRACE_STATX_H */ diff --git a/tests/.gitignore b/tests/.gitignore index 6e44e5c..e2b68bf 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -329,6 +329,7 @@ stat stat64 statfs statfs64 +statx swap symlink symlinkat diff --git a/tests/Makefile.am b/tests/Makefile.am index 5a7a45f..71e85fb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -389,6 +389,7 @@ check_PROGRAMS = \ stat64 \ statfs \ statfs64 \ + statx \ swap \ symlink \ symlinkat \ @@ -782,6 +783,7 @@ DECODER_TESTS = \ stat64.test \ statfs.test \ statfs64.test \ + statx.test \ sun_path.test \ swap.test \ symlink.test \ diff --git a/tests/statx.c b/tests/statx.c new file mode 100644 index 0000000..f36fb0e --- /dev/null +++ b/tests/statx.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 The strace developers. + * 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 <asm/unistd.h> + +#ifdef __NR_statx + +# include <linux/stat.h> +# include "xlat.h" +# include "xlat/statx_masks.h" +# include "xlat/statx_attrs.h" +# include "xlat/at_statx_sync_types.h" + +# define IS_STATX 1 +# define TEST_SYSCALL_STR "statx" +# define STRUCT_STAT struct statx +# define STRUCT_STAT_STR "struct statx" +# define STRUCT_STAT_IS_STAT64 0 + +static unsigned TEST_SYSCALL_STATX_FLAGS = AT_STATX_SYNC_AS_STAT; +static const char *TEST_SYSCALL_STATX_FLAGS_STR = "AT_STATX_SYNC_AS_STAT"; +static unsigned TEST_SYSCALL_STATX_MASK = STATX_ALL; +static const char *TEST_SYSCALL_STATX_MASK_STR = "STATX_ALL"; + +# define TEST_SYSCALL_INVOKE(sample, pst) \ + syscall(__NR_statx, AT_FDCWD, sample, TEST_SYSCALL_STATX_FLAGS, \ + TEST_SYSCALL_STATX_MASK, pst) +# define PRINT_SYSCALL_HEADER(sample) \ + do { \ + int saved_errno = errno; \ + printf("%s(AT_FDCWD, \"%s\", %s, %s, ", \ + TEST_SYSCALL_STR, sample, TEST_SYSCALL_STATX_FLAGS_STR, \ + TEST_SYSCALL_STATX_MASK_STR) +# define PRINT_SYSCALL_FOOTER(rc) \ + errno = saved_errno; \ + printf(") = %s\n", sprintrc(rc)); \ + } while (0) + +# include "xstatx.c" + +#else + +SKIP_MAIN_UNDEFINED("__NR_statx") + +#endif diff --git a/tests/statx.test b/tests/statx.test new file mode 100755 index 0000000..a571241 --- /dev/null +++ b/tests/statx.test @@ -0,0 +1,5 @@ +#!/bin/sh + +# Check statx syscall decoding. + +. "${srcdir=.}/statx.sh" diff --git a/tests/xstatx.c b/tests/xstatx.c index 874f309..a486091 100644 --- a/tests/xstatx.c +++ b/tests/xstatx.c @@ -47,6 +47,8 @@ # include <unistd.h> # include <sys/sysmacros.h> +# include "statx.h" + # ifndef STRUCT_STAT # define STRUCT_STAT struct stat # define STRUCT_STAT_STR "struct stat" @@ -109,6 +111,10 @@ typedef off_t libc_off_t; # define OLD_STAT 0 # endif +# ifndef IS_STATX +# define IS_STATX 0 +# endif + static void print_ftype(const unsigned int mode) { @@ -130,6 +136,8 @@ print_perms(const unsigned int mode) printf("%#o", mode & ~S_IFMT); } +# if !IS_STATX + static void print_stat(const STRUCT_STAT *st) { @@ -144,12 +152,12 @@ print_stat(const STRUCT_STAT *st) printf(", st_nlink=%llu", zero_extend_signed_to_ull(st->st_nlink)); printf(", st_uid=%llu", zero_extend_signed_to_ull(st->st_uid)); printf(", st_gid=%llu", zero_extend_signed_to_ull(st->st_gid)); -# if OLD_STAT +# if OLD_STAT printf(", st_blksize=0, st_blocks=0"); -# else /* !OLD_STAT */ +# else /* !OLD_STAT */ printf(", st_blksize=%llu", zero_extend_signed_to_ull(st->st_blksize)); printf(", st_blocks=%llu", zero_extend_signed_to_ull(st->st_blocks)); -# endif /* OLD_STAT */ +# endif /* OLD_STAT */ switch (st->st_mode & S_IFMT) { case S_IFCHR: case S_IFBLK: @@ -161,13 +169,13 @@ print_stat(const STRUCT_STAT *st) printf(", st_size=%llu", zero_extend_signed_to_ull(st->st_size)); } -# if defined(HAVE_STRUCT_STAT_ST_MTIME_NSEC) && !OLD_STAT -# define TIME_NSEC(val) zero_extend_signed_to_ull(val) -# else -# define TIME_NSEC(val) 0 -# endif +# if defined(HAVE_STRUCT_STAT_ST_MTIME_NSEC) && !OLD_STAT +# define TIME_NSEC(val) zero_extend_signed_to_ull(val) +# else +# define TIME_NSEC(val) 0 +# endif -# define PRINT_ST_TIME(field) \ +# define PRINT_ST_TIME(field) \ printf(", st_" #field "="); \ print_time_t_nsec(sign_extend_unsigned_to_ll(st->st_ ## field), \ TIME_NSEC(st->st_ ## field ## _nsec)) @@ -178,6 +186,57 @@ print_stat(const STRUCT_STAT *st) printf("}"); } +# else /* !IS_STATX */ + +static void +print_stat(const STRUCT_STAT *st) +{ +# define PRINT_FIELD_U(field) \ + printf(", %s=%llu", #field, (unsigned long long) st->field) + +# define PRINT_FIELD_U32_UID(field) \ + if (st->field == (uint32_t) -1) \ + printf(", %s=-1", #field); \ + else \ + printf(", %s=%llu", #field, (unsigned long long) st->field) + +# define PRINT_FIELD_TIME(field) \ + printf(", %s=", #field); \ + print_time_t_nsec(st->field.tv_sec, st->field.tv_nsec) + + printf("{stx_mask="); + printflags(statx_masks, st->stx_mask, "STATX_???"); + + PRINT_FIELD_U(stx_blksize); + + printf(", stx_attributes="); + printflags(statx_attrs, st->stx_attributes, "STATX_ATTR_???"); + + PRINT_FIELD_U(stx_nlink); + PRINT_FIELD_U32_UID(stx_uid); + PRINT_FIELD_U32_UID(stx_gid); + + printf(", stx_mode="); + print_ftype(st->stx_mode); + printf("|"); + print_perms(st->stx_mode); + + PRINT_FIELD_U(stx_ino); + PRINT_FIELD_U(stx_size); + PRINT_FIELD_U(stx_blocks); + PRINT_FIELD_TIME(stx_atime); + PRINT_FIELD_TIME(stx_btime); + PRINT_FIELD_TIME(stx_ctime); + PRINT_FIELD_TIME(stx_mtime); + PRINT_FIELD_U(stx_rdev_major); + PRINT_FIELD_U(stx_rdev_minor); + PRINT_FIELD_U(stx_dev_major); + PRINT_FIELD_U(stx_dev_minor); + printf("}"); +} + +# endif /* !IS_STATX */ + static int create_sample(const char *fname, const libc_off_t size) { @@ -246,25 +305,50 @@ main(void) return 77; } } - (void) unlink(sample); + +# if IS_STATX +# define ST_SIZE_FIELD stx_size +# else +# define ST_SIZE_FIELD st_size +# endif if (!rc && zero_extend_signed_to_ull(SAMPLE_SIZE) != - zero_extend_signed_to_ull(st[0].st_size)) { + zero_extend_signed_to_ull(st[0].ST_SIZE_FIELD)) { fprintf(stderr, "Size mismatch: " "requested size(%llu) != st_size(%llu)\n", zero_extend_signed_to_ull(SAMPLE_SIZE), - zero_extend_signed_to_ull(st[0].st_size)); + zero_extend_signed_to_ull(st[0].ST_SIZE_FIELD)); fprintf(stderr, "The most likely reason for this is incorrect" " definition of %s.\n" "Here is some diagnostics that might help:\n", STRUCT_STAT_STR); -#define LOG_STAT_OFFSETOF_SIZEOF(object, member) \ +# define LOG_STAT_OFFSETOF_SIZEOF(object, member) \ fprintf(stderr, "offsetof(%s, %s) = %zu" \ ", sizeof(%s) = %zu\n", \ STRUCT_STAT_STR, #member, \ offsetof(STRUCT_STAT, member), \ #member, sizeof((object).member)) +# if IS_STATX + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_mask); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_blksize); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_attributes); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_nlink); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_uid); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_gid); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_mode); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_ino); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_size); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_blocks); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_atime); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_btime); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_ctime); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_mtime); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_rdev_major); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_rdev_minor); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_dev_major); + LOG_STAT_OFFSETOF_SIZEOF(st[0], stx_dev_minor); +# else LOG_STAT_OFFSETOF_SIZEOF(st[0], st_dev); LOG_STAT_OFFSETOF_SIZEOF(st[0], st_ino); LOG_STAT_OFFSETOF_SIZEOF(st[0], st_mode); @@ -273,11 +357,14 @@ main(void) LOG_STAT_OFFSETOF_SIZEOF(st[0], st_gid); LOG_STAT_OFFSETOF_SIZEOF(st[0], st_rdev); LOG_STAT_OFFSETOF_SIZEOF(st[0], st_size); -# if !OLD_STAT +# if !OLD_STAT LOG_STAT_OFFSETOF_SIZEOF(st[0], st_blksize); LOG_STAT_OFFSETOF_SIZEOF(st[0], st_blocks); -# endif /* !OLD_STAT */ +# endif /* !OLD_STAT */ +# endif /* IS_STATX */ + + (void) unlink(sample); return 1; } @@ -288,6 +375,77 @@ main(void) print_stat(st); PRINT_SYSCALL_FOOTER(rc); +# if IS_STATX + + /* + * Check that our idea of struct_statx is no smaller than the kernel's. + * (If it is, statx is expected to fail with EFAULT.) + */ + STRUCT_STAT *st_cut2 = tail_alloc(sizeof(struct_statx)); + if ((rc = TEST_SYSCALL_INVOKE(sample, st_cut2))) { + perror(TEST_SYSCALL_STR); + (void) unlink(sample); + return 1; + } + PRINT_SYSCALL_HEADER(sample); + print_stat(st_cut2); + PRINT_SYSCALL_FOOTER(rc); + +# define INVOKE() \ + rc = TEST_SYSCALL_INVOKE(sample, st); \ + PRINT_SYSCALL_HEADER(sample); \ + if (rc) \ + printf("%p", st); \ + else \ + print_stat(st); \ + PRINT_SYSCALL_FOOTER(rc) + +# define SET_FLAGS_INVOKE(flags, flags_str) \ + TEST_SYSCALL_STATX_FLAGS = flags; \ + TEST_SYSCALL_STATX_FLAGS_STR = flags_str; \ + INVOKE() + +# define SET_MASK_INVOKE(mask, mask_str) \ + TEST_SYSCALL_STATX_MASK = mask; \ + TEST_SYSCALL_STATX_MASK_STR = mask_str; \ + INVOKE() + + unsigned old_flags = TEST_SYSCALL_STATX_FLAGS; + const char *old_flags_str = TEST_SYSCALL_STATX_FLAGS_STR; + unsigned old_mask = TEST_SYSCALL_STATX_MASK; + const char *old_mask_str = TEST_SYSCALL_STATX_MASK_STR; + + SET_FLAGS_INVOKE(AT_SYMLINK_FOLLOW | 0xffff0000U, + "AT_SYMLINK_FOLLOW|0xffff0000|AT_STATX_SYNC_AS_STAT"); + + SET_FLAGS_INVOKE(AT_STATX_SYNC_TYPE, "AT_STATX_SYNC_TYPE"); + + SET_FLAGS_INVOKE(0xffffff, + "AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW|" + "AT_NO_AUTOMOUNT|AT_EMPTY_PATH|0xff80ff|AT_STATX_SYNC_TYPE"); + + // we're done playing with flags + TEST_SYSCALL_STATX_FLAGS = old_flags; + TEST_SYSCALL_STATX_FLAGS_STR = old_flags_str; + + SET_MASK_INVOKE(0, "0"); + SET_MASK_INVOKE(~STATX_ALL, "0xfffff000 /* STATX_??? */"); + + SET_MASK_INVOKE(~STATX_NLINK, + "STATX_TYPE|STATX_MODE|STATX_UID|STATX_GID|STATX_ATIME|" + "STATX_MTIME|STATX_CTIME|STATX_INO|STATX_SIZE|STATX_BLOCKS|" + "STATX_BTIME|0xfffff000"); + + SET_MASK_INVOKE(STATX_UID, "STATX_UID"); + + // ...and with mask + TEST_SYSCALL_STATX_MASK = old_mask; + TEST_SYSCALL_STATX_MASK_STR = old_mask_str; + +# endif /* IS_STATX */ + + (void) unlink(sample); + puts("+++ exited with 0 +++"); return 0; } diff --git a/xlat/at_statx_sync_types.in b/xlat/at_statx_sync_types.in new file mode 100644 index 0000000..5d0ed49 --- /dev/null +++ b/xlat/at_statx_sync_types.in @@ -0,0 +1,5 @@ +AT_STATX_SYNC_AS_STAT 0x0000 +AT_STATX_FORCE_SYNC 0x2000 +AT_STATX_DONT_SYNC 0x4000 + +AT_STATX_SYNC_TYPE 0x6000 diff --git a/xlat/statx_attrs.in b/xlat/statx_attrs.in new file mode 100644 index 0000000..f6e4078 --- /dev/null +++ b/xlat/statx_attrs.in @@ -0,0 +1,6 @@ +STATX_ATTR_COMPRESSED 0x00000004 +STATX_ATTR_IMMUTABLE 0x00000010 +STATX_ATTR_APPEND 0x00000020 +STATX_ATTR_NODUMP 0x00000040 +STATX_ATTR_ENCRYPTED 0x00000800 +STATX_ATTR_AUTOMOUNT 0x00001000 diff --git a/xlat/statx_masks.in b/xlat/statx_masks.in new file mode 100644 index 0000000..d18dd25 --- /dev/null +++ b/xlat/statx_masks.in @@ -0,0 +1,15 @@ +STATX_ALL 0x00000fffU +STATX_BASIC_STATS 0x000007ffU + +STATX_TYPE 0x00000001U +STATX_MODE 0x00000002U +STATX_NLINK 0x00000004U +STATX_UID 0x00000008U +STATX_GID 0x00000010U +STATX_ATIME 0x00000020U +STATX_MTIME 0x00000040U +STATX_CTIME 0x00000080U +STATX_INO 0x00000100U +STATX_SIZE 0x00000200U +STATX_BLOCKS 0x00000400U +STATX_BTIME 0x00000800U -- 2.10.2 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel