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