skalibs

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

open3_at.c (1130B)


      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 <errno.h>
     14 
     15 #include <skalibs/fcntl.h>
     16 #include <skalibs/unix-transactional.h>
     17 
     18 int open3_at (int dirfd, char const *file, int flags, unsigned int mode)
     19 {
     20   int fd ;
     21   do fd = openat(dirfd, file, flags, mode) ; /* all systems that support openat() have O_CLOEXEC */
     22   while (fd == -1 && errno == EINTR) ;
     23   return fd ;
     24 }
     25 
     26 #else
     27 
     28 #include <sys/stat.h>
     29 #include <errno.h>
     30 
     31 #include <skalibs/fcntl.h>
     32 #include <skalibs/djbunix.h>
     33 #include <skalibs/unix-transactional.h>
     34 
     35 int open3_at (int dirfd, char const *file, int flags, unsigned int mode)
     36 {
     37   int fd ;
     38   int fdhere = open_read(".") ;
     39   if (fdhere < 0) return -1 ;
     40   if (fd_chdir(dirfd) < 0) goto errclose ;
     41   fd = open3(file, flags, mode) ;
     42   if (fd < 0)
     43   {
     44     int e = errno ;
     45     fd_chdir(fdhere) ;
     46     errno = e ;
     47     goto errclose ;
     48   }
     49   if (fd_chdir(fdhere) < 0)
     50   {
     51     fd_close(fd) ;
     52     goto errclose ;
     53   }
     54   fd_close(fdhere) ;
     55   return fd ;
     56 
     57  errclose:
     58   fd_close(fdhere) ;
     59   return -1 ;
     60 }
     61 
     62 #endif