f5bc3685e77476b4d0fd69a1dfb726a00e6b6892
[musl] / src / stat / fstatat.c
1 #define _BSD_SOURCE
2 #include <sys/stat.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 #include "syscall.h"
7
8 int fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag)
9 {
10         int ret;
11
12         if (flag==AT_EMPTY_PATH && fd>=0 && !*path) {
13                 ret = __syscall(SYS_fstat, fd, st);
14                 if (ret==-EBADF && __syscall(SYS_fcntl, fd, F_GETFD)>=0) {
15                         ret = __syscall(SYS_fstatat, fd, path, st, flag);
16                         if (ret==-EINVAL) {
17                                 char buf[15+3*sizeof(int)];
18                                 __procfdname(buf, fd);
19 #ifdef SYS_stat
20                                 ret = __syscall(SYS_stat, buf, st);
21 #else
22                                 ret = __syscall(SYS_fstatat, AT_FDCWD, buf, st, 0);
23 #endif
24                         }
25                 }
26         }
27 #ifdef SYS_lstat
28         else if ((fd == AT_FDCWD || *path=='/') && flag==AT_SYMLINK_NOFOLLOW)
29                 ret = __syscall(SYS_lstat, path, st);
30 #endif
31 #ifdef SYS_stat
32         else if ((fd == AT_FDCWD || *path=='/') && !flag)
33                 ret = __syscall(SYS_stat, path, st);
34 #endif
35         else ret = __syscall(SYS_fstatat, fd, path, st, flag);
36
37         return __syscall_ret(ret);
38 }
39
40 weak_alias(fstatat, fstatat64);