Page MenuHomeFreeBSD

D23174.id66743.diff
No OneTemporary

D23174.id66743.diff

Index: include/stdlib.h
===================================================================
--- include/stdlib.h
+++ include/stdlib.h
@@ -339,6 +339,9 @@
errno_t);
/* K3.6.1.3 */
void ignore_handler_s(const char * __restrict, void * __restrict, errno_t);
+/* K.3.6.3.2 */
+errno_t qsort_s(void *, size_t, size_t, void *,
+ int (*)(const void *, const void *, void *));
#endif /* __EXT1_VISIBLE */
__END_DECLS
Index: lib/libc/stdlib/Makefile.inc
===================================================================
--- lib/libc/stdlib/Makefile.inc
+++ lib/libc/stdlib/Makefile.inc
@@ -11,7 +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 \
+ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.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 \
@@ -51,7 +52,7 @@
MLINKS+=insque.3 remque.3
MLINKS+=lsearch.3 lfind.3
MLINKS+=ptsname.3 grantpt.3 ptsname.3 unlockpt.3
-MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 qsort.3 qsort_r.3
+MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 qsort.3 qsort_r.3 qsort_s.3
MLINKS+=rand.3 rand_r.3 rand.3 srand.3
MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \
random.3 srandomdev.3
Index: lib/libc/stdlib/Symbol.map
===================================================================
--- lib/libc/stdlib/Symbol.map
+++ lib/libc/stdlib/Symbol.map
@@ -120,6 +120,7 @@
__cxa_thread_atexit_impl;
abort_handler_s;
ignore_handler_s;
+ qsort_s;
set_constraint_handler_s;
};
Index: lib/libc/stdlib/qsort.3
===================================================================
--- lib/libc/stdlib/qsort.3
+++ lib/libc/stdlib/qsort.3
@@ -32,7 +32,7 @@
.\" @(#)qsort.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd February 20, 2013
+.Dd January 14, 2020
.Dt QSORT 3
.Os
.Sh NAME
@@ -98,6 +98,15 @@
.Fa "size_t size"
.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]"
.Fc
+.Fd #define __STDC_WANT_LIB_EXT1__ 1
+.Ft errno_t
+.Fo qsort_s
+.Fa "void *base"
+.Fa "size_t nmemb"
+.Fa "size_t size"
+.Fa "void *thunk"
+.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *, void *\*[rp]"
+.Fc
.Sh DESCRIPTION
The
.Fn qsort
@@ -238,6 +247,27 @@
.Fn heapsort .
Memory availability and pre-existing order in the data can make this
untrue.
+.Pp
+The
+.Fn qsort_s
+function behaves the same as
+.Fn qsort_r
+except the order of arguments to
+.Fa compar
+is changed,
+and that an error is returned and the currently registered
+runtime-constraint handler is called if
+.Fa nmemb
+or
+.Fa size
+are greater than
+.Dv RSIZE_MAX ,
+or
+.Fa nmemb
+is not zero and
+.Fa compar
+is NULL.
+The runtime-constraint handler is called first and may not return.
.Sh RETURN VALUES
The
.Fn qsort
@@ -245,6 +275,9 @@
.Fn qsort_r
functions
return no value.
+The
+.Fn qsort_s
+function returns zero on success, non-zero on error.
.Pp
.Rv -std heapsort mergesort
.Sh EXAMPLES
@@ -288,6 +321,19 @@
}
.Ed
.Sh COMPATIBILITY
+The order of arguments for the comparison function used with
+.Fn qsort_r
+is different from the one used by
+.Fn qsort_s ,
+and the GNU libc implementation of
+.Fn qsort_r .
+When porting software written for GNU libc, it is usually possible
+to replace
+.Fn qsort_r
+with
+.Fn qsort_s
+to work around this problem.
+.Pp
Previous versions of
.Fn qsort
did not permit the comparison routine itself to call
@@ -366,6 +412,10 @@
function
conforms to
.St -isoC .
+.Fn qsort_s
+conforms to
+.St -isoC-2011
+K.3.6.3.2.
.Sh HISTORY
The variants of these functions that take blocks as arguments first appeared in
Mac OS X.
Index: lib/libc/stdlib/qsort.c
===================================================================
--- lib/libc/stdlib/qsort.c
+++ lib/libc/stdlib/qsort.c
@@ -35,10 +35,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
+#include <stdint.h>
#include <stdlib.h>
+#include "libc_private.h"
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
typedef int cmp_t(void *, const void *, const void *);
+#elif defined(I_AM_QSORT_S)
+typedef int cmp_t(const void *, const void *, void *);
#else
typedef int cmp_t(const void *, const void *);
#endif
@@ -65,15 +70,17 @@
#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((t), (x), (y)))
+#elif defined(I_AM_QSORT_S)
+#define CMP(t, x, y) (cmp((x), (y), (t)))
#else
#define CMP(t, x, y) (cmp((x), (y)))
#endif
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_S)
__unused
#endif
)
@@ -83,9 +90,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)
+#elif defined(I_AM_QSORT_S)
+errno_t
+qsort_s(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
#else
#define thunk NULL
void
@@ -97,6 +107,24 @@
int cmp_result;
int swap_cnt;
+#ifdef I_AM_QSORT_S
+ if (n > RSIZE_MAX) {
+ __throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL);
+ return (EINVAL);
+ } else if (es > RSIZE_MAX) {
+ __throw_constraint_handler_s("qsort_s : es > RSIZE_MAX", EINVAL);
+ return (EINVAL);
+ } else if (n != 0) {
+ if (a == NULL) {
+ __throw_constraint_handler_s("qsort_s : a == NULL", EINVAL);
+ return (EINVAL);
+ } else if (cmp == NULL) {
+ __throw_constraint_handler_s("qsort_s : cmp == NULL", EINVAL);
+ return (EINVAL);
+ }
+ }
+#endif
+
loop:
swap_cnt = 0;
if (n < 7) {
@@ -105,7 +133,11 @@
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
pl -= es)
swapfunc(pl, pl - es, es);
+#ifdef I_AM_QSORT_S
+ return (0);
+#else
return;
+#endif
}
pm = (char *)a + (n / 2) * es;
if (n > 7) {
@@ -154,7 +186,11 @@
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
pl -= es)
swapfunc(pl, pl - es, es);
+#ifdef I_AM_QSORT_S
+ return (0);
+#else
return;
+#endif
}
pn = (char *)a + n * es;
@@ -168,8 +204,10 @@
if (d1 <= d2) {
/* Recurse on left partition, then iterate on right partition */
if (d1 > es) {
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
qsort_r(a, d1 / es, es, thunk, cmp);
+#elif defined(I_AM_QSORT_S)
+ qsort_s(a, d1 / es, es, thunk, cmp);
#else
qsort(a, d1 / es, es, cmp);
#endif
@@ -184,8 +222,10 @@
} else {
/* Recurse on right partition, then iterate on left partition */
if (d2 > es) {
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
qsort_r(pn - d2, d2 / es, es, thunk, cmp);
+#elif defined(I_AM_QSORT_S)
+ qsort_s(pn - d2, d2 / es, es, thunk, cmp);
#else
qsort(pn - d2, d2 / es, es, cmp);
#endif
@@ -197,4 +237,8 @@
goto loop;
}
}
+
+#ifdef I_AM_QSORT_S
+ return (0);
+#endif
}
Index: lib/libc/stdlib/qsort_s.c
===================================================================
--- lib/libc/stdlib/qsort_s.c
+++ lib/libc/stdlib/qsort_s.c
@@ -2,18 +2,8 @@
* This file is in the public domain. Originally written by Garrett
* A. Wollman.
*
- * $FreeBSD: head/lib/libc/stdlib/qsort_r.c 264143 2014-04-05 08:17:48Z theraven $
+ * $FreeBSD: head/lib/libc/stdlib/qsort_s.c 264143 2014-04-05 08:17:48Z theraven $
*/
#include "block_abi.h"
-#define I_AM_QSORT_R
+#define I_AM_QSORT_S
#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));
-}

File Metadata

Mime Type
text/plain
Expires
Thu, Jun 25, 4:20 AM (22 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34303997
Default Alt Text
D23174.id66743.diff (7 KB)

Event Timeline