skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

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