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:
parent
12781b7466
commit
5e925d6d9c
@ -234,6 +234,8 @@ strace_SOURCES = \
|
||||
stat64.c \
|
||||
statfs.c \
|
||||
statfs.h \
|
||||
statx.c \
|
||||
statx.h \
|
||||
strace.c \
|
||||
swapon.c \
|
||||
syscall.c \
|
||||
|
1
NEWS
1
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.
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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" },
|
||||
|
@ -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
111
statx.c
Normal 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
69
statx.h
Normal 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
1
tests/.gitignore
vendored
@ -331,6 +331,7 @@ stat
|
||||
stat64
|
||||
statfs
|
||||
statfs64
|
||||
statx
|
||||
swap
|
||||
symlink
|
||||
symlinkat
|
||||
|
@ -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
70
tests/statx.c
Normal 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
5
tests/statx.test
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check statx syscall decoding.
|
||||
|
||||
. "${srcdir=.}/statx.sh"
|
196
tests/xstatx.c
196
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)
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
5
xlat/at_statx_sync_types.in
Normal file
5
xlat/at_statx_sync_types.in
Normal 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
6
xlat/statx_attrs.in
Normal 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
15
xlat/statx_masks.in
Normal 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
|
Loading…
x
Reference in New Issue
Block a user