summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib')
-rw-r--r--src/lib/libc/stdlib/Makefile.inc33
-rw-r--r--src/lib/libc/stdlib/_rand48.c4
-rw-r--r--src/lib/libc/stdlib/a64l.3122
-rw-r--r--src/lib/libc/stdlib/a64l.c28
-rw-r--r--src/lib/libc/stdlib/abort.39
-rw-r--r--src/lib/libc/stdlib/abort.c16
-rw-r--r--src/lib/libc/stdlib/abs.33
-rw-r--r--src/lib/libc/stdlib/abs.c3
-rw-r--r--src/lib/libc/stdlib/alloca.36
-rw-r--r--src/lib/libc/stdlib/atexit.33
-rw-r--r--src/lib/libc/stdlib/atexit.c3
-rw-r--r--src/lib/libc/stdlib/atexit.h3
-rw-r--r--src/lib/libc/stdlib/atof.33
-rw-r--r--src/lib/libc/stdlib/atof.c3
-rw-r--r--src/lib/libc/stdlib/atoi.310
-rw-r--r--src/lib/libc/stdlib/atoi.c3
-rw-r--r--src/lib/libc/stdlib/atol.33
-rw-r--r--src/lib/libc/stdlib/atol.c3
-rw-r--r--src/lib/libc/stdlib/bsearch.313
-rw-r--r--src/lib/libc/stdlib/bsearch.c3
-rw-r--r--src/lib/libc/stdlib/calloc.35
-rw-r--r--src/lib/libc/stdlib/calloc.c6
-rw-r--r--src/lib/libc/stdlib/cfree.c49
-rw-r--r--src/lib/libc/stdlib/div.33
-rw-r--r--src/lib/libc/stdlib/div.c3
-rw-r--r--src/lib/libc/stdlib/drand48.c4
-rw-r--r--src/lib/libc/stdlib/erand48.c4
-rw-r--r--src/lib/libc/stdlib/exit.33
-rw-r--r--src/lib/libc/stdlib/exit.c3
-rw-r--r--src/lib/libc/stdlib/free.382
-rw-r--r--src/lib/libc/stdlib/getenv.313
-rw-r--r--src/lib/libc/stdlib/getenv.c65
-rw-r--r--src/lib/libc/stdlib/getopt.319
-rw-r--r--src/lib/libc/stdlib/getopt.c3
-rw-r--r--src/lib/libc/stdlib/getsubopt.3148
-rw-r--r--src/lib/libc/stdlib/getsubopt.c106
-rw-r--r--src/lib/libc/stdlib/heapsort.c3
-rw-r--r--src/lib/libc/stdlib/jrand48.c4
-rw-r--r--src/lib/libc/stdlib/l64a.c15
-rw-r--r--src/lib/libc/stdlib/labs.33
-rw-r--r--src/lib/libc/stdlib/labs.c3
-rw-r--r--src/lib/libc/stdlib/lcong48.c4
-rw-r--r--src/lib/libc/stdlib/ldiv.33
-rw-r--r--src/lib/libc/stdlib/ldiv.c3
-rw-r--r--src/lib/libc/stdlib/lrand48.c4
-rw-r--r--src/lib/libc/stdlib/malloc.3297
-rw-r--r--src/lib/libc/stdlib/malloc.c1529
-rw-r--r--src/lib/libc/stdlib/memory.33
-rw-r--r--src/lib/libc/stdlib/merge.c7
-rw-r--r--src/lib/libc/stdlib/mrand48.c4
-rw-r--r--src/lib/libc/stdlib/multibyte.c3
-rw-r--r--src/lib/libc/stdlib/nrand48.c4
-rw-r--r--src/lib/libc/stdlib/putenv.c19
-rw-r--r--src/lib/libc/stdlib/qabs.33
-rw-r--r--src/lib/libc/stdlib/qabs.c3
-rw-r--r--src/lib/libc/stdlib/qdiv.33
-rw-r--r--src/lib/libc/stdlib/qdiv.c3
-rw-r--r--src/lib/libc/stdlib/qsort.33
-rw-r--r--src/lib/libc/stdlib/qsort.c34
-rw-r--r--src/lib/libc/stdlib/radixsort.310
-rw-r--r--src/lib/libc/stdlib/radixsort.c7
-rw-r--r--src/lib/libc/stdlib/rand.38
-rw-r--r--src/lib/libc/stdlib/rand.c3
-rw-r--r--src/lib/libc/stdlib/rand48.33
-rw-r--r--src/lib/libc/stdlib/rand48.h2
-rw-r--r--src/lib/libc/stdlib/random.326
-rw-r--r--src/lib/libc/stdlib/random.c48
-rw-r--r--src/lib/libc/stdlib/realloc.3100
-rw-r--r--src/lib/libc/stdlib/realpath.35
-rw-r--r--src/lib/libc/stdlib/realpath.c10
-rw-r--r--src/lib/libc/stdlib/seed48.c4
-rw-r--r--src/lib/libc/stdlib/setenv.c8
-rw-r--r--src/lib/libc/stdlib/srand48.c4
-rw-r--r--src/lib/libc/stdlib/strtod.33
-rw-r--r--src/lib/libc/stdlib/strtod.c236
-rw-r--r--src/lib/libc/stdlib/strtol.37
-rw-r--r--src/lib/libc/stdlib/strtol.c70
-rw-r--r--src/lib/libc/stdlib/strtoq.c60
-rw-r--r--src/lib/libc/stdlib/strtoul.33
-rw-r--r--src/lib/libc/stdlib/strtoul.c44
-rw-r--r--src/lib/libc/stdlib/strtouq.c36
-rw-r--r--src/lib/libc/stdlib/system.311
-rw-r--r--src/lib/libc/stdlib/system.c7
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3116
-rw-r--r--src/lib/libc/stdlib/tsearch.c126
86 files changed, 2745 insertions, 1000 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index 782a4ab022..e75fc0d8bf 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,24 +1,28 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
3 2
4# stdlib sources 3# stdlib sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib 4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
6 5
7SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \
8 exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ 7 cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c l64a.c \
9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ 8 malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c rand.c \
10 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ 9 random.c realpath.c setenv.c strtod.c strtol.c strtoq.c strtoul.c \
10 strtouq.c system.c tfind.c tsearch.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13 13
14.if (${MACHINE_ARCH} == "m68k") 14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c 15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
16.elif (${MACHINE_ARCH} == "i386") 17.elif (${MACHINE_ARCH} == "i386")
17SRCS+= abs.S div.S labs.S ldiv.S 18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
18.elif (${MACHINE_ARCH} == "ns32k") 20.elif (${MACHINE_ARCH} == "ns32k")
19SRCS+= abs.S div.c labs.c ldiv.c 21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
20.elif (${MACHINE_ARCH} == "tahoe") 23.elif (${MACHINE_ARCH} == "tahoe")
21SRCS+= abs.S div.c labs.c ldiv.c 24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
22.elif (${MACHINE_ARCH} == "vax") 26.elif (${MACHINE_ARCH} == "vax")
23SRCS+= abs.c div.c labs.c ldiv.c 27SRCS+= abs.c div.c labs.c ldiv.c
24.elif (${MACHINE_ARCH} == "alpha") 28.elif (${MACHINE_ARCH} == "alpha")
@@ -28,18 +32,23 @@ SRCS+= abs.c div.c labs.c ldiv.c
28SRCS+= abs.c div.c labs.c ldiv.c 32SRCS+= abs.c div.c labs.c ldiv.c
29.endif 33.endif
30 34
31MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
32 calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ 36 calloc.3 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \
33 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ 37 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
34 rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ 38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
35 system.3
36 39
37MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
41MLINKS+=malloc.3 free.3 malloc.3 realloc.3
42MLINKS+=malloc.3 cfree.3
38MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 43MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
39MLINKS+=rand.3 srand.3 44MLINKS+=rand.3 srand.3
40MLINKS+=strtol.3 strtoq.3
41MLINKS+=strtoul.3 strtouq.3
42MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 45MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3
43MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 46MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
44MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 47MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
45MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 48MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
49MLINKS+=strtol.3 strtoq.3
50MLINKS+=strtoul.3 strtouq.3
51MLINKS+=tsearch.3 tfind.3
52MLINKS+=tsearch.3 tdelete.3
53MLINKS+=tsearch.3 twalk.3
54MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
index 83ade4645a..fed7372f68 100644
--- a/src/lib/libc/stdlib/_rand48.c
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: _rand48.c,v 1.2 1996/08/19 08:33:19 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16unsigned short __rand48_seed[3] = { 20unsigned short __rand48_seed[3] = {
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..4ec707adf1
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,122 @@
1.\"
2.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may not be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26.\"
27.\" $OpenBSD: a64l.3,v 1.2 1998/06/21 22:13:48 millert Exp $
28.\"
29.Dd August 17, 1997
30.Dt A64L 3
31.Os
32.Sh NAME
33.Nm a64l ,
34.Nm l64a
35.Nd convert between 32-bit integer and radix-64 ASCII string
36.Sh SYNOPSIS
37.Fd #include <stdlib.h>
38.Ft long
39.Fn a64l "const char *s"
40.Ft char *
41.Fn l64a "long l"
42.Sh DESCRIPTION
43The
44.Fn a64l
45and
46.Fn l64a
47functions are used to maintain numbers stored in radix-64
48ASCII characters. This is a notation by which 32-bit integers
49can be represented by up to six characters; each character
50represents a "digit" in a radix-64 notation.
51.Pp
52The characters used to represent "digits" are '.' for 0, '/' for 1,
53'0' through '9' for 2-11, 'A' through 'Z' for 12-37, and 'a' through
54'z' for 38-63.
55.Pp
56The
57.Fn a64l
58function takes a pointer to a null-terminated radix-64 representation
59and returns a corresponding 32-bit value. If the string pointed to by
60.Ar s
61contains more than six characters,
62.Fn a64l
63will use the first six.
64.Fn A64l
65scans the character string from left to right, decoding
66each character as a 6-bit radix-64 number. If a long integer is
67larger than 32 bits, the return value will be sign-extended.
68.Pp
69.Fn l64a
70takes a long integer argument
71.Ar l
72and returns a pointer to the corresponding radix-64 representation.
73.Sh RETURN VALUES
74On success,
75.Fn a64l
76returns a 32-bit representation of
77.Ar s .
78If
79.Ar s
80is a NULL pointer or if it contains "digits" other than those described above,
81.Fn a64l
82returns -1L and sets the global variable errno to
83.Va EINVAL .
84.Pp
85On success,
86.Fn l64a
87returns a pointer to a string containing the radix-64 representation of
88.Ar l .
89If
90.Ar l
91is 0,
92.Fn l64a
93returns a pointer to the empty string.
94If
95.Ar l
96is negative,
97.Fn l64a
98returns a NULL pointer and sets the global variable errno to
99.Va EINVAL .
100.Sh WARNINGS
101The value returned by
102.Fn l64a
103is a pointer into a static buffer, the contents of which
104will be overwritten by subsequent calls.
105.Pp
106The value returned by
107.Fn a64l
108may be incorrect if the value is too large; for that reason, only strings
109that resulted from a call to
110.Fn l64a
111should be used to call
112.Fn a64l .
113.Pp
114If a long integer is larger than 32 bits, only the low-order
11532 bits are used.
116.Sh STANDARDS
117The
118.Fn a64l
119and
120.Fn l64a
121functions conform to
122.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
index 03fc77e034..a68f0a6dcd 100644
--- a/src/lib/libc/stdlib/a64l.c
+++ b/src/lib/libc/stdlib/a64l.c
@@ -4,8 +4,11 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; 7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
9 12
10long 13long
11a64l(s) 14a64l(s)
@@ -14,21 +17,30 @@ a64l(s)
14 long value, digit, shift; 17 long value, digit, shift;
15 int i; 18 int i;
16 19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
17 value = 0; 25 value = 0;
18 shift = 0; 26 shift = 0;
19 for (i = 0; *s && i < 6; i++, s++) { 27 for (i = 0; *s && i < 6; i++, s++) {
20 if (*s <= '/') 28 if (*s >= '.' && *s <= '/')
21 digit = *s - '.'; 29 digit = *s - '.';
22 else if (*s <= '9') 30 else if (*s >= '0' && *s <= '9')
23 digit = *s - '0' + 2; 31 digit = *s - '0' + 2;
24 else if (*s <= 'Z') 32 else if (*s >= 'A' && *s <= 'Z')
25 digit = *s - 'A' + 12; 33 digit = *s - 'A' + 12;
26 else 34 else if (*s >= 'a' && *s <= 'z')
27 digit = *s - 'a' + 38; 35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
28 40
29 value |= digit << shift; 41 value |= digit << shift;
30 shift += 6; 42 shift += 6;
31 } 43 }
32 44
33 return (long) value; 45 return(value);
34} 46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
index ab57327585..92c9a354d0 100644
--- a/src/lib/libc/stdlib/abort.3
+++ b/src/lib/libc/stdlib/abort.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)abort.3 6.7 (Berkeley) 6/29/91 36.\" $OpenBSD: abort.3,v 1.4 1997/07/17 07:39:41 deraadt Exp $
37.\" $Id: abort.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt ABORT 3 39.Dt ABORT 3
@@ -54,7 +53,7 @@ signal
54.Dv SIGABRT 53.Dv SIGABRT
55is being caught and the signal handler does not return. 54is being caught and the signal handler does not return.
56.Pp 55.Pp
57No open streams are closed or flushed. 56Any open streams are flushed and closed.
58.Sh RETURN VALUES 57.Sh RETURN VALUES
59The 58The
60.Nm abort 59.Nm abort
@@ -62,10 +61,10 @@ function
62never returns. 61never returns.
63.Sh SEE ALSO 62.Sh SEE ALSO
64.Xr sigaction 2 , 63.Xr sigaction 2 ,
65.Xr exit 2 64.Xr exit 3
66.Sh STANDARDS 65.Sh STANDARDS
67The 66The
68.Fn abort 67.Fn abort
69function 68function
70conforms to 69conforms to
71.St -ansiC . 70.St -p1003.1-90 .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
index c298e016b4..4ea8a2ca4b 100644
--- a/src/lib/libc/stdlib/abort.c
+++ b/src/lib/libc/stdlib/abort.c
@@ -32,19 +32,22 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: abort.c,v 1.5 1997/06/22 20:21:25 tholo Exp $";
36static char *rcsid = "$Id: abort.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <signal.h> 38#include <signal.h>
40#include <stdlib.h> 39#include <stdlib.h>
41#include <unistd.h> 40#include <unistd.h>
42 41
42void (*__cleanup)();
43
43void 44void
44abort() 45abort()
45{ 46{
47 static int cleanup_called = 0;
46 sigset_t mask; 48 sigset_t mask;
47 49
50
48 sigfillset(&mask); 51 sigfillset(&mask);
49 /* 52 /*
50 * don't block SIGABRT to give any handler a chance; we ignore 53 * don't block SIGABRT to give any handler a chance; we ignore
@@ -52,6 +55,15 @@ abort()
52 */ 55 */
53 sigdelset(&mask, SIGABRT); 56 sigdelset(&mask, SIGABRT);
54 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 57 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
58
59 /*
60 * POSIX requires we flush stdio buffers on abort
61 */
62 if (cleanup_called == 0 && __cleanup != NULL) {
63 cleanup_called = 1;
64 (*__cleanup)();
65 }
66
55 (void)kill(getpid(), SIGABRT); 67 (void)kill(getpid(), SIGABRT);
56 68
57 /* 69 /*
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
index 4748d89e77..77f82b9402 100644
--- a/src/lib/libc/stdlib/abs.3
+++ b/src/lib/libc/stdlib/abs.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)abs.3 6.4 (Berkeley) 6/29/91 36.\" $OpenBSD: abs.3,v 1.2 1996/08/19 08:33:21 tholo Exp $
37.\" $Id: abs.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt ABS 3 39.Dt ABS 3
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
index 64468e0224..7c79e4073c 100644
--- a/src/lib/libc/stdlib/abs.c
+++ b/src/lib/libc/stdlib/abs.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abs.c 5.2 (Berkeley) 5/17/90";*/ 35static char *rcsid = "$OpenBSD: abs.c,v 1.2 1996/08/19 08:33:21 tholo Exp $";
36static char *rcsid = "$Id: abs.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
index dcb97ab11c..ef87220772 100644
--- a/src/lib/libc/stdlib/alloca.3
+++ b/src/lib/libc/stdlib/alloca.3
@@ -29,8 +29,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" from: @(#)alloca.3 5.1 (Berkeley) 5/2/91 32.\" $OpenBSD: alloca.3,v 1.3 1996/08/19 08:33:22 tholo Exp $
33.\" $Id: alloca.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
34.\" 33.\"
35.Dd May 2, 1991 34.Dd May 2, 1991
36.Dt ALLOCA 3 35.Dt ALLOCA 3
@@ -55,9 +54,6 @@ return.
55The 54The
56.Fn alloca 55.Fn alloca
57function returns a pointer to the beginning of the allocated space. 56function returns a pointer to the beginning of the allocated space.
58If the allocation failed, a
59.Dv NULL
60pointer is returned.
61.Sh SEE ALSO 57.Sh SEE ALSO
62.Xr brk 2 , 58.Xr brk 2 ,
63.Xr pagesize 2 59.Xr pagesize 2
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
index 07de054d3c..0b10f010fa 100644
--- a/src/lib/libc/stdlib/atexit.3
+++ b/src/lib/libc/stdlib/atexit.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)atexit.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: atexit.3,v 1.2 1996/08/19 08:33:22 tholo Exp $
37.\" $Id: atexit.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt ATEXIT 3 39.Dt ATEXIT 3
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 4da1eb0d9c..c0fb624141 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)atexit.c 5.2 (Berkeley) 11/14/90";*/ 38static char *rcsid = "$OpenBSD: atexit.c,v 1.2 1996/08/19 08:33:22 tholo Exp $";
39static char *rcsid = "$Id: atexit.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <stdlib.h> 41#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
index 8b756e8fe2..e41a7cb86c 100644
--- a/src/lib/libc/stdlib/atexit.h
+++ b/src/lib/libc/stdlib/atexit.h
@@ -30,8 +30,7 @@
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 * 32 *
33 * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90 33 * $OpenBSD: atexit.h,v 1.2 1996/08/19 08:33:23 tholo Exp $
34 * $Id: atexit.h,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
35 */ 34 */
36 35
37/* must be at least 32 to guarantee ANSI conformance */ 36/* must be at least 32 to guarantee ANSI conformance */
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
index 53e04f71c5..cc1b500b0f 100644
--- a/src/lib/libc/stdlib/atof.3
+++ b/src/lib/libc/stdlib/atof.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)atof.3 6.4 (Berkeley) 6/29/91 36.\" $OpenBSD: atof.3,v 1.2 1996/08/19 08:33:23 tholo Exp $
37.\" $Id: atof.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt ATOF 3 39.Dt ATOF 3
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
index 9202de50bb..30bac19899 100644
--- a/src/lib/libc/stdlib/atof.c
+++ b/src/lib/libc/stdlib/atof.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/ 35static char *rcsid = "$OpenBSD: atof.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36static char *rcsid = "$Id: atof.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
index 219ba73c00..280a989e8e 100644
--- a/src/lib/libc/stdlib/atoi.3
+++ b/src/lib/libc/stdlib/atoi.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -33,10 +33,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)atoi.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: atoi.3,v 1.2 1996/08/10 04:51:31 tholo Exp $
37.\" $Id: atoi.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 4, 1993
40.Dt ATOI 3 39.Dt ATOI 3
41.Os 40.Os
42.Sh NAME 41.Sh NAME
@@ -58,7 +57,6 @@ to
58representation. 57representation.
59.Pp 58.Pp
60It is equivalent to: 59It is equivalent to:
61.Pp
62.Bd -literal -offset indent 60.Bd -literal -offset indent
63(int)strtol(nptr, (char **)NULL, 10); 61(int)strtol(nptr, (char **)NULL, 10);
64.Ed 62.Ed
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
index df7845f90c..a74d6e1351 100644
--- a/src/lib/libc/stdlib/atoi.c
+++ b/src/lib/libc/stdlib/atoi.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atoi.c 5.7 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: atoi.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36static char *rcsid = "$Id: atoi.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
index 86e3d324a3..2b49bd1f2c 100644
--- a/src/lib/libc/stdlib/atol.3
+++ b/src/lib/libc/stdlib/atol.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)atol.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: atol.3,v 1.2 1996/08/19 08:33:25 tholo Exp $
37.\" $Id: atol.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt ATOL 3 39.Dt ATOL 3
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
index 31ed06298b..528a932214 100644
--- a/src/lib/libc/stdlib/atol.c
+++ b/src/lib/libc/stdlib/atol.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atol.c 5.7 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: atol.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36static char *rcsid = "$Id: atol.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 1622c96c6b..570a4227b4 100644
--- a/src/lib/libc/stdlib/bsearch.3
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -33,10 +33,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)bsearch.3 5.6 (Berkeley) 6/29/91 36.\" $OpenBSD: bsearch.3,v 1.3 1997/06/13 23:41:35 deraadt Exp $
37.\" $Id: bsearch.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd April 19, 1994
40.Dt BSEARCH 3 39.Dt BSEARCH 3
41.Os 40.Os
42.Sh NAME 41.Sh NAME
@@ -65,7 +64,7 @@ to the comparison function referenced by
65The 64The
66.Fa compar 65.Fa compar
67routine 66routine
68is expected to have two 67is expected to have
69two arguments which point to the 68two arguments which point to the
70.Fa key 69.Fa key
71object and to an array member, in that order, and should return an integer 70object and to an array member, in that order, and should return an integer
@@ -83,7 +82,7 @@ If two members compare as equal, which member is matched is unspecified.
83.Xr db 3 , 82.Xr db 3 ,
84.Xr lsearch 3 , 83.Xr lsearch 3 ,
85.Xr qsort 3 , 84.Xr qsort 3 ,
86.\" .Xr tsearch 3 85.Xr tsearch 3
87.Sh STANDARDS 86.Sh STANDARDS
88The 87The
89.Fn bsearch 88.Fn bsearch
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
index fac03f694f..eeef9bffc6 100644
--- a/src/lib/libc/stdlib/bsearch.c
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bsearch.c 5.4 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: bsearch.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/calloc.3
index d0754b46a0..13a912169c 100644
--- a/src/lib/libc/stdlib/calloc.3
+++ b/src/lib/libc/stdlib/calloc.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)calloc.3 5.2 (Berkeley) 6/29/91 36.\" $OpenBSD: calloc.3,v 1.3 1996/12/10 09:06:10 deraadt Exp $
37.\" $Id: calloc.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt CALLOC 3 39.Dt CALLOC 3
@@ -58,7 +57,7 @@ The space is initialized to all bits zero.
58The 57The
59.Fn calloc 58.Fn calloc
60function returns 59function returns
61a pointer to the 60a pointer to
62the allocated space if successful; otherwise a null pointer is returned. 61the allocated space if successful; otherwise a null pointer is returned.
63.Sh SEE ALSO 62.Sh SEE ALSO
64.Xr malloc 3 , 63.Xr malloc 3 ,
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
index 3353fab052..a2c4f84493 100644
--- a/src/lib/libc/stdlib/calloc.c
+++ b/src/lib/libc/stdlib/calloc.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)calloc.c 5.6 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: calloc.c,v 1.3 1996/08/20 17:42:33 downsj Exp $";
36static char *rcsid = "$Id: calloc.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
@@ -47,7 +46,8 @@ calloc(num, size)
47 register void *p; 46 register void *p;
48 47
49 size *= num; 48 size *= num;
50 if (p = malloc(size)) 49 p = malloc(size);
50 if (p)
51 memset(p, '\0', size); 51 memset(p, '\0', size);
52 return(p); 52 return(p);
53} 53}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..3af32039a9
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $ */
2
3/*
4 * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by SigmaSoft, Th. Lockert.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char rcsid[] = "$OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/cdefs.h>
38
39#ifdef __indr_reference
40__indr_reference(free, cfree);
41#else
42
43void
44cfree(p)
45 void *p;
46{
47 free(p);
48}
49#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
index a4730694a5..0d8c56d86b 100644
--- a/src/lib/libc/stdlib/div.3
+++ b/src/lib/libc/stdlib/div.3
@@ -31,8 +31,7 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 32.\" SUCH DAMAGE.
33.\" 33.\"
34.\" from: @(#)div.3 5.2 (Berkeley) 4/19/91 34.\" $OpenBSD: div.3,v 1.2 1996/08/19 08:33:28 tholo Exp $
35.\" $Id: div.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
36.\" 35.\"
37.Dd April 19, 1991 36.Dd April 19, 1991
38.Dt DIV 3 37.Dt DIV 3
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
index 122ac0deec..c1fae29008 100644
--- a/src/lib/libc/stdlib/div.c
+++ b/src/lib/libc/stdlib/div.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)div.c 5.2 (Berkeley) 4/16/91";*/ 38static char *rcsid = "$OpenBSD: div.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
39static char *rcsid = "$Id: div.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <stdlib.h> /* div_t */ 41#include <stdlib.h> /* div_t */
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
index ae1a8634dc..02886d5b62 100644
--- a/src/lib/libc/stdlib/drand48.c
+++ b/src/lib/libc/stdlib/drand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: drand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
index cc9fbf770c..b92dacffcc 100644
--- a/src/lib/libc/stdlib/erand48.c
+++ b/src/lib/libc/stdlib/erand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: erand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16double 20double
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
index adb81ffcb4..6dd2affef9 100644
--- a/src/lib/libc/stdlib/exit.3
+++ b/src/lib/libc/stdlib/exit.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)exit.3 6.6 (Berkeley) 6/29/91 36.\" $OpenBSD: exit.3,v 1.2 1996/08/19 08:33:30 tholo Exp $
37.\" $Id: exit.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt EXIT 3 39.Dt EXIT 3
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
index b1412f42bb..e358c94fd6 100644
--- a/src/lib/libc/stdlib/exit.c
+++ b/src/lib/libc/stdlib/exit.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: exit.c,v 1.2 1996/08/19 08:33:30 tholo Exp $";
36static char *rcsid = "$Id: exit.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/free.3 b/src/lib/libc/stdlib/free.3
deleted file mode 100644
index 3d0131d7de..0000000000
--- a/src/lib/libc/stdlib/free.3
+++ /dev/null
@@ -1,82 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" from: @(#)free.3 5.2 (Berkeley) 6/29/91
37.\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\"
39.Dd June 29, 1991
40.Dt FREE 3
41.Os
42.Sh NAME
43.Nm free
44.Nd free up memory allocated with malloc, calloc or realloc
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn free "void *ptr"
49.Sh DESCRIPTION
50The
51.Fn free
52function causes the space pointed to by
53.Fa ptr
54to be deallocated, that is, made available
55for further allocation.
56If
57.Fa ptr
58is a null pointer, no action occurs.
59Otherwise, if the argument does not match a pointer earlier
60returned by the
61.Xr calloc ,
62.Xr malloc ,
63or
64.Xr realloc
65function, or if the space has been deallocated by a call to
66.Fn free
67or
68.Xr realloc ,
69general havoc may occur.
70.Sh RETURN VALUES
71The
72.Fn free
73function returns no value.
74.Sh SEE ALSO
75.Xr calloc 3 ,
76.Xr malloc 3 ,
77.Xr realloc 3
78.Sh STANDARDS
79The
80.Fn free
81function conforms to
82.St -ansiC .
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
index 411eb35da4..24a8d3d095 100644
--- a/src/lib/libc/stdlib/getenv.3
+++ b/src/lib/libc/stdlib/getenv.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1988, 1991 The Regents of the University of California. 1.\" Copyright (c) 1988, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -33,10 +33,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)getenv.3 6.11 (Berkeley) 6/29/91 36.\" $OpenBSD: getenv.3,v 1.2 1996/08/10 05:03:00 tholo Exp $
37.\" $Id: getenv.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd December 11, 1993
40.Dt GETENV 3 39.Dt GETENV 3
41.Os 40.Os
42.Sh NAME 41.Sh NAME
@@ -75,7 +74,7 @@ function obtains the current value of the environment variable,
75.Ar name . 74.Ar name .
76If the variable 75If the variable
77.Ar name 76.Ar name
78is not in the current environment , 77is not in the current environment,
79a null pointer is returned. 78a null pointer is returned.
80.Pp 79.Pp
81The 80The
@@ -121,7 +120,7 @@ return zero if successful; otherwise the global variable
121is set to indicate the error and a 120is set to indicate the error and a
122\-1 is returned. 121\-1 is returned.
123.Sh ERRORS 122.Sh ERRORS
124.Bl -tag -width Er 123.Bl -tag -width [ENOMEM]
125.It Bq Er ENOMEM 124.It Bq Er ENOMEM
126The function 125The function
127.Fn setenv 126.Fn setenv
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 09d47f2149..4db86df915 100644
--- a/src/lib/libc/stdlib/getenv.c
+++ b/src/lib/libc/stdlib/getenv.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 1987 Regents of the University of California. 2 * Copyright (c) 1987, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -32,28 +32,13 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)getenv.c 5.8 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: getenv.c,v 1.4 1998/07/16 18:02:33 deraadt Exp $";
36static char *rcsid = "$Id: getenv.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
40#include <string.h> 39#include <string.h>
41 40
42/* 41/*
43 * getenv --
44 * Returns ptr to value associated with name, if any, else NULL.
45 */
46char *
47getenv(name)
48 const char *name;
49{
50 int offset;
51 char *__findenv();
52
53 return(__findenv(name, &offset));
54}
55
56/*
57 * __findenv -- 42 * __findenv --
58 * Returns pointer to value associated with name, if any, else NULL. 43 * Returns pointer to value associated with name, if any, else NULL.
59 * Sets offset to be the offset of the name/value combination in the 44 * Sets offset to be the offset of the name/value combination in the
@@ -64,19 +49,41 @@ getenv(name)
64 */ 49 */
65char * 50char *
66__findenv(name, offset) 51__findenv(name, offset)
67 register char *name; 52 register const char *name;
68 int *offset; 53 int *offset;
69{ 54{
70 extern char **environ; 55 extern char **environ;
71 register int len; 56 register int len, i;
72 register char **P, *C; 57 register const char *np;
58 register char **p, *cp;
73 59
74 for (C = name, len = 0; *C && *C != '='; ++C, ++len); 60 if (name == NULL || environ == NULL)
75 for (P = environ; *P; ++P) 61 return (NULL);
76 if (!strncmp(*P, name, len)) 62 for (np = name; *np && *np != '='; ++np)
77 if (*(C = *P + len) == '=') { 63 ;
78 *offset = P - environ; 64 len = np - name;
79 return(++C); 65 for (p = environ; (cp = *p) != NULL; ++p) {
80 } 66 for (np = name, i = len; i && *cp; i--)
81 return(NULL); 67 if (*cp++ != *np++)
68 break;
69 if (i == 0 && *cp++ == '=') {
70 *offset = p - environ;
71 return (cp);
72 }
73 }
74 return (NULL);
75}
76
77/*
78 * getenv --
79 * Returns ptr to value associated with name, if any, else NULL.
80 */
81char *
82getenv(name)
83 const char *name;
84{
85 int offset;
86 char *__findenv();
87
88 return(__findenv(name, &offset));
82} 89}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
index f843881afd..4340ff54fd 100644
--- a/src/lib/libc/stdlib/getopt.3
+++ b/src/lib/libc/stdlib/getopt.3
@@ -29,7 +29,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" @(#)getopt.3 8.4 (Berkeley) 4/19/94 32.\" $OpenBSD: getopt.3,v 1.6 1998/05/05 19:36:03 deraadt Exp $
33.\" 33.\"
34.Dd April 19, 1994 34.Dd April 19, 1994
35.Dt GETOPT 3 35.Dt GETOPT 3
@@ -137,12 +137,12 @@ returns \-1.
137If the 137If the
138.Fn getopt 138.Fn getopt
139function encounters a character not found in the string 139function encounters a character not found in the string
140.Va optarg 140.Va optstring
141or detects 141or detects
142a missing option argument it writes an error message and returns 142a missing option argument it writes an error message to
143.Ql ? 143.Em stderr
144to the 144and returns
145.Em stderr . 145.Ql ? .
146Setting 146Setting
147.Va opterr 147.Va opterr
148to a zero will disable these error messages. 148to a zero will disable these error messages.
@@ -174,8 +174,8 @@ extern int optind;
174int bflag, ch, fd; 174int bflag, ch, fd;
175 175
176bflag = 0; 176bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) 177while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch(ch) { 178 switch (ch) {
179 case 'b': 179 case 'b':
180 bflag = 1; 180 bflag = 1;
181 break; 181 break;
@@ -189,6 +189,7 @@ while ((ch = getopt(argc, argv, "bf:")) != -1)
189 case '?': 189 case '?':
190 default: 190 default:
191 usage(); 191 usage();
192 }
192} 193}
193argc -= optind; 194argc -= optind;
194argv += optind; 195argv += optind;
@@ -213,7 +214,7 @@ from
213.Pp 214.Pp
214A single dash 215A single dash
215.Dq Li - 216.Dq Li -
216may be specified as an character in 217may be specified as a character in
217.Fa optstring , 218.Fa optstring ,
218however it should 219however it should
219.Em never 220.Em never
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
index 63c5e6a479..b7f6163662 100644
--- a/src/lib/libc/stdlib/getopt.c
+++ b/src/lib/libc/stdlib/getopt.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */ 35static char *rcsid = "$OpenBSD: getopt.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
36static char *rcsid = "$Id: getopt.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdio.h> 38#include <stdio.h>
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..8acc91bdd1
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,148 @@
1.\" $OpenBSD: getsubopt.3,v 1.2 1998/06/15 17:55:07 mickey Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt GETSUBOPT 3
38.Os
39.Sh NAME
40.Nm getsubopt
41.Nd get sub options from an argument
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Vt extern char *suboptarg
45.Ft int
46.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
47.Sh DESCRIPTION
48The
49.Fn getsubopt
50function
51parses a string containing tokens delimited by one or more tab, space or
52comma
53.Pq Ql \&,
54characters.
55It is intended for use in parsing groups of option arguments provided
56as part of a utility command line.
57.Pp
58The argument
59.Fa optionp
60is a pointer to a pointer to the string.
61The argument
62.Fa tokens
63is a pointer to a
64.Dv NULL Ns -terminated
65array of pointers to strings.
66.Pp
67The
68.Fn getsubopt
69function
70returns the zero-based offset of the pointer in the
71.Fa tokens
72array referencing a string which matches the first token
73in the string, or, \-1 if the string contains no tokens or
74.Fa tokens
75does not contain a matching string.
76.Pp
77If the token is of the form ``name=value'', the location referenced by
78.Fa valuep
79will be set to point to the start of the ``value'' portion of the token.
80.Pp
81On return from
82.Fn getsubopt ,
83.Fa optionp
84will be set to point to the start of the next token in the string,
85or the null at the end of the string if no more tokens are present.
86The external variable
87.Fa suboptarg
88will be set to point to the start of the current token, or
89.Dv NULL
90if no
91tokens were present.
92The argument
93.Fa valuep
94will be set to point to the ``value'' portion of the token, or
95.Dv NULL
96if no ``value'' portion was present.
97.Sh EXAMPLE
98.Bd -literal -compact
99char *tokens[] = {
100 #define ONE 0
101 "one",
102 #define TWO 1
103 "two",
104 NULL
105};
106
107\&...
108
109extern char *optarg, *suboptarg;
110char *options, *value;
111
112while ((ch = getopt(argc, argv, "ab:")) != \-1) {
113 switch(ch) {
114 case 'a':
115 /* process ``a'' option */
116 break;
117 case 'b':
118 options = optarg;
119 while (*options) {
120 switch(getsubopt(&options, tokens, &value)) {
121 case ONE:
122 /* process ``one'' sub option */
123 break;
124 case TWO:
125 /* process ``two'' sub option */
126 if (!value)
127 error("no value for two");
128 i = atoi(value);
129 break;
130 case \-1:
131 if (suboptarg)
132 error("illegal sub option %s",
133 suboptarg);
134 else
135 error("missing sub option");
136 break;
137 }
138 break;
139 }
140.Ed
141.Sh SEE ALSO
142.Xr getopt 3 ,
143.Xr strsep 3
144.Sh HISTORY
145The
146.Fn getsubopt
147function first appeared in
148.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/getsubopt.c b/src/lib/libc/stdlib/getsubopt.c
new file mode 100644
index 0000000000..1667a31d7d
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $";
41#endif
42#endif /* not lint */
43
44#include <unistd.h>
45#include <stdlib.h>
46#include <string.h>
47
48/*
49 * The SVID interface to getsubopt provides no way of figuring out which
50 * part of the suboptions list wasn't matched. This makes error messages
51 * tricky... The extern variable suboptarg is a pointer to the token
52 * which didn't match.
53 */
54char *suboptarg;
55
56int
57getsubopt(optionp, tokens, valuep)
58 register char **optionp, **valuep;
59 register char * const *tokens;
60{
61 register int cnt;
62 register char *p;
63
64 suboptarg = *valuep = NULL;
65
66 if (!optionp || !*optionp)
67 return(-1);
68
69 /* skip leading white-space, commas */
70 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
71
72 if (!*p) {
73 *optionp = p;
74 return(-1);
75 }
76
77 /* save the start of the token, and skip the rest of the token. */
78 for (suboptarg = p;
79 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
80
81 if (*p) {
82 /*
83 * If there's an equals sign, set the value pointer, and
84 * skip over the value part of the token. Terminate the
85 * token.
86 */
87 if (*p == '=') {
88 *p = '\0';
89 for (*valuep = ++p;
90 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
91 if (*p)
92 *p++ = '\0';
93 } else
94 *p++ = '\0';
95 /* Skip any whitespace or commas after this token. */
96 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
97 }
98
99 /* set optionp for next round. */
100 *optionp = p;
101
102 for (cnt = 0; *tokens; ++tokens, ++cnt)
103 if (!strcmp(suboptarg, *tokens))
104 return(cnt);
105 return(-1);
106}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
index bd998fa357..e3e4392e05 100644
--- a/src/lib/libc/stdlib/heapsort.c
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";*/ 38static char *rcsid = "$OpenBSD: heapsort.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
39static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <sys/types.h> 41#include <sys/types.h>
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
index 205781e0ee..99cddb71e5 100644
--- a/src/lib/libc/stdlib/jrand48.c
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: jrand48.c,v 1.2 1996/08/19 08:33:33 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
index 3069b31bf6..4e99391254 100644
--- a/src/lib/libc/stdlib/l64a.c
+++ b/src/lib/libc/stdlib/l64a.c
@@ -4,13 +4,14 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: l64a.c,v 1.4 1995/05/11 23:04:52 jtc Exp $"; 7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9 9
10#include <errno.h>
10#include <stdlib.h> 11#include <stdlib.h>
11 12
12char * 13char *
13l64a (value) 14l64a(value)
14 long value; 15 long value;
15{ 16{
16 static char buf[8]; 17 static char buf[8];
@@ -18,8 +19,10 @@ l64a (value)
18 int digit; 19 int digit;
19 int i; 20 int i;
20 21
21 if (!value) 22 if (value < 0) {
22 return NULL; 23 errno = EINVAL;
24 return(NULL);
25 }
23 26
24 for (i = 0; value != 0 && i < 6; i++) { 27 for (i = 0; value != 0 && i < 6; i++) {
25 digit = value & 0x3f; 28 digit = value & 0x3f;
@@ -39,5 +42,5 @@ l64a (value)
39 42
40 *s = '\0'; 43 *s = '\0';
41 44
42 return buf; 45 return(buf);
43} 46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
index 28e4d2053c..05eae329df 100644
--- a/src/lib/libc/stdlib/labs.3
+++ b/src/lib/libc/stdlib/labs.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: labs.3,v 1.2 1996/08/19 08:33:34 tholo Exp $
37.\" $Id: labs.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt LABS 3 39.Dt LABS 3
diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c
index ccf1415792..f20e2c29be 100644
--- a/src/lib/libc/stdlib/labs.c
+++ b/src/lib/libc/stdlib/labs.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 35static char *rcsid = "$OpenBSD: labs.c,v 1.2 1996/08/19 08:33:34 tholo Exp $";
36static char *rcsid = "$Id: labs.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
index 965d46b17a..44bd74e48a 100644
--- a/src/lib/libc/stdlib/lcong48.c
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lcong48.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
index a7b5ccf878..8757f4ddd5 100644
--- a/src/lib/libc/stdlib/ldiv.3
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: ldiv.3,v 1.2 1996/08/19 08:33:35 tholo Exp $
37.\" $Id: ldiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt LDIV 3 39.Dt LDIV 3
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
index f7074507e5..908c2bf0aa 100644
--- a/src/lib/libc/stdlib/ldiv.c
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 38static char *rcsid = "$OpenBSD: ldiv.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
39static char *rcsid = "$Id: ldiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <stdlib.h> /* ldiv_t */ 41#include <stdlib.h> /* ldiv_t */
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
index 8e7f26237f..6b7524a51b 100644
--- a/src/lib/libc/stdlib/lrand48.c
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lrand48.c,v 1.2 1996/08/19 08:33:36 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index 3bbf2bf65e..d5f8837ec2 100644
--- a/src/lib/libc/stdlib/malloc.3
+++ b/src/lib/libc/stdlib/malloc.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California. 1.\" Copyright (c) 1980, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -33,19 +33,33 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)malloc.3 6.7 (Berkeley) 6/29/91 36.\" $OpenBSD: malloc.3,v 1.9 1998/08/15 20:32:02 deraadt Exp $
37.\" $Id: malloc.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd August 27, 1996
40.Dt MALLOC 3 39.Dt MALLOC 3
41.Os BSD 4 40.Os OpenBSD
42.Sh NAME 41.Sh NAME
43.Nm malloc 42.Nm malloc ,
44.Nd general memory allocation function 43.Nd general memory allocation function
44.Pp
45.Nm free ,
46.Nm cfree
47.Nd free up memory allocated with malloc, calloc or realloc
48.Pp
49.Nm realloc
50.Nd reallocation of memory function
45.Sh SYNOPSIS 51.Sh SYNOPSIS
46.Fd #include <stdlib.h> 52.Fd #include <stdlib.h>
47.Ft void * 53.Ft void *
48.Fn malloc "size_t size" 54.Fn malloc "size_t size"
55.Ft void
56.Fn free "void *ptr"
57.Ft void
58.Fn cfree "void *ptr"
59.Ft void *
60.Fn realloc "void *ptr" "size_t size"
61.Ft char *
62.Va malloc_options
49.Sh DESCRIPTION 63.Sh DESCRIPTION
50The 64The
51.Fn malloc 65.Fn malloc
@@ -62,30 +76,275 @@ suitably aligned (after possible pointer
62coercion) for storage of any type of object. If the space is of 76coercion) for storage of any type of object. If the space is of
63.Em pagesize 77.Em pagesize
64or larger, the memory returned will be page-aligned. 78or larger, the memory returned will be page-aligned.
79.Pp
80Allocation of a zero size object returns a pointer to a zero size object.
81.Pp
82The
83.Fn free
84function causes the space pointed to by
85.Fa ptr
86to be deallocated, that is, at least made available for further allocation,
87but if possible, it will passed back to the kernel with
88.Xr sbrk 2 .
89If
90.Fa ptr
91is a null pointer, no action occurs.
92.Pp
93A
94.Fn cfree
95function is also provided for compatibility with old systems and other
96.Nm malloc
97libraries; it is simply an alias for
98.Fn free .
99.Pp
100The
101.Fn realloc
102function changes the size of the object pointed to by
103.Fa ptr
104to the size specified by
105.Fa size .
106The contents of the object are unchanged up to the lesser
107of the new and old sizes.
108If the new size is larger, the value of the newly allocated portion
109of the object is indeterminate and uninitialized.
110If
111.Fa ptr
112is a null pointer, the
113.Fn realloc
114function behaves like the
115.Fn malloc
116function for the specified size.
117If the space cannot be allocated, the object
118pointed to by
119.Fa ptr
120is unchanged.
121If
122.Fa size
123is zero and
124.Fa ptr
125is not a null pointer, the object it points to is freed and a new zero size
126object is returned.
127.Pp
128When using
129.Fn realloc
130one must be careful to avoid the following idiom:
131.Pp
132.Bd -literal -offset indent
133if ((p = realloc(p, nsize)) == NULL)
134 return NULL;
135.Ed
136.Pp
137In most cases, this will result in a leak of memory.
138As stated earlier, a return value of
139.Fa NULL
140indicates that the old object still remains allocated.
141Better code looks like this:
142.Bd -literal -offset indent
143if ((p2 = realloc(p, nsize)) == NULL) {
144 if (p)
145 free(p);
146 p = NULL;
147 return NULL;
148}
149p = p2;
150.Ed
151.Pp
152Malloc will first look for a symbolic link called
153.Pa /etc/malloc.conf
154and next check the environment for a variable called
155.Ev MALLOC_OPTIONS
156and finally for the global variable
157.Va malloc_options
158and scan them for flags in that order.
159Flags are single letters, uppercase means on, lowercase means off.
160.Bl -tag -width indent
161.It A
162``abort'' malloc will coredump the process, rather than tolerate failure.
163This is a very handy debugging aid, since the core file will represent the
164time of failure,
165rather than when the NULL pointer was accessed.
166
167.It D
168``dump'' malloc will dump statistics in a file called ``malloc.out'' at exit.
169This option requires the library to have been compiled with -DMALLOC_STATS in
170order to have any effect.
171
172.It J
173``junk'' fill some junk into the area allocated.
174Currently junk is bytes of 0xd0, this is pronounced ``Duh'' :-)
175
176.It H
177``hint'' pass a hint to the kernel about pages we don't use. If the
178machine is paging a lot this may help a bit.
179
180.It N
181Do not output warning messages when encountering possible corruption
182or bad pointers.
183
184.It R
185``realloc'' always reallocate when
186.Fn realloc
187is called, even if the initial allocation was big enough.
188This can substantially aid in compacting memory.
189
190.It U
191``utrace'' generate entries for
192.Xr ktrace 1
193for all operations.
194Consult the source for this one.
195
196.It X
197``xmalloc''
198rather than return failure,
199.Xr abort 3
200the program with a diagnostic message on stderr.
201It is the intention that this option be set at compile time by
202including in the source:
203.Bd -literal -offset indent
204extern char *malloc_options;
205malloc_options = "X";
206.Ed
207
208.It Z
209``zero'' fill some junk into the area allocated (see ``J''),
210except for the exact length the user asked for, which is zeroed.
211
212.It <
213``Half the cache size'' Reduce the size of the cache by a factor of two.
214
215.It >
216``Double the cache size'' Double the size of the cache by a factor of two.
217.El
218.Pp
219So to set a systemwide reduction of cache size and coredumps on problems
220one would:
221.Li ln -s 'A<' /etc/malloc.conf
222.Pp
223The ``J'' and ``Z'' is mostly for testing and debugging,
224if a program changes behavior if either of these options are used,
225it is buggy.
226.Pp
227The default cache size is 16 pages.
228.Sh ENVIRONMENT
229See above.
65.Sh RETURN VALUES 230.Sh RETURN VALUES
66The 231The
67.Fn malloc 232.Fn malloc
68function returns 233function returns
69a pointer to the allocated space if successful; otherwise 234a pointer to the allocated space if successful; otherwise
70a null pointer is returned. 235a null pointer is returned.
236.Pp
237The
238.Fn free
239function returns no value.
240.Pp
241The
242.Fn realloc
243function a pointer to the possibly moved allocated space;
244otherwise a null pointer is returned.
245.Sh MESSAGES
246If
247.Fn malloc ,
248.Fn free
249or
250.Fn realloc
251detects an error or warning condition,
252a message will be printed to filedescriptor
2532 (not using stdio).
254Errors will always result in the process being
255.Xr abort 2 'ed,
256If the ``A'' option has been specified, also warnings will
257.Xr abort 2
258the process.
259.Pp
260Here is a brief description of the error messages and what they mean:
261.Pp
262``(ES): mumble mumble mumble'':
263malloc have been compiled with -DEXTRA_SANITY and something looks
264fishy in there. Consult sources and or wizards.
265.Pp
266``allocation failed''
267if the ``A'' option is specified it is an error for
268.Fn malloc
269or
270.Fn realloc
271to return NULL.
272.Pp
273``mmap(2) failed, check limits.''
274This is a rather weird condition that is most likely to mean that
275the system is seriously overloaded or that your ulimits are sick.
276.Pp
277``freelist is destroyed.''
278mallocs internal freelist has been stomped on.
279.Pp
280Here is a brief description of the warning messages and what they mean:
281.Pp
282``chunk/page is already free.''
283A pointer to a free chunk is attempted freed again.
284.Pp
285``junk pointer, too high to make sense.''
286The pointer doesn't make sense. It's above the area of memory that
287malloc knows something about.
288This could be a pointer from some
289.Xr mmap 2 'ed
290memory.
291.Pp
292``junk pointer, too low to make sense.''
293The pointer doesn't make sense. It's below the area of memory that
294malloc knows something about.
295This pointer probably came from your data or bss segments.
296.Pp
297``malloc() has never been called.''
298Nothing has ever been allocated, yet something is being freed or
299realloc'ed.
300.Pp
301``modified (chunk-/page-) pointer.''
302The pointer passed to free or realloc has been modified.
303.Pp
304``pointer to wrong page.''
305The pointer that malloc is trying to free is not pointing to
306a sensible page.
307.Pp
308``recursive call.''
309You have tried to call recursively into these functions.
310I can only imagine this as happening if you call one of these
311functions from a signal function, which happens to be called
312while you're already in here.
313Well, sorry to say: that's not supported.
314If this is a problem for you I'd like to hear about it. It
315would be possible to add a sigblock() around this package,
316but it would have a performance penalty that is not acceptable
317as the default.
318.Pp
319``unknown char in MALLOC_OPTIONS''
320we found something we didn't understand.
71.Sh SEE ALSO 321.Sh SEE ALSO
72.Xr brk 2 , 322.Xr brk 2 ,
73.Xr getpagesize 2 ,
74.Xr free 3 ,
75.Xr calloc 3 ,
76.Xr alloca 3 , 323.Xr alloca 3 ,
77.Xr realloc 3 , 324.Xr calloc 3 ,
325.Xr getpagesize 3 ,
78.Xr memory 3 326.Xr memory 3
327.Pa /usr/share/doc/papers/malloc.ascii.gz
79.Sh STANDARDS 328.Sh STANDARDS
80The 329The
81.Fn malloc 330.Fn malloc
82function conforms to 331function conforms to
83.St -ansiC . 332.St -ansiC .
84.Sh BUGS 333.Sh HISTORY
85The current implementation of 334The present implementation of malloc started out as a filesystem on a drum
86.Xr malloc 335attached to a 20bit binary challenged computer built with discrete germanium
87does not always fail gracefully when system 336transistors, and it has since graduated to handle primary storage rather than
88memory limits are approached. 337secondary.
89It may fail to allocate memory when larger free blocks could be broken 338.Pp
90up, or when limits are exceeded because the size is rounded up. 339The main difference from other malloc implementations are believed to be that
91It is optimized for sizes that are powers of two. 340the free pages are not accessed until allocated.
341Most malloc implementations will store a data structure containing a,
342possibly double-, linked list in the free chunks of memory, used to tie
343all the free memory together.
344That is a quite suboptimal thing to do.
345Every time the free-list is traversed, all the otherwise unused, and very
346likely paged out, pages get faulted into primary memory, just to see what
347lies after them in the list.
348.Pp
349On systems which are paging, this can make a factor five in difference on the
350page-faults of a process.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 3c57fad024..d1d8759791 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,421 +1,1242 @@
1/* 1/*
2 * Copyright (c) 1983 Regents of the University of California. 2 * ----------------------------------------------------------------------------
3 * All rights reserved. 3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * Redistribution and use in source and binary forms, with or without 5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * modification, are permitted provided that the following conditions 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * are met: 7 * ----------------------------------------------------------------------------
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */ 8 */
33 9
34#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.32 1998/08/06 16:26:32 millert Exp $";
36static char *rcsid = "$Id: malloc.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
38 13
39/* 14/*
40 * malloc.c (Caltech) 2/21/82 15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
41 * Chris Kingsley, kingsley@cit-20. 16 * related to internal conditions and consistency in malloc.c. This has
42 * 17 * a noticeable runtime performance hit, and generally will not do you
43 * This is a very fast storage allocator. It allocates blocks of a small 18 * any good unless you fiddle with the internals of malloc or want
44 * number of different sizes, and keeps free lists of each size. Blocks that 19 * to catch random pointer corruption as early as possible.
45 * don't exactly fit are passed up to the next larger size. In this
46 * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
47 * This is designed for use in a virtual memory environment.
48 */ 20 */
21#ifndef MALLOC_EXTRA_SANITY
22#undef MALLOC_EXTRA_SANITY
23#endif
49 24
50#include <sys/types.h> 25/*
26 * Defining MALLOC_STATS will enable you to call malloc_dump() and set
27 * the [dD] options in the MALLOC_OPTIONS environment variable.
28 * It has no run-time performance hit, but does pull in stdio...
29 */
30#ifndef MALLOC_STATS
31#undef MALLOC_STATS
32#endif
33
34/*
35 * What to use for Junk. This is the byte value we use to fill with
36 * when the 'J' option is enabled.
37 */
38#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
39
40#include <stdio.h>
51#include <stdlib.h> 41#include <stdlib.h>
52#include <string.h> 42#include <string.h>
53#include <unistd.h> 43#include <unistd.h>
44#include <fcntl.h>
45#include <errno.h>
46#include <sys/types.h>
47#include <sys/param.h>
48#include <sys/mman.h>
49
50/*
51 * The basic parameters you can tweak.
52 *
53 * malloc_pageshift pagesize = 1 << malloc_pageshift
54 * It's probably best if this is the native
55 * page size, but it shouldn't have to be.
56 *
57 * malloc_minsize minimum size of an allocation in bytes.
58 * If this is too small it's too much work
59 * to manage them. This is also the smallest
60 * unit of alignment used for the storage
61 * returned by malloc/realloc.
62 *
63 */
64
65#if defined(__i386__) && defined(__FreeBSD__)
66# define malloc_pageshift 12U
67# define malloc_minsize 16U
68#endif /* __i386__ && __FreeBSD__ */
54 69
55#define NULL 0 70#if defined(__sparc__) && !defined(__OpenBSD__)
71# define malloc_pageshirt 12U
72# define malloc_minsize 16U
73# define MAP_ANON (0)
74# define USE_DEV_ZERO
75# define MADV_FREE MADV_DONTNEED
76#endif /* __sparc__ */
56 77
57static void morecore(); 78/* Insert your combination here... */
58static int findbucket(); 79#if defined(__FOOCPU__) && defined(__BAROS__)
80# define malloc_pageshift 12U
81# define malloc_minsize 16U
82#endif /* __FOOCPU__ && __BAROS__ */
83
84#if defined(__OpenBSD__) && !defined(__sparc__)
85# define malloc_pageshift (PGSHIFT)
86# define malloc_minsize 16U
87#endif /* __OpenBSD__ */
88
89#ifdef _THREAD_SAFE
90#include <pthread.h>
91static pthread_mutex_t malloc_lock;
92#define THREAD_LOCK() pthread_mutex_lock(&malloc_lock)
93#define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock)
94#define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0);
95#else
96#define THREAD_LOCK()
97#define THREAD_UNLOCK()
98#define THREAD_LOCK_INIT()
99#endif
59 100
60/* 101/*
61 * The overhead on a block is at least 4 bytes. When free, this space 102 * No user serviceable parts behind this point.
62 * contains a pointer to the next free block, and the bottom two bits must 103 *
63 * be zero. When in use, the first byte is set to MAGIC, and the second 104 * This structure describes a page worth of chunks.
64 * byte is the size index. The remaining bytes are for alignment.
65 * If range checking is enabled then a second word holds the size of the
66 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
67 * The order of elements is critical: ov_magic must overlay the low order
68 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
69 */ 105 */
70union overhead { 106
71 union overhead *ov_next; /* when free */ 107struct pginfo {
72 struct { 108 struct pginfo *next; /* next on the free list */
73 u_char ovu_magic; /* magic number */ 109 void *page; /* Pointer to the page */
74 u_char ovu_index; /* bucket # */ 110 u_short size; /* size of this page's chunks */
75#ifdef RCHECK 111 u_short shift; /* How far to shift for this size chunks */
76 u_short ovu_rmagic; /* range magic number */ 112 u_short free; /* How many free chunks */
77 u_long ovu_size; /* actual block size */ 113 u_short total; /* How many chunk */
78#endif 114 u_long bits[1]; /* Which chunks are free */
79 } ovu; 115};
80#define ov_magic ovu.ovu_magic 116
81#define ov_index ovu.ovu_index 117/*
82#define ov_rmagic ovu.ovu_rmagic 118 * This structure describes a number of free pages.
83#define ov_size ovu.ovu_size 119 */
120
121struct pgfree {
122 struct pgfree *next; /* next run of free pages */
123 struct pgfree *prev; /* prev run of free pages */
124 void *page; /* pointer to free pages */
125 void *end; /* pointer to end of free pages */
126 u_long size; /* number of bytes free */
84}; 127};
85 128
86#define MAGIC 0xef /* magic # on accounting info */ 129/*
87#define RMAGIC 0x5555 /* magic # on range info */ 130 * How many bits per u_long in the bitmap.
131 * Change only if not 8 bits/byte
132 */
133#define MALLOC_BITS (8*sizeof(u_long))
134
135/*
136 * Magic values to put in the page_directory
137 */
138#define MALLOC_NOT_MINE ((struct pginfo*) 0)
139#define MALLOC_FREE ((struct pginfo*) 1)
140#define MALLOC_FIRST ((struct pginfo*) 2)
141#define MALLOC_FOLLOW ((struct pginfo*) 3)
142#define MALLOC_MAGIC ((struct pginfo*) 4)
143
144#ifndef malloc_pageshift
145#define malloc_pageshift 12U
146#endif
147
148#ifndef malloc_minsize
149#define malloc_minsize 16U
150#endif
151
152#ifndef malloc_pageshift
153#error "malloc_pageshift undefined"
154#endif
155
156#if !defined(malloc_pagesize)
157#define malloc_pagesize (1UL<<malloc_pageshift)
158#endif
159
160#if ((1UL<<malloc_pageshift) != malloc_pagesize)
161#error "(1UL<<malloc_pageshift) != malloc_pagesize"
162#endif
163
164#ifndef malloc_maxsize
165#define malloc_maxsize ((malloc_pagesize)>>1)
166#endif
167
168/* A mask for the offset inside a page. */
169#define malloc_pagemask ((malloc_pagesize)-1)
170
171#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
172#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
88 173
89#ifdef RCHECK 174/* fd of /dev/zero */
90#define RSLOP sizeof (u_short) 175#ifdef USE_DEV_ZERO
176static int fdzero;
177#define MMAP_FD fdzero
178#define INIT_MMAP() \
179 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
180 wrterror("open of /dev/zero"); }
91#else 181#else
92#define RSLOP 0 182#define MMAP_FD (-1)
183#define INIT_MMAP()
93#endif 184#endif
94 185
186/* Set when initialization has been done */
187static unsigned malloc_started;
188
189/* Number of free pages we cache */
190static unsigned malloc_cache = 16;
191
192/* The offset from pagenumber to index into the page directory */
193static u_long malloc_origo;
194
195/* The last index in the page directory we care about */
196static u_long last_index;
197
198/* Pointer to page directory. Allocated "as if with" malloc */
199static struct pginfo **page_dir;
200
201/* How many slots in the page directory */
202static size_t malloc_ninfo;
203
204/* Free pages line up here */
205static struct pgfree free_list;
206
207/* Abort(), user doesn't handle problems. */
208static int malloc_abort;
209
210/* Are we trying to die ? */
211static int suicide;
212
213#ifdef MALLOC_STATS
214/* dump statistics */
215static int malloc_stats;
216#endif
217
218/* avoid outputting warnings? */
219static int malloc_silent;
220
221/* always realloc ? */
222static int malloc_realloc;
223
224#ifdef __FreeBSD__
225/* pass the kernel a hint on free pages ? */
226static int malloc_hint;
227#endif
228
229/* xmalloc behaviour ? */
230static int malloc_xmalloc;
231
232/* zero fill ? */
233static int malloc_zero;
234
235/* junk fill ? */
236static int malloc_junk;
237
238#ifdef __FreeBSD__
239/* utrace ? */
240static int malloc_utrace;
241
242struct ut { void *p; size_t s; void *r; };
243
244void utrace __P((struct ut *, int));
245
246#define UTRACE(a, b, c) \
247 if (malloc_utrace) \
248 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
249#else /* !__FreeBSD__ */
250#define UTRACE(a,b,c)
251#endif
252
253/* my last break. */
254static void *malloc_brk;
255
256/* one location cache for free-list holders */
257static struct pgfree *px;
258
259/* compile-time options */
260char *malloc_options;
261
262/* Name of the current public function */
263static char *malloc_func;
264
265/* Macro for mmap */
266#define MMAP(size) \
267 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
268 MMAP_FD, (off_t)0);
269
95/* 270/*
96 * nextf[i] is the pointer to the next free block of size 2^(i+3). The 271 * Necessary function declarations
97 * smallest allocatable block is 8 bytes. The overhead information
98 * precedes the data area returned to the user.
99 */ 272 */
100#define NBUCKETS 30 273static int extend_pgdir(u_long index);
101static union overhead *nextf[NBUCKETS]; 274static void *imalloc(size_t size);
102extern char *sbrk(); 275static void ifree(void *ptr);
276static void *irealloc(void *ptr, size_t size);
277static void *malloc_bytes(size_t size);
278
279#ifdef MALLOC_STATS
280void
281malloc_dump(fd)
282 FILE *fd;
283{
284 struct pginfo **pd;
285 struct pgfree *pf;
286 int j;
287
288 pd = page_dir;
289
290 /* print out all the pages */
291 for(j=0;j<=last_index;j++) {
292 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
293 if (pd[j] == MALLOC_NOT_MINE) {
294 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
295 ;
296 j--;
297 fprintf(fd, ".. %5d not mine\n", j);
298 } else if (pd[j] == MALLOC_FREE) {
299 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
300 ;
301 j--;
302 fprintf(fd, ".. %5d free\n", j);
303 } else if (pd[j] == MALLOC_FIRST) {
304 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
305 ;
306 j--;
307 fprintf(fd, ".. %5d in use\n", j);
308 } else if (pd[j] < MALLOC_MAGIC) {
309 fprintf(fd, "(%p)\n", pd[j]);
310 } else {
311 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
312 pd[j], pd[j]->free, pd[j]->total,
313 pd[j]->size, pd[j]->page, pd[j]->next);
314 }
315 }
316
317 for(pf=free_list.next; pf; pf=pf->next) {
318 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
319 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
320 if (pf == pf->next) {
321 fprintf(fd, "Free_list loops.\n");
322 break;
323 }
324 }
325
326 /* print out various info */
327 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
328 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
329 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
330 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
331 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
332 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
333 (last_index + malloc_pageshift) << malloc_pageshift);
334 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
335}
336#endif /* MALLOC_STATS */
337
338extern char *__progname;
339
340static void
341wrterror(p)
342 char *p;
343{
344 char *q = " error: ";
345 write(2, __progname, strlen(__progname));
346 write(2, malloc_func, strlen(malloc_func));
347 write(2, q, strlen(q));
348 write(2, p, strlen(p));
349 suicide = 1;
350#ifdef MALLOC_STATS
351 if (malloc_stats)
352 malloc_dump(stderr);
353#endif /* MALLOC_STATS */
354 abort();
355}
356
357static void
358wrtwarning(p)
359 char *p;
360{
361 char *q = " warning: ";
362 if (malloc_abort)
363 wrterror(p);
364 else if (malloc_silent)
365 return;
366 write(2, __progname, strlen(__progname));
367 write(2, malloc_func, strlen(malloc_func));
368 write(2, q, strlen(q));
369 write(2, p, strlen(p));
370}
371
372#ifdef MALLOC_STATS
373static void
374malloc_exit()
375{
376 FILE *fd = fopen("malloc.out", "a");
377 char *q = "malloc() warning: Couldn't dump stats.\n";
378 if (fd) {
379 malloc_dump(fd);
380 fclose(fd);
381 } else
382 write(2, q, strlen(q));
383}
384#endif /* MALLOC_STATS */
103 385
104static int pagesz; /* page size */
105static int pagebucket; /* page size bucket */
106 386
107#ifdef MSTATS
108/* 387/*
109 * nmalloc[i] is the difference between the number of mallocs and frees 388 * Allocate a number of pages from the OS
110 * for a given block size.
111 */ 389 */
112static u_int nmalloc[NBUCKETS]; 390static void *
113#include <stdio.h> 391map_pages(pages)
114#endif 392 int pages;
393{
394 caddr_t result, tail;
115 395
116#if defined(DEBUG) || defined(RCHECK) 396 result = (caddr_t)pageround((u_long)sbrk(0));
117#define ASSERT(p) if (!(p)) botch("p") 397 tail = result + (pages << malloc_pageshift);
118#include <stdio.h> 398
119static 399 if (brk(tail)) {
120botch(s) 400#ifdef MALLOC_EXTRA_SANITY
121 char *s; 401 wrterror("(ES): map_pages fails\n");
402#endif /* MALLOC_EXTRA_SANITY */
403 return 0;
404 }
405
406 last_index = ptr2index(tail) - 1;
407 malloc_brk = tail;
408
409 if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
410 return 0;
411
412 return result;
413}
414
415/*
416 * Extend page directory
417 */
418static int
419extend_pgdir(index)
420 u_long index;
122{ 421{
123 fprintf(stderr, "\r\nassertion botched: %s\r\n", s); 422 struct pginfo **new, **old;
124 (void) fflush(stderr); /* just in case user buffered it */ 423 size_t i, oldlen;
125 abort(); 424
425 /* Make it this many pages */
426 i = index * sizeof *page_dir;
427 i /= malloc_pagesize;
428 i += 2;
429
430 /* remember the old mapping size */
431 oldlen = malloc_ninfo * sizeof *page_dir;
432
433 /*
434 * NOTE: we allocate new pages and copy the directory rather than tempt
435 * fate by trying to "grow" the region.. There is nothing to prevent
436 * us from accidently re-mapping space that's been allocated by our caller
437 * via dlopen() or other mmap().
438 *
439 * The copy problem is not too bad, as there is 4K of page index per
440 * 4MB of malloc arena.
441 *
442 * We can totally avoid the copy if we open a file descriptor to associate
443 * the anon mappings with. Then, when we remap the pages at the new
444 * address, the old pages will be "magically" remapped.. But this means
445 * keeping open a "secret" file descriptor.....
446 */
447
448 /* Get new pages */
449 new = (struct pginfo**) MMAP(i * malloc_pagesize);
450 if (new == (struct pginfo **)-1)
451 return 0;
452
453 /* Copy the old stuff */
454 memcpy(new, page_dir,
455 malloc_ninfo * sizeof *page_dir);
456
457 /* register the new size */
458 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
459
460 /* swap the pointers */
461 old = page_dir;
462 page_dir = new;
463
464 /* Now free the old stuff */
465 munmap(old, oldlen);
466 return 1;
126} 467}
127#else
128#define ASSERT(p)
129#endif
130 468
131void * 469/*
132malloc(nbytes) 470 * Initialize the world
133 size_t nbytes; 471 */
472static void
473malloc_init ()
134{ 474{
135 register union overhead *op; 475 char *p, b[64];
136 register long bucket, n; 476 int i, j;
137 register unsigned amt; 477 int save_errno = errno;
138 478
139 /* 479 THREAD_LOCK_INIT();
140 * First time malloc is called, setup page size and 480
141 * align break pointer so all data will be page aligned. 481 INIT_MMAP();
142 */ 482
143 if (pagesz == 0) { 483#ifdef MALLOC_EXTRA_SANITY
144 pagesz = n = getpagesize(); 484 malloc_junk = 1;
145 op = (union overhead *)sbrk(0); 485#endif /* MALLOC_EXTRA_SANITY */
146 n = n - sizeof (*op) - ((long)op & (n - 1)); 486
147 if (n < 0) 487 for (i = 0; i < 3; i++) {
148 n += pagesz; 488 if (i == 0) {
149 if (n) { 489 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
150 if (sbrk(n) == (char *)-1) 490 if (j <= 0)
151 return (NULL); 491 continue;
152 } 492 b[j] = '\0';
153 bucket = 0; 493 p = b;
154 amt = 8; 494 } else if (i == 1) {
155 while (pagesz > amt) { 495 if (issetugid() == 0)
156 amt <<= 1; 496 p = getenv("MALLOC_OPTIONS");
157 bucket++; 497 else
158 } 498 continue;
159 pagebucket = bucket; 499 } else if (i == 2) {
500 p = malloc_options;
160 } 501 }
161 /* 502 for (; p && *p; p++) {
162 * Convert amount of memory requested into closest block size 503 switch (*p) {
163 * stored in hash buckets which satisfies request. 504 case '>': malloc_cache <<= 1; break;
164 * Account for space used per block for accounting. 505 case '<': malloc_cache >>= 1; break;
165 */ 506 case 'a': malloc_abort = 0; break;
166 if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { 507 case 'A': malloc_abort = 1; break;
167#ifndef RCHECK 508#ifdef MALLOC_STATS
168 amt = 8; /* size of first bucket */ 509 case 'd': malloc_stats = 0; break;
169 bucket = 0; 510 case 'D': malloc_stats = 1; break;
170#else 511#endif /* MALLOC_STATS */
171 amt = 16; /* size of first bucket */ 512#ifdef __FreeBSD__
172 bucket = 1; 513 case 'h': malloc_hint = 0; break;
173#endif 514 case 'H': malloc_hint = 1; break;
174 n = -((long)sizeof (*op) + RSLOP); 515#endif /* __FreeBSD__ */
175 } else { 516 case 'r': malloc_realloc = 0; break;
176 amt = pagesz; 517 case 'R': malloc_realloc = 1; break;
177 bucket = pagebucket; 518 case 'j': malloc_junk = 0; break;
519 case 'J': malloc_junk = 1; break;
520 case 'n': malloc_silent = 0; break;
521 case 'N': malloc_silent = 1; break;
522#ifdef __FreeBSD__
523 case 'u': malloc_utrace = 0; break;
524 case 'U': malloc_utrace = 1; break;
525#endif /* __FreeBSD__ */
526 case 'x': malloc_xmalloc = 0; break;
527 case 'X': malloc_xmalloc = 1; break;
528 case 'z': malloc_zero = 0; break;
529 case 'Z': malloc_zero = 1; break;
530 default:
531 j = malloc_abort;
532 malloc_abort = 0;
533 wrtwarning("unknown char in MALLOC_OPTIONS\n");
534 malloc_abort = j;
535 break;
536 }
178 } 537 }
179 while (nbytes > amt + n) { 538 }
180 amt <<= 1; 539
181 if (amt == 0) 540 UTRACE(0, 0, 0);
182 return (NULL); 541
183 bucket++; 542 /*
543 * We want junk in the entire allocation, and zero only in the part
544 * the user asked for.
545 */
546 if (malloc_zero)
547 malloc_junk=1;
548
549#ifdef MALLOC_STATS
550 if (malloc_stats)
551 atexit(malloc_exit);
552#endif /* MALLOC_STATS */
553
554 /* Allocate one page for the page directory */
555 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
556
557 if (page_dir == (struct pginfo **) -1)
558 wrterror("mmap(2) failed, check limits.\n");
559
560 /*
561 * We need a maximum of malloc_pageshift buckets, steal these from the
562 * front of the page_directory;
563 */
564 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
565 malloc_origo -= malloc_pageshift;
566
567 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
568
569 /* Been here, done that */
570 malloc_started++;
571
572 /* Recalculate the cache size in bytes, and make sure it's nonzero */
573
574 if (!malloc_cache)
575 malloc_cache++;
576
577 malloc_cache <<= malloc_pageshift;
578
579 /*
580 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
581 * We can sbrk(2) further back when we keep this on a low address.
582 */
583 px = (struct pgfree *) imalloc (sizeof *px);
584 errno = save_errno;
585}
586
587/*
588 * Allocate a number of complete pages
589 */
590static void *
591malloc_pages(size)
592 size_t size;
593{
594 void *p, *delay_free = 0;
595 int i;
596 struct pgfree *pf;
597 u_long index;
598
599 size = pageround(size);
600
601 p = 0;
602 /* Look for free pages before asking for more */
603 for(pf = free_list.next; pf; pf = pf->next) {
604
605#ifdef MALLOC_EXTRA_SANITY
606 if (pf->size & malloc_pagemask)
607 wrterror("(ES): junk length entry on free_list\n");
608 if (!pf->size)
609 wrterror("(ES): zero length entry on free_list\n");
610 if (pf->page == pf->end)
611 wrterror("(ES): zero entry on free_list\n");
612 if (pf->page > pf->end)
613 wrterror("(ES): sick entry on free_list\n");
614 if ((void*)pf->page >= (void*)sbrk(0))
615 wrterror("(ES): entry on free_list past brk\n");
616 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
617 wrterror("(ES): non-free first page on free-list\n");
618 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
619 wrterror("(ES): non-free last page on free-list\n");
620#endif /* MALLOC_EXTRA_SANITY */
621
622 if (pf->size < size)
623 continue;
624
625 if (pf->size == size) {
626 p = pf->page;
627 if (pf->next)
628 pf->next->prev = pf->prev;
629 pf->prev->next = pf->next;
630 delay_free = pf;
631 break;
632 }
633
634 p = pf->page;
635 pf->page = (char *)pf->page + size;
636 pf->size -= size;
637 break;
638 }
639
640#ifdef MALLOC_EXTRA_SANITY
641 if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
642 wrterror("(ES): allocated non-free page on free-list\n");
643#endif /* MALLOC_EXTRA_SANITY */
644
645 size >>= malloc_pageshift;
646
647 /* Map new pages */
648 if (!p)
649 p = map_pages(size);
650
651 if (p) {
652
653 index = ptr2index(p);
654 page_dir[index] = MALLOC_FIRST;
655 for (i=1;i<size;i++)
656 page_dir[index+i] = MALLOC_FOLLOW;
657
658 if (malloc_junk)
659 memset(p, SOME_JUNK, size << malloc_pageshift);
660 }
661
662 if (delay_free) {
663 if (!px)
664 px = delay_free;
665 else
666 ifree(delay_free);
667 }
668
669 return p;
670}
671
672/*
673 * Allocate a page of fragments
674 */
675
676static __inline__ int
677malloc_make_chunks(bits)
678 int bits;
679{
680 struct pginfo *bp;
681 void *pp;
682 int i, k, l;
683
684 /* Allocate a new bucket */
685 pp = malloc_pages((size_t)malloc_pagesize);
686 if (!pp)
687 return 0;
688
689 /* Find length of admin structure */
690 l = sizeof *bp - sizeof(u_long);
691 l += sizeof(u_long) *
692 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
693
694 /* Don't waste more than two chunks on this */
695 if ((1UL<<(bits)) <= l+l) {
696 bp = (struct pginfo *)pp;
697 } else {
698 bp = (struct pginfo *)imalloc(l);
699 if (!bp) {
700 ifree(pp);
701 return 0;
184 } 702 }
185 /* 703 }
186 * If nothing in hash bucket right now, 704
187 * request more memory from the system. 705 bp->size = (1UL<<bits);
188 */ 706 bp->shift = bits;
189 if ((op = nextf[bucket]) == NULL) { 707 bp->total = bp->free = malloc_pagesize >> bits;
190 morecore(bucket); 708 bp->page = pp;
191 if ((op = nextf[bucket]) == NULL) 709
192 return (NULL); 710 /* set all valid bits in the bitmap */
711 k = bp->total;
712 i = 0;
713
714 /* Do a bunch at a time */
715 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
716 bp->bits[i / MALLOC_BITS] = ~0UL;
717
718 for(; i < k; i++)
719 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
720
721 if (bp == bp->page) {
722 /* Mark the ones we stole for ourselves */
723 for(i=0;l > 0;i++) {
724 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
725 bp->free--;
726 bp->total--;
727 l -= (1 << bits);
193 } 728 }
194 /* remove from linked list */ 729 }
195 nextf[bucket] = op->ov_next; 730
196 op->ov_magic = MAGIC; 731 /* MALLOC_LOCK */
197 op->ov_index = bucket; 732
198#ifdef MSTATS 733 page_dir[ptr2index(pp)] = bp;
199 nmalloc[bucket]++; 734
200#endif 735 bp->next = page_dir[bits];
201#ifdef RCHECK 736 page_dir[bits] = bp;
202 /* 737
203 * Record allocated size of block and 738 /* MALLOC_UNLOCK */
204 * bound space with magic numbers. 739
205 */ 740 return 1;
206 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
207 op->ov_rmagic = RMAGIC;
208 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
209#endif
210 return ((char *)(op + 1));
211} 741}
212 742
213/* 743/*
214 * Allocate more memory to the indicated bucket. 744 * Allocate a fragment
215 */ 745 */
216static void 746static void *
217morecore(bucket) 747malloc_bytes(size)
218 int bucket; 748 size_t size;
219{ 749{
220 register union overhead *op; 750 int i,j;
221 register long sz; /* size of desired block */ 751 u_long u;
222 long amt; /* amount to allocate */ 752 struct pginfo *bp;
223 int nblks; /* how many blocks we get */ 753 int k;
754 u_long *lp;
224 755
225 /* 756 /* Don't bother with anything less than this */
226 * sbrk_size <= 0 only for big, FLUFFY, requests (about 757 if (size < malloc_minsize)
227 * 2^30 bytes on a VAX, I think) or for a negative arg. 758 size = malloc_minsize;
228 */ 759
229 sz = 1 << (bucket + 3); 760 /* Find the right bucket */
230#ifdef DEBUG 761 j = 1;
231 ASSERT(sz > 0); 762 i = size-1;
232#else 763 while (i >>= 1)
233 if (sz <= 0) 764 j++;
234 return; 765
235#endif 766 /* If it's empty, make a page more of that size chunks */
236 if (sz < pagesz) { 767 if (!page_dir[j] && !malloc_make_chunks(j))
237 amt = pagesz; 768 return 0;
238 nblks = amt / sz; 769
239 } else { 770 bp = page_dir[j];
240 amt = sz + pagesz; 771
241 nblks = 1; 772 /* Find first word of bitmap which isn't empty */
242 } 773 for (lp = bp->bits; !*lp; lp++)
243 op = (union overhead *)sbrk(amt); 774 ;
244 /* no more room! */ 775
245 if ((long)op == -1) 776 /* Find that bit, and tweak it */
246 return; 777 u = 1;
247 /* 778 k = 0;
248 * Add new memory allocated to that on 779 while (!(*lp & u)) {
249 * free list for this hash bucket. 780 u += u;
250 */ 781 k++;
251 nextf[bucket] = op; 782 }
252 while (--nblks > 0) { 783 *lp ^= u;
253 op->ov_next = (union overhead *)((caddr_t)op + sz); 784
254 op = (union overhead *)((caddr_t)op + sz); 785 /* If there are no more free, remove from free-list */
255 } 786 if (!--bp->free) {
787 page_dir[j] = bp->next;
788 bp->next = 0;
789 }
790
791 /* Adjust to the real offset of that chunk */
792 k += (lp-bp->bits)*MALLOC_BITS;
793 k <<= bp->shift;
794
795 if (malloc_junk)
796 memset((char *)bp->page + k, SOME_JUNK, bp->size);
797
798 return (u_char *)bp->page + k;
256} 799}
257 800
258void 801/*
259free(cp) 802 * Allocate a piece of memory
260 void *cp; 803 */
261{ 804static void *
262 register long size; 805imalloc(size)
263 register union overhead *op; 806 size_t size;
264 807{
265 if (cp == NULL) 808 void *result;
266 return; 809
267 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 810 if (!malloc_started)
268#ifdef DEBUG 811 malloc_init();
269 ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ 812
270#else 813 if (suicide)
271 if (op->ov_magic != MAGIC) 814 abort();
272 return; /* sanity */ 815
273#endif 816 if ((size + malloc_pagesize) < size) /* Check for overflow */
274#ifdef RCHECK 817 result = 0;
275 ASSERT(op->ov_rmagic == RMAGIC); 818 else if (size <= malloc_maxsize)
276 ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); 819 result = malloc_bytes(size);
277#endif 820 else
278 size = op->ov_index; 821 result = malloc_pages(size);
279 ASSERT(size < NBUCKETS); 822
280 op->ov_next = nextf[size]; /* also clobbers ov_magic */ 823 if (malloc_abort && !result)
281 nextf[size] = op; 824 wrterror("allocation failed.\n");
282#ifdef MSTATS 825
283 nmalloc[size]--; 826 if (malloc_zero && result)
284#endif 827 memset(result, 0, size);
828
829 return result;
285} 830}
286 831
287/* 832/*
288 * When a program attempts "storage compaction" as mentioned in the 833 * Change the size of an allocation.
289 * old malloc man page, it realloc's an already freed block. Usually
290 * this is the last block it freed; occasionally it might be farther
291 * back. We have to search all the free lists for the block in order
292 * to determine its bucket: 1st we make one pass thru the lists
293 * checking only the first block in each; if that fails we search
294 * ``realloc_srchlen'' blocks in each list for a match (the variable
295 * is extern so the caller can modify it). If that fails we just copy
296 * however many bytes was given to realloc() and hope it's not huge.
297 */ 834 */
298int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ 835static void *
836irealloc(ptr, size)
837 void *ptr;
838 size_t size;
839{
840 void *p;
841 u_long osize, index;
842 struct pginfo **mp;
843 int i;
299 844
300void * 845 if (suicide)
301realloc(cp, nbytes) 846 abort();
302 void *cp; 847
303 size_t nbytes; 848 if (!malloc_started) {
304{ 849 wrtwarning("malloc() has never been called.\n");
305 register u_long onb; 850 return 0;
306 register long i; 851 }
307 union overhead *op; 852
308 char *res; 853 index = ptr2index(ptr);
309 int was_alloced = 0; 854
310 855 if (index < malloc_pageshift) {
311 if (cp == NULL) 856 wrtwarning("junk pointer, too low to make sense.\n");
312 return (malloc(nbytes)); 857 return 0;
313 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 858 }
314 if (op->ov_magic == MAGIC) { 859
315 was_alloced++; 860 if (index > last_index) {
316 i = op->ov_index; 861 wrtwarning("junk pointer, too high to make sense.\n");
317 } else { 862 return 0;
318 /* 863 }
319 * Already free, doing "compaction". 864
320 * 865 mp = &page_dir[index];
321 * Search for the old block of memory on the 866
322 * free list. First, check the most common 867 if (*mp == MALLOC_FIRST) { /* Page allocation */
323 * case (last element free'd), then (this failing) 868
324 * the last ``realloc_srchlen'' items free'd. 869 /* Check the pointer */
325 * If all lookups fail, then assume the size of 870 if ((u_long)ptr & malloc_pagemask) {
326 * the memory block being realloc'd is the 871 wrtwarning("modified (page-) pointer.\n");
327 * largest possible (so that all "nbytes" of new 872 return 0;
328 * memory are copied into). Note that this could cause 873 }
329 * a memory fault if the old area was tiny, and the moon 874
330 * is gibbous. However, that is very unlikely. 875 /* Find the size in bytes */
331 */ 876 for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
332 if ((i = findbucket(op, 1)) < 0 && 877 osize += malloc_pagesize;
333 (i = findbucket(op, realloc_srchlen)) < 0) 878
334 i = NBUCKETS; 879 if (!malloc_realloc && /* unless we have to, */
880 size <= osize && /* .. or are too small, */
881 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
882 return ptr; /* don't do anything. */
883 }
884
885 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
886
887 /* Check the pointer for sane values */
888 if (((u_long)ptr & ((*mp)->size-1))) {
889 wrtwarning("modified (chunk-) pointer.\n");
890 return 0;
335 } 891 }
336 onb = 1 << (i + 3); 892
337 if (onb < pagesz) 893 /* Find the chunk index in the page */
338 onb -= sizeof (*op) + RSLOP; 894 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
895
896 /* Verify that it isn't a free chunk already */
897 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
898 wrtwarning("chunk is already free.\n");
899 return 0;
900 }
901
902 osize = (*mp)->size;
903
904 if (!malloc_realloc && /* Unless we have to, */
905 size < osize && /* ..or are too small, */
906 (size > osize/2 || /* ..or could use a smaller size, */
907 osize == malloc_minsize)) { /* ..(if there is one) */
908 return ptr; /* ..Don't do anything */
909 }
910
911 } else {
912 wrtwarning("pointer to wrong page.\n");
913 return 0;
914 }
915
916 p = imalloc(size);
917
918 if (p) {
919 /* copy the lesser of the two sizes, and free the old one */
920 if (osize < size)
921 memcpy(p, ptr, osize);
339 else 922 else
340 onb += pagesz - sizeof (*op) - RSLOP; 923 memcpy(p, ptr, size);
341 /* avoid the copy if same size block */ 924 ifree(ptr);
342 if (was_alloced) { 925 }
343 if (i) { 926 return p;
344 i = 1 << (i + 2); 927}
345 if (i < pagesz) 928
346 i -= sizeof (*op) + RSLOP; 929/*
347 else 930 * Free a sequence of pages
348 i += pagesz - sizeof (*op) - RSLOP; 931 */
349 } 932
350 if (nbytes <= onb && nbytes > i) { 933static __inline__ void
351#ifdef RCHECK 934free_pages(ptr, index, info)
352 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 935 void *ptr;
353 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 936 int index;
937 struct pginfo *info;
938{
939 int i;
940 struct pgfree *pf, *pt=0;
941 u_long l;
942 void *tail;
943
944 if (info == MALLOC_FREE) {
945 wrtwarning("page is already free.\n");
946 return;
947 }
948
949 if (info != MALLOC_FIRST) {
950 wrtwarning("pointer to wrong page.\n");
951 return;
952 }
953
954 if ((u_long)ptr & malloc_pagemask) {
955 wrtwarning("modified (page-) pointer.\n");
956 return;
957 }
958
959 /* Count how many pages and mark them free at the same time */
960 page_dir[index] = MALLOC_FREE;
961 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
962 page_dir[index + i] = MALLOC_FREE;
963
964 l = i << malloc_pageshift;
965
966 if (malloc_junk)
967 memset(ptr, SOME_JUNK, l);
968
969#ifdef __FreeBSD__
970 if (malloc_hint)
971 madvise(ptr, l, MADV_FREE);
354#endif 972#endif
355 return(cp); 973
356 } else 974 tail = (char *)ptr+l;
357 free(cp); 975
976 /* add to free-list */
977 if (!px)
978 px = imalloc(sizeof *px); /* This cannot fail... */
979 px->page = ptr;
980 px->end = tail;
981 px->size = l;
982 if (!free_list.next) {
983
984 /* Nothing on free list, put this at head */
985 px->next = free_list.next;
986 px->prev = &free_list;
987 free_list.next = px;
988 pf = px;
989 px = 0;
990
991 } else {
992
993 /* Find the right spot, leave pf pointing to the modified entry. */
994 tail = (char *)ptr+l;
995
996 for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
997 ; /* Race ahead here */
998
999 if (pf->page > tail) {
1000 /* Insert before entry */
1001 px->next = pf;
1002 px->prev = pf->prev;
1003 pf->prev = px;
1004 px->prev->next = px;
1005 pf = px;
1006 px = 0;
1007 } else if (pf->end == ptr ) {
1008 /* Append to the previous entry */
1009 pf->end = (char *)pf->end + l;
1010 pf->size += l;
1011 if (pf->next && pf->end == pf->next->page ) {
1012 /* And collapse the next too. */
1013 pt = pf->next;
1014 pf->end = pt->end;
1015 pf->size += pt->size;
1016 pf->next = pt->next;
1017 if (pf->next)
1018 pf->next->prev = pf;
1019 }
1020 } else if (pf->page == tail) {
1021 /* Prepend to entry */
1022 pf->size += l;
1023 pf->page = ptr;
1024 } else if (!pf->next) {
1025 /* Append at tail of chain */
1026 px->next = 0;
1027 px->prev = pf;
1028 pf->next = px;
1029 pf = px;
1030 px = 0;
1031 } else {
1032 wrterror("freelist is destroyed.\n");
358 } 1033 }
359 if ((res = malloc(nbytes)) == NULL) 1034 }
360 return (NULL); 1035
361 if (cp != res) /* common optimization if "compacting" */ 1036 /* Return something to OS ? */
362 bcopy(cp, res, (nbytes < onb) ? nbytes : onb); 1037 if (!pf->next && /* If we're the last one, */
363 return (res); 1038 pf->size > malloc_cache && /* ..and the cache is full, */
1039 pf->end == malloc_brk && /* ..and none behind us, */
1040 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1041
1042 /*
1043 * Keep the cache intact. Notice that the '>' above guarantees that
1044 * the pf will always have at least one page afterwards.
1045 */
1046 pf->end = (char *)pf->page + malloc_cache;
1047 pf->size = malloc_cache;
1048
1049 brk(pf->end);
1050 malloc_brk = pf->end;
1051
1052 index = ptr2index(pf->end);
1053 last_index = index - 1;
1054
1055 for(i=index;i <= last_index;)
1056 page_dir[i++] = MALLOC_NOT_MINE;
1057
1058 /* XXX: We could realloc/shrink the pagedir here I guess. */
1059 }
1060 if (pt)
1061 ifree(pt);
364} 1062}
365 1063
366/* 1064/*
367 * Search ``srchlen'' elements of each free list for a block whose 1065 * Free a chunk, and possibly the page it's on, if the page becomes empty.
368 * header starts at ``freep''. If srchlen is -1 search the whole list.
369 * Return bucket number, or -1 if not found.
370 */ 1066 */
371static 1067
372findbucket(freep, srchlen) 1068/* ARGSUSED */
373 union overhead *freep; 1069static __inline__ void
374 int srchlen; 1070free_bytes(ptr, index, info)
1071 void *ptr;
1072 int index;
1073 struct pginfo *info;
375{ 1074{
376 register union overhead *p; 1075 int i;
377 register int i, j; 1076 struct pginfo **mp;
378 1077 void *vp;
379 for (i = 0; i < NBUCKETS; i++) { 1078
380 j = 0; 1079 /* Find the chunk number on the page */
381 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { 1080 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
382 if (p == freep) 1081
383 return (i); 1082 if (((u_long)ptr & (info->size-1))) {
384 j++; 1083 wrtwarning("modified (chunk-) pointer.\n");
385 } 1084 return;
386 } 1085 }
387 return (-1); 1086
1087 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
1088 wrtwarning("chunk is already free.\n");
1089 return;
1090 }
1091
1092 if (malloc_junk)
1093 memset(ptr, SOME_JUNK, info->size);
1094
1095 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
1096 info->free++;
1097
1098 mp = page_dir + info->shift;
1099
1100 if (info->free == 1) {
1101
1102 /* Page became non-full */
1103
1104 mp = page_dir + info->shift;
1105 /* Insert in address order */
1106 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
1107 mp = &(*mp)->next;
1108 info->next = *mp;
1109 *mp = info;
1110 return;
1111 }
1112
1113 if (info->free != info->total)
1114 return;
1115
1116 /* Find & remove this page in the queue */
1117 while (*mp != info) {
1118 mp = &((*mp)->next);
1119#ifdef MALLOC_EXTRA_SANITY
1120 if (!*mp)
1121 wrterror("(ES): Not on queue\n");
1122#endif /* MALLOC_EXTRA_SANITY */
1123 }
1124 *mp = info->next;
1125
1126 /* Free the page & the info structure if need be */
1127 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
1128 vp = info->page; /* Order is important ! */
1129 if(vp != (void*)info)
1130 ifree(info);
1131 ifree(vp);
1132}
1133
1134static void
1135ifree(ptr)
1136 void *ptr;
1137{
1138 struct pginfo *info;
1139 int index;
1140
1141 /* This is legal */
1142 if (!ptr)
1143 return;
1144
1145 if (!malloc_started) {
1146 wrtwarning("malloc() has never been called.\n");
1147 return;
1148 }
1149
1150 /* If we're already sinking, don't make matters any worse. */
1151 if (suicide)
1152 return;
1153
1154 index = ptr2index(ptr);
1155
1156 if (index < malloc_pageshift) {
1157 wrtwarning("junk pointer, too low to make sense.\n");
1158 return;
1159 }
1160
1161 if (index > last_index) {
1162 wrtwarning("junk pointer, too high to make sense.\n");
1163 return;
1164 }
1165
1166 info = page_dir[index];
1167
1168 if (info < MALLOC_MAGIC)
1169 free_pages(ptr, index, info);
1170 else
1171 free_bytes(ptr, index, info);
1172 return;
388} 1173}
389 1174
390#ifdef MSTATS
391/* 1175/*
392 * mstats - print out statistics about malloc 1176 * These are the public exported interface routines.
393 *
394 * Prints two lines of numbers, one showing the length of the free list
395 * for each size category, the second showing the number of mallocs -
396 * frees for each size category.
397 */ 1177 */
398mstats(s) 1178
399 char *s; 1179static int malloc_active;
1180
1181void *
1182malloc(size_t size)
1183{
1184 register void *r;
1185
1186 malloc_func = " in malloc():";
1187 THREAD_LOCK();
1188 if (malloc_active++) {
1189 wrtwarning("recursive call.\n");
1190 malloc_active--;
1191 return (0);
1192 }
1193 r = imalloc(size);
1194 UTRACE(0, size, r);
1195 malloc_active--;
1196 THREAD_UNLOCK();
1197 if (malloc_xmalloc && !r)
1198 wrterror("out of memory.\n");
1199 return (r);
1200}
1201
1202void
1203free(void *ptr)
400{ 1204{
401 register int i, j; 1205 malloc_func = " in free():";
402 register union overhead *p; 1206 THREAD_LOCK();
403 int totfree = 0, 1207 if (malloc_active++) {
404 totused = 0; 1208 wrtwarning("recursive call.\n");
405 1209 malloc_active--;
406 fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); 1210 return;
407 for (i = 0; i < NBUCKETS; i++) { 1211 }
408 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) 1212 ifree(ptr);
409 ; 1213 UTRACE(ptr, 0, 0);
410 fprintf(stderr, " %d", j); 1214 malloc_active--;
411 totfree += j * (1 << (i + 3)); 1215 THREAD_UNLOCK();
412 } 1216 return;
413 fprintf(stderr, "\nused:\t"); 1217}
414 for (i = 0; i < NBUCKETS; i++) { 1218
415 fprintf(stderr, " %d", nmalloc[i]); 1219void *
416 totused += nmalloc[i] * (1 << (i + 3)); 1220realloc(void *ptr, size_t size)
417 } 1221{
418 fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", 1222 register void *r;
419 totused, totfree); 1223
1224 malloc_func = " in realloc():";
1225 THREAD_LOCK();
1226 if (malloc_active++) {
1227 wrtwarning("recursive call.\n");
1228 malloc_active--;
1229 return (0);
1230 }
1231 if (!ptr) {
1232 r = imalloc(size);
1233 } else {
1234 r = irealloc(ptr, size);
1235 }
1236 UTRACE(ptr, size, r);
1237 malloc_active--;
1238 THREAD_UNLOCK();
1239 if (malloc_xmalloc && !r)
1240 wrterror("out of memory.\n");
1241 return (r);
420} 1242}
421#endif
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
index 735252c837..712c7c45d2 100644
--- a/src/lib/libc/stdlib/memory.3
+++ b/src/lib/libc/stdlib/memory.3
@@ -29,8 +29,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" from: @(#)memory.3 5.1 (Berkeley) 5/2/91 32.\" $OpenBSD: memory.3,v 1.2 1996/08/19 08:33:37 tholo Exp $
33.\" $Id: memory.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\" 33.\"
35.Dd May 2, 1991 34.Dd May 2, 1991
36.Dt MEMORY 3 35.Dt MEMORY 3
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
index 381fdc0830..0a1015ad9d 100644
--- a/src/lib/libc/stdlib/merge.c
+++ b/src/lib/libc/stdlib/merge.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)merge.c 8.2 (Berkeley) 2/14/94";*/ 38static char *rcsid = "$OpenBSD: merge.c,v 1.3 1996/09/15 09:31:50 tholo Exp $";
39static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42/* 41/*
@@ -148,7 +147,7 @@ mergesort(base, nmemb, size, cmp)
148 sense = 0; 147 sense = 0;
149 } 148 }
150 if (!big) { /* here i = 0 */ 149 if (!big) { /* here i = 0 */
151LINEAR: while ((b += size) < t && cmp(q, b) >sense) 150 while ((b += size) < t && cmp(q, b) >sense)
152 if (++i == 6) { 151 if (++i == 6) {
153 big = 1; 152 big = 1;
154 goto EXPONENTIAL; 153 goto EXPONENTIAL;
@@ -169,7 +168,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1)
169 goto FASTCASE; 168 goto FASTCASE;
170 } else 169 } else
171 b = p; 170 b = p;
172SLOWCASE: while (t > b+size) { 171 while (t > b+size) {
173 i = (((t - b) / size) >> 1) * size; 172 i = (((t - b) / size) >> 1) * size;
174 if ((*cmp)(q, p = b + i) <= sense) 173 if ((*cmp)(q, p = b + i) <= sense)
175 t = p; 174 t = p;
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
index 43356e66b3..cd34260b5c 100644
--- a/src/lib/libc/stdlib/mrand48.c
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: mrand48.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
index fe1cd5781b..12e70c4a2c 100644
--- a/src/lib/libc/stdlib/multibyte.c
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/ 35static char *rcsid = "$OpenBSD: multibyte.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
36static char *rcsid = "$Id: multibyte.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
index 63f839cb05..b1ec2cebb1 100644
--- a/src/lib/libc/stdlib/nrand48.c
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: nrand48.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
index 2194c2c608..d8c4886d4b 100644
--- a/src/lib/libc/stdlib/putenv.c
+++ b/src/lib/libc/stdlib/putenv.c
@@ -1,6 +1,6 @@
1/*- 1/*-
2 * Copyright (c) 1988 The Regents of the University of California. 2 * Copyright (c) 1988, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)putenv.c 5.4 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: putenv.c,v 1.2 1996/08/10 05:03:00 tholo Exp $";
36static char *rcsid = "$Id: putenv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
@@ -43,17 +42,17 @@ int
43putenv(str) 42putenv(str)
44 const char *str; 43 const char *str;
45{ 44{
46 register char *p, *equal; 45 char *p, *equal;
47 int rval; 46 int rval;
48 47
49 if (!(p = strdup(str))) 48 if ((p = strdup(str)) == NULL)
50 return(1); 49 return (-1);
51 if (!(equal = strchr(p, '='))) { 50 if ((equal = strchr(p, '=')) == NULL) {
52 (void)free(p); 51 (void)free(p);
53 return(1); 52 return (-1);
54 } 53 }
55 *equal = '\0'; 54 *equal = '\0';
56 rval = setenv(p, equal + 1, 1); 55 rval = setenv(p, equal + 1, 1);
57 (void)free(p); 56 (void)free(p);
58 return(rval); 57 return (rval);
59} 58}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
index cb1e052191..92a8bdc4b9 100644
--- a/src/lib/libc/stdlib/qabs.3
+++ b/src/lib/libc/stdlib/qabs.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: qabs.3,v 1.2 1996/08/19 08:33:40 tholo Exp $
37.\" $Id: qabs.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt QABS 3 39.Dt QABS 3
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c
index 9c51a8baa9..ccc42cbec6 100644
--- a/src/lib/libc/stdlib/qabs.c
+++ b/src/lib/libc/stdlib/qabs.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 35static char *rcsid = "$OpenBSD: qabs.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
36static char *rcsid = "$Id: qabs.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
index 0efcfc96ef..12aca0b1ea 100644
--- a/src/lib/libc/stdlib/qdiv.3
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: qdiv.3,v 1.2 1996/08/19 08:33:41 tholo Exp $
37.\" $Id: qdiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt QDIV 3 39.Dt QDIV 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
index 8f8e3f89c4..07e84cd649 100644
--- a/src/lib/libc/stdlib/qdiv.c
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 38static char *rcsid = "$OpenBSD: qdiv.c,v 1.2 1996/08/19 08:33:41 tholo Exp $";
39static char *rcsid = "$Id: qdiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <stdlib.h> /* qdiv_t */ 41#include <stdlib.h> /* qdiv_t */
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
index eb122cde12..a65c5819d0 100644
--- a/src/lib/libc/stdlib/qsort.3
+++ b/src/lib/libc/stdlib/qsort.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)qsort.3 8.1 (Berkeley) 6/4/93 36.\" $OpenBSD: qsort.3,v 1.2 1996/08/19 08:33:42 tholo Exp $
37.\" $Id: qsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 37.\"
39.Dd June 4, 1993 38.Dd June 4, 1993
40.Dt QSORT 3 39.Dt QSORT 3
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
index c06bd54054..1c3020b595 100644
--- a/src/lib/libc/stdlib/qsort.c
+++ b/src/lib/libc/stdlib/qsort.c
@@ -32,15 +32,14 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char sccsid[] = "from: @(#)qsort.c 8.1 (Berkeley) 6/4/93";*/ 35static char *rcsid = "$OpenBSD: qsort.c,v 1.5 1997/06/20 11:19:38 deraadt Exp $";
36static char *rcsid = "$Id: qsort.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <sys/types.h> 38#include <sys/types.h>
40#include <stdlib.h> 39#include <stdlib.h>
41 40
42static inline char *med3 __P((char *, char *, char *, int (*)())); 41static __inline char *med3 __P((char *, char *, char *, int (*)()));
43static inline void swapfunc __P((char *, char *, int, int)); 42static __inline void swapfunc __P((char *, char *, int, int));
44 43
45#define min(a, b) (a) < (b) ? a : b 44#define min(a, b) (a) < (b) ? a : b
46 45
@@ -61,12 +60,12 @@ static inline void swapfunc __P((char *, char *, int, int));
61#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 60#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
62 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 61 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
63 62
64static inline void 63static __inline void
65swapfunc(a, b, n, swaptype) 64swapfunc(a, b, n, swaptype)
66 char *a, *b; 65 char *a, *b;
67 int n, swaptype; 66 int n, swaptype;
68{ 67{
69 if(swaptype <= 1) 68 if (swaptype <= 1)
70 swapcode(long, a, b, n) 69 swapcode(long, a, b, n)
71 else 70 else
72 swapcode(char, a, b, n) 71 swapcode(char, a, b, n)
@@ -82,7 +81,7 @@ swapfunc(a, b, n, swaptype)
82 81
83#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) 82#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
84 83
85static inline char * 84static __inline char *
86med3(a, b, c, cmp) 85med3(a, b, c, cmp)
87 char *a, *b, *c; 86 char *a, *b, *c;
88 int (*cmp)(); 87 int (*cmp)();
@@ -93,27 +92,28 @@ med3(a, b, c, cmp)
93} 92}
94 93
95void 94void
96qsort(a, n, es, cmp) 95qsort(aa, n, es, cmp)
97 void *a; 96 void *aa;
98 size_t n, es; 97 size_t n, es;
99 int (*cmp)(); 98 int (*cmp)();
100{ 99{
101 char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 100 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
102 int d, r, swaptype, swap_cnt; 101 int d, r, swaptype, swap_cnt;
102 register char *a = aa;
103 103
104loop: SWAPINIT(a, es); 104loop: SWAPINIT(a, es);
105 swap_cnt = 0; 105 swap_cnt = 0;
106 if (n < 7) { 106 if (n < 7) {
107 for (pm = a + es; pm < (char *) a + n * es; pm += es) 107 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es) 109 pl -= es)
110 swap(pl, pl - es); 110 swap(pl, pl - es);
111 return; 111 return;
112 } 112 }
113 pm = a + (n / 2) * es; 113 pm = (char *)a + (n / 2) * es;
114 if (n > 7) { 114 if (n > 7) {
115 pl = a; 115 pl = (char *)a;
116 pn = a + (n - 1) * es; 116 pn = (char *)a + (n - 1) * es;
117 if (n > 40) { 117 if (n > 40) {
118 d = (n / 8) * es; 118 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp); 119 pl = med3(pl, pl + d, pl + 2 * d, cmp);
@@ -123,9 +123,9 @@ loop: SWAPINIT(a, es);
123 pm = med3(pl, pm, pn, cmp); 123 pm = med3(pl, pm, pn, cmp);
124 } 124 }
125 swap(a, pm); 125 swap(a, pm);
126 pa = pb = a + es; 126 pa = pb = (char *)a + es;
127 127
128 pc = pd = a + (n - 1) * es; 128 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) { 129 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) { 130 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) { 131 if (r == 0) {
@@ -151,14 +151,14 @@ loop: SWAPINIT(a, es);
151 pc -= es; 151 pc -= es;
152 } 152 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */ 153 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = a + es; pm < (char *) a + n * es; pm += es) 154 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es) 156 pl -= es)
157 swap(pl, pl - es); 157 swap(pl, pl - es);
158 return; 158 return;
159 } 159 }
160 160
161 pn = a + n * es; 161 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa); 162 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r); 163 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es); 164 r = min(pd - pc, pn - pd - es);
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
index a2af9f17a4..8b0ea89a0f 100644
--- a/src/lib/libc/stdlib/radixsort.3
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -29,8 +29,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94 32.\" $OpenBSD: radixsort.3,v 1.4 1998/06/15 17:55:08 mickey Exp $
33.\" $Id: radixsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\" 33.\"
35.Dd January 27, 1994 34.Dd January 27, 1994
36.Dt RADIXSORT 3 35.Dt RADIXSORT 3
@@ -42,9 +41,9 @@
42.Fd #include <limits.h> 41.Fd #include <limits.h>
43.Fd #include <stdlib.h> 42.Fd #include <stdlib.h>
44.Ft int 43.Ft int
45.Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 44.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
46.Ft int 45.Ft int
47.Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 46.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
48.Sh DESCRIPTION 47.Sh DESCRIPTION
49The 48The
50.Fn radixsort 49.Fn radixsort
@@ -158,4 +157,5 @@ for any of the errors specified for the library routine
158.Sh HISTORY 157.Sh HISTORY
159The 158The
160.Fn radixsort 159.Fn radixsort
161function first appeared in 4.4BSD. 160function first appeared in
161.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
index dd51013c94..41ed962466 100644
--- a/src/lib/libc/stdlib/radixsort.c
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)radixsort.c 8.1 (Berkeley) 6/4/93";*/ 38static char *rcsid = "$OpenBSD: radixsort.c,v 1.3 1996/08/19 08:33:44 tholo Exp $";
39static char *rcsid = "$Id: radixsort.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42/* 41/*
@@ -61,7 +60,7 @@ typedef struct {
61 int sn, si; 60 int sn, si;
62} stack; 61} stack;
63 62
64static inline void simplesort 63static __inline void simplesort
65 __P((const u_char **, int, int, const u_char *, u_int)); 64 __P((const u_char **, int, int, const u_char *, u_int));
66static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); 65static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int));
67static void r_sort_b __P((const u_char **, 66static void r_sort_b __P((const u_char **,
@@ -295,7 +294,7 @@ r_sort_b(a, ta, n, i, tr, endch)
295 } 294 }
296} 295}
297 296
298static inline void 297static __inline void
299simplesort(a, n, b, tr, endch) /* insertion sort */ 298simplesort(a, n, b, tr, endch) /* insertion sort */
300 register const u_char **a; 299 register const u_char **a;
301 int n, b; 300 int n, b;
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
index a0e7740e66..32d32761f1 100644
--- a/src/lib/libc/stdlib/rand.3
+++ b/src/lib/libc/stdlib/rand.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)rand.3 6.7 (Berkeley) 6/29/91 36.\" $OpenBSD: rand.3,v 1.4 1998/07/05 19:54:22 millert Exp $
37.\" $Id: rand.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt RAND 3 39.Dt RAND 3
@@ -51,7 +50,8 @@
51.Fn rand void 50.Fn rand void
52.Sh DESCRIPTION 51.Sh DESCRIPTION
53.Bf -symbolic 52.Bf -symbolic
54These interfaces are obsoleted by random(3). 53These interfaces are obsoleted by
54.Xr random 3 .
55.Ef 55.Ef
56.Pp 56.Pp
57The 57The
@@ -74,6 +74,8 @@ with the same seed value.
74If no seed value is provided, the functions are automatically 74If no seed value is provided, the functions are automatically
75seeded with a value of 1. 75seeded with a value of 1.
76.Sh SEE ALSO 76.Sh SEE ALSO
77.Xr arc4random 3 ,
78.Xr rand48 3 ,
77.Xr random 3 79.Xr random 3
78.Sh STANDARDS 80.Sh STANDARDS
79The 81The
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
index 361d473448..f270ffd986 100644
--- a/src/lib/libc/stdlib/rand.c
+++ b/src/lib/libc/stdlib/rand.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)rand.c 5.6 (Berkeley) 6/24/91";*/ 35static char *rcsid = "$OpenBSD: rand.c,v 1.2 1996/08/19 08:33:44 tholo Exp $";
36static char *rcsid = "$Id: rand.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <sys/types.h> 38#include <sys/types.h>
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
index 5a772c9a8c..d5236a4779 100644
--- a/src/lib/libc/stdlib/rand48.3
+++ b/src/lib/libc/stdlib/rand48.3
@@ -9,7 +9,7 @@
9.\" of any kind. I shall in no event be liable for anything that happens 9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software. 10.\" to anyone/anything when using this software.
11.\" 11.\"
12.\" $Id: rand48.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ 12.\" $OpenBSD: rand48.3,v 1.3 1998/07/05 19:54:23 millert Exp $
13.\" 13.\"
14.Dd October 8, 1993 14.Dd October 8, 1993
15.Dt RAND48 3 15.Dt RAND48 3
@@ -156,5 +156,6 @@ For a more powerful random number generator, see
156.Sh AUTHOR 156.Sh AUTHOR
157Martin Birgmeier 157Martin Birgmeier
158.Sh SEE ALSO 158.Sh SEE ALSO
159.Xr arc4random 3 ,
159.Xr rand 3 , 160.Xr rand 3 ,
160.Xr random 3 . 161.Xr random 3 .
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
index 12496d1c8c..e7cb3e0333 100644
--- a/src/lib/libc/stdlib/rand48.h
+++ b/src/lib/libc/stdlib/rand48.h
@@ -9,6 +9,8 @@
9 * This software is provided ``as is'', and comes with no warranties 9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens 10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.2 1996/08/19 08:33:45 tholo Exp $
12 */ 14 */
13 15
14#ifndef _RAND48_H_ 16#ifndef _RAND48_H_
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
index 38c15a9803..acfbd8cdeb 100644
--- a/src/lib/libc/stdlib/random.3
+++ b/src/lib/libc/stdlib/random.3
@@ -29,8 +29,7 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" from: @(#)random.3 6.5 (Berkeley) 4/19/91 32.\" $OpenBSD: random.3,v 1.6 1998/07/05 19:54:25 millert Exp $
33.\" $Id: random.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\" 33.\"
35.Dd April 19, 1991 34.Dd April 19, 1991
36.Dt RANDOM 3 35.Dt RANDOM 3
@@ -46,11 +45,11 @@
46.Ft long 45.Ft long
47.Fn random void 46.Fn random void
48.Ft void 47.Ft void
49.Fn srandom "unsigned seed" 48.Fn srandom "unsigned int seed"
50.Ft char * 49.Ft char *
51.Fn initstate "unsigned seed" "char *state" "int n" 50.Fn initstate "unsigned int seed" "char *state" "size_t n"
52.Ft char * 51.Ft char *
53.Fn setstate "char *state" 52.Fn setstate "const char *state"
54.Sh DESCRIPTION 53.Sh DESCRIPTION
55The 54The
56.Fn random 55.Fn random
@@ -60,6 +59,12 @@ default table of size 31 long integers to return successive pseudo-random
60numbers in the range from 0 to 59numbers in the range from 0 to
61.if t 2\u\s731\s10\d\(mi1. 60.if t 2\u\s731\s10\d\(mi1.
62.if n (2**31)\(mi1. 61.if n (2**31)\(mi1.
62The maximum value returned by
63.Fn random
64is
65.Dv LONG_MAX
66(as defined by the header file
67.Aq Pa limits.h ) .
63The period of this random number generator is very large, approximately 68The period of this random number generator is very large, approximately
64.if t 16\(mu(2\u\s731\s10\d\(mi1). 69.if t 16\(mu(2\u\s731\s10\d\(mi1).
65.if n 16*((2**31)\(mi1). 70.if n 16*((2**31)\(mi1).
@@ -157,7 +162,18 @@ is called with less than 8 bytes of state information, or if
157detects that the state information has been garbled, error 162detects that the state information has been garbled, error
158messages are printed on the standard error output. 163messages are printed on the standard error output.
159.Sh SEE ALSO 164.Sh SEE ALSO
165.Xr arc4random 3 ,
166.Xr drand48 3 ,
160.Xr rand 3 167.Xr rand 3
168.Sh STANDARDS
169The
170.Fn random ,
171.Fn srandom ,
172.Fn initstate ,
173and
174.Fn setstate
175functions conform to
176.St -xpg4.2 .
161.Sh HISTORY 177.Sh HISTORY
162These 178These
163functions appeared in 179functions appeared in
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..79344f30f1 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: random.c,v 1.6 1998/02/07 02:16:25 millert Exp $";
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdio.h> 38#include <stdio.h>
@@ -136,12 +135,12 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
136 135
137static long randtbl[DEG_3 + 1] = { 136static long randtbl[DEG_3 + 1] = {
138 TYPE_3, 137 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 138 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 139 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 140 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 141 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 142 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 143 0xf3bec5da,
145}; 144};
146 145
147/* 146/*
@@ -193,15 +192,26 @@ void
193srandom(x) 192srandom(x)
194 u_int x; 193 u_int x;
195{ 194{
196 register int i, j; 195 register long int test;
196 register int i;
197 ldiv_t val;
197 198
198 if (rand_type == TYPE_0) 199 if (rand_type == TYPE_0)
199 state[0] = x; 200 state[0] = x;
200 else { 201 else {
201 j = 1;
202 state[0] = x; 202 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 203 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 204 /*
205 * Implement the following, without overflowing 31 bits:
206 *
207 * state[i] = (16807 * state[i - 1]) % 2147483647;
208 *
209 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
210 */
211 val = ldiv(state[i-1], 127773);
212 test = 16807 * val.rem - 2836 * val.quot;
213 state[i] = test + (test < 0 ? 2147483647 : 0);
214 }
205 fptr = &state[rand_sep]; 215 fptr = &state[rand_sep];
206 rptr = &state[0]; 216 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 217 for (i = 0; i < 10 * rand_deg; i++)
@@ -232,7 +242,7 @@ char *
232initstate(seed, arg_state, n) 242initstate(seed, arg_state, n)
233 u_int seed; /* seed for R.N.G. */ 243 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */ 244 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */ 245 size_t n; /* # bytes of state info */
236{ 246{
237 register char *ostate = (char *)(&state[-1]); 247 register char *ostate = (char *)(&state[-1]);
238 248
@@ -240,11 +250,8 @@ initstate(seed, arg_state, n)
240 state[-1] = rand_type; 250 state[-1] = rand_type;
241 else 251 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 252 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 253 if (n < BREAK_0)
244 (void)fprintf(stderr, 254 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 255 if (n < BREAK_1) {
249 rand_type = TYPE_0; 256 rand_type = TYPE_0;
250 rand_deg = DEG_0; 257 rand_deg = DEG_0;
@@ -293,7 +300,7 @@ initstate(seed, arg_state, n)
293 */ 300 */
294char * 301char *
295setstate(arg_state) 302setstate(arg_state)
296 char *arg_state; 303 const char *arg_state;
297{ 304{
298 register long *new_state = (long *)arg_state; 305 register long *new_state = (long *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 306 register int type = new_state[0] % MAX_TYPES;
@@ -315,8 +322,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 322 rand_sep = seps[type];
316 break; 323 break;
317 default: 324 default:
318 (void)fprintf(stderr, 325 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 326 }
321 state = &new_state[1]; 327 state = &new_state[1];
322 if (rand_type != TYPE_0) { 328 if (rand_type != TYPE_0) {
diff --git a/src/lib/libc/stdlib/realloc.3 b/src/lib/libc/stdlib/realloc.3
deleted file mode 100644
index 66f09b2081..0000000000
--- a/src/lib/libc/stdlib/realloc.3
+++ /dev/null
@@ -1,100 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" from: @(#)realloc.3 5.1 (Berkeley) 5/2/91
33.\" $Id: realloc.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt REALLOC 3
37.Os
38.Sh NAME
39.Nm realloc
40.Nd reallocation of memory function
41.Sh SYNOPSIS
42.Fd #include <stdlib.h>
43.Ft void *
44.Fn realloc "void *ptr" "size_t size"
45.Sh DESCRIPTION
46The
47.Fn realloc
48function changes the size of the object pointed to by
49.Fa ptr
50to the size specified by
51.Fa size .
52The contents of the object are unchanged up to the lesser
53of the new and old sizes.
54If the new size is larger, the value of the newly allocated portion
55of the object is indeterminate.
56If
57.Fa ptr
58is a null pointer, the
59.Fn realloc
60function behaves like the
61.Xr malloc 3
62function for the specified size.
63Otherwise, if
64.Fa ptr
65does not match a pointer earlier returned by the
66.Xr calloc 3 ,
67.Xr malloc 3 ,
68or
69.Fn realloc
70function, or if the space has been deallocated
71by a call to the
72.Xr free
73or
74.Fn realloc
75function, unpredictable and usually detrimental
76behavior will occur.
77If the space cannot be allocated, the object
78pointed to by
79.Fa ptr
80is unchanged.
81If
82.Fa size
83is zero and
84.Fa ptr
85is not a null pointer, the object it points to is freed.
86.Pp
87The
88.Fn realloc
89function returns either a null pointer or a pointer
90to the possibly moved allocated space.
91.Sh SEE ALSO
92.Xr alloca 3 ,
93.Xr calloc 3 ,
94.Xr free 3 ,
95.Xr malloc 3 ,
96.Sh STANDARDS
97The
98.Fn realloc
99function conforms to
100.St -ansiC .
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
index 9d8b1ff2ce..cc140029e4 100644
--- a/src/lib/libc/stdlib/realpath.3
+++ b/src/lib/libc/stdlib/realpath.3
@@ -32,10 +32,9 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 33.\" SUCH DAMAGE.
34.\" 34.\"
35.\" from: @(#)realpath.3 8.2 (Berkeley) 2/16/94 35.\" $OpenBSD: realpath.3,v 1.3 1997/05/30 07:48:30 deraadt Exp $
36.\" $Id: realpath.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
37.\" 36.\"
38.Dd "February 16, 1994" 37.Dd February, 16, 1994
39.Dt REALPATH 3 38.Dt REALPATH 3
40.Os 39.Os
41.Sh NAME 40.Sh NAME
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index e349b7e068..0288601464 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ 38static char *rcsid = "$OpenBSD: realpath.c,v 1.4 1998/05/18 09:55:19 deraadt Exp $";
39static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <sys/param.h> 41#include <sys/param.h>
@@ -63,6 +62,7 @@ realpath(path, resolved)
63 struct stat sb; 62 struct stat sb;
64 int fd, n, rootd, serrno; 63 int fd, n, rootd, serrno;
65 char *p, *q, wbuf[MAXPATHLEN]; 64 char *p, *q, wbuf[MAXPATHLEN];
65 int symlinks = 0;
66 66
67 /* Save the starting point. */ 67 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) { 68 if ((fd = open(".", O_RDONLY)) < 0) {
@@ -101,7 +101,11 @@ loop:
101 /* Deal with the last component. */ 101 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) { 102 if (lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) { 103 if (S_ISLNK(sb.st_mode)) {
104 n = readlink(p, resolved, MAXPATHLEN); 104 if (++symlinks > MAXSYMLINKS) {
105 errno = ELOOP;
106 goto err1;
107 }
108 n = readlink(p, resolved, MAXPATHLEN-1);
105 if (n < 0) 109 if (n < 0)
106 goto err1; 110 goto err1;
107 resolved[n] = '\0'; 111 resolved[n] = '\0';
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
index e3d31901dd..c4dcd0ead8 100644
--- a/src/lib/libc/stdlib/seed48.c
+++ b/src/lib/libc/stdlib/seed48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: seed48.c,v 1.2 1996/08/19 08:33:48 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..b6f261e61c 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ 35static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $";
36static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
@@ -72,10 +71,11 @@ setenv(name, value, rewrite)
72 71
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 72 for (P = environ, cnt = 0; *P; ++P, ++cnt);
74 if (alloced) { /* just increase size */ 73 if (alloced) { /* just increase size */
75 environ = (char **)realloc((char *)environ, 74 P = (char **)realloc((void *)environ,
76 (size_t)(sizeof(char *) * (cnt + 2))); 75 (size_t)(sizeof(char *) * (cnt + 2)));
77 if (!environ) 76 if (!P)
78 return (-1); 77 return (-1);
78 environ = P;
79 } 79 }
80 else { /* get new space */ 80 else { /* get new space */
81 alloced = 1; /* copy old entries into it */ 81 alloced = 1; /* copy old entries into it */
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
index daf733f93e..fcff8a172e 100644
--- a/src/lib/libc/stdlib/srand48.c
+++ b/src/lib/libc/stdlib/srand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: srand48.c,v 1.2 1996/08/19 08:33:49 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
index 0b7f973857..3476fa41d6 100644
--- a/src/lib/libc/stdlib/strtod.3
+++ b/src/lib/libc/stdlib/strtod.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)strtod.3 5.3 (Berkeley) 6/29/91 36.\" $OpenBSD: strtod.3,v 1.2 1996/08/19 08:33:49 tholo Exp $
37.\" $Id: strtod.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt STRTOD 3 39.Dt STRTOD 3
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index b13fa128f5..55d9e91224 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -90,12 +90,13 @@
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 93static char *rcsid = "$OpenBSD: strtod.c,v 1.12 1998/08/28 20:49:24 mickey Exp $";
94#endif /* LIBC_SCCS and not lint */ 94#endif /* LIBC_SCCS and not lint */
95 95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) 97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98#include <machine/endian.h> 98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__)
99#include <sys/types.h>
99#if BYTE_ORDER == BIG_ENDIAN 100#if BYTE_ORDER == BIG_ENDIAN
100#define IEEE_BIG_ENDIAN 101#define IEEE_BIG_ENDIAN
101#else 102#else
@@ -103,6 +104,15 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
103#endif 104#endif
104#endif 105#endif
105 106
107#ifdef __arm32__
108/*
109 * Although the CPU is little endian the FP has different
110 * byte and word endianness. The byte order is still little endian
111 * but the word order is big endian.
112 */
113#define IEEE_BIG_ENDIAN
114#endif
115
106#ifdef vax 116#ifdef vax
107#define VAX 117#define VAX
108#endif 118#endif
@@ -212,19 +222,24 @@ Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
212IBM should be defined. 222IBM should be defined.
213#endif 223#endif
214 224
225typedef union {
226 double d;
227 ULong ul[2];
228} _double;
229#define value(x) ((x).d)
215#ifdef IEEE_LITTLE_ENDIAN 230#ifdef IEEE_LITTLE_ENDIAN
216#define word0(x) ((ULong *)&x)[1] 231#define word0(x) ((x).ul[1])
217#define word1(x) ((ULong *)&x)[0] 232#define word1(x) ((x).ul[0])
218#else 233#else
219#define word0(x) ((ULong *)&x)[0] 234#define word0(x) ((x).ul[0])
220#define word1(x) ((ULong *)&x)[1] 235#define word1(x) ((x).ul[1])
221#endif 236#endif
222 237
223/* The following definition of Storeinc is appropriate for MIPS processors. 238/* The following definition of Storeinc is appropriate for MIPS processors.
224 * An alternative that might be better on some machines is 239 * An alternative that might be better on some machines is
225 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 240 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
226 */ 241 */
227#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) 242#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
228#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 243#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
229((unsigned short *)a)[0] = (unsigned short)c, a++) 244((unsigned short *)a)[0] = (unsigned short)c, a++)
230#else 245#else
@@ -899,14 +914,16 @@ diff
899 static double 914 static double
900ulp 915ulp
901#ifdef KR_headers 916#ifdef KR_headers
902 (x) double x; 917 (_x) double _x;
903#else 918#else
904 (double x) 919 (double _x)
905#endif 920#endif
906{ 921{
922 _double x;
907 register Long L; 923 register Long L;
908 double a; 924 _double a;
909 925
926 value(x) = _x;
910 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 927 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
911#ifndef Sudden_Underflow 928#ifndef Sudden_Underflow
912 if (L > 0) { 929 if (L > 0) {
@@ -931,7 +948,7 @@ ulp
931 } 948 }
932 } 949 }
933#endif 950#endif
934 return a; 951 return value(a);
935 } 952 }
936 953
937 static double 954 static double
@@ -944,7 +961,7 @@ b2d
944{ 961{
945 ULong *xa, *xa0, w, y, z; 962 ULong *xa, *xa0, w, y, z;
946 int k; 963 int k;
947 double d; 964 _double d;
948#ifdef VAX 965#ifdef VAX
949 ULong d0, d1; 966 ULong d0, d1;
950#else 967#else
@@ -1001,22 +1018,27 @@ b2d
1001#undef d0 1018#undef d0
1002#undef d1 1019#undef d1
1003#endif 1020#endif
1004 return d; 1021 return value(d);
1005 } 1022 }
1006 1023
1007 static Bigint * 1024 static Bigint *
1008d2b 1025d2b
1009#ifdef KR_headers 1026#ifdef KR_headers
1010 (d, e, bits) double d; int *e, *bits; 1027 (_d, e, bits) double d; int *e, *bits;
1011#else 1028#else
1012 (double d, int *e, int *bits) 1029 (double _d, int *e, int *bits)
1013#endif 1030#endif
1014{ 1031{
1015 Bigint *b; 1032 Bigint *b;
1016 int de, i, k; 1033 int de, i, k;
1017 ULong *x, y, z; 1034 ULong *x, y, z;
1035 _double d;
1018#ifdef VAX 1036#ifdef VAX
1019 ULong d0, d1; 1037 ULong d0, d1;
1038#endif
1039
1040 value(d) = _d;
1041#ifdef VAX
1020 d0 = word0(d) >> 16 | word0(d) << 16; 1042 d0 = word0(d) >> 16 | word0(d) << 16;
1021 d1 = word1(d) >> 16 | word1(d) << 16; 1043 d1 = word1(d) >> 16 | word1(d) << 16;
1022#else 1044#else
@@ -1141,11 +1163,11 @@ ratio
1141 (Bigint *a, Bigint *b) 1163 (Bigint *a, Bigint *b)
1142#endif 1164#endif
1143{ 1165{
1144 double da, db; 1166 _double da, db;
1145 int k, ka, kb; 1167 int k, ka, kb;
1146 1168
1147 da = b2d(a, &ka); 1169 value(da) = b2d(a, &ka);
1148 db = b2d(b, &kb); 1170 value(db) = b2d(b, &kb);
1149#ifdef Pack_32 1171#ifdef Pack_32
1150 k = ka - kb + 32*(a->wds - b->wds); 1172 k = ka - kb + 32*(a->wds - b->wds);
1151#else 1173#else
@@ -1171,7 +1193,7 @@ ratio
1171 word0(db) += k*Exp_msk1; 1193 word0(db) += k*Exp_msk1;
1172 } 1194 }
1173#endif 1195#endif
1174 return da / db; 1196 return value(da) / value(db);
1175 } 1197 }
1176 1198
1177static CONST double 1199static CONST double
@@ -1211,7 +1233,8 @@ strtod
1211 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1233 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1212 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1234 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1213 CONST char *s, *s0, *s1; 1235 CONST char *s, *s0, *s1;
1214 double aadj, aadj1, adj, rv, rv0; 1236 double aadj, aadj1, adj;
1237 _double rv, rv0;
1215 Long L; 1238 Long L;
1216 ULong y, z; 1239 ULong y, z;
1217 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1240 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@@ -1223,10 +1246,10 @@ strtod
1223#endif 1246#endif
1224 1247
1225 sign = nz0 = nz = 0; 1248 sign = nz0 = nz = 0;
1226 rv = 0.; 1249 value(rv) = 0.;
1227 1250
1228 1251
1229 for(s = s00; isspace(*s); s++) 1252 for(s = s00; isspace((unsigned char) *s); s++)
1230 ; 1253 ;
1231 1254
1232 if (*s == '-') { 1255 if (*s == '-') {
@@ -1340,9 +1363,9 @@ strtod
1340 if (!nd0) 1363 if (!nd0)
1341 nd0 = nd; 1364 nd0 = nd;
1342 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1365 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1343 rv = y; 1366 value(rv) = y;
1344 if (k > 9) 1367 if (k > 9)
1345 rv = tens[k - 9] * rv + z; 1368 value(rv) = tens[k - 9] * value(rv) + z;
1346 bd0 = 0; 1369 bd0 = 0;
1347 if (nd <= DBL_DIG 1370 if (nd <= DBL_DIG
1348#ifndef RND_PRODQUOT 1371#ifndef RND_PRODQUOT
@@ -1356,7 +1379,8 @@ strtod
1356#ifdef VAX 1379#ifdef VAX
1357 goto vax_ovfl_check; 1380 goto vax_ovfl_check;
1358#else 1381#else
1359 /* rv = */ rounded_product(rv, tens[e]); 1382 /* value(rv) = */ rounded_product(value(rv),
1383 tens[e]);
1360 goto ret; 1384 goto ret;
1361#endif 1385#endif
1362 } 1386 }
@@ -1366,27 +1390,30 @@ strtod
1366 * this for larger i values. 1390 * this for larger i values.
1367 */ 1391 */
1368 e -= i; 1392 e -= i;
1369 rv *= tens[i]; 1393 value(rv) *= tens[i];
1370#ifdef VAX 1394#ifdef VAX
1371 /* VAX exponent range is so narrow we must 1395 /* VAX exponent range is so narrow we must
1372 * worry about overflow here... 1396 * worry about overflow here...
1373 */ 1397 */
1374 vax_ovfl_check: 1398 vax_ovfl_check:
1375 word0(rv) -= P*Exp_msk1; 1399 word0(rv) -= P*Exp_msk1;
1376 /* rv = */ rounded_product(rv, tens[e]); 1400 /* value(rv) = */ rounded_product(value(rv),
1401 tens[e]);
1377 if ((word0(rv) & Exp_mask) 1402 if ((word0(rv) & Exp_mask)
1378 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1403 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1379 goto ovfl; 1404 goto ovfl;
1380 word0(rv) += P*Exp_msk1; 1405 word0(rv) += P*Exp_msk1;
1381#else 1406#else
1382 /* rv = */ rounded_product(rv, tens[e]); 1407 /* value(rv) = */ rounded_product(value(rv),
1408 tens[e]);
1383#endif 1409#endif
1384 goto ret; 1410 goto ret;
1385 } 1411 }
1386 } 1412 }
1387#ifndef Inaccurate_Divide 1413#ifndef Inaccurate_Divide
1388 else if (e >= -Ten_pmax) { 1414 else if (e >= -Ten_pmax) {
1389 /* rv = */ rounded_quotient(rv, tens[-e]); 1415 /* value(rv) = */ rounded_quotient(value(rv),
1416 tens[-e]);
1390 goto ret; 1417 goto ret;
1391 } 1418 }
1392#endif 1419#endif
@@ -1397,13 +1424,13 @@ strtod
1397 1424
1398 if (e1 > 0) { 1425 if (e1 > 0) {
1399 if (i = e1 & 15) 1426 if (i = e1 & 15)
1400 rv *= tens[i]; 1427 value(rv) *= tens[i];
1401 if (e1 &= ~15) { 1428 if (e1 &= ~15) {
1402 if (e1 > DBL_MAX_10_EXP) { 1429 if (e1 > DBL_MAX_10_EXP) {
1403 ovfl: 1430 ovfl:
1404 errno = ERANGE; 1431 errno = ERANGE;
1405#ifdef __STDC__ 1432#ifdef __STDC__
1406 rv = HUGE_VAL; 1433 value(rv) = HUGE_VAL;
1407#else 1434#else
1408 /* Can't trust HUGE_VAL */ 1435 /* Can't trust HUGE_VAL */
1409#ifdef IEEE_Arith 1436#ifdef IEEE_Arith
@@ -1421,10 +1448,10 @@ strtod
1421 if (e1 >>= 4) { 1448 if (e1 >>= 4) {
1422 for(j = 0; e1 > 1; j++, e1 >>= 1) 1449 for(j = 0; e1 > 1; j++, e1 >>= 1)
1423 if (e1 & 1) 1450 if (e1 & 1)
1424 rv *= bigtens[j]; 1451 value(rv) *= bigtens[j];
1425 /* The last multiplication could overflow. */ 1452 /* The last multiplication could overflow. */
1426 word0(rv) -= P*Exp_msk1; 1453 word0(rv) -= P*Exp_msk1;
1427 rv *= bigtens[j]; 1454 value(rv) *= bigtens[j];
1428 if ((z = word0(rv) & Exp_mask) 1455 if ((z = word0(rv) & Exp_mask)
1429 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1456 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1430 goto ovfl; 1457 goto ovfl;
@@ -1443,23 +1470,23 @@ strtod
1443 else if (e1 < 0) { 1470 else if (e1 < 0) {
1444 e1 = -e1; 1471 e1 = -e1;
1445 if (i = e1 & 15) 1472 if (i = e1 & 15)
1446 rv /= tens[i]; 1473 value(rv) /= tens[i];
1447 if (e1 &= ~15) { 1474 if (e1 &= ~15) {
1448 e1 >>= 4; 1475 e1 >>= 4;
1449 if (e1 >= 1 << n_bigtens) 1476 if (e1 >= 1 << n_bigtens)
1450 goto undfl; 1477 goto undfl;
1451 for(j = 0; e1 > 1; j++, e1 >>= 1) 1478 for(j = 0; e1 > 1; j++, e1 >>= 1)
1452 if (e1 & 1) 1479 if (e1 & 1)
1453 rv *= tinytens[j]; 1480 value(rv) *= tinytens[j];
1454 /* The last multiplication could underflow. */ 1481 /* The last multiplication could underflow. */
1455 rv0 = rv; 1482 value(rv0) = value(rv);
1456 rv *= tinytens[j]; 1483 value(rv) *= tinytens[j];
1457 if (!rv) { 1484 if (!value(rv)) {
1458 rv = 2.*rv0; 1485 value(rv) = 2.*value(rv0);
1459 rv *= tinytens[j]; 1486 value(rv) *= tinytens[j];
1460 if (!rv) { 1487 if (!value(rv)) {
1461 undfl: 1488 undfl:
1462 rv = 0.; 1489 value(rv) = 0.;
1463 errno = ERANGE; 1490 errno = ERANGE;
1464 if (bd0) 1491 if (bd0)
1465 goto retfree; 1492 goto retfree;
@@ -1483,7 +1510,7 @@ strtod
1483 for(;;) { 1510 for(;;) {
1484 bd = Balloc(bd0->k); 1511 bd = Balloc(bd0->k);
1485 Bcopy(bd, bd0); 1512 Bcopy(bd, bd0);
1486 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ 1513 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1487 bs = i2b(1); 1514 bs = i2b(1);
1488 1515
1489 if (e >= 0) { 1516 if (e >= 0) {
@@ -1595,12 +1622,12 @@ strtod
1595 break; 1622 break;
1596#endif 1623#endif
1597 if (dsign) 1624 if (dsign)
1598 rv += ulp(rv); 1625 value(rv) += ulp(value(rv));
1599#ifndef ROUND_BIASED 1626#ifndef ROUND_BIASED
1600 else { 1627 else {
1601 rv -= ulp(rv); 1628 value(rv) -= ulp(value(rv));
1602#ifndef Sudden_Underflow 1629#ifndef Sudden_Underflow
1603 if (!rv) 1630 if (!value(rv))
1604 goto undfl; 1631 goto undfl;
1605#endif 1632#endif
1606 } 1633 }
@@ -1651,10 +1678,10 @@ strtod
1651 /* Check for overflow */ 1678 /* Check for overflow */
1652 1679
1653 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 1680 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1654 rv0 = rv; 1681 value(rv0) = value(rv);
1655 word0(rv) -= P*Exp_msk1; 1682 word0(rv) -= P*Exp_msk1;
1656 adj = aadj1 * ulp(rv); 1683 adj = aadj1 * ulp(value(rv));
1657 rv += adj; 1684 value(rv) += adj;
1658 if ((word0(rv) & Exp_mask) >= 1685 if ((word0(rv) & Exp_mask) >=
1659 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 1686 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1660 if (word0(rv0) == Big0 && word1(rv0) == Big1) 1687 if (word0(rv0) == Big0 && word1(rv0) == Big1)
@@ -1669,10 +1696,10 @@ strtod
1669 else { 1696 else {
1670#ifdef Sudden_Underflow 1697#ifdef Sudden_Underflow
1671 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 1698 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1672 rv0 = rv; 1699 value(rv0) = value(rv);
1673 word0(rv) += P*Exp_msk1; 1700 word0(rv) += P*Exp_msk1;
1674 adj = aadj1 * ulp(rv); 1701 adj = aadj1 * ulp(value(rv));
1675 rv += adj; 1702 value(rv) += adj;
1676#ifdef IBM 1703#ifdef IBM
1677 if ((word0(rv) & Exp_mask) < P*Exp_msk1) 1704 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1678#else 1705#else
@@ -1690,8 +1717,8 @@ strtod
1690 word0(rv) -= P*Exp_msk1; 1717 word0(rv) -= P*Exp_msk1;
1691 } 1718 }
1692 else { 1719 else {
1693 adj = aadj1 * ulp(rv); 1720 adj = aadj1 * ulp(value(rv));
1694 rv += adj; 1721 value(rv) += adj;
1695 } 1722 }
1696#else 1723#else
1697 /* Compute adj so that the IEEE rounding rules will 1724 /* Compute adj so that the IEEE rounding rules will
@@ -1706,8 +1733,8 @@ strtod
1706 if (!dsign) 1733 if (!dsign)
1707 aadj1 = -aadj1; 1734 aadj1 = -aadj1;
1708 } 1735 }
1709 adj = aadj1 * ulp(rv); 1736 adj = aadj1 * ulp(value(rv));
1710 rv += adj; 1737 value(rv) += adj;
1711#endif 1738#endif
1712 } 1739 }
1713 z = word0(rv) & Exp_mask; 1740 z = word0(rv) & Exp_mask;
@@ -1738,7 +1765,7 @@ strtod
1738 ret: 1765 ret:
1739 if (se) 1766 if (se)
1740 *se = (char *)s; 1767 *se = (char *)s;
1741 return sign ? -rv : rv; 1768 return sign ? -value(rv) : value(rv);
1742 } 1769 }
1743 1770
1744 static int 1771 static int
@@ -1884,10 +1911,10 @@ quorem
1884 char * 1911 char *
1885__dtoa 1912__dtoa
1886#ifdef KR_headers 1913#ifdef KR_headers
1887 (d, mode, ndigits, decpt, sign, rve) 1914 (_d, mode, ndigits, decpt, sign, rve)
1888 double d; int mode, ndigits, *decpt, *sign; char **rve; 1915 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1889#else 1916#else
1890 (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) 1917 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1891#endif 1918#endif
1892{ 1919{
1893 /* Arguments ndigits, decpt, sign are similar to those 1920 /* Arguments ndigits, decpt, sign are similar to those
@@ -1933,11 +1960,13 @@ __dtoa
1933 ULong x; 1960 ULong x;
1934#endif 1961#endif
1935 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1962 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1936 double d2, ds, eps; 1963 double ds;
1937 char *s, *s0; 1964 char *s, *s0;
1938 static Bigint *result; 1965 static Bigint *result;
1939 static int result_k; 1966 static int result_k;
1967 _double d, d2, eps;
1940 1968
1969 value(d) = _d;
1941 if (result) { 1970 if (result) {
1942 result->k = result_k; 1971 result->k = result_k;
1943 result->maxwds = 1 << result_k; 1972 result->maxwds = 1 << result_k;
@@ -1977,9 +2006,9 @@ __dtoa
1977 } 2006 }
1978#endif 2007#endif
1979#ifdef IBM 2008#ifdef IBM
1980 d += 0; /* normalize */ 2009 value(d) += 0; /* normalize */
1981#endif 2010#endif
1982 if (!d) { 2011 if (!value(d)) {
1983 *decpt = 1; 2012 *decpt = 1;
1984 s = "0"; 2013 s = "0";
1985 if (rve) 2014 if (rve)
@@ -1987,18 +2016,18 @@ __dtoa
1987 return s; 2016 return s;
1988 } 2017 }
1989 2018
1990 b = d2b(d, &be, &bbits); 2019 b = d2b(value(d), &be, &bbits);
1991#ifdef Sudden_Underflow 2020#ifdef Sudden_Underflow
1992 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 2021 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1993#else 2022#else
1994 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 2023 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
1995#endif 2024#endif
1996 d2 = d; 2025 value(d2) = value(d);
1997 word0(d2) &= Frac_mask1; 2026 word0(d2) &= Frac_mask1;
1998 word0(d2) |= Exp_11; 2027 word0(d2) |= Exp_11;
1999#ifdef IBM 2028#ifdef IBM
2000 if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 2029 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2001 d2 /= 1 << j; 2030 value(d2) /= 1 << j;
2002#endif 2031#endif
2003 2032
2004 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 2033 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2037,19 +2066,20 @@ __dtoa
2037 i = bbits + be + (Bias + (P-1) - 1); 2066 i = bbits + be + (Bias + (P-1) - 1);
2038 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2067 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2039 : word1(d) << 32 - i; 2068 : word1(d) << 32 - i;
2040 d2 = x; 2069 value(d2) = x;
2041 word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2070 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2042 i -= (Bias + (P-1) - 1) + 1; 2071 i -= (Bias + (P-1) - 1) + 1;
2043 denorm = 1; 2072 denorm = 1;
2044 } 2073 }
2045#endif 2074#endif
2046 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2075 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2076 i*0.301029995663981;
2047 k = (int)ds; 2077 k = (int)ds;
2048 if (ds < 0. && ds != k) 2078 if (ds < 0. && ds != k)
2049 k--; /* want k = floor(ds) */ 2079 k--; /* want k = floor(ds) */
2050 k_check = 1; 2080 k_check = 1;
2051 if (k >= 0 && k <= Ten_pmax) { 2081 if (k >= 0 && k <= Ten_pmax) {
2052 if (d < tens[k]) 2082 if (value(d) < tens[k])
2053 k--; 2083 k--;
2054 k_check = 0; 2084 k_check = 0;
2055 } 2085 }
@@ -2116,7 +2146,7 @@ __dtoa
2116 /* Try to get by with floating-point arithmetic. */ 2146 /* Try to get by with floating-point arithmetic. */
2117 2147
2118 i = 0; 2148 i = 0;
2119 d2 = d; 2149 value(d2) = value(d);
2120 k0 = k; 2150 k0 = k;
2121 ilim0 = ilim; 2151 ilim0 = ilim;
2122 ieps = 2; /* conservative */ 2152 ieps = 2; /* conservative */
@@ -2126,7 +2156,7 @@ __dtoa
2126 if (j & Bletch) { 2156 if (j & Bletch) {
2127 /* prevent overflows */ 2157 /* prevent overflows */
2128 j &= Bletch - 1; 2158 j &= Bletch - 1;
2129 d /= bigtens[n_bigtens-1]; 2159 value(d) /= bigtens[n_bigtens-1];
2130 ieps++; 2160 ieps++;
2131 } 2161 }
2132 for(; j; j >>= 1, i++) 2162 for(; j; j >>= 1, i++)
@@ -2134,32 +2164,32 @@ __dtoa
2134 ieps++; 2164 ieps++;
2135 ds *= bigtens[i]; 2165 ds *= bigtens[i];
2136 } 2166 }
2137 d /= ds; 2167 value(d) /= ds;
2138 } 2168 }
2139 else if (j1 = -k) { 2169 else if (j1 = -k) {
2140 d *= tens[j1 & 0xf]; 2170 value(d) *= tens[j1 & 0xf];
2141 for(j = j1 >> 4; j; j >>= 1, i++) 2171 for(j = j1 >> 4; j; j >>= 1, i++)
2142 if (j & 1) { 2172 if (j & 1) {
2143 ieps++; 2173 ieps++;
2144 d *= bigtens[i]; 2174 value(d) *= bigtens[i];
2145 } 2175 }
2146 } 2176 }
2147 if (k_check && d < 1. && ilim > 0) { 2177 if (k_check && value(d) < 1. && ilim > 0) {
2148 if (ilim1 <= 0) 2178 if (ilim1 <= 0)
2149 goto fast_failed; 2179 goto fast_failed;
2150 ilim = ilim1; 2180 ilim = ilim1;
2151 k--; 2181 k--;
2152 d *= 10.; 2182 value(d) *= 10.;
2153 ieps++; 2183 ieps++;
2154 } 2184 }
2155 eps = ieps*d + 7.; 2185 value(eps) = ieps*value(d) + 7.;
2156 word0(eps) -= (P-1)*Exp_msk1; 2186 word0(eps) -= (P-1)*Exp_msk1;
2157 if (ilim == 0) { 2187 if (ilim == 0) {
2158 S = mhi = 0; 2188 S = mhi = 0;
2159 d -= 5.; 2189 value(d) -= 5.;
2160 if (d > eps) 2190 if (value(d) > value(eps))
2161 goto one_digit; 2191 goto one_digit;
2162 if (d < -eps) 2192 if (value(d) < -value(eps))
2163 goto no_digits; 2193 goto no_digits;
2164 goto fast_failed; 2194 goto fast_failed;
2165 } 2195 }
@@ -2168,33 +2198,33 @@ __dtoa
2168 /* Use Steele & White method of only 2198 /* Use Steele & White method of only
2169 * generating digits needed. 2199 * generating digits needed.
2170 */ 2200 */
2171 eps = 0.5/tens[ilim-1] - eps; 2201 value(eps) = 0.5/tens[ilim-1] - value(eps);
2172 for(i = 0;;) { 2202 for(i = 0;;) {
2173 L = d; 2203 L = value(d);
2174 d -= L; 2204 value(d) -= L;
2175 *s++ = '0' + (int)L; 2205 *s++ = '0' + (int)L;
2176 if (d < eps) 2206 if (value(d) < value(eps))
2177 goto ret1; 2207 goto ret1;
2178 if (1. - d < eps) 2208 if (1. - value(d) < value(eps))
2179 goto bump_up; 2209 goto bump_up;
2180 if (++i >= ilim) 2210 if (++i >= ilim)
2181 break; 2211 break;
2182 eps *= 10.; 2212 value(eps) *= 10.;
2183 d *= 10.; 2213 value(d) *= 10.;
2184 } 2214 }
2185 } 2215 }
2186 else { 2216 else {
2187#endif 2217#endif
2188 /* Generate ilim digits, then fix them up. */ 2218 /* Generate ilim digits, then fix them up. */
2189 eps *= tens[ilim-1]; 2219 value(eps) *= tens[ilim-1];
2190 for(i = 1;; i++, d *= 10.) { 2220 for(i = 1;; i++, value(d) *= 10.) {
2191 L = d; 2221 L = value(d);
2192 d -= L; 2222 value(d) -= L;
2193 *s++ = '0' + (int)L; 2223 *s++ = '0' + (int)L;
2194 if (i == ilim) { 2224 if (i == ilim) {
2195 if (d > 0.5 + eps) 2225 if (value(d) > 0.5 + value(eps))
2196 goto bump_up; 2226 goto bump_up;
2197 else if (d < 0.5 - eps) { 2227 else if (value(d) < 0.5 - value(eps)) {
2198 while(*--s == '0'); 2228 while(*--s == '0');
2199 s++; 2229 s++;
2200 goto ret1; 2230 goto ret1;
@@ -2207,7 +2237,7 @@ __dtoa
2207#endif 2237#endif
2208 fast_failed: 2238 fast_failed:
2209 s = s0; 2239 s = s0;
2210 d = d2; 2240 value(d) = value(d2);
2211 k = k0; 2241 k = k0;
2212 ilim = ilim0; 2242 ilim = ilim0;
2213 } 2243 }
@@ -2219,24 +2249,24 @@ __dtoa
2219 ds = tens[k]; 2249 ds = tens[k];
2220 if (ndigits < 0 && ilim <= 0) { 2250 if (ndigits < 0 && ilim <= 0) {
2221 S = mhi = 0; 2251 S = mhi = 0;
2222 if (ilim < 0 || d <= 5*ds) 2252 if (ilim < 0 || value(d) <= 5*ds)
2223 goto no_digits; 2253 goto no_digits;
2224 goto one_digit; 2254 goto one_digit;
2225 } 2255 }
2226 for(i = 1;; i++) { 2256 for(i = 1;; i++) {
2227 L = d / ds; 2257 L = value(d) / ds;
2228 d -= L*ds; 2258 value(d) -= L*ds;
2229#ifdef Check_FLT_ROUNDS 2259#ifdef Check_FLT_ROUNDS
2230 /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2260 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2231 if (d < 0) { 2261 if (value(d) < 0) {
2232 L--; 2262 L--;
2233 d += ds; 2263 value(d) += ds;
2234 } 2264 }
2235#endif 2265#endif
2236 *s++ = '0' + (int)L; 2266 *s++ = '0' + (int)L;
2237 if (i == ilim) { 2267 if (i == ilim) {
2238 d += d; 2268 value(d) += value(d);
2239 if (d > ds || d == ds && L & 1) { 2269 if (value(d) > ds || value(d) == ds && L & 1) {
2240 bump_up: 2270 bump_up:
2241 while(*--s == '9') 2271 while(*--s == '9')
2242 if (s == s0) { 2272 if (s == s0) {
@@ -2248,7 +2278,7 @@ __dtoa
2248 } 2278 }
2249 break; 2279 break;
2250 } 2280 }
2251 if (!(d *= 10.)) 2281 if (!(value(d) *= 10.))
2252 break; 2282 break;
2253 } 2283 }
2254 goto ret1; 2284 goto ret1;
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
index 808ba90165..b7d2cd1225 100644
--- a/src/lib/libc/stdlib/strtol.3
+++ b/src/lib/libc/stdlib/strtol.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)strtol.3 5.4 (Berkeley) 6/25/92 36.\" $OpenBSD: strtol.3,v 1.3 1996/08/19 08:33:51 tholo Exp $
37.\" $Id: strtol.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 37.\"
39.Dd June 25, 1992 38.Dd June 25, 1992
40.Dt STRTOL 3 39.Dt STRTOL 3
@@ -46,13 +45,13 @@
46.Fd #include <stdlib.h> 45.Fd #include <stdlib.h>
47.Fd #include <limits.h> 46.Fd #include <limits.h>
48.Ft long 47.Ft long
49.Fn strtol "char *nptr" "char **endptr" "int base" 48.Fn strtol "const char *nptr" "char **endptr" "int base"
50 49
51.Fd #include <sys/types.h> 50.Fd #include <sys/types.h>
52.Fd #include <stdlib.h> 51.Fd #include <stdlib.h>
53.Fd #include <limits.h> 52.Fd #include <limits.h>
54.Ft quad_t 53.Ft quad_t
55.Fn strtoq "char *nptr" "char **endptr" "int base" 54.Fn strtoq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 55.Sh DESCRIPTION
57The 56The
58.Fn strtol 57.Fn strtol
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..e4ad557fd5 100644
--- a/src/lib/libc/stdlib/strtol.c
+++ b/src/lib/libc/stdlib/strtol.c
@@ -32,13 +32,12 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: strtol.c,v 1.4 1996/08/19 08:33:51 tholo Exp $";
36static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <limits.h>
40#include <ctype.h> 38#include <ctype.h>
41#include <errno.h> 39#include <errno.h>
40#include <limits.h>
42#include <stdlib.h> 41#include <stdlib.h>
43 42
44 43
@@ -54,25 +53,28 @@ strtol(nptr, endptr, base)
54 char **endptr; 53 char **endptr;
55 register int base; 54 register int base;
56{ 55{
57 register const char *s = nptr; 56 register const char *s;
58 register unsigned long acc; 57 register long acc, cutoff;
59 register int c; 58 register int c;
60 register unsigned long cutoff; 59 register int neg, any, cutlim;
61 register int neg = 0, any, cutlim;
62 60
63 /* 61 /*
64 * Skip white space and pick up leading +/- sign if any. 62 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 63 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 64 * assume decimal; if base is already 16, allow 0x.
67 */ 65 */
66 s = nptr;
68 do { 67 do {
69 c = *s++; 68 c = (unsigned char) *s++;
70 } while (isspace(c)); 69 } while (isspace(c));
71 if (c == '-') { 70 if (c == '-') {
72 neg = 1; 71 neg = 1;
73 c = *s++; 72 c = *s++;
74 } else if (c == '+') 73 } else {
75 c = *s++; 74 neg = 0;
75 if (c == '+')
76 c = *s++;
77 }
76 if ((base == 0 || base == 16) && 78 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 79 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 80 c = s[1];
@@ -99,10 +101,17 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 101 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 102 * overflow.
101 */ 103 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 104 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 105 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 106 cutoff /= base;
105 for (acc = 0, any = 0;; c = *s++) { 107 if (neg) {
108 if (cutlim > 0) {
109 cutlim -= base;
110 cutoff += 1;
111 }
112 cutlim = -cutlim;
113 }
114 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
106 if (isdigit(c)) 115 if (isdigit(c))
107 c -= '0'; 116 c -= '0';
108 else if (isalpha(c)) 117 else if (isalpha(c))
@@ -111,19 +120,30 @@ strtol(nptr, endptr, base)
111 break; 120 break;
112 if (c >= base) 121 if (c >= base)
113 break; 122 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 123 if (any < 0)
115 any = -1; 124 continue;
116 else { 125 if (neg) {
117 any = 1; 126 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 127 any = -1;
119 acc += c; 128 acc = LONG_MIN;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc -= c;
134 }
135 } else {
136 if (acc > cutoff || acc == cutoff && c > cutlim) {
137 any = -1;
138 acc = LONG_MAX;
139 errno = ERANGE;
140 } else {
141 any = 1;
142 acc *= base;
143 acc += c;
144 }
120 } 145 }
121 } 146 }
122 if (any < 0) {
123 acc = neg ? LONG_MIN : LONG_MAX;
124 errno = ERANGE;
125 } else if (neg)
126 acc = -acc;
127 if (endptr != 0) 147 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 148 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 149 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoq.c
index fc559e9d7f..44aabd73f0 100644
--- a/src/lib/libc/stdlib/strtoq.c
+++ b/src/lib/libc/stdlib/strtoq.c
@@ -32,14 +32,14 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; 35static char rcsid[] = "$OpenBSD: strtoq.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39 39
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45/* 45/*
@@ -55,9 +55,8 @@ strtoq(nptr, endptr, base)
55 register int base; 55 register int base;
56{ 56{
57 register const char *s; 57 register const char *s;
58 register u_quad_t acc; 58 register quad_t acc, cutoff;
59 register int c; 59 register int c;
60 register u_quad_t qbase, cutoff;
61 register int neg, any, cutlim; 60 register int neg, any, cutlim;
62 61
63 /* 62 /*
@@ -67,7 +66,7 @@ strtoq(nptr, endptr, base)
67 */ 66 */
68 s = nptr; 67 s = nptr;
69 do { 68 do {
70 c = *s++; 69 c = (unsigned char) *s++;
71 } while (isspace(c)); 70 } while (isspace(c));
72 if (c == '-') { 71 if (c == '-') {
73 neg = 1; 72 neg = 1;
@@ -104,11 +103,17 @@ strtoq(nptr, endptr, base)
104 * Set any if any `digits' consumed; make it negative to indicate 103 * Set any if any `digits' consumed; make it negative to indicate
105 * overflow. 104 * overflow.
106 */ 105 */
107 qbase = (unsigned)base; 106 cutoff = neg ? QUAD_MIN : QUAD_MAX;
108 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 107 cutlim = cutoff % base;
109 cutlim = cutoff % qbase; 108 cutoff /= base;
110 cutoff /= qbase; 109 if (neg) {
111 for (acc = 0, any = 0;; c = *s++) { 110 if (cutlim > 0) {
111 cutlim -= base;
112 cutoff += 1;
113 }
114 cutlim = -cutlim;
115 }
116 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
112 if (isdigit(c)) 117 if (isdigit(c))
113 c -= '0'; 118 c -= '0';
114 else if (isalpha(c)) 119 else if (isalpha(c))
@@ -117,19 +122,30 @@ strtoq(nptr, endptr, base)
117 break; 122 break;
118 if (c >= base) 123 if (c >= base)
119 break; 124 break;
120 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 125 if (any < 0)
121 any = -1; 126 continue;
122 else { 127 if (neg) {
123 any = 1; 128 if (acc < cutoff || acc == cutoff && c > cutlim) {
124 acc *= qbase; 129 any = -1;
125 acc += c; 130 acc = QUAD_MIN;
131 errno = ERANGE;
132 } else {
133 any = 1;
134 acc *= base;
135 acc -= c;
136 }
137 } else {
138 if (acc > cutoff || acc == cutoff && c > cutlim) {
139 any = -1;
140 acc = QUAD_MAX;
141 errno = ERANGE;
142 } else {
143 any = 1;
144 acc *= base;
145 acc += c;
146 }
126 } 147 }
127 } 148 }
128 if (any < 0) {
129 acc = neg ? QUAD_MIN : QUAD_MAX;
130 errno = ERANGE;
131 } else if (neg)
132 acc = -acc;
133 if (endptr != 0) 149 if (endptr != 0)
134 *endptr = (char *) (any ? s - 1 : nptr); 150 *endptr = (char *) (any ? s - 1 : nptr);
135 return (acc); 151 return (acc);
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
index db551b0141..b8234122a2 100644
--- a/src/lib/libc/stdlib/strtoul.3
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)strtoul.3 5.4 (Berkeley) 6/25/92 36.\" $OpenBSD: strtoul.3,v 1.2 1996/08/19 08:33:52 tholo Exp $
37.\" $Id: strtoul.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 37.\"
39.Dd June 25, 1992 38.Dd June 25, 1992
40.Dt STRTOUL 3 39.Dt STRTOUL 3
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..d3b363fa04 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -32,13 +32,12 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: strtoul.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <limits.h>
40#include <ctype.h> 38#include <ctype.h>
41#include <errno.h> 39#include <errno.h>
40#include <limits.h>
42#include <stdlib.h> 41#include <stdlib.h>
43 42
44/* 43/*
@@ -53,23 +52,26 @@ strtoul(nptr, endptr, base)
53 char **endptr; 52 char **endptr;
54 register int base; 53 register int base;
55{ 54{
56 register const char *s = nptr; 55 register const char *s;
57 register unsigned long acc; 56 register unsigned long acc, cutoff;
58 register int c; 57 register int c;
59 register unsigned long cutoff; 58 register int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 59
62 /* 60 /*
63 * See strtol for comments as to the logic used. 61 * See strtol for comments as to the logic used.
64 */ 62 */
63 s = nptr;
65 do { 64 do {
66 c = *s++; 65 c = (unsigned char) *s++;
67 } while (isspace(c)); 66 } while (isspace(c));
68 if (c == '-') { 67 if (c == '-') {
69 neg = 1; 68 neg = 1;
70 c = *s++; 69 c = *s++;
71 } else if (c == '+') 70 } else {
72 c = *s++; 71 neg = 0;
72 if (c == '+')
73 c = *s++;
74 }
73 if ((base == 0 || base == 16) && 75 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 76 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 77 c = s[1];
@@ -78,9 +80,10 @@ strtoul(nptr, endptr, base)
78 } 80 }
79 if (base == 0) 81 if (base == 0)
80 base = c == '0' ? 8 : 10; 82 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 83
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 84 cutoff = ULONG_MAX / (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 85 cutlim = ULONG_MAX % (unsigned long)base;
86 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
84 if (isdigit(c)) 87 if (isdigit(c))
85 c -= '0'; 88 c -= '0';
86 else if (isalpha(c)) 89 else if (isalpha(c))
@@ -89,18 +92,19 @@ strtoul(nptr, endptr, base)
89 break; 92 break;
90 if (c >= base) 93 if (c >= base)
91 break; 94 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 95 if (any < 0)
96 continue;
97 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 98 any = -1;
94 else { 99 acc = ULONG_MAX;
100 errno = ERANGE;
101 } else {
95 any = 1; 102 any = 1;
96 acc *= base; 103 acc *= (unsigned long)base;
97 acc += c; 104 acc += c;
98 } 105 }
99 } 106 }
100 if (any < 0) { 107 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 108 acc = -acc;
105 if (endptr != 0) 109 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 110 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtouq.c
index cc647d8d28..1f29a22f33 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtouq.c
@@ -32,14 +32,14 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; 35static char rcsid[] = "$OpenBSD: strtouq.c,v 1.4 1996/08/19 08:33:53 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39 39
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45/* 45/*
@@ -54,10 +54,9 @@ strtouq(nptr, endptr, base)
54 char **endptr; 54 char **endptr;
55 register int base; 55 register int base;
56{ 56{
57 register const char *s = nptr; 57 register const char *s;
58 register u_quad_t acc; 58 register u_quad_t acc, cutoff;
59 register int c; 59 register int c;
60 register u_quad_t qbase, cutoff;
61 register int neg, any, cutlim; 60 register int neg, any, cutlim;
62 61
63 /* 62 /*
@@ -65,7 +64,7 @@ strtouq(nptr, endptr, base)
65 */ 64 */
66 s = nptr; 65 s = nptr;
67 do { 66 do {
68 c = *s++; 67 c = (unsigned char) *s++;
69 } while (isspace(c)); 68 } while (isspace(c));
70 if (c == '-') { 69 if (c == '-') {
71 neg = 1; 70 neg = 1;
@@ -83,10 +82,10 @@ strtouq(nptr, endptr, base)
83 } 82 }
84 if (base == 0) 83 if (base == 0)
85 base = c == '0' ? 8 : 10; 84 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 85
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 86 cutoff = UQUAD_MAX / (u_quad_t)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 87 cutlim = UQUAD_MAX % (u_quad_t)base;
89 for (acc = 0, any = 0;; c = *s++) { 88 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
90 if (isdigit(c)) 89 if (isdigit(c))
91 c -= '0'; 90 c -= '0';
92 else if (isalpha(c)) 91 else if (isalpha(c))
@@ -95,18 +94,19 @@ strtouq(nptr, endptr, base)
95 break; 94 break;
96 if (c >= base) 95 if (c >= base)
97 break; 96 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 97 if (any < 0)
98 continue;
99 if (acc > cutoff || acc == cutoff && c > cutlim) {
99 any = -1; 100 any = -1;
100 else { 101 acc = UQUAD_MAX;
102 errno = ERANGE;
103 } else {
101 any = 1; 104 any = 1;
102 acc *= qbase; 105 acc *= (u_quad_t)base;
103 acc += c; 106 acc += c;
104 } 107 }
105 } 108 }
106 if (any < 0) { 109 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 110 acc = -acc;
111 if (endptr != 0) 111 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 112 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
index 520f51db0a..985adb07de 100644
--- a/src/lib/libc/stdlib/system.3
+++ b/src/lib/libc/stdlib/system.3
@@ -33,8 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" from: @(#)system.3 6.5 (Berkeley) 6/29/91 36.\" $OpenBSD: system.3,v 1.5 1996/12/11 23:09:53 tholo Exp $
37.\" $Id: system.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 37.\"
39.Dd June 29, 1991 38.Dd June 29, 1991
40.Dt SYSTEM 3 39.Dt SYSTEM 3
@@ -72,7 +71,7 @@ will return non-zero.
72Otherwise, 71Otherwise,
73.Fn system 72.Fn system
74returns the termination status of the shell in the format specified by 73returns the termination status of the shell in the format specified by
75.Xr waitpid 3 . 74.Xr waitpid 2 .
76.Sh RETURN VALUES 75.Sh RETURN VALUES
77If a child process cannot be created, or the termination status of 76If a child process cannot be created, or the termination status of
78the shell cannot be obtained, 77the shell cannot be obtained,
@@ -87,8 +86,8 @@ returns the termination status for a program that terminates with a call of
87.Sh SEE ALSO 86.Sh SEE ALSO
88.Xr sh 1 , 87.Xr sh 1 ,
89.Xr execve 2 , 88.Xr execve 2 ,
90.Xr popen 3 , 89.Xr waitpid 2 ,
91.Xr waitpid 3 , 90.Xr popen 3
92.Sh STANDARDS 91.Sh STANDARDS
93The 92The
94.Fn system 93.Fn system
@@ -96,4 +95,4 @@ function
96conforms to 95conforms to
97.St -ansiC 96.St -ansiC
98and 97and
99.St -1003.2-92 . 98.St -p1003.2-92 .
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index c2f39325f6..3e1b047393 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -32,8 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/ 35static char *rcsid = "$OpenBSD: system.c,v 1.3 1996/09/15 09:31:52 tholo Exp $";
36static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
38 37
39#include <sys/types.h> 38#include <sys/types.h>
@@ -53,11 +52,13 @@ system(command)
53 sig_t intsave, quitsave; 52 sig_t intsave, quitsave;
54 int omask; 53 int omask;
55 int pstat; 54 int pstat;
56 char *argp[] = {"sh", "-c", (char *) command, NULL}; 55 char *argp[] = {"sh", "-c", NULL, NULL};
57 56
58 if (!command) /* just checking... */ 57 if (!command) /* just checking... */
59 return(1); 58 return(1);
60 59
60 argp[2] = (char *)command;
61
61 omask = sigblock(sigmask(SIGCHLD)); 62 omask = sigblock(sigmask(SIGCHLD));
62 switch(pid = vfork()) { 63 switch(pid = vfork()) {
63 case -1: /* error */ 64 case -1: /* error */
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..9e5bd4b0f2
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12#include <search.h>
13
14typedef struct node_t
15{
16 char *key;
17 struct node_t *llink, *rlink;
18} node;
19
20/* find a node, or return 0 */
21void *
22tfind(vkey, vrootp, compar)
23 const void *vkey; /* key to be found */
24 void *const *vrootp; /* address of the tree root */
25 int (*compar) __P((const void *, const void *));
26{
27 char *key = (char *)vkey;
28 node **rootp = (node **)vrootp;
29
30 if (rootp == (struct node_t **)0)
31 return ((struct node_t *)0);
32 while (*rootp != (struct node_t *)0) { /* T1: */
33 int r;
34 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
35 return (*rootp); /* key found */
36 rootp = (r < 0) ?
37 &(*rootp)->llink : /* T3: follow left branch */
38 &(*rootp)->rlink; /* T4: follow right branch */
39 }
40 return (node *)0;
41}
diff --git a/src/lib/libc/stdlib/tsearch.3 b/src/lib/libc/stdlib/tsearch.3
new file mode 100644
index 0000000000..dbdae7943c
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,116 @@
1.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. The name of the author may not be used to endorse or promote products
13.\" derived from this software without specific prior written permission.
14.\"
15.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp $
27.\"
28.Dd June 15, 1997
29.Dt TSEARCH 3
30.Os
31.Sh NAME
32.Nm tsearch, tfind, tdelete, twalk
33.Nd manipulate binary search trees
34.Sh SYNOPSIS
35.Fd #include <search.h>
36.Ft void *
37.Fn tdelete "const void *key" "void **rootp", "int (*compar) (const void *, const void *)"
38.Ft void *
39.Fn tfind "const void *key" "void * const *rootp", "int (*compar) (const void *, const void *)"
40.Ft void *
41.Fn tsearch "const void *key" "void **rootp", "int (*compar) (const void *, const void *)"
42.Ft void
43.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)"
44.Sh DESCRIPTION
45The
46.Fn tdelete ,
47.Fn tfind ,
48.Fn tsearch ,
49and
50.Fn twalk
51functions manage binary search trees based on algorithms T and D
52from Knuth (6.2.2). The comparison function passed in by
53the user has the same style of return values as
54.Xr strcmp 3 .
55.Pp
56.Fn Tfind
57searches for the datum matched by the argument
58.Fa key
59in the binary tree rooted at
60.Fa rootp ,
61returning a pointer to the datum if it is found and NULL
62if it is not.
63.Pp
64.Fn Tsearch
65is identical to
66.Fn tfind
67except that if no match is found,
68.Fa key
69is inserted into the tree and a pointer to it is returned. If
70.Fa rootp
71points to a NULL value a new binary search tree is created.
72.Pp
73.Fn Tdelete
74deletes a node from the specified binary search tree and returns
75a pointer to the parent of the node to be deleted.
76It takes the same arguments as
77.Fn tfind
78and
79.Fn tsearch .
80If the node to be deleted is the root of the binary search tree,
81.Fa rootp
82will be adjusted.
83.Pp
84.Fn Twalk
85walks the binary search tree rooted in
86.fa root
87and calls the function
88.Fa action
89on each node.
90.Fa Action
91is called with three arguments: a pointer to the current node,
92a value from the enum
93.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
94specifying the traversal type, and a node level (where level
95zero is the root of the tree).
96.Sh SEE ALSO
97.Xr bsearch 3 ,
98.Xr hsearch 3 ,
99.Xr lsearch 3
100.Sh RETURN VALUES
101The
102.Fn tsearch
103function returns NULL if allocation of a new node fails (usually
104due to a lack of free memory).
105.Pp
106.Fn Tfind ,
107.Fn tsearch ,
108and
109.Fn tdelete
110return NULL if
111.Fa rootp
112is NULL or the datum cannot be found.
113.Pp
114The
115.Fn twalk
116function returns no value.
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..562ace1845
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,126 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12
13#include <search.h>
14#include <stdlib.h>
15
16typedef struct node_t {
17 char *key;
18 struct node_t *left, *right;
19} node;
20
21/* find or insert datum into search tree */
22void *
23tsearch(vkey, vrootp, compar)
24 const void *vkey; /* key to be located */
25 void **vrootp; /* address of tree root */
26 int (*compar) __P((const void *, const void *));
27{
28 register node *q;
29 char *key = (char *)vkey;
30 node **rootp = (node **)vrootp;
31
32 if (rootp == (struct node_t **)0)
33 return ((void *)0);
34 while (*rootp != (struct node_t *)0) { /* Knuth's T1: */
35 int r;
36
37 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
38 return ((void *)*rootp); /* we found it! */
39 rootp = (r < 0) ?
40 &(*rootp)->left : /* T3: follow left branch */
41 &(*rootp)->right; /* T4: follow right branch */
42 }
43 q = (node *) malloc(sizeof(node)); /* T5: key not found */
44 if (q != (struct node_t *)0) { /* make new node */
45 *rootp = q; /* link new node to old */
46 q->key = key; /* initialize new node */
47 q->left = q->right = (struct node_t *)0;
48 }
49 return ((void *)q);
50}
51
52/* delete node with given key */
53void *
54tdelete(vkey, vrootp, compar)
55 const void *vkey; /* key to be deleted */
56 void **vrootp; /* address of the root of tree */
57 int (*compar) __P((const void *, const void *));
58{
59 node **rootp = (node **)vrootp;
60 char *key = (char *)vkey;
61 node *p;
62 register node *q;
63 register node *r;
64 int cmp;
65
66 if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
67 return ((struct node_t *)0);
68 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
69 p = *rootp;
70 rootp = (cmp < 0) ?
71 &(*rootp)->left : /* follow left branch */
72 &(*rootp)->right; /* follow right branch */
73 if (*rootp == (struct node_t *)0)
74 return ((void *)0); /* key not found */
75 }
76 r = (*rootp)->right; /* D1: */
77 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
78 q = r;
79 else if (r != (struct node_t *)0) { /* Right link is null? */
80 if (r->left == (struct node_t *)0) { /* D2: Find successor */
81 r->left = q;
82 q = r;
83 } else { /* D3: Find (struct node_t *)0 link */
84 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
85 r = q;
86 r->left = q->right;
87 q->left = (*rootp)->left;
88 q->right = (*rootp)->right;
89 }
90 }
91 free((struct node_t *) *rootp); /* D4: Free node */
92 *rootp = q; /* link parent to new node */
93 return(p);
94}
95
96/* Walk the nodes of a tree */
97static void
98trecurse(root, action, level)
99 register node *root; /* Root of the tree to be walked */
100 register void (*action)(); /* Function to be called at each node */
101 register int level;
102{
103 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
104 (*action)(root, leaf, level);
105 else {
106 (*action)(root, preorder, level);
107 if (root->left != (struct node_t *)0)
108 trecurse(root->left, action, level + 1);
109 (*action)(root, postorder, level);
110 if (root->right != (struct node_t *)0)
111 trecurse(root->right, action, level + 1);
112 (*action)(root, endorder, level);
113 }
114}
115
116/* Walk the nodes of a tree */
117void
118twalk(vroot, action)
119 const void *vroot; /* Root of the tree to be walked */
120 void (*action) __P((const void *, VISIT, int));
121{
122 node *root = (node *)vroot;
123
124 if (root != (node *)0 && action != (void(*)())0)
125 trecurse(root, action, 0);
126}