Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ dnl glibc uses `* dev' as fourth argument of __xmknod.
dnl Although the test below should probably be more general
dnl (not just __xmknod, but also mknod etc), at the moment this
dnl seems enough, as probably glibc is the only that does this.
AC_CHECK_FUNC(__xmknod,[
AC_MSG_CHECKING([for type of arg of __xmknod])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
Expand All @@ -198,13 +199,24 @@ AC_MSG_CHECKING([for type of arg of __xmknod])
const char *pathname ,
mode_t mode , dev_t *dev);
]])],[
dnl XXX: __xmknod is not declared in public headers in glibc 2.36 and newer.
dnl Assume __xkmnod takes a dev_t pointer this case anyway.
AC_DEFINE(XMKNOD_FRTH_ARG,[*])
AC_MSG_RESULT([needs *])
],[
AC_DEFINE(XMKNOD_FRTH_ARG,)
AC_MSG_RESULT([no extra *])

])
],
[
dnl glibc does not export __xmknod symbol. In this case WRAP_MKNOD expands
dnl to mknod, and XMKNOD_FRTH_ARG is acutally the 3rd argument of mknod,
dnl which must be dev_t (not the pointer)
AC_DEFINE(XMKNOD_FRTH_ARG,)
AC_MSG_RESULT([no extra *])
])


dnl Possibly this should only be done if we actually have mknodat
dnl on the system. Nothing breaks by running the test itself though.
Expand All @@ -213,6 +225,8 @@ dnl glibc uses `* dev' as fifth argument of __xmknodat.
dnl Although the test below should probably be more general
dnl (not just __xmknodat, but also mknod etc), at the moment this
dnl seems enough, as probably glibc is the only that does this.

AC_CHECK_FUNC(__xmknodat,[
AC_MSG_CHECKING([for type of arg of __xmknodat])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
Expand All @@ -235,6 +249,14 @@ AC_MSG_CHECKING([for type of arg of __xmknodat])
AC_MSG_RESULT([no extra *])

])
],
[
dnl glibc does not export __xmknodat symbol. In this case WRAP_MKNODAT expands
dnl to mknodat, and XMKNODAT_FIFTH_ARG is acutally the 4th argument of mknodat,
dnl which must be dev_t (not the pointer)
AC_DEFINE(XMKNODAT_FIFTH_ARG,)
AC_MSG_RESULT([no extra *])
])

AH_TEMPLATE([INITGROUPS_SECOND_ARG], [second argument of initgroups])
dnl FreeBSD 4.7 uses int instead of gid_t
Expand Down Expand Up @@ -381,6 +403,23 @@ time64_hack=yes

:>fakerootconfig.h.tmp

dnl Before glibc 2.33 the stat family of functions (and mknod)
dnl used to be inline wrappers around calls to xstat, fxstat,
dnl lxstat, xmknod, which all take a leading version number
dnl argument designating the data structure and bits used.
dnl Thus libfakeroot needs to wrap xstat, fxstat, xmknod only.
dnl
dnl In glibc 2.33 inline wrapper functions have been removed.
dnl Instead libc.so.6 exports stat, stat64, etc symbols.
dnl xstat, fxstat, xmknod still exist (for compatibility reasons).
dnl Thus libfakeroot must wrap both stat (fstat, statat, fstatat, etc)
dnl and internal xstat (fxstat, etc) functions.
dnl
dnl However some new architectures (such as LoongArch lp64d ABI)
dnl decided to be 64-bit only since the day 0 and don't use any wrappers.
dnl Here libfakeroot should wrap only stat (statat, fstat, fstatat).
dnl A special care should be taken to avoid the double definition.

for SEARCH in %stat f%stat l%stat f%statat %stat64 f%stat64 l%stat64 f%statat64 %mknod %mknodat; do
FUNC=`echo $SEARCH|sed -e 's/.*%//'`
PRE=`echo $SEARCH|sed -e 's/%.*//'`
Expand Down Expand Up @@ -437,6 +476,15 @@ dnl FOUND=$WRAPPED
echo "#define ${PF}_ARG(a,b,c${DEF_END}) (${DEF_BEGIN}b,c${DEF_END})"
} >>fakerootconfig.h.tmp

