7 #include <sys/sysmacros.h>
14 uint64_t stx_attributes
;
23 uint64_t stx_attributes_mask
;
28 } stx_atime
, stx_btime
, stx_ctime
, stx_mtime
;
29 uint32_t stx_rdev_major
;
30 uint32_t stx_rdev_minor
;
31 uint32_t stx_dev_major
;
32 uint32_t stx_dev_minor
;
36 static int fstatat_statx(int fd
, const char *restrict path
, struct stat
*restrict st
, int flag
)
40 int ret
= __syscall(SYS_statx
, fd
, path
, flag
, 0x7ff, &stx
);
44 .st_dev
= makedev(stx
.stx_dev_major
, stx
.stx_dev_minor
),
45 .st_ino
= stx
.stx_ino
,
46 .st_mode
= stx
.stx_mode
,
47 .st_nlink
= stx
.stx_nlink
,
48 .st_uid
= stx
.stx_uid
,
49 .st_gid
= stx
.stx_gid
,
50 .st_rdev
= makedev(stx
.stx_rdev_major
, stx
.stx_rdev_minor
),
51 .st_size
= stx
.stx_size
,
52 .st_blksize
= stx
.stx_blksize
,
53 .st_blocks
= stx
.stx_blocks
,
54 .st_atim
.tv_sec
= stx
.stx_atime
.tv_sec
,
55 .st_atim
.tv_nsec
= stx
.stx_atime
.tv_nsec
,
56 .st_mtim
.tv_sec
= stx
.stx_mtime
.tv_sec
,
57 .st_mtim
.tv_nsec
= stx
.stx_mtime
.tv_nsec
,
58 .st_ctim
.tv_sec
= stx
.stx_ctime
.tv_sec
,
59 .st_ctim
.tv_nsec
= stx
.stx_ctime
.tv_nsec
,
61 .__st_atim32
.tv_sec
= stx
.stx_atime
.tv_sec
,
62 .__st_atim32
.tv_nsec
= stx
.stx_atime
.tv_nsec
,
63 .__st_mtim32
.tv_sec
= stx
.stx_mtime
.tv_sec
,
64 .__st_mtim32
.tv_nsec
= stx
.stx_mtime
.tv_nsec
,
65 .__st_ctim32
.tv_sec
= stx
.stx_ctime
.tv_sec
,
66 .__st_ctim32
.tv_nsec
= stx
.stx_ctime
.tv_nsec
,
72 static int fstatat_kstat(int fd
, const char *restrict path
, struct stat
*restrict st
, int flag
)
77 if (flag
==AT_EMPTY_PATH
&& fd
>=0 && !*path
) {
78 ret
= __syscall(SYS_fstat
, fd
, &kst
);
79 if (ret
==-EBADF
&& __syscall(SYS_fcntl
, fd
, F_GETFD
)>=0) {
80 ret
= __syscall(SYS_fstatat
, fd
, path
, &kst
, flag
);
82 char buf
[15+3*sizeof(int)];
83 __procfdname(buf
, fd
);
85 ret
= __syscall(SYS_stat
, buf
, &kst
);
87 ret
= __syscall(SYS_fstatat
, AT_FDCWD
, buf
, &kst
, 0);
93 else if ((fd
== AT_FDCWD
|| *path
=='/') && flag
==AT_SYMLINK_NOFOLLOW
)
94 ret
= __syscall(SYS_lstat
, path
, &kst
);
97 else if ((fd
== AT_FDCWD
|| *path
=='/') && !flag
)
98 ret
= __syscall(SYS_stat
, path
, &kst
);
100 else ret
= __syscall(SYS_fstatat
, fd
, path
, &kst
, flag
);
105 .st_dev
= kst
.st_dev
,
106 .st_ino
= kst
.st_ino
,
107 .st_mode
= kst
.st_mode
,
108 .st_nlink
= kst
.st_nlink
,
109 .st_uid
= kst
.st_uid
,
110 .st_gid
= kst
.st_gid
,
111 .st_rdev
= kst
.st_rdev
,
112 .st_size
= kst
.st_size
,
113 .st_blksize
= kst
.st_blksize
,
114 .st_blocks
= kst
.st_blocks
,
115 .st_atim
.tv_sec
= kst
.st_atime_sec
,
116 .st_atim
.tv_nsec
= kst
.st_atime_nsec
,
117 .st_mtim
.tv_sec
= kst
.st_mtime_sec
,
118 .st_mtim
.tv_nsec
= kst
.st_mtime_nsec
,
119 .st_ctim
.tv_sec
= kst
.st_ctime_sec
,
120 .st_ctim
.tv_nsec
= kst
.st_ctime_nsec
,
122 .__st_atim32
.tv_sec
= kst
.st_atime_sec
,
123 .__st_atim32
.tv_nsec
= kst
.st_atime_nsec
,
124 .__st_mtim32
.tv_sec
= kst
.st_mtime_sec
,
125 .__st_mtim32
.tv_nsec
= kst
.st_mtime_nsec
,
126 .__st_ctim32
.tv_sec
= kst
.st_ctime_sec
,
127 .__st_ctim32
.tv_nsec
= kst
.st_ctime_nsec
,
134 int fstatat(int fd
, const char *restrict path
, struct stat
*restrict st
, int flag
)
137 if (sizeof((struct kstat
){0}.st_atime_sec
) < sizeof(time_t)) {
138 ret
= fstatat_statx(fd
, path
, st
, flag
);
139 if (ret
!=-ENOSYS
) return __syscall_ret(ret
);
141 ret
= fstatat_kstat(fd
, path
, st
, flag
);
142 return __syscall_ret(ret
);
146 weak_alias(fstatat
, fstatat64
);