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.
This commit is contained in:
Victor Krapivensky 2017-03-18 18:19:07 +03:00 committed by Dmitry V. Levin
parent 12781b7466
commit 5e925d6d9c
16 changed files with 463 additions and 26 deletions

View File

@ -234,6 +234,8 @@ strace_SOURCES = \
stat64.c \
statfs.c \
statfs.h \
statx.c \
statx.h \
strace.c \
swapon.c \
syscall.c \

1
NEWS
View File

@ -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.

View File

@ -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"

View File

@ -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.

View File

@ -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" },

View File

@ -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 */

111
statx.c Normal file
View File

@ -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(", ");
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;
}

69
statx.h Normal file
View File

@ -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 */

1
tests/.gitignore vendored
View File

@ -331,6 +331,7 @@ stat
stat64
statfs
statfs64
statx
swap
symlink
symlinkat

View File

@ -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 \

70
tests/statx.c Normal file
View File

@ -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

5
tests/statx.test Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
# Check statx syscall decoding.
. "${srcdir=.}/statx.sh"

View File

@ -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)
{
@ -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;
}

View File

@ -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

6
xlat/statx_attrs.in Normal file
View File

@ -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

15
xlat/statx_masks.in Normal file
View File

@ -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