summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r--lib/libc/stdlib/Makefile.inc5
-rw-r--r--lib/libc/stdlib/Symbol.map2
-rw-r--r--lib/libc/stdlib/atexit.34
-rw-r--r--lib/libc/stdlib/exit.32
-rw-r--r--lib/libc/stdlib/jemalloc/Symbol.map1
-rw-r--r--lib/libc/stdlib/qsort.c53
-rw-r--r--lib/libc/stdlib/quick_exit.34
-rw-r--r--lib/libc/stdlib/random.35
-rw-r--r--lib/libc/stdlib/reallocarray.3142
-rw-r--r--lib/libc/stdlib/reallocarray.c42
-rw-r--r--lib/libc/stdlib/system.c15
-rw-r--r--lib/libc/stdlib/tdelete.c9
12 files changed, 245 insertions, 39 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 57205a7..7cee03a 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -10,7 +10,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.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 \
- random.c reallocf.c realpath.c remque.c strfmon.c strtoimax.c \
+ random.c reallocarray.c reallocf.c realpath.c remque.c strfmon.c \
+ strtoimax.c \
strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \
strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
@@ -25,7 +26,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 memory.3 ptsname.3 qsort.3 \
quick_exit.3 \
- radixsort.3 rand.3 random.3 reallocf.3 \
+ radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 \
realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
tsearch.3
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 8355f9a..782023e 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -113,9 +113,11 @@ FBSD_1.4 {
hcreate_r;
hdestroy_r;
hsearch_r;
+ reallocarray;
};
FBSDprivate_1.0 {
__system;
_system;
+ __libc_system;
};
diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3
index 68f4e8f..3cdc59f 100644
--- a/lib/libc/stdlib/atexit.3
+++ b/lib/libc/stdlib/atexit.3
@@ -88,12 +88,12 @@ The existing list of functions is unmodified.
.It Bq Er ENOSYS
The
.Fn atexit_b
-function was called by a program that did not supply a
+function was called by a program that did not supply a
.Fn _Block_copy
implementation.
.El
.Sh SEE ALSO
-.Xr at_quick_exit 3
+.Xr at_quick_exit 3 ,
.Xr exit 3
.Sh STANDARDS
The
diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3
index 07ce0d7..7d657c9 100644
--- a/lib/libc/stdlib/exit.3
+++ b/lib/libc/stdlib/exit.3
@@ -117,8 +117,8 @@ never return.
.Sh SEE ALSO
.Xr _exit 2 ,
.Xr wait 2 ,
-.Xr atexit 3 ,
.Xr at_quick_exit 3 ,
+.Xr atexit 3 ,
.Xr intro 3 ,
.Xr quick_exit 3 ,
.Xr sysexits 3 ,
diff --git a/lib/libc/stdlib/jemalloc/Symbol.map b/lib/libc/stdlib/jemalloc/Symbol.map
index 35a5dad..132664a 100644
--- a/lib/libc/stdlib/jemalloc/Symbol.map
+++ b/lib/libc/stdlib/jemalloc/Symbol.map
@@ -55,4 +55,5 @@ FBSDprivate_1.0 {
_malloc_thread_cleanup;
_malloc_prefork;
_malloc_postfork;
+ _malloc_first_thread;
};
diff --git a/lib/libc/stdlib/qsort.c b/lib/libc/stdlib/qsort.c
index 93e22cd..e97ea92 100644
--- a/lib/libc/stdlib/qsort.c
+++ b/lib/libc/stdlib/qsort.c
@@ -41,47 +41,55 @@ typedef int cmp_t(void *, const void *, const void *);
typedef int cmp_t(const void *, const void *);
#endif
static inline char *med3(char *, char *, char *, cmp_t *, void *);
-static inline void swapfunc(char *, char *, int, int);
+static inline void swapfunc(char *, char *, int, int, int);
-#define min(a, b) (a) < (b) ? a : b
+#define MIN(a, b) ((a) < (b) ? a : b)
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
-#define swapcode(TYPE, parmi, parmj, n) { \
- long i = (n) / sizeof (TYPE); \
- TYPE *pi = (TYPE *) (parmi); \
- TYPE *pj = (TYPE *) (parmj); \
+#define swapcode(TYPE, parmi, parmj, n) { \
+ long i = (n) / sizeof (TYPE); \
+ TYPE *pi = (TYPE *) (parmi); \
+ TYPE *pj = (TYPE *) (parmj); \
do { \
TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
- } while (--i > 0); \
+ } while (--i > 0); \
}
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+#define SWAPINIT(TYPE, a, es) swaptype_ ## TYPE = \
+ ((char *)a - (char *)0) % sizeof(TYPE) || \
+ es % sizeof(TYPE) ? 2 : es == sizeof(TYPE) ? 0 : 1;
static inline void
-swapfunc(a, b, n, swaptype)
+swapfunc(a, b, n, swaptype_long, swaptype_int)
char *a, *b;
- int n, swaptype;
+ int n, swaptype_long, swaptype_int;
{
- if(swaptype <= 1)
+ if (swaptype_long <= 1)
swapcode(long, a, b, n)
+ else if (swaptype_int <= 1)
+ swapcode(int, a, b, n)
else
swapcode(char, a, b, n)
}
-#define swap(a, b) \
- if (swaptype == 0) { \
+#define swap(a, b) \
+ if (swaptype_long == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
+ } else if (swaptype_int == 0) { \
+ int t = *(int *)(a); \
+ *(int *)(a) = *(int *)(b); \
+ *(int *)(b) = t; \
} else \
- swapfunc(a, b, es, swaptype)
+ swapfunc(a, b, es, swaptype_long, swaptype_int)
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+#define vecswap(a, b, n) \
+ 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)))
@@ -98,14 +106,14 @@ __unused
{
return CMP(thunk, a, b) < 0 ?
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
- :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
+ :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
}
#ifdef I_AM_QSORT_R
void
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
#else
-#define thunk NULL
+#define thunk NULL
void
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
#endif
@@ -113,9 +121,10 @@ qsort(void *a, size_t n, size_t es, cmp_t *cmp)
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
size_t d, r;
int cmp_result;
- int swaptype, swap_cnt;
+ int swaptype_long, swaptype_int, swap_cnt;
-loop: SWAPINIT(a, es);
+loop: SWAPINIT(long, a, es);
+ SWAPINIT(int, a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
@@ -175,9 +184,9 @@ loop: SWAPINIT(a, es);
}
pn = (char *)a + n * es;
- r = min(pa - (char *)a, pb - pa);
+ r = MIN(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r);
- r = min(pd - pc, pn - pd - es);
+ r = MIN(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
#ifdef I_AM_QSORT_R
diff --git a/lib/libc/stdlib/quick_exit.3 b/lib/libc/stdlib/quick_exit.3
index f2ea379..7bbd2f3 100644
--- a/lib/libc/stdlib/quick_exit.3
+++ b/lib/libc/stdlib/quick_exit.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 7, 2011
+.Dd December 13, 2014
.Dt QUICK_EXIT 3
.Os
.Sh NAME
@@ -35,7 +35,7 @@
.Sh SYNOPSIS
.In stdlib.h
.Ft _Noreturn void
-.Fn quick_exit "void"
+.Fn quick_exit "int status"
.Sh DESCRIPTION
The
.Fn quick_exit
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3
index dc8e961..254be0a 100644
--- a/lib/libc/stdlib/random.3
+++ b/lib/libc/stdlib/random.3
@@ -54,9 +54,8 @@
.Fn setstate "char *state"
.Sh DESCRIPTION
.Bf -symbolic
-The functions described in this manual page are not cryptographically
-secure.
-Cryptographic applications should use
+The functions described in this manual page are not secure.
+Applications which require unpredictable random numbers should use
.Xr arc4random 3
instead.
.Ef
diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3
new file mode 100644
index 0000000..8e714f4
--- /dev/null
+++ b/lib/libc/stdlib/reallocarray.3
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 1, 2015
+.Dt REALLOCARRAY 3
+.Os
+.Sh NAME
+.Nm reallocarray
+.Nd memory reallocation function
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft void *
+.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size"
+.Sh DESCRIPTION
+The
+.Fn reallocarray
+function is similar to the
+.Fn realloc
+function
+except it operates on
+.Fa nmemb
+members of size
+.Fa size
+and checks for integer overflow in the calculation
+.Fa nmemb
+*
+.Fa size .
+.Sh RETURN VALUES
+The
+.Fn reallocarray
+function returns a pointer to the allocated space; otherwise, a
+.Dv NULL
+pointer is returned and
+.Va errno
+is set to
+.Er ENOMEM .
+.Sh EXAMPLES
+Consider
+.Fn reallocarray
+when there is multiplication in the
+.Fa size
+argument of
+.Fn malloc
+or
+.Fn realloc .
+For example, avoid this common idiom as it may lead to integer overflow:
+.Bd -literal -offset indent
+if ((p = malloc(num * size)) == NULL)
+ err(1, "malloc");
+.Ed
+.Pp
+A drop-in replacement is the
+.Ox
+extension
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((p = reallocarray(NULL, num, size)) == NULL)
+ err(1, "reallocarray");
+.Ed
+.Pp
+When using
+.Fn realloc ,
+be careful to avoid the following idiom:
+.Bd -literal -offset indent
+size += 50;
+if ((p = realloc(p, size)) == NULL)
+ return (NULL);
+.Ed
+.Pp
+Do not adjust the variable describing how much memory has been allocated
+until the allocation has been successful.
+This can cause aberrant program behavior if the incorrect size value is used.
+In most cases, the above sample will also result in a leak of memory.
+As stated earlier, a return value of
+.Dv NULL
+indicates that the old object still remains allocated.
+Better code looks like this:
+.Bd -literal -offset indent
+newsize = size + 50;
+if ((newp = realloc(p, newsize)) == NULL) {
+ free(p);
+ p = NULL;
+ size = 0;
+ return (NULL);
+}
+p = newp;
+size = newsize;
+.Ed
+.Pp
+As with
+.Fn malloc ,
+it is important to ensure the new size value will not overflow;
+i.e. avoid allocations like the following:
+.Bd -literal -offset indent
+if ((newp = realloc(p, num * size)) == NULL) {
+ ...
+.Ed
+.Pp
+Instead, use
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((newp = reallocarray(p, num, size)) == NULL) {
+ ...
+.Ed
+.Sh SEE ALSO
+.Xr realloc 3
+.Sh HISTORY
+The
+.Fn reallocarray
+function first appeared in
+.Ox 5.6
+and
+.Fx 11.0 .
diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c
new file mode 100644
index 0000000..e1e9b7c
--- /dev/null
+++ b/lib/libc/stdlib/reallocarray.c
@@ -0,0 +1,42 @@
+/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ return (realloc(optr, size * nmemb));
+}
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c
index e018e6f..bd9ea5a 100644
--- a/lib/libc/stdlib/system.c
+++ b/lib/libc/stdlib/system.c
@@ -46,8 +46,17 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
+#pragma weak system
int
-__system(const char *command)
+system(const char *command)
+{
+
+ return (((int (*)(const char *))
+ __libc_interposing[INTERPOS_system])(command));
+}
+
+int
+__libc_system(const char *command)
{
pid_t pid, savedpid;
int pstat;
@@ -95,5 +104,5 @@ __system(const char *command)
return(pid == -1 ? -1 : pstat);
}
-__weak_reference(__system, system);
-__weak_reference(__system, _system);
+__weak_reference(__libc_system, __system);
+__weak_reference(__libc_system, _system);
diff --git a/lib/libc/stdlib/tdelete.c b/lib/libc/stdlib/tdelete.c
index c83afb8..bef187e 100644
--- a/lib/libc/stdlib/tdelete.c
+++ b/lib/libc/stdlib/tdelete.c
@@ -14,7 +14,7 @@
#include <sys/cdefs.h>
#if 0
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $");
+__RCSID("$NetBSD: tdelete.c,v 1.6 2012/06/25 22:32:45 abs Exp $");
#endif /* LIBC_SCCS and not lint */
#endif
__FBSDID("$FreeBSD$");
@@ -25,9 +25,9 @@ __FBSDID("$FreeBSD$");
/*
- * delete node with given key
+ * find a node with given key
*
- * vkey: key to be deleted
+ * vkey: key to be found
* vrootp: address of the root of the tree
* compar: function to carry out node comparisons
*/
@@ -65,7 +65,8 @@ tdelete(const void * __restrict vkey, void ** __restrict vrootp,
q->rlink = (*rootp)->rlink;
}
}
- free(*rootp); /* D4: Free node */
+ if (p != *rootp)
+ free(*rootp); /* D4: Free node */
*rootp = q; /* link parent to new node */
return p;
}
OpenPOWER on IntegriCloud