openat.h 2.98 KB
Newer Older
1
/* provide a replacement openat function
Paul Eggert's avatar
Paul Eggert committed
2
   Copyright (C) 2004-2006, 2008-2020 Free Software Foundation, Inc.
3 4 5 6 7 8 9 10 11 12 13 14

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
Paul Eggert's avatar
Paul Eggert committed
15
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 17 18 19 20 21 22 23 24 25 26 27 28

/* written by Jim Meyering */

#ifndef _GL_HEADER_OPENAT
#define _GL_HEADER_OPENAT

#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>

Paul Eggert's avatar
Paul Eggert committed
29 30 31
#ifndef _GL_INLINE_HEADER_BEGIN
 #error "Please include config.h first."
#endif
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
_GL_INLINE_HEADER_BEGIN

#if !HAVE_OPENAT

int openat_permissive (int fd, char const *file, int flags, mode_t mode,
                       int *cwd_errno);
bool openat_needs_fchdir (void);

#else

# define openat_permissive(Fd, File, Flags, Mode, Cwd_errno) \
    openat (Fd, File, Flags, Mode)
# define openat_needs_fchdir() false

#endif

_Noreturn void openat_restore_fail (int);
_Noreturn void openat_save_fail (int);

/* Using these function names makes application code
   slightly more readable than it would be with
   fchownat (..., 0) or fchownat (..., AT_SYMLINK_NOFOLLOW).  */

Paul Eggert's avatar
Paul Eggert committed
55
#if GNULIB_CHOWNAT
56

Paul Eggert's avatar
Paul Eggert committed
57 58
# ifndef CHOWNAT_INLINE
#  define CHOWNAT_INLINE _GL_INLINE
59 60
# endif

Paul Eggert's avatar
Paul Eggert committed
61
CHOWNAT_INLINE int
62 63 64 65 66
chownat (int fd, char const *file, uid_t owner, gid_t group)
{
  return fchownat (fd, file, owner, group, 0);
}

Paul Eggert's avatar
Paul Eggert committed
67
CHOWNAT_INLINE int
68 69 70 71 72 73 74
lchownat (int fd, char const *file, uid_t owner, gid_t group)
{
  return fchownat (fd, file, owner, group, AT_SYMLINK_NOFOLLOW);
}

#endif

Paul Eggert's avatar
Paul Eggert committed
75
#if GNULIB_CHMODAT
76

Paul Eggert's avatar
Paul Eggert committed
77 78
# ifndef CHMODAT_INLINE
#  define CHMODAT_INLINE _GL_INLINE
79 80
# endif

Paul Eggert's avatar
Paul Eggert committed
81
CHMODAT_INLINE int
82 83 84 85 86
chmodat (int fd, char const *file, mode_t mode)
{
  return fchmodat (fd, file, mode, 0);
}

Paul Eggert's avatar
Paul Eggert committed
87
CHMODAT_INLINE int
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
lchmodat (int fd, char const *file, mode_t mode)
{
  return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW);
}

#endif

#if GNULIB_STATAT

# ifndef STATAT_INLINE
#  define STATAT_INLINE _GL_INLINE
# endif

STATAT_INLINE int
statat (int fd, char const *name, struct stat *st)
{
  return fstatat (fd, name, st, 0);
}

STATAT_INLINE int
lstatat (int fd, char const *name, struct stat *st)
{
  return fstatat (fd, name, st, AT_SYMLINK_NOFOLLOW);
}

#endif

/* For now, there are no wrappers named laccessat or leuidaccessat,
   since gnulib doesn't support faccessat(,AT_SYMLINK_NOFOLLOW) and
   since access rights on symlinks are of limited utility.  Likewise,
   wrappers are not provided for accessat or euidaccessat, so as to
   avoid dragging in -lgen on some platforms.  */

_GL_INLINE_HEADER_END

#endif /* _GL_HEADER_OPENAT */