Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160404257
D23174.id66743.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D23174.id66743.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D23174: Add qsort_s(3)
Attached
Detach File
Event Timeline
Log In to Comment