106 lines · c
1//===-- Wrapper over SYS_statx syscall ------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H10#define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H11 12#include "hdr/stdint_proxy.h"13#include "src/__support/OSUtil/syscall.h" // For internal syscall function.14#include "src/__support/common.h"15#include "src/__support/macros/config.h"16 17#include <sys/stat.h>18#include <sys/syscall.h> // For syscall numbers.19 20// It is safe to include this kernel header as it is designed to be21// included from user programs without causing any name pollution.22#include <linux/kdev_t.h>23 24namespace {25 26// The type definitions in the internal namespace match kernel's definition of27// the statx_timestamp and statx types in linux/stat.h. We define equivalent28// types here instead of including that header file to avoid name mixup between29// linux/stat.h and the libc's stat.h.30struct statx_timestamp {31 int64_t tv_sec;32 uint32_t tv_nsec;33 int32_t __reserved;34};35 36struct statx_buf {37 uint32_t stx_mask; // What results were written38 uint32_t stx_blksize; // Preferred general I/O size39 uint64_t stx_attributes; // Flags conveying information about the file40 uint32_t stx_nlink; // Number of hard links41 uint32_t stx_uid; // User ID of owner42 uint32_t stx_gid; // Group ID of owner43 uint16_t stx_mode; // File mode44 uint16_t __spare0[1];45 uint64_t stx_ino; // Inode number46 uint64_t stx_size; // File size47 uint64_t stx_blocks; // Number of 512-byte blocks allocated48 uint64_t stx_attributes_mask; // Mask to show what's supported in49 // stx_attributes50 struct statx_timestamp stx_atime; // Last access time51 struct statx_timestamp stx_btime; // File creation time52 struct statx_timestamp stx_ctime; // Last attribute change time53 struct statx_timestamp stx_mtime; // Last data modification time54 uint32_t stx_rdev_major; // Device ID of special file55 uint32_t stx_rdev_minor;56 uint32_t stx_dev_major; // ID of device containing file57 uint32_t stx_dev_minor;58 uint64_t stx_mnt_id;59 uint64_t __spare2;60 uint64_t __spare3[12]; // Spare space for future expansion61};62 63// The below mask value is based on the definition of a similarly64// named macro in linux/stat.h. When this flag is passed for the65// mask argument to the statx syscall, all fields except the66// stx_btime field will be filled in.67constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF;68 69} // Anonymous namespace70 71namespace LIBC_NAMESPACE_DECL {72 73LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags,74 struct stat *__restrict statbuf) {75 // We make a statx syscall and copy out the result into the |statbuf|.76 ::statx_buf xbuf;77 int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, dirfd, path, flags,78 ::STATX_BASIC_STATS_MASK, &xbuf);79 if (ret < 0)80 return -ret;81 82 statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);83 statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino);84 statbuf->st_mode = xbuf.stx_mode;85 statbuf->st_nlink = xbuf.stx_nlink;86 statbuf->st_uid = xbuf.stx_uid;87 statbuf->st_gid = xbuf.stx_gid;88 statbuf->st_rdev = MKDEV(xbuf.stx_rdev_major, xbuf.stx_rdev_minor);89 statbuf->st_size = xbuf.stx_size;90 statbuf->st_atim.tv_sec = xbuf.stx_atime.tv_sec;91 statbuf->st_atim.tv_nsec = xbuf.stx_atime.tv_nsec;92 statbuf->st_mtim.tv_sec = xbuf.stx_mtime.tv_sec;93 statbuf->st_mtim.tv_nsec = xbuf.stx_mtime.tv_nsec;94 statbuf->st_ctim.tv_sec = xbuf.stx_ctime.tv_sec;95 statbuf->st_ctim.tv_nsec = xbuf.stx_ctime.tv_nsec;96 statbuf->st_blksize = xbuf.stx_blksize;97 statbuf->st_blocks =98 static_cast<decltype(statbuf->st_blocks)>(xbuf.stx_blocks);99 100 return 0;101}102 103} // namespace LIBC_NAMESPACE_DECL104 105#endif // LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H106