FreeBSD Bugzilla – Attachment 197013 Details for
Bug 231256
[exp-run] Change qsort_r(3) to match glibc
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for fixing up qsort_r()
qsort_r-20180910.diff (text/plain), 16.37 KB, created by
Ed Schouten
on 2018-09-10 18:18:49 UTC
(
hide
)
Description:
Patch for fixing up qsort_r()
Filename:
MIME Type:
Creator:
Ed Schouten
Created:
2018-09-10 18:18:49 UTC
Size:
16.37 KB
patch
obsolete
>Index: include/stdlib.h >=================================================================== >--- include/stdlib.h (revision 338535) >+++ include/stdlib.h (working copy) >@@ -297,8 +297,8 @@ > #endif > int mkostemp(char *, int); > int mkostemps(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 >@@ -319,6 +319,19 @@ > __uint64_t > strtouq(const char *, char **, int); > >+/* >+ * Attempt to trap calls of the historical qsort_r() function. The order >+ * of the last two arguments of this function have changed. If the last >+ * argument matches the type of the traditional comparator function, >+ * call an integer instead, which will generate a compiler error. >+ */ >+#if defined(__generic) && !defined(__cplusplus) >+extern int __calling_qsort_r_incorrectly; >+#define qsort_r(base, nel, width, compar, arg) \ >+ __generic(arg, int (*)(void *, const void *, const void *), \ >+ __calling_qsort_r_incorrectly, qsort_r)(base, nel, width, compar, arg) >+#endif >+ > extern char *suboptarg; /* getsubopt(3) external variable */ > #endif /* __BSD_VISIBLE */ > >Index: lib/libc/gen/scandir-compat11.c >=================================================================== >--- lib/libc/gen/scandir-compat11.c (revision 338535) >+++ lib/libc/gen/scandir-compat11.c (working copy) >@@ -60,8 +60,8 @@ > #define SELECT(x) select(x) > #endif > >-static int freebsd11_alphasort_thunk(void *thunk, const void *p1, >- const void *p2); >+static int freebsd11_alphasort_thunk(const void *p1, const void *p2, >+ void *thunk); > > int > #ifdef I_AM_SCANDIR_B >@@ -129,7 +129,7 @@ > (void*)dcomp); > #else > qsort_r(names, numitems, sizeof(struct freebsd11_dirent *), >- &dcomp, freebsd11_alphasort_thunk); >+ freebsd11_alphasort_thunk, &dcomp); > #endif > *namelist = names; > return (numitems); >@@ -155,7 +155,7 @@ > } > > static int >-freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2) >+freebsd11_alphasort_thunk(const void *p1, const void *p2, void *thunk) > { > int (*dc)(const struct freebsd11_dirent **, const struct > freebsd11_dirent **); >Index: lib/libc/gen/scandir.c >=================================================================== >--- lib/libc/gen/scandir.c (revision 338535) >+++ lib/libc/gen/scandir.c (working copy) >@@ -57,7 +57,7 @@ > #define SELECT(x) select(x) > #endif > >-static int alphasort_thunk(void *thunk, const void *p1, const void *p2); >+static int alphasort_thunk(const void *p1, const void *p2, void *thunk); > > int > #ifdef I_AM_SCANDIR_B >@@ -121,7 +121,7 @@ > qsort_b(names, numitems, sizeof(struct dirent *), (void*)dcomp); > #else > qsort_r(names, numitems, sizeof(struct dirent *), >- &dcomp, alphasort_thunk); >+ alphasort_thunk, &dcomp); > #endif > *namelist = names; > return (numitems); >@@ -146,7 +146,7 @@ > } > > static int >-alphasort_thunk(void *thunk, const void *p1, const void *p2) >+alphasort_thunk(const void *p1, const void *p2, void *thunk) > { > int (*dc)(const struct dirent **, const struct dirent **); > >Index: lib/libc/stdlib/Makefile.inc >=================================================================== >--- lib/libc/stdlib/Makefile.inc (revision 338535) >+++ lib/libc/stdlib/Makefile.inc (working copy) >@@ -11,8 +11,8 @@ > getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \ > hsearch_r.c imaxabs.c imaxdiv.c \ > insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ >- merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \ >- radixsort.c rand.c \ >+ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \ >+ quick_exit.c radixsort.c rand.c \ > random.c reallocarray.c reallocf.c realpath.c remque.c \ > set_constraint_handler_s.c strfmon.c strtoimax.c \ > strtol.c strtold.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ >Index: lib/libc/stdlib/Symbol.map >=================================================================== >--- lib/libc/stdlib/Symbol.map (revision 338535) >+++ lib/libc/stdlib/Symbol.map (working copy) >@@ -49,7 +49,6 @@ > lfind; > mergesort; > putenv; >- qsort_r; > qsort; > radixsort; > sradixsort; >@@ -122,6 +121,7 @@ > abort_handler_s; > ignore_handler_s; > set_constraint_handler_s; >+ qsort_r; > }; > > FBSDprivate_1.0 { >Index: lib/libc/stdlib/qsort.3 >=================================================================== >--- lib/libc/stdlib/qsort.3 (revision 338535) >+++ lib/libc/stdlib/qsort.3 (working copy) >@@ -32,7 +32,7 @@ > .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 > .\" $FreeBSD$ > .\" >-.Dd February 20, 2013 >+.Dd September 8, 2018 > .Dt QSORT 3 > .Os > .Sh NAME >@@ -67,8 +67,8 @@ > .Fa "void *base" > .Fa "size_t nmemb" > .Fa "size_t size" >+.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *, void *\*[rp]" > .Fa "void *thunk" >-.Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]" > .Fc > .Ft int > .Fo heapsort >@@ -148,7 +148,7 @@ > .Fn qsort , > except that it takes an additional argument, > .Fa thunk , >-which is passed unchanged as the first argument to function pointed to >+which is passed unchanged as the last argument to function pointed to > .Fa compar . > This allows the comparison function to access additional > data without using global variables, and thus >@@ -370,3 +370,9 @@ > The variants of these functions that take blocks as arguments first appeared in > Mac OS X. > This implementation was created by David Chisnall. >+.Pp >+In >+.Fx 13.0 , >+the prototype of >+.Fn qsort_r >+was updated to match glibc. >Index: lib/libc/stdlib/qsort.c >=================================================================== >--- lib/libc/stdlib/qsort.c (revision 338535) >+++ lib/libc/stdlib/qsort.c (working copy) >@@ -37,7 +37,9 @@ > > #include <stdlib.h> > >-#ifdef I_AM_QSORT_R >+#if defined(I_AM_QSORT_R) >+typedef int cmp_t(const void *, const void *, void *); >+#elif defined(I_AM_QSORT_R_COMPAT) > typedef int cmp_t(void *, const void *, const void *); > #else > typedef int cmp_t(const void *, const void *); >@@ -65,7 +67,9 @@ > #define vecswap(a, b, n) \ > if ((n) > 0) swapfunc(a, b, n) > >-#ifdef I_AM_QSORT_R >+#if defined(I_AM_QSORT_R) >+#define CMP(t, x, y) (cmp((x), (y), (t))) >+#elif defined(I_AM_QSORT_R_COMPAT) > #define CMP(t, x, y) (cmp((t), (x), (y))) > #else > #define CMP(t, x, y) (cmp((x), (y))) >@@ -73,7 +77,7 @@ > > static inline char * > med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk >-#ifndef I_AM_QSORT_R >+#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_R_COMPAT) > __unused > #endif > ) >@@ -83,9 +87,12 @@ > :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); > } > >-#ifdef I_AM_QSORT_R >+#if defined(I_AM_QSORT_R) > void >-qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) >+(qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) >+#elif defined(I_AM_QSORT_R_COMPAT) >+void >+__qsort_r_compat(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) > #else > #define thunk NULL > void >@@ -168,8 +175,10 @@ > if (d1 <= d2) { > /* Recurse on left partition, then iterate on right partition */ > if (d1 > es) { >-#ifdef I_AM_QSORT_R >- qsort_r(a, d1 / es, es, thunk, cmp); >+#if defined(I_AM_QSORT_R) >+ qsort_r(a, d1 / es, es, cmp, thunk); >+#elif defined(I_AM_QSORT_R_COMPAT) >+ __qsort_r_compat(a, d1 / es, es, thunk, cmp); > #else > qsort(a, d1 / es, es, cmp); > #endif >@@ -184,8 +193,10 @@ > } else { > /* Recurse on right partition, then iterate on left partition */ > if (d2 > es) { >-#ifdef I_AM_QSORT_R >- qsort_r(pn - d2, d2 / es, es, thunk, cmp); >+#if defined(I_AM_QSORT_R) >+ qsort_r(pn - d2, d2 / es, es, cmp, thunk); >+#elif defined(I_AM_QSORT_R_COMPAT) >+ __qsort_r_compat(pn - d2, d2 / es, es, thunk, cmp); > #else > qsort(pn - d2, d2 / es, es, cmp); > #endif >Index: lib/libc/stdlib/qsort_r.c >=================================================================== >--- lib/libc/stdlib/qsort_r.c (revision 338535) >+++ lib/libc/stdlib/qsort_r.c (working copy) >@@ -4,16 +4,5 @@ > * > * $FreeBSD$ > */ >-#include "block_abi.h" > #define I_AM_QSORT_R > #include "qsort.c" >- >-typedef DECLARE_BLOCK(int, qsort_block, const void *, const void *); >- >-void >-qsort_b(void *base, size_t nel, size_t width, qsort_block compar) >-{ >- qsort_r(base, nel, width, compar, >- (int (*)(void *, const void *, const void *)) >- GET_BLOCK_FUNCTION(compar)); >-} >Index: lib/libc/stdlib/qsort_r_compat.c >=================================================================== >--- lib/libc/stdlib/qsort_r_compat.c (nonexistent) >+++ lib/libc/stdlib/qsort_r_compat.c (working copy) >@@ -0,0 +1,21 @@ >+/* >+ * This file is in the public domain. Originally written by Garrett >+ * A. Wollman. >+ * >+ * $FreeBSD$ >+ */ >+#include "block_abi.h" >+#define I_AM_QSORT_R_COMPAT >+#include "qsort.c" >+ >+typedef DECLARE_BLOCK(int, qsort_block, const void *, const void *); >+ >+void >+qsort_b(void *base, size_t nel, size_t width, qsort_block compar) >+{ >+ __qsort_r_compat(base, nel, width, compar, >+ (int (*)(void *, const void *, const void *)) >+ GET_BLOCK_FUNCTION(compar)); >+} >+ >+__sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0); >Index: lib/libproc/proc_sym.c >=================================================================== >--- lib/libproc/proc_sym.c (revision 338535) >+++ lib/libproc/proc_sym.c (working copy) >@@ -108,7 +108,7 @@ > }; > > static int >-symvalcmp(void *_thunk, const void *a1, const void *a2) >+symvalcmp(const void *a1, const void *a2, void *_thunk) > { > GElf_Sym sym1, sym2; > struct symsort_thunk *thunk; >@@ -195,7 +195,7 @@ > > thunk.e = e; > thunk.symtab = symtab; >- qsort_r(symtab->index, nsyms, sizeof(u_int), &thunk, symvalcmp); >+ qsort_r(symtab->index, nsyms, sizeof(u_int), symvalcmp, &thunk); > > return (0); > } >Index: sys/compat/linuxkpi/common/src/linux_compat.c >=================================================================== >--- sys/compat/linuxkpi/common/src/linux_compat.c (revision 338535) >+++ sys/compat/linuxkpi/common/src/linux_compat.c (working copy) >@@ -2059,7 +2059,7 @@ > }; > > static inline int >-linux_le_cmp(void *priv, const void *d1, const void *d2) >+linux_le_cmp(const void *d1, const void *d2, void *priv) > { > struct list_head *le1, *le2; > struct list_sort_thunk *thunk; >@@ -2087,7 +2087,7 @@ > ar[i++] = le; > thunk.cmp = cmp; > thunk.priv = priv; >- qsort_r(ar, count, sizeof(struct list_head *), &thunk, linux_le_cmp); >+ qsort_r(ar, count, sizeof(struct list_head *), linux_le_cmp, &thunk); > INIT_LIST_HEAD(head); > for (i = 0; i < count; i++) > list_add_tail(ar[i], head); >Index: sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c >=================================================================== >--- sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c (revision 338535) >+++ sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c (working copy) >@@ -59,8 +59,7 @@ > > #include "bhnd_nvram_storevar.h" > >-static int bhnd_nvstore_idx_cmp(void *ctx, >- const void *lhs, const void *rhs); >+static int bhnd_nvstore_idx_cmp(const void *lhs, const void *rhs, void *ctx); > > /** > * Allocate and initialize a new path instance. >@@ -198,7 +197,7 @@ > > /* sort function for bhnd_nvstore_index_prepare() */ > static int >-bhnd_nvstore_idx_cmp(void *ctx, const void *lhs, const void *rhs) >+bhnd_nvstore_idx_cmp(const void *lhs, const void *rhs, void *ctx) > { > struct bhnd_nvram_store *sc; > void *l_cookiep, *r_cookiep; >@@ -259,8 +258,8 @@ > BHND_NVSTORE_LOCK_ASSERT(sc, MA_OWNED); > > /* Sort the index table */ >- qsort_r(index->cookiep, index->count, sizeof(index->cookiep[0]), sc, >- bhnd_nvstore_idx_cmp); >+ qsort_r(index->cookiep, index->count, sizeof(index->cookiep[0]), >+ bhnd_nvstore_idx_cmp, sc); > > return (0); > } >Index: sys/dev/drm2/drm_linux_list_sort.c >=================================================================== >--- sys/dev/drm2/drm_linux_list_sort.c (revision 338535) >+++ sys/dev/drm2/drm_linux_list_sort.c (working copy) >@@ -38,7 +38,7 @@ > }; > > static int >-drm_le_cmp(void *priv, const void *d1, const void *d2) >+drm_le_cmp(const void *d1, const void *d2, void *priv) > { > struct list_head *le1, *le2; > struct drm_list_sort_thunk *thunk; >@@ -69,7 +69,7 @@ > ar[i++] = le; > thunk.cmp = cmp; > thunk.priv = priv; >- qsort_r(ar, count, sizeof(struct list_head *), &thunk, drm_le_cmp); >+ qsort_r(ar, count, sizeof(struct list_head *), drm_le_cmp, &thunk); > INIT_LIST_HEAD(head); > for (i = 0; i < count; i++) > list_add_tail(ar[i], head); >Index: sys/libkern/qsort.c >=================================================================== >--- sys/libkern/qsort.c (revision 338535) >+++ sys/libkern/qsort.c (working copy) >@@ -36,7 +36,7 @@ > #include <sys/libkern.h> > > #ifdef I_AM_QSORT_R >-typedef int cmp_t(void *, const void *, const void *); >+typedef int cmp_t(const void *, const void *, void *); > #else > typedef int cmp_t(const void *, const void *); > #endif >@@ -88,7 +88,7 @@ > if ((n) > 0) swapfunc(a, b, n, swaptype_long, swaptype_int) > > #ifdef I_AM_QSORT_R >-#define CMP(t, x, y) (cmp((t), (x), (y))) >+#define CMP(t, x, y) (cmp((x), (y), (t))) > #else > #define CMP(t, x, y) (cmp((x), (y))) > #endif >@@ -107,7 +107,7 @@ > > #ifdef I_AM_QSORT_R > void >-qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) >+(qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) > #else > #define thunk NULL > void >@@ -192,7 +192,7 @@ > /* Recurse on left partition, then iterate on right partition */ > if (d1 > es) { > #ifdef I_AM_QSORT_R >- qsort_r(a, d1 / es, es, thunk, cmp); >+ qsort_r(a, d1 / es, es, cmp, thunk); > #else > qsort(a, d1 / es, es, cmp); > #endif >@@ -208,7 +208,7 @@ > /* Recurse on right partition, then iterate on left partition */ > if (d2 > es) { > #ifdef I_AM_QSORT_R >- qsort_r(pn - d2, d2 / es, es, thunk, cmp); >+ qsort_r(pn - d2, d2 / es, es, cmp, thunk); > #else > qsort(pn - d2, d2 / es, es, cmp); > #endif >Index: sys/netgraph/ng_ppp.c >=================================================================== >--- sys/netgraph/ng_ppp.c (revision 338535) >+++ sys/netgraph/ng_ppp.c (working copy) >@@ -322,7 +322,7 @@ > static void ng_ppp_frag_checkstale(node_p node); > static void ng_ppp_frag_reset(node_p node); > static void ng_ppp_mp_strategy(node_p node, int len, int *distrib); >-static int ng_ppp_intcmp(void *latency, const void *v1, const void *v2); >+static int ng_ppp_intcmp(const void *v1, const void *v2, void *latency); > static struct mbuf *ng_ppp_addproto(struct mbuf *m, uint16_t proto, int compOK); > static struct mbuf *ng_ppp_cutproto(struct mbuf *m, uint16_t *proto); > static struct mbuf *ng_ppp_prepend(struct mbuf *m, const void *buf, int len); >@@ -2319,8 +2319,8 @@ > } > > /* Sort active links by latency */ >- qsort_r(sortByLatency, >- priv->numActiveLinks, sizeof(*sortByLatency), latency, ng_ppp_intcmp); >+ qsort_r(sortByLatency, priv->numActiveLinks, sizeof(*sortByLatency), >+ ng_ppp_intcmp, latency); > > /* Find the interval we need (add links in sortByLatency[] order) */ > for (numFragments = 1; >@@ -2404,7 +2404,7 @@ > * Compare two integers > */ > static int >-ng_ppp_intcmp(void *latency, const void *v1, const void *v2) >+ng_ppp_intcmp(const void *v1, const void *v2, void *latency) > { > const int index1 = *((const int *) v1); > const int index2 = *((const int *) v2); >Index: sys/sys/libkern.h >=================================================================== >--- sys/sys/libkern.h (revision 338535) >+++ sys/sys/libkern.h (working copy) >@@ -162,8 +162,8 @@ > void *memmem(const void *l, size_t l_len, const void *s, size_t s_len); > void qsort(void *base, size_t nmemb, size_t size, > int (*compar)(const void *, const void *)); >-void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, >- int (*compar)(void *, const void *, const void *)); >+void qsort_r(void *base, size_t nmemb, size_t size, >+ int (*compar)(const void *, const void *, void *), void *thunk); > u_long random(void); > int scanc(u_int, const u_char *, const u_char *, int); > void srandom(u_long); >@@ -189,6 +189,19 @@ > char *strstr(const char *, const char *); > int strvalid(const char *, size_t); > >+/* >+ * Attempt to trap calls of the historical qsort_r() function. The order >+ * of the last two arguments of this function have changed. If the last >+ * argument matches the type of the traditional comparator function, >+ * call an integer instead, which will generate a compiler error. >+ */ >+#if defined(__generic) && !defined(__cplusplus) >+extern int __calling_qsort_r_incorrectly; >+#define qsort_r(base, nel, width, compar, arg) \ >+ __generic(arg, int (*)(void *, const void *, const void *), \ >+ __calling_qsort_r_incorrectly, qsort_r)(base, nel, width, compar, arg) >+#endif >+ > extern const uint32_t crc32_tab[]; > > static __inline uint32_t
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 231256
: 197013 |
197107