From 4e5f24ae426732cf6e3b1d68fa43c058a8d35156 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 21 Sep 2022 20:52:54 -0400 Subject: [PATCH] Use an autoconf test to detect for a BSD- or GNU-style qsort_r function BSD is planning on changing their qsort_r() implementation to align with the POSIX/GNU-style qsort_r() function signature. So use an autoconf test to determine which qsort_r() a system has. Signed-off-by: Theodore Ts'o --- configure | 90 ++++++++++++++++++++++++++++++++++++++++++ configure.ac | 28 +++++++++++++ e2fsck/rehash.c | 10 ++--- lib/config.h.in | 109 ++++++++++++++++++++++++++++++++++++++++++--------- lib/support/sort_r.h | 6 ++- 5 files changed, 218 insertions(+), 25 deletions(-) diff --git a/configure b/configure index 4935423..caf6661 100755 --- a/configure +++ b/configure @@ -13270,6 +13270,12 @@ then : printf "%s\n" "#define HAVE_PWRITE64 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "qsort_r" "ac_cv_func_qsort_r" +if test "x$ac_cv_func_qsort_r" = xyes +then : + printf "%s\n" "#define HAVE_QSORT_R 1" >>confdefs.h + +fi ac_fn_c_check_func "$LINENO" "secure_getenv" "ac_cv_func_secure_getenv" if test "x$ac_cv_func_secure_getenv" = xyes then : @@ -13951,6 +13957,90 @@ fi fi fi +if test "$ac_cv_func_qsort_r" != no +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether qsort_r is GNU version" >&5 +printf %s "checking whether qsort_r is GNU version... " >&6; } +if test ${e2_cv_gnu_qsort_r+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +void (qsort_r)(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg); + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + e2_cv_gnu_qsort_r=yes +else $as_nop + e2_cv_gnu_qsort_r=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $e2_cv_gnu_qsort_r" >&5 +printf "%s\n" "$e2_cv_gnu_qsort_r" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether qsort_r is BSD version" >&5 +printf %s "checking whether qsort_r is BSD version... " >&6; } +if test ${e2_cv_bsd_qsort_r+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +void (qsort_r)(void *base, size_t nmemb, size_t size, + void *arg, int (*compar)(void *, const void *, const void *)); + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + e2_cv_bsd_qsort_r=yes +else $as_nop + e2_cv_bsd_qsort_r=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $e2_cv_bsd_qsort_r" >&5 +printf "%s\n" "$e2_cv_bsd_qsort_r" >&6; } + case "$e2_cv_gnu_qsort_r:$e2_cv_bsd_qsort_r" in #( + yes:no) : + + printf "%s\n" "#define HAVE_GNU_QSORT_R 1" >>confdefs.h + + ;; #( + no:yes) : + + printf "%s\n" "#define HAVE_BSD_QSORT_R 1" >>confdefs.h + + ;; #( + *) : + ;; +esac + +fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unified diff option" >&5 printf %s "checking for unified diff option... " >&6; } if diff -u $0 $0 > /dev/null 2>&1 ; then diff --git a/configure.ac b/configure.ac index 78f71fd..4ece83e 100644 --- a/configure.ac +++ b/configure.ac @@ -1226,6 +1226,7 @@ AC_CHECK_FUNCS(m4_flatten([ pwrite pread64 pwrite64 + qsort_r secure_getenv setmntent setresgid @@ -1351,6 +1352,33 @@ then fi AC_SUBST(SEM_INIT_LIB) dnl +dnl qsort_r detection +dnl +AS_IF([test "$ac_cv_func_qsort_r" != no], [ + AC_CACHE_CHECK(whether qsort_r is GNU version, e2_cv_gnu_qsort_r, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +@%:@include +void (qsort_r)(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg); +]], [[ ]])],[e2_cv_gnu_qsort_r=yes],[e2_cv_gnu_qsort_r=no]) + ]) + AC_CACHE_CHECK(whether qsort_r is BSD version, e2_cv_bsd_qsort_r, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +@%:@include +void (qsort_r)(void *base, size_t nmemb, size_t size, + void *arg, int (*compar)(void *, const void *, const void *)); +]], [[ ]])],[e2_cv_bsd_qsort_r=yes],[e2_cv_bsd_qsort_r=no]) + ]) + AS_CASE("$e2_cv_gnu_qsort_r:$e2_cv_bsd_qsort_r", + [yes:no], [ + AC_DEFINE(HAVE_GNU_QSORT_R, 1, [ Define to 1 if you have the GNU-style 'qsort_r' function.]) + ], + [no:yes], [ + AC_DEFINE(HAVE_BSD_QSORT_R, 1, [ Define to 1 if you have the BSD-style 'qsort_r' function.]) + ]) +]) +dnl dnl Check for unified diff dnl AC_MSG_CHECKING(for unified diff option) diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c index 210cfdf..c79a5ac 100644 --- a/e2fsck/rehash.c +++ b/e2fsck/rehash.c @@ -1053,13 +1053,11 @@ retry_nohash: /* Sort the list */ resort: if (fd.compress && fd.num_array > 1) - sort_r_simple(fd.harray+2, fd.num_array-2, - sizeof(struct hash_entry), - hash_cmp, &name_cmp_ctx); + sort_r(fd.harray+2, fd.num_array-2, sizeof(struct hash_entry), + hash_cmp, &name_cmp_ctx); else - sort_r_simple(fd.harray, fd.num_array, - sizeof(struct hash_entry), - hash_cmp, &name_cmp_ctx); + sort_r(fd.harray, fd.num_array, sizeof(struct hash_entry), + hash_cmp, &name_cmp_ctx); /* * Look for duplicates diff --git a/lib/config.h.in b/lib/config.h.in index b5856bb..6cf1f47 100644 --- a/lib/config.h.in +++ b/lib/config.h.in @@ -55,6 +55,9 @@ /* Define to 1 if blkid has blkid_topology_get_dax */ #undef HAVE_BLKID_TOPOLOGY_GET_DAX +/* Define to 1 if you have the BSD-style 'qsort_r' function. */ +#undef HAVE_BSD_QSORT_R + /* Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */ #undef HAVE_CFLOCALECOPYPREFERREDLANGUAGES @@ -154,6 +157,9 @@ /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT +/* Define to 1 if you have the GNU-style 'qsort_r' function. */ +#undef HAVE_GNU_QSORT_R + /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV @@ -220,12 +226,12 @@ /* Define to 1 if you have the `memalign' function. */ #undef HAVE_MEMALIGN -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - /* Define to 1 if you have the `mempcpy' function. */ #undef HAVE_MEMPCPY +/* Define to 1 if you have the header file. */ +#undef HAVE_MINIX_CONFIG_H + /* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP @@ -298,6 +304,9 @@ /* Define to 1 if you have the `pwrite64' function. */ #undef HAVE_PWRITE64 +/* Define to 1 if you have the `qsort_r' function. */ +#undef HAVE_QSORT_R + /* Define to 1 if dirent has d_reclen */ #undef HAVE_RECLEN_DIRENT @@ -343,6 +352,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H @@ -478,6 +490,9 @@ /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + /* Define to 1 if you have the `__secure_getenv' function. */ #undef HAVE___SECURE_GETENV @@ -524,7 +539,9 @@ /* The size of `time_t', as computed by sizeof. */ #undef SIZEOF_TIME_T -/* Define to 1 if you have the ANSI C header files. */ +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* If the compiler supports a TLS storage class define it to that here */ @@ -534,21 +551,87 @@ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif -/* Enable threading extensions on Solaris. */ +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE #endif @@ -573,14 +656,4 @@ /* Define to 1 if Apple Darwin libintl workaround is needed */ #undef _INTL_REDIRECT_MACROS -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - #include diff --git a/lib/support/sort_r.h b/lib/support/sort_r.h index 3292a26..ebf7837 100644 --- a/lib/support/sort_r.h +++ b/lib/support/sort_r.h @@ -24,7 +24,11 @@ void sort_r(void *base, size_t nel, size_t width, #define _SORT_R_INLINE inline -#if (defined __gnu_hurd__ || defined __GNU__ || \ +#if (defined HAVE_GNU_QSORT_R) +# define _SORT_R_LINUX +#elif (defined HAVE_BSD_QSORT_R) +# define _SORT_R_BSD +#elif (defined __gnu_hurd__ || defined __GNU__ || \ defined __linux__ || defined __MINGW32__ || defined __GLIBC__) # define _SORT_R_LINUX #elif (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \ -- 1.8.3.1