From 693a3597ea7fccfb62f357503ff177bd3e3d5a89 Mon Sep 17 00:00:00 2001
From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
Date: Mon, 22 Feb 2021 21:47:09 -0800
Subject: [PATCH] fix glibc 2.33+ compatibility

Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
---
 configure.ac        | 20 ++++++++++++++++++++
 src/ftw.c           |  2 +-
 src/ftw64.c         | 14 +++++++++++---
 src/libfakechroot.h | 15 +++++++++++++++
 src/lstat.c         |  2 +-
 src/lstat.h         |  2 +-
 src/lstat64.c       |  2 +-
 src/mknod.c         |  2 +-
 src/mknodat.c       |  2 +-
 src/stat.c          |  2 +-
 src/stat64.c        |  2 +-
 11 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/configure.ac b/configure.ac
index f8cdb323..9cc2e779 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,26 @@ ACX_CHECK_C_ATTRIBUTE_VISIBILITY
 # Checks for libraries.
 AC_CHECK_LIB([dl], [dlsym])
 
+AH_TEMPLATE([NEW_GLIBC], [glibc >= 2.33])
+AC_MSG_CHECKING([for glibc 2.33+])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+       #include <sys/stat.h>
+  ]], [[
+#ifdef __GLIBC__
+#if !__GLIBC_PREREQ(2,33)
+#error glibc<2.33
+#endif
+#else
+#error not glibc
+#endif
+  ]])],[
+   AC_DEFINE(NEW_GLIBC,1)
+   AC_MSG_RESULT([yes])
+  ],[
+   AC_DEFINE(NEW_GLIBC,0)
+   AC_MSG_RESULT([no])
+  ])
+
 # Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
diff --git a/src/ftw.c b/src/ftw.c
index 92fc126c..a9abc853 100644
--- a/src/ftw.c
+++ b/src/ftw.c
@@ -185,7 +185,7 @@ int rpl_lstat (const char *, struct stat *);
 # define NFTW_NEW_NAME __new_nftw
 # define INO_T ino_t
 # define STAT stat
-# ifdef _LIBC
+# if defined(_LIBC) && !NEW_GLIBC
 #  define LXSTAT __lxstat
 #  define XSTAT __xstat
 #  define FXSTATAT __fxstatat
diff --git a/src/ftw64.c b/src/ftw64.c
index 7cc8cdfd..cee1f2bc 100644
--- a/src/ftw64.c
+++ b/src/ftw64.c
@@ -18,6 +18,8 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include "config.h"
+
 #define __FTW64_C
 #define FTW_NAME ftw64
 #define NFTW_NAME nftw64
@@ -25,9 +27,15 @@
 #define NFTW_NEW_NAME __new_nftw64
 #define INO_T ino64_t
 #define STAT stat64
-#define LXSTAT __lxstat64
-#define XSTAT __xstat64
-#define FXSTATAT __fxstatat64
+#if NEW_GLIBC
+#  define LXSTAT(V,f,sb) lstat64 (f,sb)
+#  define XSTAT(V,f,sb) stat64 (f,sb)
+#  define FXSTATAT(V,d,f,sb,m) fstatat64 (d, f, sb, m)
+#else
+#  define LXSTAT __lxstat64
+#  define XSTAT __xstat64
+#  define FXSTATAT __fxstatat64
+#endif
 #define FTW_FUNC_T __ftw64_func_t
 #define NFTW_FUNC_T __nftw64_func_t
 
diff --git a/src/libfakechroot.h b/src/libfakechroot.h
index 4cf199ff..64ff15fb 100644
--- a/src/libfakechroot.h
+++ b/src/libfakechroot.h
@@ -200,6 +200,21 @@
 # endif
 #endif
 
+#ifndef _STAT_VER
+ #if defined (__aarch64__)
+  #define _STAT_VER 0
+ #elif defined (__powerpc__) && __WORDSIZE == 64
+  #define _STAT_VER 1
+ #elif defined (__riscv) && __riscv_xlen==64
+  #define _STAT_VER 0
+ #elif defined (__s390x__)
+  #define _STAT_VER 1
+ #elif defined (__x86_64__)
+  #define _STAT_VER 1
+ #else
+  #define _STAT_VER 3
+ #endif
+#endif
 
 typedef void (*fakechroot_wrapperfn_t)(void);
 
diff --git a/src/lstat.c b/src/lstat.c
index 54e3263f..fa383234 100644
--- a/src/lstat.c
+++ b/src/lstat.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#ifndef HAVE___LXSTAT
+#if !defined(HAVE___LXSTAT) || NEW_GLIBC
 
 #include <sys/stat.h>
 #include <unistd.h>
diff --git a/src/lstat.h b/src/lstat.h
index ee483033..c46a2b9b 100644
--- a/src/lstat.h
+++ b/src/lstat.h
@@ -24,7 +24,7 @@
 #include <config.h>
 #include "libfakechroot.h"
 
-#ifndef HAVE___LXSTAT
+#if !defined(HAVE___LXSTAT) || NEW_GLIBC
 
 wrapper_proto(lstat, int, (const char *, struct stat *));
 
diff --git a/src/lstat64.c b/src/lstat64.c
index b6212fc8..a332d7c3 100644
--- a/src/lstat64.c
+++ b/src/lstat64.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#if defined(HAVE_LSTAT64) && !defined(HAVE___LXSTAT64)
+#if defined(HAVE_LSTAT64) && (!defined(HAVE___LXSTAT64) || NEW_GLIBC)
 
 #define _LARGEFILE64_SOURCE
 #define _BSD_SOURCE
diff --git a/src/mknod.c b/src/mknod.c
index 27710372..aeb750b0 100644
--- a/src/mknod.c
+++ b/src/mknod.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#ifndef HAVE___XMKNOD
+#if !defined(HAVE___XMKNOD) || NEW_GLIBC
 
 #include <sys/stat.h>
 #include "libfakechroot.h"
diff --git a/src/mknodat.c b/src/mknodat.c
index 732a22bc..3239b357 100644
--- a/src/mknodat.c
+++ b/src/mknodat.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#if defined(HAVE_MKNODAT) && !defined(HAVE___XMKNODAT)
+#if defined(HAVE_MKNODAT) && (!defined(HAVE___XMKNODAT) || NEW_GLIBC)
 
 #define _ATFILE_SOURCE
 #include <sys/stat.h>
diff --git a/src/stat.c b/src/stat.c
index 7b377933..5ef57bab 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#ifndef HAVE___XSTAT
+#if !defined(HAVE___XSTAT) || NEW_GLIBC
 
 #define _BSD_SOURCE
 #define _DEFAULT_SOURCE
diff --git a/src/stat64.c b/src/stat64.c
index a360f66f..993ce808 100644
--- a/src/stat64.c
+++ b/src/stat64.c
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#if defined(HAVE_STAT64) && !defined(HAVE___XSTAT64)
+#if defined(HAVE_STAT64) && (!defined(HAVE___XSTAT64) || NEW_GLIBC)
 
 #define _BSD_SOURCE
 #define _LARGEFILE64_SOURCE
