From: Victor Krapivensky Date: Sat, 18 Mar 2017 15:19:07 +0000 (+0300) Subject: Implement decoding of statx syscall X-Git-Tag: v4.17~152 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e925d6d9c4384e89cb37c713137d0c8b4ff597f;p=strace Implement decoding of statx syscall * 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. --- diff --git a/Makefile.am b/Makefile.am index c77f463f..8af709b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -234,6 +234,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 2a701c2a..24702716 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Noteworthy changes in release ?.?? (????-??-??) arm, avr32, bfin, cris, hppa, m68k, metag, microblaze, mips, nios2, or1k, powerpc, powerpc64, riscv, sh, sh64, sparc, sparc64, tile, x86, and xtensa architectures. + * 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 8ef1b1cd..84c5bdec 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 30a684a8..60bda375 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 62960d21..73165b88 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 d991aeda..90974f4d 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 00000000..7c647fa3 --- /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 + +#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(", "); + + unsigned int flags = tcp->u_arg[2]; + printflags(at_statx_sync_types, flags & AT_STATX_SYNC_TYPE, + NULL); + flags &= ~AT_STATX_SYNC_TYPE; + if (flags) { + tprints("|"); + printflags(at_flags, flags, NULL); + } + + 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 00000000..d946291a --- /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 + +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 a1ed6d05..477529d0 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -331,6 +331,7 @@ stat stat64 statfs statfs64 +statx swap symlink symlinkat diff --git a/tests/Makefile.am b/tests/Makefile.am index a75b7fca..c6c28cc0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -391,6 +391,7 @@ check_PROGRAMS = \ stat64 \ statfs \ statfs64 \ + statx \ swap \ symlink \ symlinkat \ @@ -785,6 +786,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 00000000..f36fb0e1 --- /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 + +#ifdef __NR_statx + +# include +# 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 00000000..a5712419 --- /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 c7298b9b..774aae00 100644 --- a/tests/xstatx.c +++ b/tests/xstatx.c @@ -47,6 +47,8 @@ # include # include +# 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) { @@ -244,38 +303,66 @@ main(void) return rc; } } - (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->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->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)) - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_dev); - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_ino); - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_mode); - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_nlink); - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_uid); - 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 - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_blksize); - LOG_STAT_OFFSETOF_SIZEOF(st[0], st_blocks); -# endif /* !OLD_STAT */ +# if IS_STATX + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_mask); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_blksize); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_attributes); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_nlink); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_uid); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_gid); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_mode); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_ino); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_size); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_blocks); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_atime); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_btime); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_ctime); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_mtime); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_rdev_major); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_rdev_minor); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_dev_major); + LOG_STAT_OFFSETOF_SIZEOF(*st, stx_dev_minor); +# else + LOG_STAT_OFFSETOF_SIZEOF(*st, st_dev); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_ino); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_mode); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_nlink); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_uid); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_gid); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_rdev); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_size); +# if !OLD_STAT + LOG_STAT_OFFSETOF_SIZEOF(*st, st_blksize); + LOG_STAT_OFFSETOF_SIZEOF(*st, st_blocks); +# endif /* !OLD_STAT */ + +# endif /* IS_STATX */ + (void) unlink(sample); return 1; } @@ -286,6 +373,65 @@ main(void) print_stat(st); PRINT_SYSCALL_FOOTER(rc); +# if IS_STATX + +# 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_STATX_SYNC_AS_STAT|AT_SYMLINK_FOLLOW|0xffff0000"); + + SET_FLAGS_INVOKE(AT_STATX_SYNC_TYPE, + "AT_STATX_FORCE_SYNC|AT_STATX_DONT_SYNC"); + + SET_FLAGS_INVOKE(0xffffff, + "AT_STATX_FORCE_SYNC|AT_STATX_DONT_SYNC|AT_SYMLINK_NOFOLLOW|" + "AT_REMOVEDIR|AT_SYMLINK_FOLLOW|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|" + "0xff80ff"); + + /* 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(0xfffff000U, "0xfffff000 /* STATX_??? */"); + + SET_MASK_INVOKE(0xfffffffbU, + "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 00000000..5d0ed494 --- /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 00000000..f6e40786 --- /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 00000000..d18dd259 --- /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