//===-- Wrapper over SYS_statx syscall ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H #define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include "src/__support/macros/config.h" #include #include #include // For syscall numbers. // It is safe to include this kernel header as it is designed to be // included from user programs without causing any name pollution. #include namespace { // The type definitions in the internal namespace match kernel's definition of // the statx_timestamp and statx types in linux/stat.h. We define equivalent // types here instead of including that header file to avoid name mixup between // linux/stat.h and the libc's stat.h. struct statx_timestamp { int64_t tv_sec; uint32_t tv_nsec; int32_t __reserved; }; struct statx_buf { uint32_t stx_mask; // What results were written uint32_t stx_blksize; // Preferred general I/O size uint64_t stx_attributes; // Flags conveying information about the file 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 __spare0[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 stx_attributes_mask; // Mask to show what's supported in // stx_attributes 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 uint32_t stx_rdev_minor; uint32_t stx_dev_major; // ID of device containing file uint32_t stx_dev_minor; uint64_t stx_mnt_id; uint64_t __spare2; uint64_t __spare3[12]; // Spare space for future expansion }; // The below mask value is based on the definition of a similarly // named macro in linux/stat.h. When this flag is passed for the // mask argument to the statx syscall, all fields except the // stx_btime field will be filled in. constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF; } // Anonymous namespace namespace LIBC_NAMESPACE_DECL { LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags, struct stat *__restrict statbuf) { // We make a statx syscall and copy out the result into the |statbuf|. ::statx_buf xbuf; int ret = LIBC_NAMESPACE::syscall_impl(SYS_statx, dirfd, path, flags, ::STATX_BASIC_STATS_MASK, &xbuf); if (ret < 0) return -ret; statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor); statbuf->st_ino = static_castst_ino)>(xbuf.stx_ino); statbuf->st_mode = xbuf.stx_mode; statbuf->st_nlink = xbuf.stx_nlink; statbuf->st_uid = xbuf.stx_uid; statbuf->st_gid = xbuf.stx_gid; statbuf->st_rdev = MKDEV(xbuf.stx_rdev_major, xbuf.stx_rdev_minor); statbuf->st_size = xbuf.stx_size; statbuf->st_atim.tv_sec = xbuf.stx_atime.tv_sec; statbuf->st_atim.tv_nsec = xbuf.stx_atime.tv_nsec; statbuf->st_mtim.tv_sec = xbuf.stx_mtime.tv_sec; statbuf->st_mtim.tv_nsec = xbuf.stx_mtime.tv_nsec; statbuf->st_ctim.tv_sec = xbuf.stx_ctime.tv_sec; statbuf->st_ctim.tv_nsec = xbuf.stx_ctime.tv_nsec; statbuf->st_blksize = xbuf.stx_blksize; statbuf->st_blocks = static_castst_blocks)>(xbuf.stx_blocks); return 0; } } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H