1 /*
2  * fstatat64() for uClibc
3  *
4  * Copyright (C) 2009 Analog Devices Inc.
5  *
6  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
7  */
8 
9 #include <_lfs_64.h>
10 #include <bits/wordsize.h>
11 #include <sys/syscall.h>
12 #include <linux/version.h>
13 
14 #if defined __mips__
15 # include <sgidefs.h>
16 #endif
17 
18 /* 64bit ports tend to favor newfstatat() */
19 #if __WORDSIZE == 64 && defined __NR_newfstatat
20 # define __NR_fstatat64 __NR_newfstatat
21 #endif
22 /* mips N32 ABI use newfstatat(), too */
23 #if defined __mips__ && _MIPS_SIM == _ABIN32
24 # define __NR_fstatat64 __NR_newfstatat
25 #endif
26 
27 #if defined(__NR_fstatat64) && (!defined(__UCLIBC_USE_TIME64__)  || LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))
28 # include <sys/stat.h>
29 # include "xstatconv.h"
fstatat64(int fd,const char * file,struct stat64 * buf,int flag)30 int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
31 {
32 # ifdef __ARCH_HAS_DEPRECATED_SYSCALLS__
33 	int ret;
34 	struct kernel_stat64 kbuf;
35 
36 	ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag);
37 	if (ret == 0)
38 		__xstat64_conv(&kbuf, buf);
39 
40 	return ret;
41 # else
42 	return INLINE_SYSCALL(fstatat64, 4, fd, file, buf, flag);
43 # endif
44 }
45 libc_hidden_def(fstatat64)
46 #else
47 
48 #if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__)
49 # include <sys/stat.h>
50 # include <statx_cp.h>
51 # include <fcntl.h> // for AT_NO_AUTOMOUNT
52 
53 int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
54 {
55 	struct statx tmp;
56 
57 	int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
58 			       STATX_BASIC_STATS, &tmp);
59 
60 	if (r == 0)
61 		__cp_stat64_statx ((struct stat64 *)buf, &tmp);
62 
63 	return r;
64 }
65 libc_hidden_def(fstatat64)
66 #endif
67 
68 /* should add emulation with fstat64() and /proc/self/fd/ ... */
69 #endif
70