1e310f8bdSSiva Chandra Reddy //===-- Wrapper over SYS_statx syscall ------------------------------------===// 2e310f8bdSSiva Chandra Reddy // 3e310f8bdSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e310f8bdSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 5e310f8bdSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e310f8bdSSiva Chandra Reddy // 7e310f8bdSSiva Chandra Reddy //===----------------------------------------------------------------------===// 8e310f8bdSSiva Chandra Reddy 9270547f3SGuillaume Chatelet #ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H 10270547f3SGuillaume Chatelet #define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H 11e310f8bdSSiva Chandra Reddy 12e310f8bdSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function. 1305d9cc47SSiva Chandra Reddy #include "src/__support/common.h" 145ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 15e310f8bdSSiva Chandra Reddy 16e310f8bdSSiva Chandra Reddy #include <stdint.h> 17e310f8bdSSiva Chandra Reddy #include <sys/stat.h> 18e310f8bdSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers. 19e310f8bdSSiva Chandra Reddy 20e310f8bdSSiva Chandra Reddy // It is safe to include this kernel header as it is designed to be 21e310f8bdSSiva Chandra Reddy // included from user programs without causing any name pollution. 22e310f8bdSSiva Chandra Reddy #include <linux/kdev_t.h> 23e310f8bdSSiva Chandra Reddy 24e310f8bdSSiva Chandra Reddy namespace { 25e310f8bdSSiva Chandra Reddy 26e310f8bdSSiva Chandra Reddy // The type definitions in the internal namespace match kernel's definition of 27e310f8bdSSiva Chandra Reddy // the statx_timestamp and statx types in linux/stat.h. We define equivalent 28e310f8bdSSiva Chandra Reddy // types here instead of including that header file to avoid name mixup between 29e310f8bdSSiva Chandra Reddy // linux/stat.h and the libc's stat.h. 30e310f8bdSSiva Chandra Reddy struct statx_timestamp { 31e310f8bdSSiva Chandra Reddy int64_t tv_sec; 32e310f8bdSSiva Chandra Reddy uint32_t tv_nsec; 33e310f8bdSSiva Chandra Reddy int32_t __reserved; 34e310f8bdSSiva Chandra Reddy }; 35e310f8bdSSiva Chandra Reddy 36e310f8bdSSiva Chandra Reddy struct statx_buf { 37e310f8bdSSiva Chandra Reddy uint32_t stx_mask; // What results were written 38e310f8bdSSiva Chandra Reddy uint32_t stx_blksize; // Preferred general I/O size 39e310f8bdSSiva Chandra Reddy uint64_t stx_attributes; // Flags conveying information about the file 40e310f8bdSSiva Chandra Reddy uint32_t stx_nlink; // Number of hard links 41e310f8bdSSiva Chandra Reddy uint32_t stx_uid; // User ID of owner 42e310f8bdSSiva Chandra Reddy uint32_t stx_gid; // Group ID of owner 43e310f8bdSSiva Chandra Reddy uint16_t stx_mode; // File mode 44e310f8bdSSiva Chandra Reddy uint16_t __spare0[1]; 45e310f8bdSSiva Chandra Reddy uint64_t stx_ino; // Inode number 46e310f8bdSSiva Chandra Reddy uint64_t stx_size; // File size 47e310f8bdSSiva Chandra Reddy uint64_t stx_blocks; // Number of 512-byte blocks allocated 48e310f8bdSSiva Chandra Reddy uint64_t stx_attributes_mask; // Mask to show what's supported in 49e310f8bdSSiva Chandra Reddy // stx_attributes 50e310f8bdSSiva Chandra Reddy struct statx_timestamp stx_atime; // Last access time 51e310f8bdSSiva Chandra Reddy struct statx_timestamp stx_btime; // File creation time 52e310f8bdSSiva Chandra Reddy struct statx_timestamp stx_ctime; // Last attribute change time 53e310f8bdSSiva Chandra Reddy struct statx_timestamp stx_mtime; // Last data modification time 54e310f8bdSSiva Chandra Reddy uint32_t stx_rdev_major; // Device ID of special file 55e310f8bdSSiva Chandra Reddy uint32_t stx_rdev_minor; 56e310f8bdSSiva Chandra Reddy uint32_t stx_dev_major; // ID of device containing file 57e310f8bdSSiva Chandra Reddy uint32_t stx_dev_minor; 58e310f8bdSSiva Chandra Reddy uint64_t stx_mnt_id; 59e310f8bdSSiva Chandra Reddy uint64_t __spare2; 60e310f8bdSSiva Chandra Reddy uint64_t __spare3[12]; // Spare space for future expansion 61e310f8bdSSiva Chandra Reddy }; 62e310f8bdSSiva Chandra Reddy 63e310f8bdSSiva Chandra Reddy // The below mask value is based on the definition of a similarly 64e310f8bdSSiva Chandra Reddy // named macro in linux/stat.h. When this flag is passed for the 65e310f8bdSSiva Chandra Reddy // mask argument to the statx syscall, all fields except the 66e310f8bdSSiva Chandra Reddy // stx_btime field will be filled in. 67e310f8bdSSiva Chandra Reddy constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF; 68e310f8bdSSiva Chandra Reddy 69e310f8bdSSiva Chandra Reddy } // Anonymous namespace 70e310f8bdSSiva Chandra Reddy 715ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 72e310f8bdSSiva Chandra Reddy 7305d9cc47SSiva Chandra Reddy LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags, 74e310f8bdSSiva Chandra Reddy struct stat *__restrict statbuf) { 75e310f8bdSSiva Chandra Reddy // We make a statx syscall and copy out the result into the |statbuf|. 76e310f8bdSSiva Chandra Reddy ::statx_buf xbuf; 77b6bc9d72SGuillaume Chatelet int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, dirfd, path, flags, 781801c356SMichael Jones ::STATX_BASIC_STATS_MASK, &xbuf); 7955612b8eSSiva Chandra Reddy if (ret < 0) 8055612b8eSSiva Chandra Reddy return -ret; 81e310f8bdSSiva Chandra Reddy 82e310f8bdSSiva Chandra Reddy statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor); 83*91bf0a07SMikhail R. Gadelha statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino); 84e310f8bdSSiva Chandra Reddy statbuf->st_mode = xbuf.stx_mode; 85e310f8bdSSiva Chandra Reddy statbuf->st_nlink = xbuf.stx_nlink; 86e310f8bdSSiva Chandra Reddy statbuf->st_uid = xbuf.stx_uid; 87e310f8bdSSiva Chandra Reddy statbuf->st_gid = xbuf.stx_gid; 88e310f8bdSSiva Chandra Reddy statbuf->st_rdev = MKDEV(xbuf.stx_rdev_major, xbuf.stx_rdev_minor); 89e310f8bdSSiva Chandra Reddy statbuf->st_size = xbuf.stx_size; 90e310f8bdSSiva Chandra Reddy statbuf->st_atim.tv_sec = xbuf.stx_atime.tv_sec; 91e310f8bdSSiva Chandra Reddy statbuf->st_atim.tv_nsec = xbuf.stx_atime.tv_nsec; 92e310f8bdSSiva Chandra Reddy statbuf->st_mtim.tv_sec = xbuf.stx_mtime.tv_sec; 93e310f8bdSSiva Chandra Reddy statbuf->st_mtim.tv_nsec = xbuf.stx_mtime.tv_nsec; 94e310f8bdSSiva Chandra Reddy statbuf->st_ctim.tv_sec = xbuf.stx_ctime.tv_sec; 95e310f8bdSSiva Chandra Reddy statbuf->st_ctim.tv_nsec = xbuf.stx_ctime.tv_nsec; 96e310f8bdSSiva Chandra Reddy statbuf->st_blksize = xbuf.stx_blksize; 97*91bf0a07SMikhail R. Gadelha statbuf->st_blocks = 98*91bf0a07SMikhail R. Gadelha static_cast<decltype(statbuf->st_blocks)>(xbuf.stx_blocks); 99e310f8bdSSiva Chandra Reddy 100e310f8bdSSiva Chandra Reddy return 0; 101e310f8bdSSiva Chandra Reddy } 102e310f8bdSSiva Chandra Reddy 1035ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 104e310f8bdSSiva Chandra Reddy 105270547f3SGuillaume Chatelet #endif // LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H 106