if test "x${FOUND}" = "x${PRE}${FUNC}"; then
dnl Some architectures are 64-bit only from day 0 and don't have xstat, etc
dnl internal functions. For such architectures WRAP_STAT evaluates to stat,
dnl so an extra wrapper is NOT required.
AC_MSG_RESULT([Extra wrapper for ${PRE}${FUNC} is not necessary])
AC_DEFINE_UNQUOTED(NO_WRAP_${PF}_SYMBOL, 1)
else
AC_MSG_RESULT([Extra wrapper for ${PRE}${FUNC} is required because of ${FOUND}])
fi
break
fi
done
Expand Down Expand Up @@ -571,60 +619,70 @@ AH_VERBATIM([WRAP_STAT],
#define WRAP_STAT_RAW __astat
#define TMP_STAT __astat
#define NEXT_STAT_NOARG next___astat
#undef NO_WRAP_STAT_SYMBOL

#define WRAP_LSTAT_QUOTE __astat
#define WRAP_LSTAT __astat
#define WRAP_LSTAT_RAW __astat
#define TMP_LSTAT __astat
#define NEXT_LSTAT_NOARG next___astat
#undef NO_WRAP_LSTAT_SYMBOL

#define WRAP_FSTAT_QUOTE __astat
#define WRAP_FSTAT __astat
#define WRAP_FSTAT_RAW __astat
#define TMP_FSTAT __astat
#define NEXT_FSTAT_NOARG next___astat
#undef NO_WRAP_FSTAT_SYMBOL

#define WRAP_FSTATAT_QUOTE __astatat
#define WRAP_FSTATAT __astatat
#define WRAP_FSTATAT_RAW __astatat
#define TMP_FSTATAT __astatat
#define NEXT_FSTATAT_NOARG next___astatat
#undef NO_WRAP_FSTATAT_SYMBOL

#define WRAP_STAT64_QUOTE __astat64
#define WRAP_STAT64 __astat64
#define WRAP_STAT64_RAW __astat64
#define TMP_STAT64 __astat64
#define NEXT_STAT64_NOARG next___astat64
#undef NO_WRAP_STAT64_SYMBOL

#define WRAP_LSTAT64_QUOTE __astat64
#define WRAP_LSTAT64 __astat64
#define WRAP_LSTAT64_RAW __astat64
#define TMP_LSTAT64 __astat64
#define NEXT_LSTAT64_NOARG next___astat64
#undef NO_WRAP_LSTAT64_SYMBOL

#define WRAP_FSTAT64_QUOTE __astat64
#define WRAP_FSTAT64 __astat64
#define WRAP_FSTAT64_RAW __astat64
#define TMP_FSTAT64 __astat64
#define NEXT_FSTAT64_NOARG next___astat64
#undef NO_WRAP_FSTAT64_SYMBOL

#define WRAP_FSTATAT64_QUOTE __astatat64
#define WRAP_FSTATAT64 __astatat64
#define WRAP_FSTATAT64_RAW __astatat64
#define TMP_FSTATAT64 __astatat64
#define NEXT_FSTATAT64_NOARG next___astatat64
#undef NO_WRAP_FSTATAT64_SYMBOL

#define WRAP_MKNOD_QUOTE __amknod
#define WRAP_MKNOD __amknod
#define WRAP_MKNOD_RAW __amknod
#define TMP_MKNOD __amknod
#define NEXT_MKNOD_NOARG next___amknod
#undef NO_WRAP_MKNOD_SYMBOL

#define WRAP_MKNODAT_QUOTE __amknodat
#define WRAP_MKNODAT __amknodat
#define WRAP_MKNODAT_RAW __amknodat
#define TMP_MKNODAT __amknodat
#define NEXT_MKNODAT_NOARG next___amknodat
#undef NO_WRAP_MKNODAT_SYMBOL

#define WRAP_STAT64_TIME64_QUOTE __astat64_time64
#define WRAP_STAT64_TIME64 __astat64_time64
Expand Down
32 changes: 29 additions & 3 deletions libfakeroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1414,45 +1414,71 @@ int renameat(int olddir_fd, const char *oldpath,
#if defined(__GLIBC__)
#if __GLIBC_PREREQ(2,33)
/* Glibc 2.33 exports symbols for these functions in the shared lib */

#ifndef NO_WRAP_LSTAT_SYMBOL
/* glibc exports both lstat and __xstat */
int lstat(const char *file_name, struct stat *statbuf) {
return WRAP_LSTAT LSTAT_ARG(_STAT_VER, file_name, statbuf);
}
#endif

#ifndef NO_WRAP_STAT_SYMBOL
/* glibc exports both stat and __xstat */
int stat(const char *file_name, struct stat *st) {
return WRAP_STAT STAT_ARG(_STAT_VER, file_name, st);
}
#endif
#ifndef NO_WRAP_FSTAT_SYMBOL
/* glibc exports both fstat and __fxstat */
int fstat(int fd, struct stat *st) {
return WRAP_FSTAT FSTAT_ARG(_STAT_VER, fd, st);
}
#endif

#ifdef HAVE_FSTATAT
#if defined(HAVE_FSTATAT) && !defined(NO_WRAP_FSTATAT_SYMBOL)
/* glibc exports both fstatat and __fxstatat */
int fstatat(int dir_fd, const char *path, struct stat *st, int flags) {
return WRAP_FSTATAT FSTATAT_ARG(_STAT_VER, dir_fd, path, st, flags);
}
#endif

#ifdef STAT64_SUPPORT
#ifndef NO_WRAP_LSTAT64_SYMBOL
/* glibc exports both lstat64 and __xstat64 */
int lstat64(const char *file_name, struct stat64 *st) {
return WRAP_LSTAT64 LSTAT64_ARG(_STAT_VER, file_name, st);
}
#endif
#ifndef NO_WRAP_STAT64_SYMBOL
/* glibc exports both stat64 and __xstat64 */
int stat64(const char *file_name, struct stat64 *st) {
return WRAP_STAT64 STAT64_ARG(_STAT_VER, file_name, st);
}
#endif
#ifndef NO_WRAP_FSTAT64_SYMBOL
/* glibc exports both fstat64 and __fxstat64 */
int fstat64(int fd, struct stat64 *st) {
return WRAP_FSTAT64 FSTAT64_ARG(_STAT_VER, fd, st);
}
#endif

#ifdef HAVE_FSTATAT
#if defined(HAVE_FSTATAT) && !defined(NO_WRAP_FSTATAT64_SYMBOL)
/* glibc exports both fstatat64 and __fxstatat64 */
int fstatat64(int dir_fd, const char *path, struct stat64 *st, int flags) {
return WRAP_FSTATAT64 FSTATAT64_ARG(_STAT_VER, dir_fd, path, st, flags);
}
#endif
#endif

#ifndef NO_WRAP_MKNOD_SYMBOL
/* glibc exports both mknod and __xmknod */
int mknod(const char *pathname, mode_t mode, dev_t dev) {
return WRAP_MKNOD MKNOD_ARG(_STAT_VER, pathname, mode, &dev);
}
#endif

#if defined(HAVE_FSTATAT) && defined(HAVE_MKNODAT)
#if defined(HAVE_FSTATAT) && defined(HAVE_MKNODAT) && !defined(NO_WRAP_MKNODAT_SYMBOL)
/* glibc exports both mknodat and __xmknodat */
int mknodat(int dir_fd, const char *pathname, mode_t mode, dev_t dev) {
return WRAP_MKNODAT MKNODAT_ARG(_STAT_VER, dir_fd, pathname, mode, &dev);
}
Expand Down