diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2022-09-30 22:26:30 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2022-09-30 22:26:30 +0000 |
| commit | af3c78886fd8d4ca5eebdbe581a459a6f6d29d6a (patch) | |
| tree | 9ff804d16ae1d811e013a58e71f8c824c2ff2488 /include | |
| parent | 69d79ceb2c01931c129c5bafc300c33f3e106efd (diff) | |
Diffstat (limited to 'include')
| -rw-r--r-- | include/stdlib.h | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/include/stdlib.h b/include/stdlib.h index bf1a612190ee..754e8f5f5fd4 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -311,8 +311,8 @@ int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *)); int mkostemp(char *, int); int mkostemps(char *, int, int); int mkostempsat(int, char *, int, int); -void qsort_r(void *, size_t, size_t, void *, - int (*)(void *, const void *, const void *)); +void qsort_r(void *, size_t, size_t, + int (*)(const void *, const void *, void *), void *); int radixsort(const unsigned char **, int, const unsigned char *, unsigned); void *reallocarray(void *, size_t, size_t) __result_use_check @@ -332,6 +332,40 @@ __int64_t __uint64_t strtouq(const char *, char **, int); +/* + * In FreeBSD 14, the prototype of qsort_r() was modified to comply with + * POSIX. The standardized qsort_r()'s order of last two parameters was + * changed, and the comparator function is now taking thunk as its last + * parameter, and both are different from the ones expected by the historical + * FreeBSD qsort_r() interface. + * + * Apply a workaround where we explicitly link against the historical + * interface, qsort_r@FBSD_1.0, in case when qsort_r() is called with + * the last parameter with a function pointer that exactly matches the + * historical FreeBSD qsort_r() comparator signature, so applications + * written for the historical interface can continue to work without + * modification. + */ +#if defined(__generic) || defined(__cplusplus) +void __qsort_r_compat(void *, size_t, size_t, void *, + int (*)(void *, const void *, const void *)); +__sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0); +#endif +#if defined(__generic) && !defined(__cplusplus) +#define qsort_r(base, nel, width, arg4, arg5) \ + __generic(arg5, int (*)(void *, const void *, const void *), \ + __qsort_r_compat, qsort_r)(base, nel, width, arg4, arg5) +#elif defined(__cplusplus) +__END_DECLS +extern "C++" { +static inline void qsort_r(void *base, size_t nmemb, size_t size, + void *thunk, int (*compar)(void *, const void *, const void *)) { + __qsort_r_compat(base, nmemb, size, thunk, compar); +} +} +__BEGIN_DECLS +#endif + extern char *suboptarg; /* getsubopt(3) external variable */ #endif /* __BSD_VISIBLE */ |
