stat_at.c (1435B)
1 /* ISC license. */ 2 3 #include <skalibs/sysdeps.h> 4 5 #ifdef SKALIBS_HASOPENAT 6 7 #ifndef _ATFILE_SOURCE 8 #define _ATFILE_SOURCE 9 #endif 10 11 #include <skalibs/nonposix.h> 12 13 #include <sys/stat.h> 14 15 #include <skalibs/fcntl.h> 16 #include <skalibs/unix-transactional.h> 17 18 int stat_at (int dirfd, char const *file, struct stat *st) 19 { 20 return fstatat(dirfd, file, st, 0) ; 21 } 22 23 int lstat_at (int dirfd, char const *file, struct stat *st) 24 { 25 return fstatat(dirfd, file, st, AT_SYMLINK_NOFOLLOW) ; 26 } 27 28 #else 29 30 /* OpenBSD plz. lstat() is POSIX. */ 31 #include <skalibs/nonposix.h> 32 33 #include <sys/stat.h> 34 #include <errno.h> 35 36 #include <skalibs/fcntl.h> 37 #include <skalibs/djbunix.h> 38 #include <skalibs/unix-transactional.h> 39 40 static int fstat_at (int dirfd, char const *file, struct stat *st, int (*dostat)(char const *, struct stat *)) 41 { 42 int r ; 43 int fdhere = open_read(".") ; 44 if (fdhere < 0) return -1 ; 45 if (fd_chdir(dirfd) < 0) 46 { 47 fd_close(fdhere) ; 48 return -1 ; 49 } 50 r = (*dostat)(file, st) ; 51 if (r < 0) 52 { 53 int e = errno ; 54 fd_chdir(fdhere) ; 55 fd_close(fdhere) ; 56 errno = e ; 57 return -1 ; 58 } 59 if (fd_chdir(fdhere) < 0) 60 { 61 fd_close(fdhere) ; 62 return -1 ; 63 } 64 fd_close(fdhere) ; 65 return r ; 66 } 67 68 int stat_at (int dirfd, char const *file, struct stat *st) 69 { 70 return fstat_at(dirfd, file, st, &stat) ; 71 } 72 73 int lstat_at (int dirfd, char const *file, struct stat *st) 74 { 75 return fstat_at(dirfd, file, st, &lstat) ; 76 } 77 78 #endif