Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F97428462
D17083.id110175.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D17083.id110175.diff
View Options
diff --git a/include/stdlib.h b/include/stdlib.h
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -311,8 +311,8 @@
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,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 */
diff --git a/lib/libc/gen/scandir-compat11.c b/lib/libc/gen/scandir-compat11.c
--- a/lib/libc/gen/scandir-compat11.c
+++ b/lib/libc/gen/scandir-compat11.c
@@ -58,8 +58,8 @@
#define SELECT(x) select(x)
-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
freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist,
@@ -116,7 +116,7 @@
closedir(dirp);
if (numitems && dcomp != NULL)
qsort_r(names, numitems, sizeof(struct freebsd11_dirent *),
- &dcomp, freebsd11_alphasort_thunk);
+ freebsd11_alphasort_thunk, &dcomp);
*namelist = names;
return (numitems);
@@ -141,7 +141,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 **);
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -63,7 +63,7 @@
typedef DECLARE_BLOCK(int, dcomp_block, const struct dirent **,
const struct dirent **);
#else
-static int alphasort_thunk(void *thunk, const void *p1, const void *p2);
+static int alphasort_thunk(const void *p1, const void *p2, void *thunk);
#endif
static int
@@ -123,7 +123,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);
@@ -199,7 +199,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 **);
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -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 qsort_s.c \
- quick_exit.c radixsort.c rand.c \
+ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \
+ qsort_s.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 \
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -49,7 +49,6 @@
lfind;
mergesort;
putenv;
- qsort_r;
qsort;
radixsort;
sradixsort;
@@ -130,6 +129,7 @@
FBSD_1.7 {
clearenv;
+ qsort_r;
};
FBSDprivate_1.0 {
diff --git a/lib/libc/stdlib/qsort.3 b/lib/libc/stdlib/qsort.3
--- a/lib/libc/stdlib/qsort.3
+++ b/lib/libc/stdlib/qsort.3
@@ -32,7 +32,7 @@
.\" @(#)qsort.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd January 20, 2020
+.Dd September 12, 2022
.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
@@ -157,7 +157,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
@@ -436,3 +436,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 14.0 ,
+the prototype of
+.Fn qsort_r
+was updated to match glibc.
diff --git a/lib/libc/stdlib/qsort.c b/lib/libc/stdlib/qsort.c
--- a/lib/libc/stdlib/qsort.c
+++ b/lib/libc/stdlib/qsort.c
@@ -42,6 +42,8 @@
#include "libc_private.h"
#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 *);
#elif defined(I_AM_QSORT_S)
typedef int cmp_t(const void *, const void *, void *);
@@ -72,6 +74,8 @@
if ((n) > 0) swapfunc(a, b, n)
#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)))
#elif defined(I_AM_QSORT_S)
#define CMP(t, x, y) (cmp((x), (y), (t)))
@@ -81,7 +85,7 @@
static inline char *
med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
-#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_S)
+#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_R_COMPAT) && !defined(I_AM_QSORT_S)
__unused
#endif
)
@@ -97,6 +101,8 @@
*/
#if defined(I_AM_QSORT_R)
#define local_qsort local_qsort_r
+#elif defined(I_AM_QSORT_R_COMPAT)
+#define local_qsort local_qsort_r_compat
#elif defined(I_AM_QSORT_S)
#define local_qsort local_qsort_s
#endif
@@ -211,10 +217,16 @@
#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)
{
local_qsort_r(a, n, es, cmp, 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)
+{
+ local_qsort_r_compat(a, n, es, cmp, thunk);
+}
#elif defined(I_AM_QSORT_S)
errno_t
qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk)
diff --git a/lib/libc/stdlib/qsort_r.c b/lib/libc/stdlib/qsort_r.c
--- a/lib/libc/stdlib/qsort_r.c
+++ b/lib/libc/stdlib/qsort_r.c
@@ -13,7 +13,8 @@
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));
+ qsort_r(base, nel, width,
+ (int (*)(const void *, const void *, void *))
+ GET_BLOCK_FUNCTION(compar),
+ compar);
}
diff --git a/lib/libc/stdlib/qsort_r_compat.c b/lib/libc/stdlib/qsort_r_compat.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/stdlib/qsort_r_compat.c
@@ -0,0 +1,10 @@
+/*
+ * This file is in the public domain. Originally written by Garrett
+ * A. Wollman.
+ *
+ * $FreeBSD$
+ */
+#define I_AM_QSORT_R_COMPAT
+#include "qsort.c"
+
+__sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0);
diff --git a/lib/libc/tests/stdlib/qsort_r_test.c b/lib/libc/tests/stdlib/qsort_r_test.c
--- a/lib/libc/tests/stdlib/qsort_r_test.c
+++ b/lib/libc/tests/stdlib/qsort_r_test.c
@@ -40,7 +40,7 @@
#define THUNK 42
static int
-sorthelp_r(void *thunk, const void *a, const void *b)
+sorthelp_r(const void *a, const void *b, void *thunk)
{
const int *oa, *ob;
@@ -70,8 +70,8 @@
testvector[i] = sresvector[i] = initvector[i];
/* Sort using qsort_r(3) */
- qsort_r(testvector, j, sizeof(testvector[0]), &thunk,
- sorthelp_r);
+ qsort_r(testvector, j, sizeof(testvector[0]), sorthelp_r,
+ &thunk);
/* Sort using reference slow sorting routine */
ssort(sresvector, j);
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -105,7 +105,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;
@@ -192,7 +192,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);
}
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -2562,7 +2562,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;
@@ -2590,7 +2590,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);
diff --git a/sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c b/sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c
--- a/sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c
+++ b/sys/dev/bhnd/nvram/bhnd_nvram_store_subr.c
@@ -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);
}
diff --git a/sys/dev/drm2/drm_linux_list_sort.c b/sys/dev/drm2/drm_linux_list_sort.c
--- a/sys/dev/drm2/drm_linux_list_sort.c
+++ b/sys/dev/drm2/drm_linux_list_sort.c
@@ -37,7 +37,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;
@@ -68,7 +68,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);
diff --git a/sys/libkern/qsort.c b/sys/libkern/qsort.c
--- a/sys/libkern/qsort.c
+++ b/sys/libkern/qsort.c
@@ -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
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
--- a/sys/netgraph/ng_ppp.c
+++ b/sys/netgraph/ng_ppp.c
@@ -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);
@@ -2316,8 +2316,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;
@@ -2401,7 +2401,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);
diff --git a/sys/sys/libkern.h b/sys/sys/libkern.h
--- a/sys/sys/libkern.h
+++ b/sys/sys/libkern.h
@@ -163,8 +163,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);
int strcasecmp(const char *, const char *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Sep 30, 6:32 AM (19 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13172490
Default Alt Text
D17083.id110175.diff (14 KB)
Attached To
Mode
D17083: Alter the prototype of qsort_r(3) to match POSIX, which adopted the glibc-based interface.
Attached
Detach File
Event Timeline
Log In to Comment