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.inc54
-rw-r--r--src/lib/libc/stdlib/_rand48.c50
-rw-r--r--src/lib/libc/stdlib/a64l.3122
-rw-r--r--src/lib/libc/stdlib/a64l.c46
-rw-r--r--src/lib/libc/stdlib/abort.370
-rw-r--r--src/lib/libc/stdlib/abort.c77
-rw-r--r--src/lib/libc/stdlib/abs.373
-rw-r--r--src/lib/libc/stdlib/abs.c45
-rw-r--r--src/lib/libc/stdlib/alloca.375
-rw-r--r--src/lib/libc/stdlib/atexit.377
-rw-r--r--src/lib/libc/stdlib/atexit.c67
-rw-r--r--src/lib/libc/stdlib/atexit.h45
-rw-r--r--src/lib/libc/stdlib/atof.373
-rw-r--r--src/lib/libc/stdlib/atof.c45
-rw-r--r--src/lib/libc/stdlib/atoi.373
-rw-r--r--src/lib/libc/stdlib/atoi.c45
-rw-r--r--src/lib/libc/stdlib/atol.374
-rw-r--r--src/lib/libc/stdlib/atol.c45
-rw-r--r--src/lib/libc/stdlib/bsearch.390
-rw-r--r--src/lib/libc/stdlib/bsearch.c79
-rw-r--r--src/lib/libc/stdlib/calloc.370
-rw-r--r--src/lib/libc/stdlib/calloc.c53
-rw-r--r--src/lib/libc/stdlib/cfree.c49
-rw-r--r--src/lib/libc/stdlib/div.369
-rw-r--r--src/lib/libc/stdlib/div.c79
-rw-r--r--src/lib/libc/stdlib/drand48.c26
-rw-r--r--src/lib/libc/stdlib/erand48.c27
-rw-r--r--src/lib/libc/stdlib/exit.383
-rw-r--r--src/lib/libc/stdlib/exit.c60
-rw-r--r--src/lib/libc/stdlib/getenv.3151
-rw-r--r--src/lib/libc/stdlib/getenv.c89
-rw-r--r--src/lib/libc/stdlib/getopt.3261
-rw-r--r--src/lib/libc/stdlib/getopt.c117
-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.c183
-rw-r--r--src/lib/libc/stdlib/jrand48.c25
-rw-r--r--src/lib/libc/stdlib/l64a.c46
-rw-r--r--src/lib/libc/stdlib/labs.366
-rw-r--r--src/lib/libc/stdlib/labs.c45
-rw-r--r--src/lib/libc/stdlib/lcong48.c34
-rw-r--r--src/lib/libc/stdlib/ldiv.371
-rw-r--r--src/lib/libc/stdlib/ldiv.c58
-rw-r--r--src/lib/libc/stdlib/lrand48.c27
-rw-r--r--src/lib/libc/stdlib/malloc.3350
-rw-r--r--src/lib/libc/stdlib/malloc.c1242
-rw-r--r--src/lib/libc/stdlib/memory.370
-rw-r--r--src/lib/libc/stdlib/merge.c347
-rw-r--r--src/lib/libc/stdlib/mrand48.c27
-rw-r--r--src/lib/libc/stdlib/multibyte.c130
-rw-r--r--src/lib/libc/stdlib/nrand48.c25
-rw-r--r--src/lib/libc/stdlib/putenv.c58
-rw-r--r--src/lib/libc/stdlib/qabs.361
-rw-r--r--src/lib/libc/stdlib/qabs.c45
-rw-r--r--src/lib/libc/stdlib/qdiv.365
-rw-r--r--src/lib/libc/stdlib/qdiv.c58
-rw-r--r--src/lib/libc/stdlib/qsort.3233
-rw-r--r--src/lib/libc/stdlib/qsort.c175
-rw-r--r--src/lib/libc/stdlib/radixsort.3161
-rw-r--r--src/lib/libc/stdlib/radixsort.c317
-rw-r--r--src/lib/libc/stdlib/rand.387
-rw-r--r--src/lib/libc/stdlib/rand.c54
-rw-r--r--src/lib/libc/stdlib/rand48.3161
-rw-r--r--src/lib/libc/stdlib/rand48.h32
-rw-r--r--src/lib/libc/stdlib/random.3183
-rw-r--r--src/lib/libc/stdlib/random.c370
-rw-r--r--src/lib/libc/stdlib/realpath.3125
-rw-r--r--src/lib/libc/stdlib/realpath.c163
-rw-r--r--src/lib/libc/stdlib/seed48.c40
-rw-r--r--src/lib/libc/stdlib/setenv.c120
-rw-r--r--src/lib/libc/stdlib/srand48.c34
-rw-r--r--src/lib/libc/stdlib/strtod.3113
-rw-r--r--src/lib/libc/stdlib/strtod.c2529
-rw-r--r--src/lib/libc/stdlib/strtol.3168
-rw-r--r--src/lib/libc/stdlib/strtol.c150
-rw-r--r--src/lib/libc/stdlib/strtoq.c152
-rw-r--r--src/lib/libc/stdlib/strtoul.3163
-rw-r--r--src/lib/libc/stdlib/strtoul.c112
-rw-r--r--src/lib/libc/stdlib/strtouq.c114
-rw-r--r--src/lib/libc/stdlib/system.398
-rw-r--r--src/lib/libc/stdlib/system.c80
-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
84 files changed, 11963 insertions, 0 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000000..e75fc0d8bf
--- /dev/null
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,54 @@
1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2
3# stdlib sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \
7 cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c l64a.c \
8 malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c rand.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 \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13
14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
17.elif (${MACHINE_ARCH} == "i386")
18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
20.elif (${MACHINE_ARCH} == "ns32k")
21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
23.elif (${MACHINE_ARCH} == "tahoe")
24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
26.elif (${MACHINE_ARCH} == "vax")
27SRCS+= abs.c div.c labs.c ldiv.c
28.elif (${MACHINE_ARCH} == "alpha")
29# XXX should be .S's
30SRCS+= abs.c div.c labs.c ldiv.c
31.else
32SRCS+= abs.c div.c labs.c ldiv.c
33.endif
34
35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
36 calloc.3 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \
37 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
39
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
43MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
44MLINKS+=rand.3 srand.3
45MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3
46MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
47MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.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
new file mode 100644
index 0000000000..fed7372f68
--- /dev/null
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20unsigned short __rand48_seed[3] = {
21 RAND48_SEED_0,
22 RAND48_SEED_1,
23 RAND48_SEED_2
24};
25unsigned short __rand48_mult[3] = {
26 RAND48_MULT_0,
27 RAND48_MULT_1,
28 RAND48_MULT_2
29};
30unsigned short __rand48_add = RAND48_ADD;
31
32void
33__dorand48(unsigned short xseed[3])
34{
35 unsigned long accu;
36 unsigned short temp[2];
37
38 accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
39 (unsigned long) __rand48_add;
40 temp[0] = (unsigned short) accu; /* lower 16 bits */
41 accu >>= sizeof(unsigned short) * 8;
42 accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
43 (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
44 temp[1] = (unsigned short) accu; /* middle 16 bits */
45 accu >>= sizeof(unsigned short) * 8;
46 accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
47 xseed[0] = temp[0];
48 xseed[1] = temp[1];
49 xseed[2] = (unsigned short) accu;
50}
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
new file mode 100644
index 0000000000..a68f0a6dcd
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13long
14a64l(s)
15 const char *s;
16{
17 long value, digit, shift;
18 int i;
19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
25 value = 0;
26 shift = 0;
27 for (i = 0; *s && i < 6; i++, s++) {
28 if (*s >= '.' && *s <= '/')
29 digit = *s - '.';
30 else if (*s >= '0' && *s <= '9')
31 digit = *s - '0' + 2;
32 else if (*s >= 'A' && *s <= 'Z')
33 digit = *s - 'A' + 12;
34 else if (*s >= 'a' && *s <= 'z')
35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
40
41 value |= digit << shift;
42 shift += 6;
43 }
44
45 return(value);
46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000000..92c9a354d0
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: abort.3,v 1.4 1997/07/17 07:39:41 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABORT 3
40.Os
41.Sh NAME
42.Nm abort
43.Nd cause abnormal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn abort void
48.Sh DESCRIPTION
49The
50.Fn abort
51function causes abnormal program termination to occur, unless the
52signal
53.Dv SIGABRT
54is being caught and the signal handler does not return.
55.Pp
56Any open streams are flushed and closed.
57.Sh RETURN VALUES
58The
59.Nm abort
60function
61never returns.
62.Sh SEE ALSO
63.Xr sigaction 2 ,
64.Xr exit 3
65.Sh STANDARDS
66The
67.Fn abort
68function
69conforms to
70.St -p1003.1-90 .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000000..4ea8a2ca4b
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.c
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 1985 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abort.c,v 1.5 1997/06/22 20:21:25 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <signal.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42void (*__cleanup)();
43
44void
45abort()
46{
47 static int cleanup_called = 0;
48 sigset_t mask;
49
50
51 sigfillset(&mask);
52 /*
53 * don't block SIGABRT to give any handler a chance; we ignore
54 * any errors -- X311J doesn't allow abort to return anyway.
55 */
56 sigdelset(&mask, SIGABRT);
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
67 (void)kill(getpid(), SIGABRT);
68
69 /*
70 * if SIGABRT ignored, or caught and the handler returns, do
71 * it again, only harder.
72 */
73 (void)signal(SIGABRT, SIG_DFL);
74 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
75 (void)kill(getpid(), SIGABRT);
76 exit(1);
77}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000000..77f82b9402
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: abs.3,v 1.2 1996/08/19 08:33:21 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABS 3
40.Os
41.Sh NAME
42.Nm abs
43.Nd integer absolute value function
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn abs "int j"
48.Sh DESCRIPTION
49The
50.Fn abs
51function
52computes
53the absolute value of the integer
54.Ar j .
55.Sh RETURN VALUES
56The
57.Fn abs
58function
59returns
60the absolute value.
61.Sh SEE ALSO
62.Xr floor 3 ,
63.Xr labs 3 ,
64.Xr cabs 3 ,
65.Xr hypot 3 ,
66.Xr math 3
67.Sh STANDARDS
68The
69.Fn abs
70function conforms to
71.St -ansiC .
72.Sh BUGS
73The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
new file mode 100644
index 0000000000..7c79e4073c
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abs.c,v 1.2 1996/08/19 08:33:21 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41abs(j)
42 int j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
new file mode 100644
index 0000000000..ef87220772
--- /dev/null
+++ b/src/lib/libc/stdlib/alloca.3
@@ -0,0 +1,75 @@
1.\" Copyright (c) 1980, 1991 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.\" $OpenBSD: alloca.3,v 1.3 1996/08/19 08:33:22 tholo Exp $
33.\"
34.Dd May 2, 1991
35.Dt ALLOCA 3
36.Os BSD 4
37.Sh NAME
38.Nm alloca
39.Nd memory allocator
40.Sh SYNOPSIS
41.Fd #include <stdlib.h>
42.Ft void *
43.Fn alloca "size_t size"
44.Sh DESCRIPTION
45The
46.Fn alloca
47function
48allocates
49.Fa size
50bytes of space in the stack frame of the caller.
51This temporary space is automatically freed on
52return.
53.Sh RETURN VALUES
54The
55.Fn alloca
56function returns a pointer to the beginning of the allocated space.
57.Sh SEE ALSO
58.Xr brk 2 ,
59.Xr pagesize 2
60.Xr calloc 3 ,
61.Xr malloc 3 ,
62.Xr realloc 3 ,
63.Sh BUGS
64The
65.Fn alloca
66function
67is machine dependent; its use is discouraged.
68.\" .Sh HISTORY
69.\" The
70.\" .Fn alloca
71.\" function appeared in
72.\" .Bx ?? .
73.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
74.\" The first man page (or link to a man page that I can find at the
75.\" moment is 4.3...
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000000..0b10f010fa
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.3
@@ -0,0 +1,77 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information 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.\" $OpenBSD: atexit.3,v 1.2 1996/08/19 08:33:22 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATEXIT 3
40.Os
41.Sh NAME
42.Nm atexit
43.Nd register a function to be called on exit
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn atexit "void (*function)(void)"
48.Sh DESCRIPTION
49The
50.Fn atexit
51function
52registers the given
53.Ar function
54to be called at program exit, whether via
55.Xr exit 3
56or via return from the program's
57.Em main .
58Functions so registered are called in reverse order;
59no arguments are passed.
60At least 32 functions can always be registered,
61and more are allowed as long as sufficient memory can be allocated.
62.Sh RETURN VALUES
63.Rv -std atexit
64.Sh ERRORS
65.Bl -tag -width Er
66.It Bq Er ENOMEM
67No memory was available to add the function to the list.
68The existing list of functions is unmodified.
69.El
70.Sh SEE ALSO
71.Xr exit 3
72.Sh STANDARDS
73The
74.Fn atexit
75function
76conforms to
77.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000000..c0fb624141
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: atexit.c,v 1.2 1996/08/19 08:33:22 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h>
42#include "atexit.h"
43
44struct atexit *__atexit;
45
46/*
47 * Register a function to be performed at exit.
48 */
49int
50atexit(fn)
51 void (*fn)();
52{
53 static struct atexit __atexit0; /* one guaranteed table */
54 register struct atexit *p;
55
56 if ((p = __atexit) == NULL)
57 __atexit = p = &__atexit0;
58 else if (p->ind >= ATEXIT_SIZE) {
59 if ((p = malloc(sizeof(*p))) == NULL)
60 return (-1);
61 p->ind = 0;
62 p->next = __atexit;
63 __atexit = p;
64 }
65 p->fns[p->ind++] = fn;
66 return (0);
67}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000000..e41a7cb86c
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.h
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 *
33 * $OpenBSD: atexit.h,v 1.2 1996/08/19 08:33:23 tholo Exp $
34 */
35
36/* must be at least 32 to guarantee ANSI conformance */
37#define ATEXIT_SIZE 32
38
39struct atexit {
40 struct atexit *next; /* next in list */
41 int ind; /* next index in this table */
42 void (*fns[ATEXIT_SIZE])(); /* the table itself */
43};
44
45extern struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
new file mode 100644
index 0000000000..cc1b500b0f
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.3
@@ -0,0 +1,73 @@
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.\" $OpenBSD: atof.3,v 1.2 1996/08/19 08:33:23 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOF 3
40.Os
41.Sh NAME
42.Nm atof
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn atof "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atof
53function converts the initial portion of the string pointed to by
54.Ar nptr
55to
56.Ar double
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtod(nptr, (char **)NULL);
62.Ed
63.Sh SEE ALSO
64.Xr atoi 3 ,
65.Xr atol 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atof
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
new file mode 100644
index 0000000000..30bac19899
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atof.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40double
41atof(ascii)
42 const char *ascii;
43{
44 return(strtod(ascii, (char **)NULL));
45}
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
new file mode 100644
index 0000000000..280a989e8e
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: atoi.3,v 1.2 1996/08/10 04:51:31 tholo Exp $
37.\"
38.Dd June 4, 1993
39.Dt ATOI 3
40.Os
41.Sh NAME
42.Nm atoi
43.Nd convert
44.Tn ASCII
45string to integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft int
49.Fn atoi "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atoi
53function converts the initial portion of the string pointed to by
54.Em nptr
55to
56.Em integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61(int)strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh SEE ALSO
64.Xr atof 3 ,
65.Xr atol 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atoi
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
new file mode 100644
index 0000000000..a74d6e1351
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atoi.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41atoi(str)
42 const char *str;
43{
44 return((int)strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
new file mode 100644
index 0000000000..2b49bd1f2c
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.3
@@ -0,0 +1,74 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: atol.3,v 1.2 1996/08/19 08:33:25 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOL 3
40.Os
41.Sh NAME
42.Nm atol
43.Nd convert
44.Tn ASCII
45string to long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft long
49.Fn atol "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atol
53function converts the initial portion of the string pointed to by
54.Ar nptr
55to
56.Em long integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh SEE ALSO
64.Xr atof 3 ,
65.Xr atoi 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atol
72function
73conforms to
74.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
new file mode 100644
index 0000000000..528a932214
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atol.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41atol(str)
42 const char *str;
43{
44 return(strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
new file mode 100644
index 0000000000..570a4227b4
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,90 @@
1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" The Regents of the University of California. 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.\" $OpenBSD: bsearch.3,v 1.3 1997/06/13 23:41:35 deraadt Exp $
37.\"
38.Dd April 19, 1994
39.Dt BSEARCH 3
40.Os
41.Sh NAME
42.Nm bsearch
43.Nd binary search of a sorted table
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)"
48.Sh DESCRIPTION
49The
50.Fn bsearch
51function searches an array of
52.Fa nmemb
53objects, the initial member of which is
54pointed to by
55.Fa base ,
56for a member that matches the object pointed to by
57.Fa key .
58The size of each member of the array is specified by
59.Fa size .
60.Pp
61The contents of the array should be in ascending sorted order according
62to the comparison function referenced by
63.Fa compar .
64The
65.Fa compar
66routine
67is expected to have
68two arguments which point to the
69.Fa key
70object and to an array member, in that order, and should return an integer
71less than, equal to, or greater than zero if the
72.Fa key
73object is found, respectively, to be less than, to match, or be
74greater than the array member.
75.Sh RETURN VALUES
76The
77.Fn bsearch
78function returns a pointer to a matching member of the array, or a null
79pointer if no match is found.
80If two members compare as equal, which member is matched is unspecified.
81.Sh SEE ALSO
82.Xr db 3 ,
83.Xr lsearch 3 ,
84.Xr qsort 3 ,
85.Xr tsearch 3
86.Sh STANDARDS
87The
88.Fn bsearch
89function conforms to
90.St -ansiC .
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000000..eeef9bffc6
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bsearch.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Perform a binary search.
42 *
43 * The code below is a bit sneaky. After a comparison fails, we
44 * divide the work in half by moving either left or right. If lim
45 * is odd, moving left simply involves halving lim: e.g., when lim
46 * is 5 we look at item 2, so we change lim to 2 so that we will
47 * look at items 0 & 1. If lim is even, the same applies. If lim
48 * is odd, moving right again involes halving lim, this time moving
49 * the base up one item past p: e.g., when lim is 5 we change base
50 * to item 3 and make lim 2 so that we will look at items 3 and 4.
51 * If lim is even, however, we have to shrink it by one before
52 * halving: e.g., when lim is 4, we still looked at item 2, so we
53 * have to make lim 3, then halve, obtaining 1, so that we will only
54 * look at item 3.
55 */
56void *
57bsearch(key, base0, nmemb, size, compar)
58 register const void *key;
59 const void *base0;
60 size_t nmemb;
61 register size_t size;
62 register int (*compar) __P((const void *, const void *));
63{
64 register const char *base = base0;
65 register int lim, cmp;
66 register const void *p;
67
68 for (lim = nmemb; lim != 0; lim >>= 1) {
69 p = base + (lim >> 1) * size;
70 cmp = (*compar)(key, p);
71 if (cmp == 0)
72 return ((void *)p);
73 if (cmp > 0) { /* key > p: move right */
74 base = (char *)p + size;
75 lim--;
76 } /* else move left */
77 }
78 return (NULL);
79}
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/calloc.3
new file mode 100644
index 0000000000..13a912169c
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.3
@@ -0,0 +1,70 @@
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.\" $OpenBSD: calloc.3,v 1.3 1996/12/10 09:06:10 deraadt Exp $
37.\"
38.Dd June 29, 1991
39.Dt CALLOC 3
40.Os
41.Sh NAME
42.Nm calloc
43.Nd allocate clean memory (zero initialized space)
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn calloc "size_t nmemb" "size_t size"
48.Sh DESCRIPTION
49The
50.Fn calloc
51function allocates space for an array of
52.Fa nmemb
53objects, each of whose size is
54.Fa size .
55The space is initialized to all bits zero.
56.Sh RETURN VALUES
57The
58.Fn calloc
59function returns
60a pointer to
61the allocated space if successful; otherwise a null pointer is returned.
62.Sh SEE ALSO
63.Xr malloc 3 ,
64.Xr realloc 3 ,
65.Xr free 3
66.Sh STANDARDS
67The
68.Fn calloc
69function conforms to
70.St -ansiC .
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000000..a2c4f84493
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.c
@@ -0,0 +1,53 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: calloc.c,v 1.3 1996/08/20 17:42:33 downsj Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41void *
42calloc(num, size)
43 size_t num;
44 register size_t size;
45{
46 register void *p;
47
48 size *= num;
49 p = malloc(size);
50 if (p)
51 memset(p, '\0', size);
52 return(p);
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
new file mode 100644
index 0000000000..0d8c56d86b
--- /dev/null
+++ b/src/lib/libc/stdlib/div.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek.
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.\" $OpenBSD: div.3,v 1.2 1996/08/19 08:33:28 tholo Exp $
35.\"
36.Dd April 19, 1991
37.Dt DIV 3
38.Os
39.Sh NAME
40.Nm div
41.Nd return quotient and remainder from division
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Ft div_t
45.Fn div "int num" "int denom"
46.Sh DESCRIPTION
47The
48.Fn div
49function
50computes the value
51.Fa num/denom
52and returns the quotient and remainder in a structure named
53.Fa div_t
54that contains two
55.Em int
56members named
57.Fa quot
58and
59.Fa rem .
60.Sh SEE ALSO
61.Xr ldiv 3 ,
62.Xr qdiv 3 ,
63.Xr math 3
64.Sh STANDARDS
65The
66.Fn div
67function
68conforms to
69.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
new file mode 100644
index 0000000000..c1fae29008
--- /dev/null
+++ b/src/lib/libc/stdlib/div.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: div.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* div_t */
42
43div_t
44div(num, denom)
45 int num, denom;
46{
47 div_t r;
48
49 r.quot = num / denom;
50 r.rem = num % denom;
51 /*
52 * The ANSI standard says that |r.quot| <= |n/d|, where
53 * n/d is to be computed in infinite precision. In other
54 * words, we should always truncate the quotient towards
55 * 0, never -infinity.
56 *
57 * Machine division and remainer may work either way when
58 * one or both of n or d is negative. If only one is
59 * negative and r.quot has been truncated towards -inf,
60 * r.rem will have the same sign as denom and the opposite
61 * sign of num; if both are negative and r.quot has been
62 * truncated towards -inf, r.rem will be positive (will
63 * have the opposite sign of num). These are considered
64 * `wrong'.
65 *
66 * If both are num and denom are positive, r will always
67 * be positive.
68 *
69 * This all boils down to:
70 * if num >= 0, but r.rem < 0, we got the wrong answer.
71 * In that case, to get the right answer, add 1 to r.quot and
72 * subtract denom from r.rem.
73 */
74 if (num >= 0 && r.rem < 0) {
75 r.quot++;
76 r.rem -= denom;
77 }
78 return (r);
79}
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
new file mode 100644
index 0000000000..02886d5b62
--- /dev/null
+++ b/src/lib/libc/stdlib/drand48.c
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22double
23drand48(void)
24{
25 return erand48(__rand48_seed);
26}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
new file mode 100644
index 0000000000..b92dacffcc
--- /dev/null
+++ b/src/lib/libc/stdlib/erand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20double
21erand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ldexp((double) xseed[0], -48) +
25 ldexp((double) xseed[1], -32) +
26 ldexp((double) xseed[2], -16);
27}
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
new file mode 100644
index 0000000000..6dd2affef9
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.3
@@ -0,0 +1,83 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: exit.3,v 1.2 1996/08/19 08:33:30 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt EXIT 3
40.Os
41.Sh NAME
42.Nm exit
43.Nd perform normal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn exit "int status"
48.Sh DESCRIPTION
49.Fn Exit
50terminates a process.
51.Pp
52Before termination it performs the following functions in the
53order listed:
54.Bl -enum -offset indent
55.It
56Call the functions registered with the
57.Xr atexit 3
58function, in the reverse order of their registration.
59.It
60Flush all open output streams.
61.It
62Close all open streams.
63.It
64Unlink all files created with the
65.Xr tmpfile 3
66function.
67.El
68.Sh RETURN VALUES
69The
70.Fn exit
71function
72never returns.
73.Sh SEE ALSO
74.Xr _exit 2 ,
75.Xr atexit 3 ,
76.Xr intro 3 ,
77.Xr tmpfile 3
78.Sh STANDARDS
79The
80.Fn exit
81function
82conforms to
83.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000000..e358c94fd6
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.c
@@ -0,0 +1,60 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: exit.c,v 1.2 1996/08/19 08:33:30 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <unistd.h>
40#include "atexit.h"
41
42void (*__cleanup)();
43
44/*
45 * Exit, flushing stdio buffers if necessary.
46 */
47void
48exit(status)
49 int status;
50{
51 register struct atexit *p;
52 register int n;
53
54 for (p = __atexit; p; p = p->next)
55 for (n = p->ind; --n >= 0;)
56 (*p->fns[n])();
57 if (__cleanup)
58 (*__cleanup)();
59 _exit(status);
60}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000000..24a8d3d095
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.3
@@ -0,0 +1,151 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: getenv.3,v 1.2 1996/08/10 05:03:00 tholo Exp $
37.\"
38.Dd December 11, 1993
39.Dt GETENV 3
40.Os
41.Sh NAME
42.Nm getenv ,
43.Nm putenv ,
44.Nm setenv ,
45.Nm unsetenv
46.Nd environment variable functions
47.Sh SYNOPSIS
48.Fd #include <stdlib.h>
49.Ft char *
50.Fn getenv "const char *name"
51.Ft int
52.Fn setenv "const char *name" "const char *value" "int overwrite"
53.Ft int
54.Fn putenv "const char *string"
55.Ft void
56.Fn unsetenv "const char *name"
57.Sh DESCRIPTION
58These functions set, unset and fetch environment variables from the
59host
60.Em environment list .
61For compatibility with differing environment conventions,
62the given arguments
63.Ar name
64and
65.Ar value
66may be appended and prepended,
67respectively,
68with an equal sign
69.Dq Li \&= .
70.Pp
71The
72.Fn getenv
73function obtains the current value of the environment variable,
74.Ar name .
75If the variable
76.Ar name
77is not in the current environment,
78a null pointer is returned.
79.Pp
80The
81.Fn setenv
82function inserts or resets the environment variable
83.Ar name
84in the current environment list.
85If the variable
86.Ar name
87does not exist in the list,
88it is inserted with the given
89.Ar value.
90If the variable does exist, the argument
91.Ar overwrite
92is tested; if
93.Ar overwrite is
94zero, the
95variable is not reset, otherwise it is reset
96to the given
97.Ar value .
98.Pp
99The
100.Fn putenv
101function takes an argument of the form ``name=value'' and is
102equivalent to:
103.Bd -literal -offset indent
104setenv(name, value, 1);
105.Ed
106.Pp
107The
108.Fn unsetenv
109function
110deletes all instances of the variable name pointed to by
111.Fa name
112from the list.
113.Sh RETURN VALUES
114The functions
115.Fn setenv
116and
117.Fn putenv
118return zero if successful; otherwise the global variable
119.Va errno
120is set to indicate the error and a
121\-1 is returned.
122.Sh ERRORS
123.Bl -tag -width [ENOMEM]
124.It Bq Er ENOMEM
125The function
126.Fn setenv
127or
128.Fn putenv
129failed because they were unable to allocate memory for the environment.
130.El
131.Sh SEE ALSO
132.Xr csh 1 ,
133.Xr sh 1 ,
134.Xr execve 2 ,
135.Xr environ 7
136.Sh STANDARDS
137The
138.Fn getenv
139function conforms to
140.St -ansiC .
141.Sh HISTORY
142The functions
143.Fn setenv
144and
145.Fn unsetenv
146appeared in
147.At v7 .
148The
149.Fn putenv
150function appeared in
151.Bx 4.3 Reno .
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
new file mode 100644
index 0000000000..4db86df915
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 1987, 1993
3 * The Regents of the University of California. 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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getenv.c,v 1.4 1998/07/16 18:02:33 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * __findenv --
43 * Returns pointer to value associated with name, if any, else NULL.
44 * Sets offset to be the offset of the name/value combination in the
45 * environmental array, for use by setenv(3) and unsetenv(3).
46 * Explicitly removes '=' in argument name.
47 *
48 * This routine *should* be a static; don't use it.
49 */
50char *
51__findenv(name, offset)
52 register const char *name;
53 int *offset;
54{
55 extern char **environ;
56 register int len, i;
57 register const char *np;
58 register char **p, *cp;
59
60 if (name == NULL || environ == NULL)
61 return (NULL);
62 for (np = name; *np && *np != '='; ++np)
63 ;
64 len = np - name;
65 for (p = environ; (cp = *p) != NULL; ++p) {
66 for (np = name, i = len; i && *cp; i--)
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));
89}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
new file mode 100644
index 0000000000..4340ff54fd
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.3
@@ -0,0 +1,261 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: getopt.3,v 1.6 1998/05/05 19:36:03 deraadt Exp $
33.\"
34.Dd April 19, 1994
35.Dt GETOPT 3
36.Os BSD 4.3
37.Sh NAME
38.Nm getopt
39.Nd get option character from command line argument list
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Vt extern char *optarg;
43.Vt extern int optind;
44.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset;
47.Ft int
48.Fn getopt "int argc" "char * const *argv" "const char *optstring"
49.Sh DESCRIPTION
50The
51.Fn getopt
52function incrementally parses a command line argument list
53.Fa argv
54and returns the next
55.Em known
56option character.
57An option character is
58.Em known
59if it has been specified in the string of accepted option characters,
60.Fa optstring .
61.Pp
62The option string
63.Fa optstring
64may contain the following elements: individual characters, and
65characters followed by a colon to indicate an option argument
66is to follow.
67For example, an option string
68.Li "\&""x""
69recognizes an option
70.Dq Fl x ,
71and an option string
72.Li "\&""x:""
73recognizes an option and argument
74.Dq Fl x Ar argument .
75It does not matter to
76.Fn getopt
77if a following argument has leading white space.
78.Pp
79On return from
80.Fn getopt ,
81.Va optarg
82points to an option argument, if it is anticipated,
83and the variable
84.Va optind
85contains the index to the next
86.Fa argv
87argument for a subsequent call
88to
89.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp
97The variable
98.Va opterr
99and
100.Va optind
101are both initialized to 1.
102The
103.Va optind
104variable may be set to another value before a set of calls to
105.Fn getopt
106in order to skip over more or less argv entries.
107.Pp
108In order to use
109.Fn getopt
110to evaluate multiple sets of arguments, or to evaluate a single set of
111arguments multiple times,
112the variable
113.Va optreset
114must be set to 1 before the second and each additional set of calls to
115.Fn getopt ,
116and the variable
117.Va optind
118must be reinitialized.
119.Pp
120The
121.Fn getopt
122function
123returns \-1
124when the argument list is exhausted, or a non-recognized
125option is encountered.
126The interpretation of options in the argument list may be cancelled
127by the option
128.Ql --
129(double dash) which causes
130.Fn getopt
131to signal the end of argument processing and returns \-1.
132When all options have been processed (i.e., up to the first non-option
133argument),
134.Fn getopt
135returns \-1.
136.Sh DIAGNOSTICS
137If the
138.Fn getopt
139function encounters a character not found in the string
140.Va optstring
141or detects
142a missing option argument it writes an error message to
143.Em stderr
144and returns
145.Ql ? .
146Setting
147.Va opterr
148to a zero will disable these error messages.
149If
150.Va optstring
151has a leading
152.Ql \&:
153then a missing option argument causes a
154.Ql \&:
155to be returned in addition to suppressing any error messages.
156.Pp
157Option arguments are allowed to begin with
158.Dq Li \- ;
159this is reasonable but
160reduces the amount of error checking possible.
161.Sh EXTENSIONS
162The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt
166function multiple times.
167This is an extension to the
168.St -p1003.2
169specification.
170.Sh EXAMPLE
171.Bd -literal -compact
172extern char *optarg;
173extern int optind;
174int bflag, ch, fd;
175
176bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch (ch) {
179 case 'b':
180 bflag = 1;
181 break;
182 case 'f':
183 if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
184 (void)fprintf(stderr,
185 "myname: %s: %s\en", optarg, strerror(errno));
186 exit(1);
187 }
188 break;
189 case '?':
190 default:
191 usage();
192 }
193}
194argc -= optind;
195argv += optind;
196.Ed
197.Sh HISTORY
198The
199.Fn getopt
200function appeared
201.Bx 4.3 .
202.Sh BUGS
203The
204.Fn getopt
205function was once specified to return
206.Dv EOF
207instead of \-1.
208This was changed by
209.St -p1003.2-92
210to decouple
211.Fn getopt
212from
213.Pa <stdio.h> .
214.Pp
215A single dash
216.Dq Li -
217may be specified as a character in
218.Fa optstring ,
219however it should
220.Em never
221have an argument associated with it.
222This allows
223.Fn getopt
224to be used with programs that expect
225.Dq Li -
226as an option flag.
227This practice is wrong, and should not be used in any current development.
228It is provided for backward compatibility
229.Em only .
230By default, a single dash causes
231.Fn getopt
232to return \-1.
233This is, we believe, compatible with System V.
234.Pp
235It is also possible to handle digits as option letters.
236This allows
237.Fn getopt
238to be used with programs that expect a number
239.Pq Dq Li \&-\&3
240as an option.
241This practice is wrong, and should not be used in any current development.
242It is provided for backward compatibility
243.Em only .
244The following code fragment works in most cases.
245.Bd -literal -offset indent
246int length;
247char *p;
248
249while ((c = getopt(argc, argv, "0123456789")) != -1)
250 switch (c) {
251 case '0': case '1': case '2': case '3': case '4':
252 case '5': case '6': case '7': case '8': case '9':
253 p = argv[optind - 1];
254 if (p[0] == '-' && p[1] == ch && !p[2])
255 length = atoi(++p);
256 else
257 length = atoi(argv[optind] + 1);
258 break;
259 }
260}
261.Ed
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
new file mode 100644
index 0000000000..b7f6163662
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 1987, 1993, 1994
3 * The Regents of the University of California. 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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getopt.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
42int opterr = 1, /* if error message should be printed */
43 optind = 1, /* index into parent argv vector */
44 optopt, /* character checked for validity */
45 optreset; /* reset getopt */
46char *optarg; /* argument associated with option */
47
48#define BADCH (int)'?'
49#define BADARG (int)':'
50#define EMSG ""
51
52/*
53 * getopt --
54 * Parse argc/argv argument vector.
55 */
56int
57getopt(nargc, nargv, ostr)
58 int nargc;
59 char * const *nargv;
60 const char *ostr;
61{
62 extern char *__progname;
63 static char *place = EMSG; /* option letter processing */
64 char *oli; /* option letter list index */
65
66 if (optreset || !*place) { /* update scanning pointer */
67 optreset = 0;
68 if (optind >= nargc || *(place = nargv[optind]) != '-') {
69 place = EMSG;
70 return (-1);
71 }
72 if (place[1] && *++place == '-') { /* found "--" */
73 ++optind;
74 place = EMSG;
75 return (-1);
76 }
77 } /* option letter okay? */
78 if ((optopt = (int)*place++) == (int)':' ||
79 !(oli = strchr(ostr, optopt))) {
80 /*
81 * if the user didn't specify '-' as an option,
82 * assume it means -1.
83 */
84 if (optopt == (int)'-')
85 return (-1);
86 if (!*place)
87 ++optind;
88 if (opterr && *ostr != ':')
89 (void)fprintf(stderr,
90 "%s: illegal option -- %c\n", __progname, optopt);
91 return (BADCH);
92 }
93 if (*++oli != ':') { /* don't need argument */
94 optarg = NULL;
95 if (!*place)
96 ++optind;
97 }
98 else { /* need an argument */
99 if (*place) /* no white space */
100 optarg = place;
101 else if (nargc <= ++optind) { /* no arg */
102 place = EMSG;
103 if (*ostr == ':')
104 return (BADARG);
105 if (opterr)
106 (void)fprintf(stderr,
107 "%s: option requires an argument -- %c\n",
108 __progname, optopt);
109 return (BADCH);
110 }
111 else /* white space */
112 optarg = nargv[optind];
113 place = EMSG;
114 ++optind;
115 }
116 return (optopt); /* dump back option letter */
117}
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
new file mode 100644
index 0000000000..e3e4392e05
--- /dev/null
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,183 @@
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: heapsort.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42#include <errno.h>
43#include <stdlib.h>
44
45/*
46 * Swap two areas of size number of bytes. Although qsort(3) permits random
47 * blocks of memory to be sorted, sorting pointers is almost certainly the
48 * common case (and, were it not, could easily be made so). Regardless, it
49 * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
50 * arithmetic gets lost in the time required for comparison function calls.
51 */
52#define SWAP(a, b, count, size, tmp) { \
53 count = size; \
54 do { \
55 tmp = *a; \
56 *a++ = *b; \
57 *b++ = tmp; \
58 } while (--count); \
59}
60
61/* Copy one block of size size to another. */
62#define COPY(a, b, count, size, tmp1, tmp2) { \
63 count = size; \
64 tmp1 = a; \
65 tmp2 = b; \
66 do { \
67 *tmp1++ = *tmp2++; \
68 } while (--count); \
69}
70
71/*
72 * Build the list into a heap, where a heap is defined such that for
73 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
74 *
75 * There two cases. If j == nmemb, select largest of Ki and Kj. If
76 * j < nmemb, select largest of Ki, Kj and Kj+1.
77 */
78#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
79 for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
80 par_i = child_i) { \
81 child = base + child_i * size; \
82 if (child_i < nmemb && compar(child, child + size) < 0) { \
83 child += size; \
84 ++child_i; \
85 } \
86 par = base + par_i * size; \
87 if (compar(child, par) <= 0) \
88 break; \
89 SWAP(par, child, count, size, tmp); \
90 } \
91}
92
93/*
94 * Select the top of the heap and 'heapify'. Since by far the most expensive
95 * action is the call to the compar function, a considerable optimization
96 * in the average case can be achieved due to the fact that k, the displaced
97 * elememt, is ususally quite small, so it would be preferable to first
98 * heapify, always maintaining the invariant that the larger child is copied
99 * over its parent's record.
100 *
101 * Then, starting from the *bottom* of the heap, finding k's correct place,
102 * again maintianing the invariant. As a result of the invariant no element
103 * is 'lost' when k is assigned its correct place in the heap.
104 *
105 * The time savings from this optimization are on the order of 15-20% for the
106 * average case. See Knuth, Vol. 3, page 158, problem 18.
107 *
108 * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
109 */
110#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
111 for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
112 child = base + child_i * size; \
113 if (child_i < nmemb && compar(child, child + size) < 0) { \
114 child += size; \
115 ++child_i; \
116 } \
117 par = base + par_i * size; \
118 COPY(par, child, count, size, tmp1, tmp2); \
119 } \
120 for (;;) { \
121 child_i = par_i; \
122 par_i = child_i / 2; \
123 child = base + child_i * size; \
124 par = base + par_i * size; \
125 if (child_i == 1 || compar(k, par) < 0) { \
126 COPY(child, k, count, size, tmp1, tmp2); \
127 break; \
128 } \
129 COPY(child, par, count, size, tmp1, tmp2); \
130 } \
131}
132
133/*
134 * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
135 * and worst. While heapsort is faster than the worst case of quicksort,
136 * the BSD quicksort does median selection so that the chance of finding
137 * a data set that will trigger the worst case is nonexistent. Heapsort's
138 * only advantage over quicksort is that it requires little additional memory.
139 */
140int
141heapsort(vbase, nmemb, size, compar)
142 void *vbase;
143 size_t nmemb, size;
144 int (*compar) __P((const void *, const void *));
145{
146 register int cnt, i, j, l;
147 register char tmp, *tmp1, *tmp2;
148 char *base, *k, *p, *t;
149
150 if (nmemb <= 1)
151 return (0);
152
153 if (!size) {
154 errno = EINVAL;
155 return (-1);
156 }
157
158 if ((k = malloc(size)) == NULL)
159 return (-1);
160
161 /*
162 * Items are numbered from 1 to nmemb, so offset from size bytes
163 * below the starting address.
164 */
165 base = (char *)vbase - size;
166
167 for (l = nmemb / 2 + 1; --l;)
168 CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
169
170 /*
171 * For each element of the heap, save the largest element into its
172 * final slot, save the displaced element (k), then recreate the
173 * heap.
174 */
175 while (nmemb > 1) {
176 COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
177 COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
178 --nmemb;
179 SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
180 }
181 free(k);
182 return (0);
183}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
new file mode 100644
index 0000000000..99cddb71e5
--- /dev/null
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20long
21jrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 16) + (long) xseed[1];
25}
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
new file mode 100644
index 0000000000..4e99391254
--- /dev/null
+++ b/src/lib/libc/stdlib/l64a.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13char *
14l64a(value)
15 long value;
16{
17 static char buf[8];
18 char *s = buf;
19 int digit;
20 int i;
21
22 if (value < 0) {
23 errno = EINVAL;
24 return(NULL);
25 }
26
27 for (i = 0; value != 0 && i < 6; i++) {
28 digit = value & 0x3f;
29
30 if (digit < 2)
31 *s = digit + '.';
32 else if (digit < 12)
33 *s = digit + '0' - 2;
34 else if (digit < 38)
35 *s = digit + 'A' - 12;
36 else
37 *s = digit + 'a' - 38;
38
39 value >>= 6;
40 s++;
41 }
42
43 *s = '\0';
44
45 return(buf);
46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
new file mode 100644
index 0000000000..05eae329df
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.3
@@ -0,0 +1,66 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: labs.3,v 1.2 1996/08/19 08:33:34 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt LABS 3
40.Os
41.Sh NAME
42.Nm labs
43.Nd return the absolute value of a long integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft long
47.Fn labs "long j"
48.Sh DESCRIPTION
49The
50.Fn labs
51function
52returns the absolute value of the long integer
53.Ar j .
54.Sh SEE ALSO
55.Xr abs 3 ,
56.Xr floor 3 ,
57.Xr cabs 3 ,
58.Xr math 3
59.Sh STANDARDS
60The
61.Fn labs
62function
63conforms to
64.St -ansiC .
65.Sh BUGS
66The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c
new file mode 100644
index 0000000000..f20e2c29be
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: labs.c,v 1.2 1996/08/19 08:33:34 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41labs(j)
42 long j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
new file mode 100644
index 0000000000..44bd74e48a
--- /dev/null
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25lcong48(unsigned short p[7])
26{
27 __rand48_seed[0] = p[0];
28 __rand48_seed[1] = p[1];
29 __rand48_seed[2] = p[2];
30 __rand48_mult[0] = p[3];
31 __rand48_mult[1] = p[4];
32 __rand48_mult[2] = p[5];
33 __rand48_add = p[6];
34}
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
new file mode 100644
index 0000000000..8757f4ddd5
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,71 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information 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.\" $OpenBSD: ldiv.3,v 1.2 1996/08/19 08:33:35 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt LDIV 3
40.Os
41.Sh NAME
42.Nm ldiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft ldiv_t
47.Fn ldiv "long num" "long denom"
48.Sh DESCRIPTION
49The
50.Fn ldiv
51function
52computes the value
53.Ar num/denom
54and returns the quotient and remainder in a structure named
55.Ar ldiv_t
56that contains two
57.Em long integer
58members named
59.Ar quot
60and
61.Ar rem .
62.Sh SEE ALSO
63.Xr div 3 ,
64.Xr qdiv 3 ,
65.Xr math 3
66.Sh STANDARDS
67The
68.Fn ldiv
69function
70conforms to
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
new file mode 100644
index 0000000000..908c2bf0aa
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: ldiv.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* ldiv_t */
42
43ldiv_t
44ldiv(num, denom)
45 long num, denom;
46{
47 ldiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
new file mode 100644
index 0000000000..6b7524a51b
--- /dev/null
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23lrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1);
27}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
new file mode 100644
index 0000000000..d5f8837ec2
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.3
@@ -0,0 +1,350 @@
1.\" Copyright (c) 1980, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: malloc.3,v 1.9 1998/08/15 20:32:02 deraadt Exp $
37.\"
38.Dd August 27, 1996
39.Dt MALLOC 3
40.Os OpenBSD
41.Sh NAME
42.Nm malloc ,
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
51.Sh SYNOPSIS
52.Fd #include <stdlib.h>
53.Ft void *
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
63.Sh DESCRIPTION
64The
65.Fn malloc
66function allocates uninitialized space for an object whose
67size is specified by
68.Fa size .
69The
70.Fn malloc
71function maintains multiple lists of free blocks according to size, allocating
72space from the appropriate list.
73.Pp
74The allocated space is
75suitably aligned (after possible pointer
76coercion) for storage of any type of object. If the space is of
77.Em pagesize
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.
230.Sh RETURN VALUES
231The
232.Fn malloc
233function returns
234a pointer to the allocated space if successful; otherwise
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.
321.Sh SEE ALSO
322.Xr brk 2 ,
323.Xr alloca 3 ,
324.Xr calloc 3 ,
325.Xr getpagesize 3 ,
326.Xr memory 3
327.Pa /usr/share/doc/papers/malloc.ascii.gz
328.Sh STANDARDS
329The
330.Fn malloc
331function conforms to
332.St -ansiC .
333.Sh HISTORY
334The present implementation of malloc started out as a filesystem on a drum
335attached to a 20bit binary challenged computer built with discrete germanium
336transistors, and it has since graduated to handle primary storage rather than
337secondary.
338.Pp
339The main difference from other malloc implementations are believed to be that
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
new file mode 100644
index 0000000000..d1d8759791
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1242 @@
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 */
9
10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.32 1998/08/06 16:26:32 millert Exp $";
12#endif /* LIBC_SCCS and not lint */
13
14/*
15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
16 * related to internal conditions and consistency in malloc.c. This has
17 * a noticeable runtime performance hit, and generally will not do you
18 * any good unless you fiddle with the internals of malloc or want
19 * to catch random pointer corruption as early as possible.
20 */
21#ifndef MALLOC_EXTRA_SANITY
22#undef MALLOC_EXTRA_SANITY
23#endif
24
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>
41#include <stdlib.h>
42#include <string.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__ */
69
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__ */
77
78/* Insert your combination here... */
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
100
101/*
102 * No user serviceable parts behind this point.
103 *
104 * This structure describes a page worth of chunks.
105 */
106
107struct pginfo {
108 struct pginfo *next; /* next on the free list */
109 void *page; /* Pointer to the page */
110 u_short size; /* size of this page's chunks */
111 u_short shift; /* How far to shift for this size chunks */
112 u_short free; /* How many free chunks */
113 u_short total; /* How many chunk */
114 u_long bits[1]; /* Which chunks are free */
115};
116
117/*
118 * This structure describes a number of free pages.
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 */
127};
128
129/*
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)
173
174/* fd of /dev/zero */
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"); }
181#else
182#define MMAP_FD (-1)
183#define INIT_MMAP()
184#endif
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
270/*
271 * Necessary function declarations
272 */
273static int extend_pgdir(u_long index);
274static void *imalloc(size_t size);
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 */
385
386
387/*
388 * Allocate a number of pages from the OS
389 */
390static void *
391map_pages(pages)
392 int pages;
393{
394 caddr_t result, tail;
395
396 result = (caddr_t)pageround((u_long)sbrk(0));
397 tail = result + (pages << malloc_pageshift);
398
399 if (brk(tail)) {
400#ifdef MALLOC_EXTRA_SANITY
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;
421{
422 struct pginfo **new, **old;
423 size_t i, oldlen;
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;
467}
468
469/*
470 * Initialize the world
471 */
472static void
473malloc_init ()
474{
475 char *p, b[64];
476 int i, j;
477 int save_errno = errno;
478
479 THREAD_LOCK_INIT();
480
481 INIT_MMAP();
482
483#ifdef MALLOC_EXTRA_SANITY
484 malloc_junk = 1;
485#endif /* MALLOC_EXTRA_SANITY */
486
487 for (i = 0; i < 3; i++) {
488 if (i == 0) {
489 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
490 if (j <= 0)
491 continue;
492 b[j] = '\0';
493 p = b;
494 } else if (i == 1) {
495 if (issetugid() == 0)
496 p = getenv("MALLOC_OPTIONS");
497 else
498 continue;
499 } else if (i == 2) {
500 p = malloc_options;
501 }
502 for (; p && *p; p++) {
503 switch (*p) {
504 case '>': malloc_cache <<= 1; break;
505 case '<': malloc_cache >>= 1; break;
506 case 'a': malloc_abort = 0; break;
507 case 'A': malloc_abort = 1; break;
508#ifdef MALLOC_STATS
509 case 'd': malloc_stats = 0; break;
510 case 'D': malloc_stats = 1; break;
511#endif /* MALLOC_STATS */
512#ifdef __FreeBSD__
513 case 'h': malloc_hint = 0; break;
514 case 'H': malloc_hint = 1; break;
515#endif /* __FreeBSD__ */
516 case 'r': malloc_realloc = 0; break;
517 case 'R': malloc_realloc = 1; break;
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 }
537 }
538 }
539
540 UTRACE(0, 0, 0);
541
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;
702 }
703 }
704
705 bp->size = (1UL<<bits);
706 bp->shift = bits;
707 bp->total = bp->free = malloc_pagesize >> bits;
708 bp->page = pp;
709
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);
728 }
729 }
730
731 /* MALLOC_LOCK */
732
733 page_dir[ptr2index(pp)] = bp;
734
735 bp->next = page_dir[bits];
736 page_dir[bits] = bp;
737
738 /* MALLOC_UNLOCK */
739
740 return 1;
741}
742
743/*
744 * Allocate a fragment
745 */
746static void *
747malloc_bytes(size)
748 size_t size;
749{
750 int i,j;
751 u_long u;
752 struct pginfo *bp;
753 int k;
754 u_long *lp;
755
756 /* Don't bother with anything less than this */
757 if (size < malloc_minsize)
758 size = malloc_minsize;
759
760 /* Find the right bucket */
761 j = 1;
762 i = size-1;
763 while (i >>= 1)
764 j++;
765
766 /* If it's empty, make a page more of that size chunks */
767 if (!page_dir[j] && !malloc_make_chunks(j))
768 return 0;
769
770 bp = page_dir[j];
771
772 /* Find first word of bitmap which isn't empty */
773 for (lp = bp->bits; !*lp; lp++)
774 ;
775
776 /* Find that bit, and tweak it */
777 u = 1;
778 k = 0;
779 while (!(*lp & u)) {
780 u += u;
781 k++;
782 }
783 *lp ^= u;
784
785 /* If there are no more free, remove from free-list */
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;
799}
800
801/*
802 * Allocate a piece of memory
803 */
804static void *
805imalloc(size)
806 size_t size;
807{
808 void *result;
809
810 if (!malloc_started)
811 malloc_init();
812
813 if (suicide)
814 abort();
815
816 if ((size + malloc_pagesize) < size) /* Check for overflow */
817 result = 0;
818 else if (size <= malloc_maxsize)
819 result = malloc_bytes(size);
820 else
821 result = malloc_pages(size);
822
823 if (malloc_abort && !result)
824 wrterror("allocation failed.\n");
825
826 if (malloc_zero && result)
827 memset(result, 0, size);
828
829 return result;
830}
831
832/*
833 * Change the size of an allocation.
834 */
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;
844
845 if (suicide)
846 abort();
847
848 if (!malloc_started) {
849 wrtwarning("malloc() has never been called.\n");
850 return 0;
851 }
852
853 index = ptr2index(ptr);
854
855 if (index < malloc_pageshift) {
856 wrtwarning("junk pointer, too low to make sense.\n");
857 return 0;
858 }
859
860 if (index > last_index) {
861 wrtwarning("junk pointer, too high to make sense.\n");
862 return 0;
863 }
864
865 mp = &page_dir[index];
866
867 if (*mp == MALLOC_FIRST) { /* Page allocation */
868
869 /* Check the pointer */
870 if ((u_long)ptr & malloc_pagemask) {
871 wrtwarning("modified (page-) pointer.\n");
872 return 0;
873 }
874
875 /* Find the size in bytes */
876 for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
877 osize += malloc_pagesize;
878
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;
891 }
892
893 /* Find the chunk index in the page */
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);
922 else
923 memcpy(p, ptr, size);
924 ifree(ptr);
925 }
926 return p;
927}
928
929/*
930 * Free a sequence of pages
931 */
932
933static __inline__ void
934free_pages(ptr, index, info)
935 void *ptr;
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);
972#endif
973
974 tail = (char *)ptr+l;
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");
1033 }
1034 }
1035
1036 /* Return something to OS ? */
1037 if (!pf->next && /* If we're the last one, */
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);
1062}
1063
1064/*
1065 * Free a chunk, and possibly the page it's on, if the page becomes empty.
1066 */
1067
1068/* ARGSUSED */
1069static __inline__ void
1070free_bytes(ptr, index, info)
1071 void *ptr;
1072 int index;
1073 struct pginfo *info;
1074{
1075 int i;
1076 struct pginfo **mp;
1077 void *vp;
1078
1079 /* Find the chunk number on the page */
1080 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
1081
1082 if (((u_long)ptr & (info->size-1))) {
1083 wrtwarning("modified (chunk-) pointer.\n");
1084 return;
1085 }
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;
1173}
1174
1175/*
1176 * These are the public exported interface routines.
1177 */
1178
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)
1204{
1205 malloc_func = " in free():";
1206 THREAD_LOCK();
1207 if (malloc_active++) {
1208 wrtwarning("recursive call.\n");
1209 malloc_active--;
1210 return;
1211 }
1212 ifree(ptr);
1213 UTRACE(ptr, 0, 0);
1214 malloc_active--;
1215 THREAD_UNLOCK();
1216 return;
1217}
1218
1219void *
1220realloc(void *ptr, size_t size)
1221{
1222 register void *r;
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);
1242}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000000..712c7c45d2
--- /dev/null
+++ b/src/lib/libc/stdlib/memory.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1991 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.\" $OpenBSD: memory.3,v 1.2 1996/08/19 08:33:37 tholo Exp $
33.\"
34.Dd May 2, 1991
35.Dt MEMORY 3
36.Os BSD 4
37.Sh NAME
38.Nm malloc ,
39.Nm free ,
40.Nm realloc ,
41.Nm calloc ,
42.Nm alloca
43.Nd general memory allocation operations
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn malloc "size_t size"
48.Ft void
49.Fn free "void *ptr"
50.Ft void *
51.Fn realloc "void *ptr" "size_t size"
52.Ft void *
53.Fn calloc "size_t nelem" "size_t elsize"
54.Ft void *
55.Fn alloca "size_t size"
56.Sh DESCRIPTION
57These functions allocate and free memory for the calling process.
58They are described in the
59individual manual pages.
60.Sh SEE ALSO
61.Xr calloc 3 ,
62.Xr free 3 ,
63.Xr malloc 3 ,
64.Xr realloc 3 ,
65.Xr alloca 3 ,
66.Sh STANDARDS
67These functions, with the exception of
68.Fn alloca
69conform to
70.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000000..0a1015ad9d
--- /dev/null
+++ b/src/lib/libc/stdlib/merge.c
@@ -0,0 +1,347 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: merge.c,v 1.3 1996/09/15 09:31:50 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Hybrid exponential search/linear search merge sort with hybrid
43 * natural/pairwise first pass. Requires about .3% more comparisons
44 * for random data than LSMS with pairwise first pass alone.
45 * It works for objects as small as two bytes.
46 */
47
48#define NATURAL
49#define THRESHOLD 16 /* Best choice for natural merge cut-off. */
50
51/* #define NATURAL to get hybrid natural merge.
52 * (The default is pairwise merging.)
53 */
54
55#include <sys/types.h>
56
57#include <errno.h>
58#include <stdlib.h>
59#include <string.h>
60
61static void setup __P((u_char *, u_char *, size_t, size_t, int (*)()));
62static void insertionsort __P((u_char *, size_t, size_t, int (*)()));
63
64#define ISIZE sizeof(int)
65#define PSIZE sizeof(u_char *)
66#define ICOPY_LIST(src, dst, last) \
67 do \
68 *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \
69 while(src < last)
70#define ICOPY_ELT(src, dst, i) \
71 do \
72 *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \
73 while (i -= ISIZE)
74
75#define CCOPY_LIST(src, dst, last) \
76 do \
77 *dst++ = *src++; \
78 while (src < last)
79#define CCOPY_ELT(src, dst, i) \
80 do \
81 *dst++ = *src++; \
82 while (i -= 1)
83
84/*
85 * Find the next possible pointer head. (Trickery for forcing an array
86 * to do double duty as a linked list when objects do not align with word
87 * boundaries.
88 */
89/* Assumption: PSIZE is a power of 2. */
90#define EVAL(p) (u_char **) \
91 ((u_char *)0 + \
92 (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
93
94/*
95 * Arguments are as for qsort.
96 */
97int
98mergesort(base, nmemb, size, cmp)
99 void *base;
100 size_t nmemb;
101 register size_t size;
102 int (*cmp) __P((const void *, const void *));
103{
104 register int i, sense;
105 int big, iflag;
106 register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
107 u_char *list2, *list1, *p2, *p, *last, **p1;
108
109 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
110 errno = EINVAL;
111 return (-1);
112 }
113
114 /*
115 * XXX
116 * Stupid subtraction for the Cray.
117 */
118 iflag = 0;
119 if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
120 iflag = 1;
121
122 if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
123 return (-1);
124
125 list1 = base;
126 setup(list1, list2, nmemb, size, cmp);
127 last = list2 + nmemb * size;
128 i = big = 0;
129 while (*EVAL(list2) != last) {
130 l2 = list1;
131 p1 = EVAL(list1);
132 for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
133 p2 = *EVAL(p2);
134 f1 = l2;
135 f2 = l1 = list1 + (p2 - list2);
136 if (p2 != last)
137 p2 = *EVAL(p2);
138 l2 = list1 + (p2 - list2);
139 while (f1 < l1 && f2 < l2) {
140 if ((*cmp)(f1, f2) <= 0) {
141 q = f2;
142 b = f1, t = l1;
143 sense = -1;
144 } else {
145 q = f1;
146 b = f2, t = l2;
147 sense = 0;
148 }
149 if (!big) { /* here i = 0 */
150 while ((b += size) < t && cmp(q, b) >sense)
151 if (++i == 6) {
152 big = 1;
153 goto EXPONENTIAL;
154 }
155 } else {
156EXPONENTIAL: for (i = size; ; i <<= 1)
157 if ((p = (b + i)) >= t) {
158 if ((p = t - size) > b &&
159 (*cmp)(q, p) <= sense)
160 t = p;
161 else
162 b = p;
163 break;
164 } else if ((*cmp)(q, p) <= sense) {
165 t = p;
166 if (i == size)
167 big = 0;
168 goto FASTCASE;
169 } else
170 b = p;
171 while (t > b+size) {
172 i = (((t - b) / size) >> 1) * size;
173 if ((*cmp)(q, p = b + i) <= sense)
174 t = p;
175 else
176 b = p;
177 }
178 goto COPY;
179FASTCASE: while (i > size)
180 if ((*cmp)(q,
181 p = b + (i >>= 1)) <= sense)
182 t = p;
183 else
184 b = p;
185COPY: b = t;
186 }
187 i = size;
188 if (q == f1) {
189 if (iflag) {
190 ICOPY_LIST(f2, tp2, b);
191 ICOPY_ELT(f1, tp2, i);
192 } else {
193 CCOPY_LIST(f2, tp2, b);
194 CCOPY_ELT(f1, tp2, i);
195 }
196 } else {
197 if (iflag) {
198 ICOPY_LIST(f1, tp2, b);
199 ICOPY_ELT(f2, tp2, i);
200 } else {
201 CCOPY_LIST(f1, tp2, b);
202 CCOPY_ELT(f2, tp2, i);
203 }
204 }
205 }
206 if (f2 < l2) {
207 if (iflag)
208 ICOPY_LIST(f2, tp2, l2);
209 else
210 CCOPY_LIST(f2, tp2, l2);
211 } else if (f1 < l1) {
212 if (iflag)
213 ICOPY_LIST(f1, tp2, l1);
214 else
215 CCOPY_LIST(f1, tp2, l1);
216 }
217 *p1 = l2;
218 }
219 tp2 = list1; /* swap list1, list2 */
220 list1 = list2;
221 list2 = tp2;
222 last = list2 + nmemb*size;
223 }
224 if (base == list2) {
225 memmove(list2, list1, nmemb*size);
226 list2 = list1;
227 }
228 free(list2);
229 return (0);
230}
231
232#define swap(a, b) { \
233 s = b; \
234 i = size; \
235 do { \
236 tmp = *a; *a++ = *s; *s++ = tmp; \
237 } while (--i); \
238 a -= size; \
239 }
240#define reverse(bot, top) { \
241 s = top; \
242 do { \
243 i = size; \
244 do { \
245 tmp = *bot; *bot++ = *s; *s++ = tmp; \
246 } while (--i); \
247 s -= size2; \
248 } while(bot < s); \
249}
250
251/*
252 * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of
253 * increasing order, list2 in a corresponding linked list. Checks for runs
254 * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL
255 * is defined. Otherwise simple pairwise merging is used.)
256 */
257void
258setup(list1, list2, n, size, cmp)
259 size_t n, size;
260 int (*cmp) __P((const void *, const void *));
261 u_char *list1, *list2;
262{
263 int i, length, size2, tmp, sense;
264 u_char *f1, *f2, *s, *l2, *last, *p2;
265
266 size2 = size*2;
267 if (n <= 5) {
268 insertionsort(list1, n, size, cmp);
269 *EVAL(list2) = (u_char*) list2 + n*size;
270 return;
271 }
272 /*
273 * Avoid running pointers out of bounds; limit n to evens
274 * for simplicity.
275 */
276 i = 4 + (n & 1);
277 insertionsort(list1 + (n - i) * size, i, size, cmp);
278 last = list1 + size * (n - i);
279 *EVAL(list2 + (last - list1)) = list2 + n * size;
280
281#ifdef NATURAL
282 p2 = list2;
283 f1 = list1;
284 sense = (cmp(f1, f1 + size) > 0);
285 for (; f1 < last; sense = !sense) {
286 length = 2;
287 /* Find pairs with same sense. */
288 for (f2 = f1 + size2; f2 < last; f2 += size2) {
289 if ((cmp(f2, f2+ size) > 0) != sense)
290 break;
291 length += 2;
292 }
293 if (length < THRESHOLD) { /* Pairwise merge */
294 do {
295 p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
296 if (sense > 0)
297 swap (f1, f1 + size);
298 } while ((f1 += size2) < f2);
299 } else { /* Natural merge */
300 l2 = f2;
301 for (f2 = f1 + size2; f2 < l2; f2 += size2) {
302 if ((cmp(f2-size, f2) > 0) != sense) {
303 p2 = *EVAL(p2) = f2 - list1 + list2;
304 if (sense > 0)
305 reverse(f1, f2-size);
306 f1 = f2;
307 }
308 }
309 if (sense > 0)
310 reverse (f1, f2-size);
311 f1 = f2;
312 if (f2 < last || cmp(f2 - size, f2) > 0)
313 p2 = *EVAL(p2) = f2 - list1 + list2;
314 else
315 p2 = *EVAL(p2) = list2 + n*size;
316 }
317 }
318#else /* pairwise merge only. */
319 for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
320 p2 = *EVAL(p2) = p2 + size2;
321 if (cmp (f1, f1 + size) > 0)
322 swap(f1, f1 + size);
323 }
324#endif /* NATURAL */
325}
326
327/*
328 * This is to avoid out-of-bounds addresses in sorting the
329 * last 4 elements.
330 */
331static void
332insertionsort(a, n, size, cmp)
333 u_char *a;
334 size_t n, size;
335 int (*cmp) __P((const void *, const void *));
336{
337 u_char *ai, *s, *t, *u, tmp;
338 int i;
339
340 for (ai = a+size; --n >= 1; ai += size)
341 for (t = ai; t > a; t -= size) {
342 u = t - size;
343 if (cmp(u, t) <= 0)
344 break;
345 swap(u, t);
346 }
347}
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
new file mode 100644
index 0000000000..cd34260b5c
--- /dev/null
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23mrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1];
27}
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
new file mode 100644
index 0000000000..12e70c4a2c
--- /dev/null
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -0,0 +1,130 @@
1/*
2 * Copyright (c) 1991 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: multibyte.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Stub multibyte character functions.
42 * This cheezy implementation is fixed to the native single-byte
43 * character set.
44 */
45
46int
47mblen(s, n)
48 const char *s;
49 size_t n;
50{
51 if (s == NULL || *s == '\0')
52 return 0;
53 if (n == 0)
54 return -1;
55 return 1;
56}
57
58/*ARGSUSED*/
59int
60mbtowc(pwc, s, n)
61 wchar_t *pwc;
62 const char *s;
63 size_t n;
64{
65 if (s == NULL)
66 return 0;
67 if (n == 0)
68 return -1;
69 if (pwc)
70 *pwc = (wchar_t) *s;
71 return (*s != '\0');
72}
73
74/*ARGSUSED*/
75int
76#ifdef __STDC__
77wctomb(char *s, wchar_t wchar)
78#else
79wctomb(s, wchar)
80 char *s;
81 wchar_t wchar;
82#endif
83{
84 if (s == NULL)
85 return 0;
86
87 *s = (char) wchar;
88 return 1;
89}
90
91/*ARGSUSED*/
92size_t
93mbstowcs(pwcs, s, n)
94 wchar_t *pwcs;
95 const char *s;
96 size_t n;
97{
98 int count = 0;
99
100 if (n != 0) {
101 do {
102 if ((*pwcs++ = (wchar_t) *s++) == 0)
103 break;
104 count++;
105 } while (--n != 0);
106 }
107
108 return count;
109}
110
111/*ARGSUSED*/
112size_t
113wcstombs(s, pwcs, n)
114 char *s;
115 const wchar_t *pwcs;
116 size_t n;
117{
118 int count = 0;
119
120 if (n != 0) {
121 do {
122 if ((*s++ = (char) *pwcs++) == 0)
123 break;
124 count++;
125 } while (--n != 0);
126 }
127
128 return count;
129}
130
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
new file mode 100644
index 0000000000..b1ec2cebb1
--- /dev/null
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20long
21nrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
25}
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
new file mode 100644
index 0000000000..d8c4886d4b
--- /dev/null
+++ b/src/lib/libc/stdlib/putenv.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. 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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: putenv.c,v 1.2 1996/08/10 05:03:00 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41int
42putenv(str)
43 const char *str;
44{
45 char *p, *equal;
46 int rval;
47
48 if ((p = strdup(str)) == NULL)
49 return (-1);
50 if ((equal = strchr(p, '=')) == NULL) {
51 (void)free(p);
52 return (-1);
53 }
54 *equal = '\0';
55 rval = setenv(p, equal + 1, 1);
56 (void)free(p);
57 return (rval);
58}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
new file mode 100644
index 0000000000..92a8bdc4b9
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.3
@@ -0,0 +1,61 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: qabs.3,v 1.2 1996/08/19 08:33:40 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt QABS 3
40.Os
41.Sh NAME
42.Nm qabs
43.Nd return the absolute value of a quad integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft quad_t
47.Fn qabs "quad_t j"
48.Sh DESCRIPTION
49The
50.Fn qabs
51function
52returns the absolute value of the quad integer
53.Ar j .
54.Sh SEE ALSO
55.Xr abs 3 ,
56.Xr labs 3 ,
57.Xr floor 3 ,
58.Xr cabs 3 ,
59.Xr math 3
60.Sh BUGS
61The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c
new file mode 100644
index 0000000000..ccc42cbec6
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qabs.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40quad_t
41qabs(j)
42 quad_t j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
new file mode 100644
index 0000000000..12aca0b1ea
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information 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.\" $OpenBSD: qdiv.3,v 1.2 1996/08/19 08:33:41 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt QDIV 3
40.Os
41.Sh NAME
42.Nm qdiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft qdiv_t
47.Fn qdiv "quad_t num" "quad_t denom"
48.Sh DESCRIPTION
49The
50.Fn qdiv
51function
52computes the value
53.Ar num/denom
54and returns the quotient and remainder in a structure named
55.Ar qdiv_t
56that contains two
57.Em quad integer
58members named
59.Ar quot
60and
61.Ar rem .
62.Sh SEE ALSO
63.Xr div 3 ,
64.Xr ldiv 3 ,
65.Xr math 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
new file mode 100644
index 0000000000..07e84cd649
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: qdiv.c,v 1.2 1996/08/19 08:33:41 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* qdiv_t */
42
43qdiv_t
44qdiv(num, denom)
45 quad_t num, denom;
46{
47 qdiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
new file mode 100644
index 0000000000..a65c5819d0
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.3
@@ -0,0 +1,233 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: qsort.3,v 1.2 1996/08/19 08:33:42 tholo Exp $
37.\"
38.Dd June 4, 1993
39.Dt QSORT 3
40.Os
41.Sh NAME
42.Nm qsort, heapsort, mergesort
43.Nd sort functions
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
48.Ft int
49.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
50.Ft int
51.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
52.Sh DESCRIPTION
53The
54.Fn qsort
55function is a modified partition-exchange sort, or quicksort.
56The
57.Fn heapsort
58function is a modified selection sort.
59The
60.Fn mergesort
61function is a modified merge sort with exponential search
62intended for sorting data with pre-existing order.
63.Pp
64The
65.Fn qsort
66and
67.Fn heapsort
68functions sort an array of
69.Fa nmemb
70objects, the initial member of which is pointed to by
71.Fa base .
72The size of each object is specified by
73.Fa size .
74.Fn Mergesort
75behaves similarly, but
76.Em requires
77that
78.Fa size
79be greater than
80.Dq "sizeof(void *) / 2" .
81.Pp
82The contents of the array
83.Fa base
84are sorted in ascending order according to
85a comparison function pointed to by
86.Fa compar ,
87which requires two arguments pointing to the objects being
88compared.
89.Pp
90The comparison function must return an integer less than, equal to, or
91greater than zero if the first argument is considered to be respectively
92less than, equal to, or greater than the second.
93.Pp
94The functions
95.Fn qsort
96and
97.Fn heapsort
98are
99.Em not
100stable, that is, if two members compare as equal, their order in
101the sorted array is undefined.
102The function
103.Fn mergesort
104is stable.
105.Pp
106The
107.Fn qsort
108function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm,
109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
110Algorithm Q.
111.Fn Qsort
112takes O N lg N average time.
113This implementation uses median selection to avoid its
114O N**2 worst-case behavior.
115.Pp
116The
117.Fn heapsort
118function is an implementation of J.W.J. William's ``heapsort'' algorithm,
119a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
120.Fn Heapsort
121takes O N lg N worst-case time.
122Its
123.Em only
124advantage over
125.Fn qsort
126is that it uses almost no additional memory; while
127.Fn qsort
128does not allocate memory, it is implemented using recursion.
129.Pp
130The function
131.Fn mergesort
132requires additional memory of size
133.Fa nmemb *
134.Fa size
135bytes; it should be used only when space is not at a premium.
136.Fn Mergesort
137is optimized for data with pre-existing order; its worst case
138time is O N lg N; its best case is O N.
139.Pp
140Normally,
141.Fn qsort
142is faster than
143.Fn mergesort
144is faster than
145.Fn heapsort .
146Memory availability and pre-existing order in the data can make this
147untrue.
148.Sh RETURN VALUES
149The
150.Fn qsort
151function
152returns no value.
153.Pp
154Upon successful completion,
155.Fn heapsort
156and
157.Fn mergesort
158return 0.
159Otherwise, they return \-1 and the global variable
160.Va errno
161is set to indicate the error.
162.Sh ERRORS
163The
164.Fn heapsort
165function succeeds unless:
166.Bl -tag -width Er
167.It Bq Er EINVAL
168The
169.Fa size
170argument is zero, or,
171the
172.Fa size
173argument to
174.Fn mergesort
175is less than
176.Dq "sizeof(void *) / 2" .
177.It Bq Er ENOMEM
178.Fn Heapsort
179or
180.Fn mergesort
181were unable to allocate memory.
182.El
183.Sh COMPATIBILITY
184Previous versions of
185.Fn qsort
186did not permit the comparison routine itself to call
187.Fn qsort 3 .
188This is no longer true.
189.Sh SEE ALSO
190.Xr sort 1 ,
191.Xr radixsort 3
192.Rs
193.%A Hoare, C.A.R.
194.%D 1962
195.%T "Quicksort"
196.%J "The Computer Journal"
197.%V 5:1
198.%P pp. 10-15
199.Re
200.Rs
201.%A Williams, J.W.J
202.%D 1964
203.%T "Heapsort"
204.%J "Communications of the ACM"
205.%V 7:1
206.%P pp. 347-348
207.Re
208.Rs
209.%A Knuth, D.E.
210.%D 1968
211.%B "The Art of Computer Programming"
212.%V Vol. 3
213.%T "Sorting and Searching"
214.%P pp. 114-123, 145-149
215.Re
216.Rs
217.%A Mcilroy, P.M.
218.%T "Optimistic Sorting and Information Theoretic Complexity"
219.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
220.%V January 1992
221.Re
222.Rs
223.%A Bentley, J.L.
224.%T "Engineering a Sort Function"
225.%J "bentley@research.att.com"
226.%V January 1992
227.Re
228.Sh STANDARDS
229The
230.Fn qsort
231function
232conforms to
233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000000..1c3020b595
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.c
@@ -0,0 +1,175 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qsort.c,v 1.5 1997/06/20 11:19:38 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static __inline char *med3 __P((char *, char *, char *, int (*)()));
42static __inline void swapfunc __P((char *, char *, int, int));
43
44#define min(a, b) (a) < (b) ? a : b
45
46/*
47 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
48 */
49#define swapcode(TYPE, parmi, parmj, n) { \
50 long i = (n) / sizeof (TYPE); \
51 register TYPE *pi = (TYPE *) (parmi); \
52 register TYPE *pj = (TYPE *) (parmj); \
53 do { \
54 register TYPE t = *pi; \
55 *pi++ = *pj; \
56 *pj++ = t; \
57 } while (--i > 0); \
58}
59
60#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
61 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
62
63static __inline void
64swapfunc(a, b, n, swaptype)
65 char *a, *b;
66 int n, swaptype;
67{
68 if (swaptype <= 1)
69 swapcode(long, a, b, n)
70 else
71 swapcode(char, a, b, n)
72}
73
74#define swap(a, b) \
75 if (swaptype == 0) { \
76 long t = *(long *)(a); \
77 *(long *)(a) = *(long *)(b); \
78 *(long *)(b) = t; \
79 } else \
80 swapfunc(a, b, es, swaptype)
81
82#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
83
84static __inline char *
85med3(a, b, c, cmp)
86 char *a, *b, *c;
87 int (*cmp)();
88{
89 return cmp(a, b) < 0 ?
90 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
91 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
92}
93
94void
95qsort(aa, n, es, cmp)
96 void *aa;
97 size_t n, es;
98 int (*cmp)();
99{
100 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
101 int d, r, swaptype, swap_cnt;
102 register char *a = aa;
103
104loop: SWAPINIT(a, es);
105 swap_cnt = 0;
106 if (n < 7) {
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;
109 pl -= es)
110 swap(pl, pl - es);
111 return;
112 }
113 pm = (char *)a + (n / 2) * es;
114 if (n > 7) {
115 pl = (char *)a;
116 pn = (char *)a + (n - 1) * es;
117 if (n > 40) {
118 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp);
120 pm = med3(pm - d, pm, pm + d, cmp);
121 pn = med3(pn - 2 * d, pn - d, pn, cmp);
122 }
123 pm = med3(pl, pm, pn, cmp);
124 }
125 swap(a, pm);
126 pa = pb = (char *)a + es;
127
128 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) {
132 swap_cnt = 1;
133 swap(pa, pb);
134 pa += es;
135 }
136 pb += es;
137 }
138 while (pb <= pc && (r = cmp(pc, a)) >= 0) {
139 if (r == 0) {
140 swap_cnt = 1;
141 swap(pc, pd);
142 pd -= es;
143 }
144 pc -= es;
145 }
146 if (pb > pc)
147 break;
148 swap(pb, pc);
149 swap_cnt = 1;
150 pb += es;
151 pc -= es;
152 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */
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;
156 pl -= es)
157 swap(pl, pl - es);
158 return;
159 }
160
161 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es);
165 vecswap(pb, pn - r, r);
166 if ((r = pb - pa) > es)
167 qsort(a, r / es, es, cmp);
168 if ((r = pd - pc) > es) {
169 /* Iterate rather than recurse to save stack space */
170 a = pn - r;
171 n = r / es;
172 goto loop;
173 }
174/* qsort(pn - r, r / es, es, cmp);*/
175}
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
new file mode 100644
index 0000000000..8b0ea89a0f
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,161 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. 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.\" $OpenBSD: radixsort.3,v 1.4 1998/06/15 17:55:08 mickey Exp $
33.\"
34.Dd January 27, 1994
35.Dt RADIXSORT 3
36.Os
37.Sh NAME
38.Nm radixsort
39.Nd radix sort
40.Sh SYNOPSIS
41.Fd #include <limits.h>
42.Fd #include <stdlib.h>
43.Ft int
44.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
45.Ft int
46.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
47.Sh DESCRIPTION
48The
49.Fn radixsort
50and
51.Fn sradixsort
52functions
53are implementations of radix sort.
54.Pp
55These functions sort an array of pointers to byte strings, the initial
56member of which is referenced by
57.Fa base .
58The byte strings may contain any values; the end of each string
59is denoted by the user-specified value
60.Fa endbyte .
61.Pp
62Applications may specify a sort order by providing the
63.Fa table
64argument.
65If
66.Pf non- Dv NULL ,
67.Fa table
68must reference an array of
69.Dv UCHAR_MAX
70+ 1 bytes which contains the sort
71weight of each possible byte value.
72The end-of-string byte must have a sort weight of 0 or 255
73(for sorting in reverse order).
74More than one byte may have the same sort weight.
75The
76.Fa table
77argument
78is useful for applications which wish to sort different characters
79equally, for example, providing a table with the same weights
80for A-Z as for a-z will result in a case-insensitive sort.
81If
82.Fa table
83is NULL, the contents of the array are sorted in ascending order
84according to the
85.Tn ASCII
86order of the byte strings they reference and
87.Fa endbyte
88has a sorting weight of 0.
89.Pp
90The
91.Fn sradixsort
92function is stable, that is, if two elements compare as equal, their
93order in the sorted array is unchanged.
94The
95.Fn sradixsort
96function uses additional memory sufficient to hold
97.Fa nmemb
98pointers.
99.Pp
100The
101.Fn radixsort
102function is not stable, but uses no additional memory.
103.Pp
104These functions are variants of most-significant-byte radix sorting; in
105particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
106They take linear time relative to the number of bytes in the strings.
107.Sh RETURN VALUES
108Upon successful completion 0 is returned.
109Otherwise, \-1 is returned and the global variable
110.Va errno
111is set to indicate the error.
112.Sh ERRORS
113.Bl -tag -width Er
114.It Bq Er EINVAL
115The value of the
116.Fa endbyte
117element of
118.Fa table
119is not 0 or 255.
120.El
121.Pp
122Additionally, the
123.Fn sradixsort
124function
125may fail and set
126.Va errno
127for any of the errors specified for the library routine
128.Xr malloc 3 .
129.Sh SEE ALSO
130.Xr sort 1 ,
131.Xr qsort 3
132.Pp
133.Rs
134.%A Knuth, D.E.
135.%D 1968
136.%B "The Art of Computer Programming"
137.%T "Sorting and Searching"
138.%V Vol. 3
139.%P pp. 170-178
140.Re
141.Rs
142.%A Paige, R.
143.%D 1987
144.%T "Three Partition Refinement Algorithms"
145.%J "SIAM J. Comput."
146.%V Vol. 16
147.%N No. 6
148.Re
149.Rs
150.%A McIlroy, P.
151.%D 1993
152.%B "Engineering Radix Sort"
153.%T "Computing Systems"
154.%V Vol. 6:1
155.%P pp. 5-27
156.Re
157.Sh HISTORY
158The
159.Fn radixsort
160function first appeared in
161.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000000..41ed962466
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -0,0 +1,317 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy and by Dan Bernstein at New York University,
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: radixsort.c,v 1.3 1996/08/19 08:33:44 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Radixsort routines.
43 *
44 * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack.
45 * Use radixsort(a, n, trace, endchar) for this case.
46 *
47 * For stable sorting (using N extra pointers) use sradixsort(), which calls
48 * r_sort_b().
49 *
50 * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic,
51 * "Engineering Radix Sort".
52 */
53
54#include <sys/types.h>
55#include <stdlib.h>
56#include <errno.h>
57
58typedef struct {
59 const u_char **sa;
60 int sn, si;
61} stack;
62
63static __inline void simplesort
64 __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));
66static void r_sort_b __P((const u_char **,
67 const u_char **, int, int, const u_char *, u_int));
68
69#define THRESHOLD 20 /* Divert to simplesort(). */
70#define SIZE 512 /* Default stack size. */
71
72#define SETUP { \
73 if (tab == NULL) { \
74 tr = tr0; \
75 for (c = 0; c < endch; c++) \
76 tr0[c] = c + 1; \
77 tr0[c] = 0; \
78 for (c++; c < 256; c++) \
79 tr0[c] = c; \
80 endch = 0; \
81 } else { \
82 endch = tab[endch]; \
83 tr = tab; \
84 if (endch != 0 && endch != 255) { \
85 errno = EINVAL; \
86 return (-1); \
87 } \
88 } \
89}
90
91int
92radixsort(a, n, tab, endch)
93 const u_char **a, *tab;
94 int n;
95 u_int endch;
96{
97 const u_char *tr;
98 int c;
99 u_char tr0[256];
100
101 SETUP;
102 r_sort_a(a, n, 0, tr, endch);
103 return (0);
104}
105
106int
107sradixsort(a, n, tab, endch)
108 const u_char **a, *tab;
109 int n;
110 u_int endch;
111{
112 const u_char *tr, **ta;
113 int c;
114 u_char tr0[256];
115
116 SETUP;
117 if (n < THRESHOLD)
118 simplesort(a, n, 0, tr, endch);
119 else {
120 if ((ta = malloc(n * sizeof(a))) == NULL)
121 return (-1);
122 r_sort_b(a, ta, n, 0, tr, endch);
123 free(ta);
124 }
125 return (0);
126}
127
128#define empty(s) (s >= sp)
129#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
130#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
131#define swap(a, b, t) t = a, a = b, b = t
132
133/* Unstable, in-place sort. */
134void
135r_sort_a(a, n, i, tr, endch)
136 const u_char **a;
137 int n, i;
138 const u_char *tr;
139 u_int endch;
140{
141 static int count[256], nc, bmin;
142 register int c;
143 register const u_char **ak, *r;
144 stack s[SIZE], *sp, *sp0, *sp1, temp;
145 int *cp, bigc;
146 const u_char **an, *t, **aj, **top[256];
147
148 /* Set up stack. */
149 sp = s;
150 push(a, n, i);
151 while (!empty(s)) {
152 pop(a, n, i);
153 if (n < THRESHOLD) {
154 simplesort(a, n, i, tr, endch);
155 continue;
156 }
157 an = a + n;
158
159 /* Make character histogram. */
160 if (nc == 0) {
161 bmin = 255; /* First occupied bin, excluding eos. */
162 for (ak = a; ak < an;) {
163 c = tr[(*ak++)[i]];
164 if (++count[c] == 1 && c != endch) {
165 if (c < bmin)
166 bmin = c;
167 nc++;
168 }
169 }
170 if (sp + nc > s + SIZE) { /* Get more stack. */
171 r_sort_a(a, n, i, tr, endch);
172 continue;
173 }
174 }
175
176 /*
177 * Set top[]; push incompletely sorted bins onto stack.
178 * top[] = pointers to last out-of-place element in bins.
179 * count[] = counts of elements in bins.
180 * Before permuting: top[c-1] + count[c] = top[c];
181 * during deal: top[c] counts down to top[c-1].
182 */
183 sp0 = sp1 = sp; /* Stack position of biggest bin. */
184 bigc = 2; /* Size of biggest bin. */
185 if (endch == 0) /* Special case: set top[eos]. */
186 top[0] = ak = a + count[0];
187 else {
188 ak = a;
189 top[255] = an;
190 }
191 for (cp = count + bmin; nc > 0; cp++) {
192 while (*cp == 0) /* Find next non-empty pile. */
193 cp++;
194 if (*cp > 1) {
195 if (*cp > bigc) {
196 bigc = *cp;
197 sp1 = sp;
198 }
199 push(ak, *cp, i+1);
200 }
201 top[cp-count] = ak += *cp;
202 nc--;
203 }
204 swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */
205
206 /*
207 * Permute misplacements home. Already home: everything
208 * before aj, and in bin[c], items from top[c] on.
209 * Inner loop:
210 * r = next element to put in place;
211 * ak = top[r[i]] = location to put the next element.
212 * aj = bottom of 1st disordered bin.
213 * Outer loop:
214 * Once the 1st disordered bin is done, ie. aj >= ak,
215 * aj<-aj + count[c] connects the bins in a linked list;
216 * reset count[c].
217 */
218 for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0)
219 for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);)
220 swap(*ak, r, t);
221 }
222}
223
224/* Stable sort, requiring additional memory. */
225void
226r_sort_b(a, ta, n, i, tr, endch)
227 const u_char **a, **ta;
228 int n, i;
229 const u_char *tr;
230 u_int endch;
231{
232 static int count[256], nc, bmin;
233 register int c;
234 register const u_char **ak, **ai;
235 stack s[512], *sp, *sp0, *sp1, temp;
236 const u_char **top[256];
237 int *cp, bigc;
238
239 sp = s;
240 push(a, n, i);
241 while (!empty(s)) {
242 pop(a, n, i);
243 if (n < THRESHOLD) {
244 simplesort(a, n, i, tr, endch);
245 continue;
246 }
247
248 if (nc == 0) {
249 bmin = 255;
250 for (ak = a + n; --ak >= a;) {
251 c = tr[(*ak)[i]];
252 if (++count[c] == 1 && c != endch) {
253 if (c < bmin)
254 bmin = c;
255 nc++;
256 }
257 }
258 if (sp + nc > s + SIZE) {
259 r_sort_b(a, ta, n, i, tr, endch);
260 continue;
261 }
262 }
263
264 sp0 = sp1 = sp;
265 bigc = 2;
266 if (endch == 0) {
267 top[0] = ak = a + count[0];
268 count[0] = 0;
269 } else {
270 ak = a;
271 top[255] = a + n;
272 count[255] = 0;
273 }
274 for (cp = count + bmin; nc > 0; cp++) {
275 while (*cp == 0)
276 cp++;
277 if ((c = *cp) > 1) {
278 if (c > bigc) {
279 bigc = c;
280 sp1 = sp;
281 }
282 push(ak, c, i+1);
283 }
284 top[cp-count] = ak += c;
285 *cp = 0; /* Reset count[]. */
286 nc--;
287 }
288 swap(*sp0, *sp1, temp);
289
290 for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */
291 *--ak = *--ai;
292 for (ak = ta+n; --ak >= ta;) /* Deal to piles. */
293 *--top[tr[(*ak)[i]]] = *ak;
294 }
295}
296
297static __inline void
298simplesort(a, n, b, tr, endch) /* insertion sort */
299 register const u_char **a;
300 int n, b;
301 register const u_char *tr;
302 u_int endch;
303{
304 register u_char ch;
305 const u_char **ak, **ai, *s, *t;
306
307 for (ak = a+1; --n >= 1; ak++)
308 for (ai = ak; ai > a; ai--) {
309 for (s = ai[0] + b, t = ai[-1] + b;
310 (ch = tr[*s]) != endch; s++, t++)
311 if (ch != tr[*t])
312 break;
313 if (ch >= tr[*t])
314 break;
315 swap(ai[0], ai[-1], s);
316 }
317}
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
new file mode 100644
index 0000000000..32d32761f1
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.3
@@ -0,0 +1,87 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: rand.3,v 1.4 1998/07/05 19:54:22 millert Exp $
37.\"
38.Dd June 29, 1991
39.Dt RAND 3
40.Os
41.Sh NAME
42.Nm rand ,
43.Nm srand
44.Nd bad random number generator
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn srand "unsigned seed"
49.Ft int
50.Fn rand void
51.Sh DESCRIPTION
52.Bf -symbolic
53These interfaces are obsoleted by
54.Xr random 3 .
55.Ef
56.Pp
57The
58.Fn rand
59function computes a sequence of pseudo-random integers in the range
60of 0 to
61.Dv RAND_MAX
62(as defined by the header file
63.Aq Pa stdlib.h ) .
64.Pp
65The
66.Fn srand
67function sets its argument as the seed for a new sequence of
68pseudo-random numbers to be returned by
69.Fn rand .
70These sequences are repeatable by calling
71.Fn srand
72with the same seed value.
73.Pp
74If no seed value is provided, the functions are automatically
75seeded with a value of 1.
76.Sh SEE ALSO
77.Xr arc4random 3 ,
78.Xr rand48 3 ,
79.Xr random 3
80.Sh STANDARDS
81The
82.Fn rand
83and
84.Fn srand
85functions
86conform to
87.St -ansiC .
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000000..f270ffd986
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.c
@@ -0,0 +1,54 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: rand.c,v 1.2 1996/08/19 08:33:44 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static u_long next = 1;
42
43int
44rand()
45{
46 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1));
47}
48
49void
50srand(seed)
51u_int seed;
52{
53 next = seed;
54}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
new file mode 100644
index 0000000000..d5236a4779
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.3
@@ -0,0 +1,161 @@
1\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved.
3.\"
4.\" You may redistribute unmodified or modified versions of this source
5.\" code provided that the above copyright notice and this and the
6.\" following conditions are retained.
7.\"
8.\" This software is provided ``as is'', and comes with no warranties
9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software.
11.\"
12.\" $OpenBSD: rand48.3,v 1.3 1998/07/05 19:54:23 millert Exp $
13.\"
14.Dd October 8, 1993
15.Dt RAND48 3
16.Os
17.Sh NAME
18.Nm drand48 ,
19.Nm erand48 ,
20.Nm lrand48 ,
21.Nm nrand48 ,
22.Nm mrand48 ,
23.Nm jrand48 ,
24.Nm srand48 ,
25.Nm seed48 ,
26.Nm lcong48
27.Nd pseudo random number generators and initialization routines
28.Sh SYNOPSIS
29.Fd #include <stdlib.h>
30.Ft double
31.Fn drand48 void
32.Ft double
33.Fn erand48 "unsigned short xseed[3]"
34.Ft long
35.Fn lrand48 void
36.Ft long
37.Fn nrand48 "unsigned short xseed[3]"
38.Ft long
39.Fn mrand48 void
40.Ft long
41.Fn jrand48 "unsigned short xseed[3]"
42.Ft void
43.Fn srand48 "long seed"
44.Ft "unsigned short *"
45.Fn seed48 "unsigned short xseed[3]"
46.Ft void
47.Fn lcong48 "unsigned short p[7]"
48.Sh DESCRIPTION
49The
50.Fn rand48
51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size. The
53particular formula employed is
54r(n+1) = (a * r(n) + c) mod m
55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48.
58r(n) is called the seed of the random number generator.
59.Pp
60For all the six generator routines described next, the first
61computational step is to perform a single iteration of the algorithm.
62.Pp
63.Fn drand48
64and
65.Fn erand48
66return values of type double. The full 48 bits of r(n+1) are
67loaded into the mantissa of the returned value, with the exponent set
68such that the values produced lie in the interval [0.0, 1.0).
69.Pp
70.Fn lrand48
71and
72.Fn nrand48
73return values of type long in the range
74[0, 2**31-1]. The high-order (31) bits of
75r(n+1) are loaded into the lower bits of the returned value, with
76the topmost (sign) bit set to zero.
77.Pp
78.Fn mrand48
79and
80.Fn jrand48
81return values of type long in the range
82[-2**31, 2**31-1]. The high-order (32) bits of
83r(n+1) are loaded into the returned value.
84.Pp
85.Fn drand48 ,
86.Fn lrand48 ,
87and
88.Fn mrand48
89use an internal buffer to store r(n). For these functions
90the initial value of r(0) = 0x1234abcd330e = 20017429951246.
91.Pp
92On the other hand,
93.Fn erand48 ,
94.Fn nrand48 ,
95and
96.Fn jrand48
97use a user-supplied buffer to store the seed r(n),
98which consists of an array of 3 shorts, where the zeroth member
99holds the least significant bits.
100.Pp
101All functions share the same multiplicand and addend.
102.Pp
103.Fn srand48
104is used to initialize the internal buffer r(n) of
105.Fn drand48 ,
106.Fn lrand48 ,
107and
108.Fn mrand48
109such that the 32 bits of the seed value are copied into the upper 32 bits
110of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
111Additionally, the constant multiplicand and addend of the algorithm are
112reset to the default values given above.
113.Pp
114.Fn seed48
115also initializes the internal buffer r(n) of
116.Fn drand48 ,
117.Fn lrand48 ,
118and
119.Fn mrand48 ,
120but here all 48 bits of the seed can be specified in an array of 3 shorts,
121where the zeroth member specifies the lowest bits. Again,
122the constant multiplicand and addend of the algorithm are
123reset to the default values given above.
124.Fn seed48
125returns a pointer to an array of 3 shorts which contains the old seed.
126This array is statically allocated, thus its contents are lost after
127each new call to
128.Fn seed48 .
129.Pp
130Finally,
131.Fn lcong48
132allows full control over the multiplicand and addend used in
133.Fn drand48 ,
134.Fn erand48 ,
135.Fn lrand48 ,
136.Fn nrand48 ,
137.Fn mrand48 ,
138and
139.Fn jrand48 ,
140and the seed used in
141.Fn drand48 ,
142.Fn lrand48 ,
143and
144.Fn mrand48 .
145An array of 7 shorts is passed as parameter; the first three shorts are
146used to initialize the seed; the second three are used to initialize the
147multiplicand; and the last short is used to initialize the addend.
148It is thus not possible to use values greater than 0xffff as the addend.
149.Pp
150Note that all three methods of seeding the random number generator
151always also set the multiplicand and addend for any of the six
152generator calls.
153.Pp
154For a more powerful random number generator, see
155.Xr random 3
156.Sh AUTHOR
157Martin Birgmeier
158.Sh SEE ALSO
159.Xr arc4random 3 ,
160.Xr rand 3 ,
161.Xr random 3 .
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
new file mode 100644
index 0000000000..e7cb3e0333
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.2 1996/08/19 08:33:45 tholo Exp $
14 */
15
16#ifndef _RAND48_H_
17#define _RAND48_H_
18
19#include <math.h>
20#include <stdlib.h>
21
22void __dorand48 __P((unsigned short[3]));
23
24#define RAND48_SEED_0 (0x330e)
25#define RAND48_SEED_1 (0xabcd)
26#define RAND48_SEED_2 (0x1234)
27#define RAND48_MULT_0 (0xe66d)
28#define RAND48_MULT_1 (0xdeec)
29#define RAND48_MULT_2 (0x0005)
30#define RAND48_ADD (0x000b)
31
32#endif /* _RAND48_H_ */
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
new file mode 100644
index 0000000000..acfbd8cdeb
--- /dev/null
+++ b/src/lib/libc/stdlib/random.3
@@ -0,0 +1,183 @@
1.\" Copyright (c) 1983, 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.\" $OpenBSD: random.3,v 1.6 1998/07/05 19:54:25 millert Exp $
33.\"
34.Dd April 19, 1991
35.Dt RANDOM 3
36.Os BSD 4.2
37.Sh NAME
38.Nm random ,
39.Nm srandom ,
40.Nm initstate ,
41.Nm setstate
42.Nd better random number generator; routines for changing generators
43.Sh SYNOPSIS
44.Fd #include <stdlib.h>
45.Ft long
46.Fn random void
47.Ft void
48.Fn srandom "unsigned int seed"
49.Ft char *
50.Fn initstate "unsigned int seed" "char *state" "size_t n"
51.Ft char *
52.Fn setstate "const char *state"
53.Sh DESCRIPTION
54The
55.Fn random
56function
57uses a non-linear additive feedback random number generator employing a
58default table of size 31 long integers to return successive pseudo-random
59numbers in the range from 0 to
60.if t 2\u\s731\s10\d\(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 ) .
68The period of this random number generator is very large, approximately
69.if t 16\(mu(2\u\s731\s10\d\(mi1).
70.if n 16*((2**31)\(mi1).
71.Pp
72The
73.Fn random Ns / Fn srandom
74have (almost) the same calling sequence and initialization properties as
75.Xr rand 3 Ns / Xr srand 3 .
76The difference is that
77.Xr rand
78produces a much less random sequence \(em in fact, the low dozen bits
79generated by rand go through a cyclic pattern. All the bits generated by
80.Fn random
81are usable. For example,
82.Sq Li random()&01
83will produce a random binary
84value.
85.Pp
86Unlike
87.Xr srand ,
88.Fn srandom
89does not return the old seed; the reason for this is that the amount of
90state information used is much more than a single word. (Two other
91routines are provided to deal with restarting/changing random
92number generators). Like
93.Xr rand 3 ,
94however,
95.Fn random
96will by default produce a sequence of numbers that can be duplicated
97by calling
98.Fn srandom
99with
100.Ql 1
101as the seed.
102.Pp
103The
104.Fn initstate
105routine allows a state array, passed in as an argument, to be initialized
106for future use. The size of the state array (in bytes) is used by
107.Fn initstate
108to decide how sophisticated a random number generator it should use \(em the
109more state, the better the random numbers will be.
110(Current "optimal" values for the amount of state information are
1118, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
112the nearest known amount. Using less than 8 bytes will cause an error.)
113The seed for the initialization (which specifies a starting point for
114the random number sequence, and provides for restarting at the same
115point) is also an argument.
116The
117.Fn initstate
118function
119returns a pointer to the previous state information array.
120.Pp
121Once a state has been initialized, the
122.Fn setstate
123routine provides for rapid switching between states.
124The
125.Fn setstate
126function
127returns a pointer to the previous state array; its
128argument state array is used for further random number generation
129until the next call to
130.Fn initstate
131or
132.Fn setstate .
133.Pp
134Once a state array has been initialized, it may be restarted at a
135different point either by calling
136.Fn initstate
137(with the desired seed, the state array, and its size) or by calling
138both
139.Fn setstate
140(with the state array) and
141.Fn srandom
142(with the desired seed).
143The advantage of calling both
144.Fn setstate
145and
146.Fn srandom
147is that the size of the state array does not have to be remembered after
148it is initialized.
149.Pp
150With 256 bytes of state information, the period of the random number
151generator is greater than
152.if t 2\u\s769\s10\d,
153.if n 2**69
154which should be sufficient for most purposes.
155.Sh AUTHOR
156Earl T. Cohen
157.Sh DIAGNOSTICS
158If
159.Fn initstate
160is called with less than 8 bytes of state information, or if
161.Fn setstate
162detects that the state information has been garbled, error
163messages are printed on the standard error output.
164.Sh SEE ALSO
165.Xr arc4random 3 ,
166.Xr drand48 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 .
177.Sh HISTORY
178These
179functions appeared in
180.Bx 4.2 .
181.Sh BUGS
182About 2/3 the speed of
183.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
new file mode 100644
index 0000000000..79344f30f1
--- /dev/null
+++ b/src/lib/libc/stdlib/random.c
@@ -0,0 +1,370 @@
1/*
2 * Copyright (c) 1983 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: random.c,v 1.6 1998/02/07 02:16:25 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdio.h>
39#include <stdlib.h>
40
41/*
42 * random.c:
43 *
44 * An improved random number generation package. In addition to the standard
45 * rand()/srand() like interface, this package also has a special state info
46 * interface. The initstate() routine is called with a seed, an array of
47 * bytes, and a count of how many bytes are being passed in; this array is
48 * then initialized to contain information for random number generation with
49 * that much state information. Good sizes for the amount of state
50 * information are 32, 64, 128, and 256 bytes. The state can be switched by
51 * calling the setstate() routine with the same array as was initiallized
52 * with initstate(). By default, the package runs with 128 bytes of state
53 * information and generates far better random numbers than a linear
54 * congruential generator. If the amount of state information is less than
55 * 32 bytes, a simple linear congruential R.N.G. is used.
56 *
57 * Internally, the state information is treated as an array of longs; the
58 * zeroeth element of the array is the type of R.N.G. being used (small
59 * integer); the remainder of the array is the state information for the
60 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
61 * state information, which will allow a degree seven polynomial. (Note:
62 * the zeroeth word of state information also has some other information
63 * stored in it -- see setstate() for details).
64 *
65 * The random number generation technique is a linear feedback shift register
66 * approach, employing trinomials (since there are fewer terms to sum up that
67 * way). In this approach, the least significant bit of all the numbers in
68 * the state table will act as a linear feedback shift register, and will
69 * have period 2^deg - 1 (where deg is the degree of the polynomial being
70 * used, assuming that the polynomial is irreducible and primitive). The
71 * higher order bits will have longer periods, since their values are also
72 * influenced by pseudo-random carries out of the lower bits. The total
73 * period of the generator is approximately deg*(2**deg - 1); thus doubling
74 * the amount of state information has a vast influence on the period of the
75 * generator. Note: the deg*(2**deg - 1) is an approximation only good for
76 * large deg, when the period of the shift register is the dominant factor.
77 * With deg equal to seven, the period is actually much longer than the
78 * 7*(2**7 - 1) predicted by this formula.
79 */
80
81/*
82 * For each of the currently supported random number generators, we have a
83 * break value on the amount of state information (you need at least this
84 * many bytes of state info to support this random number generator), a degree
85 * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
86 * the separation between the two lower order coefficients of the trinomial.
87 */
88#define TYPE_0 0 /* linear congruential */
89#define BREAK_0 8
90#define DEG_0 0
91#define SEP_0 0
92
93#define TYPE_1 1 /* x**7 + x**3 + 1 */
94#define BREAK_1 32
95#define DEG_1 7
96#define SEP_1 3
97
98#define TYPE_2 2 /* x**15 + x + 1 */
99#define BREAK_2 64
100#define DEG_2 15
101#define SEP_2 1
102
103#define TYPE_3 3 /* x**31 + x**3 + 1 */
104#define BREAK_3 128
105#define DEG_3 31
106#define SEP_3 3
107
108#define TYPE_4 4 /* x**63 + x + 1 */
109#define BREAK_4 256
110#define DEG_4 63
111#define SEP_4 1
112
113/*
114 * Array versions of the above information to make code run faster --
115 * relies on fact that TYPE_i == i.
116 */
117#define MAX_TYPES 5 /* max number of types above */
118
119static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
120static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
121
122/*
123 * Initially, everything is set up as if from:
124 *
125 * initstate(1, &randtbl, 128);
126 *
127 * Note that this initialization takes advantage of the fact that srandom()
128 * advances the front and rear pointers 10*rand_deg times, and hence the
129 * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
130 * element of the state information, which contains info about the current
131 * position of the rear pointer is just
132 *
133 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
134 */
135
136static long randtbl[DEG_3 + 1] = {
137 TYPE_3,
138 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
139 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
140 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
141 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
142 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
143 0xf3bec5da,
144};
145
146/*
147 * fptr and rptr are two pointers into the state info, a front and a rear
148 * pointer. These two pointers are always rand_sep places aparts, as they
149 * cycle cyclically through the state information. (Yes, this does mean we
150 * could get away with just one pointer, but the code for random() is more
151 * efficient this way). The pointers are left positioned as they would be
152 * from the call
153 *
154 * initstate(1, randtbl, 128);
155 *
156 * (The position of the rear pointer, rptr, is really 0 (as explained above
157 * in the initialization of randtbl) because the state table pointer is set
158 * to point to randtbl[1] (as explained below).
159 */
160static long *fptr = &randtbl[SEP_3 + 1];
161static long *rptr = &randtbl[1];
162
163/*
164 * The following things are the pointer to the state information table, the
165 * type of the current generator, the degree of the current polynomial being
166 * used, and the separation between the two pointers. Note that for efficiency
167 * of random(), we remember the first location of the state information, not
168 * the zeroeth. Hence it is valid to access state[-1], which is used to
169 * store the type of the R.N.G. Also, we remember the last location, since
170 * this is more efficient than indexing every time to find the address of
171 * the last element to see if the front and rear pointers have wrapped.
172 */
173static long *state = &randtbl[1];
174static int rand_type = TYPE_3;
175static int rand_deg = DEG_3;
176static int rand_sep = SEP_3;
177static long *end_ptr = &randtbl[DEG_3 + 1];
178
179/*
180 * srandom:
181 *
182 * Initialize the random number generator based on the given seed. If the
183 * type is the trivial no-state-information type, just remember the seed.
184 * Otherwise, initializes state[] based on the given "seed" via a linear
185 * congruential generator. Then, the pointers are set to known locations
186 * that are exactly rand_sep places apart. Lastly, it cycles the state
187 * information a given number of times to get rid of any initial dependencies
188 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
189 * for default usage relies on values produced by this routine.
190 */
191void
192srandom(x)
193 u_int x;
194{
195 register long int test;
196 register int i;
197 ldiv_t val;
198
199 if (rand_type == TYPE_0)
200 state[0] = x;
201 else {
202 state[0] = x;
203 for (i = 1; i < rand_deg; i++) {
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 }
215 fptr = &state[rand_sep];
216 rptr = &state[0];
217 for (i = 0; i < 10 * rand_deg; i++)
218 (void)random();
219 }
220}
221
222/*
223 * initstate:
224 *
225 * Initialize the state information in the given array of n bytes for future
226 * random number generation. Based on the number of bytes we are given, and
227 * the break values for the different R.N.G.'s, we choose the best (largest)
228 * one we can and set things up for it. srandom() is then called to
229 * initialize the state information.
230 *
231 * Note that on return from srandom(), we set state[-1] to be the type
232 * multiplexed with the current value of the rear pointer; this is so
233 * successive calls to initstate() won't lose this information and will be
234 * able to restart with setstate().
235 *
236 * Note: the first thing we do is save the current state, if any, just like
237 * setstate() so that it doesn't matter when initstate is called.
238 *
239 * Returns a pointer to the old state.
240 */
241char *
242initstate(seed, arg_state, n)
243 u_int seed; /* seed for R.N.G. */
244 char *arg_state; /* pointer to state array */
245 size_t n; /* # bytes of state info */
246{
247 register char *ostate = (char *)(&state[-1]);
248
249 if (rand_type == TYPE_0)
250 state[-1] = rand_type;
251 else
252 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
253 if (n < BREAK_0)
254 return(NULL);
255 if (n < BREAK_1) {
256 rand_type = TYPE_0;
257 rand_deg = DEG_0;
258 rand_sep = SEP_0;
259 } else if (n < BREAK_2) {
260 rand_type = TYPE_1;
261 rand_deg = DEG_1;
262 rand_sep = SEP_1;
263 } else if (n < BREAK_3) {
264 rand_type = TYPE_2;
265 rand_deg = DEG_2;
266 rand_sep = SEP_2;
267 } else if (n < BREAK_4) {
268 rand_type = TYPE_3;
269 rand_deg = DEG_3;
270 rand_sep = SEP_3;
271 } else {
272 rand_type = TYPE_4;
273 rand_deg = DEG_4;
274 rand_sep = SEP_4;
275 }
276 state = &(((long *)arg_state)[1]); /* first location */
277 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
278 srandom(seed);
279 if (rand_type == TYPE_0)
280 state[-1] = rand_type;
281 else
282 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
283 return(ostate);
284}
285
286/*
287 * setstate:
288 *
289 * Restore the state from the given state array.
290 *
291 * Note: it is important that we also remember the locations of the pointers
292 * in the current state information, and restore the locations of the pointers
293 * from the old state information. This is done by multiplexing the pointer
294 * location into the zeroeth word of the state information.
295 *
296 * Note that due to the order in which things are done, it is OK to call
297 * setstate() with the same state as the current state.
298 *
299 * Returns a pointer to the old state information.
300 */
301char *
302setstate(arg_state)
303 const char *arg_state;
304{
305 register long *new_state = (long *)arg_state;
306 register int type = new_state[0] % MAX_TYPES;
307 register int rear = new_state[0] / MAX_TYPES;
308 char *ostate = (char *)(&state[-1]);
309
310 if (rand_type == TYPE_0)
311 state[-1] = rand_type;
312 else
313 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
314 switch(type) {
315 case TYPE_0:
316 case TYPE_1:
317 case TYPE_2:
318 case TYPE_3:
319 case TYPE_4:
320 rand_type = type;
321 rand_deg = degrees[type];
322 rand_sep = seps[type];
323 break;
324 default:
325 return(NULL);
326 }
327 state = &new_state[1];
328 if (rand_type != TYPE_0) {
329 rptr = &state[rear];
330 fptr = &state[(rear + rand_sep) % rand_deg];
331 }
332 end_ptr = &state[rand_deg]; /* set end_ptr too */
333 return(ostate);
334}
335
336/*
337 * random:
338 *
339 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
340 * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
341 * the same in all the other cases due to all the global variables that have
342 * been set up. The basic operation is to add the number at the rear pointer
343 * into the one at the front pointer. Then both pointers are advanced to
344 * the next location cyclically in the table. The value returned is the sum
345 * generated, reduced to 31 bits by throwing away the "least random" low bit.
346 *
347 * Note: the code takes advantage of the fact that both the front and
348 * rear pointers can't wrap on the same call by not testing the rear
349 * pointer if the front one has wrapped.
350 *
351 * Returns a 31-bit random number.
352 */
353long
354random()
355{
356 long i;
357
358 if (rand_type == TYPE_0)
359 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
360 else {
361 *fptr += *rptr;
362 i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
363 if (++fptr >= end_ptr) {
364 fptr = state;
365 ++rptr;
366 } else if (++rptr >= end_ptr)
367 rptr = state;
368 }
369 return(i);
370}
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000000..cc140029e4
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.3
@@ -0,0 +1,125 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Jan-Simon Pendry.
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.\" $OpenBSD: realpath.3,v 1.3 1997/05/30 07:48:30 deraadt Exp $
36.\"
37.Dd February, 16, 1994
38.Dt REALPATH 3
39.Os
40.Sh NAME
41.Nm realpath
42.Nd returns the canonicalized absolute pathname
43.Sh SYNOPSIS
44.Fd #include <sys/param.h>
45.Fd #include <stdlib.h>
46.Ft "char *"
47.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]"
48.Sh DESCRIPTION
49The
50.Fn realpath
51function resolves all symbolic links, extra
52.Dq /
53characters and references to
54.Pa /./
55and
56.Pa /../
57in
58.Fa pathname ,
59and copies the resulting absolute pathname into
60the memory referenced by
61.Fa resolvedname .
62The
63.Fa resolvedname
64argument
65.Em must
66refer to a buffer capable of storing at least
67.Dv MAXPATHLEN
68characters.
69.Pp
70The
71.Fn realpath
72function will resolve both absolute and relative paths
73and return the absolute pathname corresponding to
74.Fa pathname .
75All but the last component of
76.Fa pathname
77must exist when
78.Fn realpath
79is called.
80.Sh "RETURN VALUES"
81The
82.Fn realpath
83function returns
84.Fa resolved_name
85on success.
86If an error occurs,
87.Fn realpath
88returns
89.Dv NULL ,
90and
91.Fa resolved_name
92contains the pathname which caused the problem.
93.Sh ERRORS
94The function
95.Fn realpath
96may fail and set the external variable
97.Va errno
98for any of the errors specified for the library functions
99.Xr chdir 2 ,
100.Xr close 2 ,
101.Xr fchdir 2 ,
102.Xr lstat 2 ,
103.Xr open 2 ,
104.Xr readlink 2
105and
106.Xr getcwd 3 .
107.Sh CAVEATS
108This implementation of
109.Fn realpath
110differs slightly from the Solaris implementation.
111The
112.Bx 4.4
113version always returns absolute pathnames,
114whereas the Solaris implementation will,
115under certain circumstances, return a relative
116.Fa resolved_path
117when given a relative
118.Fa pathname .
119.Sh "SEE ALSO"
120.Xr getcwd 3
121.Sh HISTORY
122The
123.Fn realpath
124function call first appeared in
125.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
new file mode 100644
index 0000000000..0288601464
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
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
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: realpath.c,v 1.4 1998/05/18 09:55:19 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/param.h>
42#include <sys/stat.h>
43
44#include <errno.h>
45#include <fcntl.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50/*
51 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
52 *
53 * Find the real name of path, by removing all ".", ".." and symlink
54 * components. Returns (resolved) on success, or (NULL) on failure,
55 * in which case the path which caused trouble is left in (resolved).
56 */
57char *
58realpath(path, resolved)
59 const char *path;
60 char *resolved;
61{
62 struct stat sb;
63 int fd, n, rootd, serrno;
64 char *p, *q, wbuf[MAXPATHLEN];
65 int symlinks = 0;
66
67 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strcpy(resolved, ".");
70 return (NULL);
71 }
72
73 /*
74 * Find the dirname and basename from the path to be resolved.
75 * Change directory to the dirname component.
76 * lstat the basename part.
77 * if it is a symlink, read in the value and loop.
78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename.
80 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1);
82 resolved[MAXPATHLEN - 1] = '\0';
83loop:
84 q = strrchr(resolved, '/');
85 if (q != NULL) {
86 p = q + 1;
87 if (q == resolved)
88 q = "/";
89 else {
90 do {
91 --q;
92 } while (q > resolved && *q == '/');
93 q[1] = '\0';
94 q = resolved;
95 }
96 if (chdir(q) < 0)
97 goto err1;
98 } else
99 p = resolved;
100
101 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) {
104 if (++symlinks > MAXSYMLINKS) {
105 errno = ELOOP;
106 goto err1;
107 }
108 n = readlink(p, resolved, MAXPATHLEN-1);
109 if (n < 0)
110 goto err1;
111 resolved[n] = '\0';
112 goto loop;
113 }
114 if (S_ISDIR(sb.st_mode)) {
115 if (chdir(p) < 0)
116 goto err1;
117 p = "";
118 }
119 }
120
121 /*
122 * Save the last component name and get the full pathname of
123 * the current directory.
124 */
125 (void)strcpy(wbuf, p);
126 if (getcwd(resolved, MAXPATHLEN) == 0)
127 goto err1;
128
129 /*
130 * Join the two strings together, ensuring that the right thing
131 * happens if the last component is empty, or the dirname is root.
132 */
133 if (resolved[0] == '/' && resolved[1] == '\0')
134 rootd = 1;
135 else
136 rootd = 0;
137
138 if (*wbuf) {
139 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
140 errno = ENAMETOOLONG;
141 goto err1;
142 }
143 if (rootd == 0)
144 (void)strcat(resolved, "/");
145 (void)strcat(resolved, wbuf);
146 }
147
148 /* Go back to where we came from. */
149 if (fchdir(fd) < 0) {
150 serrno = errno;
151 goto err2;
152 }
153
154 /* It's okay if the close fails, what's an fd more or less? */
155 (void)close(fd);
156 return (resolved);
157
158err1: serrno = errno;
159 (void)fchdir(fd);
160err2: (void)close(fd);
161 errno = serrno;
162 return (NULL);
163}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
new file mode 100644
index 0000000000..c4dcd0ead8
--- /dev/null
+++ b/src/lib/libc/stdlib/seed48.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24unsigned short *
25seed48(unsigned short xseed[3])
26{
27 static unsigned short sseed[3];
28
29 sseed[0] = __rand48_seed[0];
30 sseed[1] = __rand48_seed[1];
31 sseed[2] = __rand48_seed[2];
32 __rand48_seed[0] = xseed[0];
33 __rand48_seed[1] = xseed[1];
34 __rand48_seed[2] = xseed[2];
35 __rand48_mult[0] = RAND48_MULT_0;
36 __rand48_mult[1] = RAND48_MULT_1;
37 __rand48_mult[2] = RAND48_MULT_2;
38 __rand48_add = RAND48_ADD;
39 return sseed;
40}
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
new file mode 100644
index 0000000000..b6f261e61c
--- /dev/null
+++ b/src/lib/libc/stdlib/setenv.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * setenv --
43 * Set the value of the environmental variable "name" to be
44 * "value". If rewrite is set, replace any current value.
45 */
46int
47setenv(name, value, rewrite)
48 register const char *name;
49 register const char *value;
50 int rewrite;
51{
52 extern char **environ;
53 static int alloced; /* if allocated space before */
54 register char *C;
55 int l_value, offset;
56 char *__findenv();
57
58 if (*value == '=') /* no `=' in value */
59 ++value;
60 l_value = strlen(value);
61 if ((C = __findenv(name, &offset))) { /* find if already exists */
62 if (!rewrite)
63 return (0);
64 if (strlen(C) >= l_value) { /* old larger; copy over */
65 while (*C++ = *value++);
66 return (0);
67 }
68 } else { /* create new slot */
69 register int cnt;
70 register char **P;
71
72 for (P = environ, cnt = 0; *P; ++P, ++cnt);
73 if (alloced) { /* just increase size */
74 P = (char **)realloc((void *)environ,
75 (size_t)(sizeof(char *) * (cnt + 2)));
76 if (!P)
77 return (-1);
78 environ = P;
79 }
80 else { /* get new space */
81 alloced = 1; /* copy old entries into it */
82 P = (char **)malloc((size_t)(sizeof(char *) *
83 (cnt + 2)));
84 if (!P)
85 return (-1);
86 bcopy(environ, P, cnt * sizeof(char *));
87 environ = P;
88 }
89 environ[cnt + 1] = NULL;
90 offset = cnt;
91 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2))))
95 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ;
98 for (*C++ = '='; *C++ = *value++; )
99 ;
100 return (0);
101}
102
103/*
104 * unsetenv(name) --
105 * Delete environmental variable "name".
106 */
107void
108unsetenv(name)
109 const char *name;
110{
111 extern char **environ;
112 register char **P;
113 int offset;
114 char *__findenv();
115
116 while (__findenv(name, &offset)) /* if set multiple times */
117 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1)))
119 break;
120}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
new file mode 100644
index 0000000000..fcff8a172e
--- /dev/null
+++ b/src/lib/libc/stdlib/srand48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
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
11 * to anyone/anything when using this software.
12 */
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
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25srand48(long seed)
26{
27 __rand48_seed[0] = RAND48_SEED_0;
28 __rand48_seed[1] = (unsigned short) seed;
29 __rand48_seed[2] = (unsigned short) (seed >> 16);
30 __rand48_mult[0] = RAND48_MULT_0;
31 __rand48_mult[1] = RAND48_MULT_1;
32 __rand48_mult[2] = RAND48_MULT_2;
33 __rand48_add = RAND48_ADD;
34}
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
new file mode 100644
index 0000000000..3476fa41d6
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.3
@@ -0,0 +1,113 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: strtod.3,v 1.2 1996/08/19 08:33:49 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRTOD 3
40.Os
41.Sh NAME
42.Nm strtod
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn strtod "const char *nptr" "char **endptr"
50.Sh DESCRIPTION
51The
52.Fn strtod
53function converts the initial portion of the string
54pointed to by
55.Fa nptr
56to
57.Em double
58representation.
59.Pp
60The expected form of the string is an optional plus (``+'') or minus
61sign (``-'') followed by a sequence of digits optionally containing
62a decimal-point character, optionally followed by an exponent.
63An exponent consists of an ``E'' or ``e'', followed by an optional plus
64or minus sign, followed by a sequence of digits.
65.Pp
66Leading white-space characters in the string (as defined by the
67.Xr isspace 3
68function) are skipped.
69.Sh RETURN VALUES
70The
71.Fn strtod
72function returns the converted value, if any.
73.Pp
74If
75.Fa endptr
76is not
77.Dv NULL ,
78a pointer to the character after the last character used
79in the conversion is stored in the location referenced by
80.Fa endptr .
81.Pp
82If no conversion is performed, zero is returned and the value of
83.Fa nptr
84is stored in the location referenced by
85.Fa endptr .
86.Pp
87If the correct value would cause overflow, plus or minus
88.Dv HUGE_VAL
89is returned (according to the sign of the value), and
90.Dv ERANGE
91is stored in
92.Va errno .
93If the correct value would cause underflow, zero is
94returned and
95.Dv ERANGE
96is stored in
97.Va errno .
98.Sh ERRORS
99.Bl -tag -width Er
100.It Bq Er ERANGE
101Overflow or underflow occurred.
102.Sh SEE ALSO
103.Xr atof 3 ,
104.Xr atoi 3 ,
105.Xr atol 3 ,
106.Xr strtol 3 ,
107.Xr strtoul 3
108.Sh STANDARDS
109The
110.Fn strtod
111function
112conforms to
113.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
new file mode 100644
index 0000000000..55d9e91224
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.c
@@ -0,0 +1,2529 @@
1/****************************************************************
2 *
3 * The author of this software is David M. Gay.
4 *
5 * Copyright (c) 1991 by AT&T.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose without fee is hereby granted, provided that this entire notice
9 * is included in all copies of any software which is or includes a copy
10 * or modification of this software and in all copies of the supporting
11 * documentation for such software.
12 *
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17 *
18 ***************************************************************/
19
20/* Please send bug reports to
21 David M. Gay
22 AT&T Bell Laboratories, Room 2C-463
23 600 Mountain Avenue
24 Murray Hill, NJ 07974-2070
25 U.S.A.
26 dmg@research.att.com or research!dmg
27 */
28
29/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
30 *
31 * This strtod returns a nearest machine number to the input decimal
32 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
33 * broken by the IEEE round-even rule. Otherwise ties are broken by
34 * biased rounding (add half and chop).
35 *
36 * Inspired loosely by William D. Clinger's paper "How to Read Floating
37 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
38 *
39 * Modifications:
40 *
41 * 1. We only require IEEE, IBM, or VAX double-precision
42 * arithmetic (not IEEE double-extended).
43 * 2. We get by with floating-point arithmetic in a case that
44 * Clinger missed -- when we're computing d * 10^n
45 * for a small integer d and the integer n is not too
46 * much larger than 22 (the maximum integer k for which
47 * we can represent 10^k exactly), we may be able to
48 * compute (d*10^k) * 10^(e-k) with just one roundoff.
49 * 3. Rather than a bit-at-a-time adjustment of the binary
50 * result in the hard case, we use floating-point
51 * arithmetic to determine the adjustment to within
52 * one bit; only in really hard cases do we need to
53 * compute a second residual.
54 * 4. Because of 3., we don't need a large table of powers of 10
55 * for ten-to-e (just some small tables, e.g. of 10^k
56 * for 0 <= k <= 22).
57 */
58
59/*
60 * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
61 * significant byte has the lowest address.
62 * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
63 * significant byte has the lowest address.
64 * #define Long int on machines with 32-bit ints and 64-bit longs.
65 * #define Sudden_Underflow for IEEE-format machines without gradual
66 * underflow (i.e., that flush to zero on underflow).
67 * #define IBM for IBM mainframe-style floating-point arithmetic.
68 * #define VAX for VAX-style floating-point arithmetic.
69 * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
70 * #define No_leftright to omit left-right logic in fast floating-point
71 * computation of dtoa.
72 * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
73 * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
74 * that use extended-precision instructions to compute rounded
75 * products and quotients) with IBM.
76 * #define ROUND_BIASED for IEEE-format with biased rounding.
77 * #define Inaccurate_Divide for IEEE-format with correctly rounded
78 * products but inaccurate quotients, e.g., for Intel i860.
79 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
80 * integer arithmetic. Whether this speeds things up or slows things
81 * down depends on the machine and the number being converted.
82 * #define KR_headers for old-style C function headers.
83 * #define Bad_float_h if your system lacks a float.h or if it does not
84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
86 * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
87 * if memory is available and otherwise does something you deem
88 * appropriate. If MALLOC is undefined, malloc will be invoked
89 * directly -- and assumed always to succeed.
90 */
91
92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$OpenBSD: strtod.c,v 1.12 1998/08/28 20:49:24 mickey Exp $";
94#endif /* LIBC_SCCS and not lint */
95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__)
99#include <sys/types.h>
100#if BYTE_ORDER == BIG_ENDIAN
101#define IEEE_BIG_ENDIAN
102#else
103#define IEEE_LITTLE_ENDIAN
104#endif
105#endif
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
116#ifdef vax
117#define VAX
118#endif
119
120#define Long int32_t
121#define ULong u_int32_t
122
123#ifdef DEBUG
124#include "stdio.h"
125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
126#endif
127
128#ifdef __cplusplus
129#include "malloc.h"
130#include "memory.h"
131#else
132#ifndef KR_headers
133#include "stdlib.h"
134#include "string.h"
135#include "locale.h"
136#else
137#include "malloc.h"
138#include "memory.h"
139#endif
140#endif
141
142#ifdef MALLOC
143#ifdef KR_headers
144extern char *MALLOC();
145#else
146extern void *MALLOC(size_t);
147#endif
148#else
149#define MALLOC malloc
150#endif
151
152#include "ctype.h"
153#include "errno.h"
154
155#ifdef Bad_float_h
156#undef __STDC__
157#ifdef IEEE_BIG_ENDIAN
158#define IEEE_ARITHMETIC
159#endif
160#ifdef IEEE_LITTLE_ENDIAN
161#define IEEE_ARITHMETIC
162#endif
163
164#ifdef IEEE_ARITHMETIC
165#define DBL_DIG 15
166#define DBL_MAX_10_EXP 308
167#define DBL_MAX_EXP 1024
168#define FLT_RADIX 2
169#define FLT_ROUNDS 1
170#define DBL_MAX 1.7976931348623157e+308
171#endif
172
173#ifdef IBM
174#define DBL_DIG 16
175#define DBL_MAX_10_EXP 75
176#define DBL_MAX_EXP 63
177#define FLT_RADIX 16
178#define FLT_ROUNDS 0
179#define DBL_MAX 7.2370055773322621e+75
180#endif
181
182#ifdef VAX
183#define DBL_DIG 16
184#define DBL_MAX_10_EXP 38
185#define DBL_MAX_EXP 127
186#define FLT_RADIX 2
187#define FLT_ROUNDS 1
188#define DBL_MAX 1.7014118346046923e+38
189#endif
190
191#ifndef LONG_MAX
192#define LONG_MAX 2147483647
193#endif
194#else
195#include "float.h"
196#endif
197#ifndef __MATH_H__
198#include "math.h"
199#endif
200
201#ifdef __cplusplus
202extern "C" {
203#endif
204
205#ifndef CONST
206#ifdef KR_headers
207#define CONST /* blank */
208#else
209#define CONST const
210#endif
211#endif
212
213#ifdef Unsigned_Shifts
214#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
215#else
216#define Sign_Extend(a,b) /*no-op*/
217#endif
218
219#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
220 defined(IBM) != 1
221Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
222IBM should be defined.
223#endif
224
225typedef union {
226 double d;
227 ULong ul[2];
228} _double;
229#define value(x) ((x).d)
230#ifdef IEEE_LITTLE_ENDIAN
231#define word0(x) ((x).ul[1])
232#define word1(x) ((x).ul[0])
233#else
234#define word0(x) ((x).ul[0])
235#define word1(x) ((x).ul[1])
236#endif
237
238/* The following definition of Storeinc is appropriate for MIPS processors.
239 * An alternative that might be better on some machines is
240 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
241 */
242#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
243#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
244((unsigned short *)a)[0] = (unsigned short)c, a++)
245#else
246#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
247((unsigned short *)a)[1] = (unsigned short)c, a++)
248#endif
249
250/* #define P DBL_MANT_DIG */
251/* Ten_pmax = floor(P*log(2)/log(5)) */
252/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
253/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
254/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
255
256#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
257#define Exp_shift 20
258#define Exp_shift1 20
259#define Exp_msk1 0x100000
260#define Exp_msk11 0x100000
261#define Exp_mask 0x7ff00000
262#define P 53
263#define Bias 1023
264#define IEEE_Arith
265#define Emin (-1022)
266#define Exp_1 0x3ff00000
267#define Exp_11 0x3ff00000
268#define Ebits 11
269#define Frac_mask 0xfffff
270#define Frac_mask1 0xfffff
271#define Ten_pmax 22
272#define Bletch 0x10
273#define Bndry_mask 0xfffff
274#define Bndry_mask1 0xfffff
275#define LSB 1
276#define Sign_bit 0x80000000
277#define Log2P 1
278#define Tiny0 0
279#define Tiny1 1
280#define Quick_max 14
281#define Int_max 14
282#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
283#else
284#undef Sudden_Underflow
285#define Sudden_Underflow
286#ifdef IBM
287#define Exp_shift 24
288#define Exp_shift1 24
289#define Exp_msk1 0x1000000
290#define Exp_msk11 0x1000000
291#define Exp_mask 0x7f000000
292#define P 14
293#define Bias 65
294#define Exp_1 0x41000000
295#define Exp_11 0x41000000
296#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
297#define Frac_mask 0xffffff
298#define Frac_mask1 0xffffff
299#define Bletch 4
300#define Ten_pmax 22
301#define Bndry_mask 0xefffff
302#define Bndry_mask1 0xffffff
303#define LSB 1
304#define Sign_bit 0x80000000
305#define Log2P 4
306#define Tiny0 0x100000
307#define Tiny1 0
308#define Quick_max 14
309#define Int_max 15
310#else /* VAX */
311#define Exp_shift 23
312#define Exp_shift1 7
313#define Exp_msk1 0x80
314#define Exp_msk11 0x800000
315#define Exp_mask 0x7f80
316#define P 56
317#define Bias 129
318#define Exp_1 0x40800000
319#define Exp_11 0x4080
320#define Ebits 8
321#define Frac_mask 0x7fffff
322#define Frac_mask1 0xffff007f
323#define Ten_pmax 24
324#define Bletch 2
325#define Bndry_mask 0xffff007f
326#define Bndry_mask1 0xffff007f
327#define LSB 0x10000
328#define Sign_bit 0x8000
329#define Log2P 1
330#define Tiny0 0x80
331#define Tiny1 0
332#define Quick_max 15
333#define Int_max 15
334#endif
335#endif
336
337#ifndef IEEE_Arith
338#define ROUND_BIASED
339#endif
340
341#ifdef RND_PRODQUOT
342#define rounded_product(a,b) a = rnd_prod(a, b)
343#define rounded_quotient(a,b) a = rnd_quot(a, b)
344#ifdef KR_headers
345extern double rnd_prod(), rnd_quot();
346#else
347extern double rnd_prod(double, double), rnd_quot(double, double);
348#endif
349#else
350#define rounded_product(a,b) a *= b
351#define rounded_quotient(a,b) a /= b
352#endif
353
354#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
355#define Big1 0xffffffff
356
357#ifndef Just_16
358/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
359 * This makes some inner loops simpler and sometimes saves work
360 * during multiplications, but it often seems to make things slightly
361 * slower. Hence the default is now to store 32 bits per Long.
362 */
363#ifndef Pack_32
364#define Pack_32
365#endif
366#endif
367
368#define Kmax 15
369
370#ifdef __cplusplus
371extern "C" double strtod(const char *s00, char **se);
372extern "C" char *__dtoa(double d, int mode, int ndigits,
373 int *decpt, int *sign, char **rve);
374#endif
375
376 struct
377Bigint {
378 struct Bigint *next;
379 int k, maxwds, sign, wds;
380 ULong x[1];
381 };
382
383 typedef struct Bigint Bigint;
384
385 static Bigint *freelist[Kmax+1];
386
387 static Bigint *
388Balloc
389#ifdef KR_headers
390 (k) int k;
391#else
392 (int k)
393#endif
394{
395 int x;
396 Bigint *rv;
397
398 if (rv = freelist[k]) {
399 freelist[k] = rv->next;
400 }
401 else {
402 x = 1 << k;
403 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
404 rv->k = k;
405 rv->maxwds = x;
406 }
407 rv->sign = rv->wds = 0;
408 return rv;
409 }
410
411 static void
412Bfree
413#ifdef KR_headers
414 (v) Bigint *v;
415#else
416 (Bigint *v)
417#endif
418{
419 if (v) {
420 v->next = freelist[v->k];
421 freelist[v->k] = v;
422 }
423 }
424
425#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
426y->wds*sizeof(Long) + 2*sizeof(int))
427
428 static Bigint *
429multadd
430#ifdef KR_headers
431 (b, m, a) Bigint *b; int m, a;
432#else
433 (Bigint *b, int m, int a) /* multiply by m and add a */
434#endif
435{
436 int i, wds;
437 ULong *x, y;
438#ifdef Pack_32
439 ULong xi, z;
440#endif
441 Bigint *b1;
442
443 wds = b->wds;
444 x = b->x;
445 i = 0;
446 do {
447#ifdef Pack_32
448 xi = *x;
449 y = (xi & 0xffff) * m + a;
450 z = (xi >> 16) * m + (y >> 16);
451 a = (int)(z >> 16);
452 *x++ = (z << 16) + (y & 0xffff);
453#else
454 y = *x * m + a;
455 a = (int)(y >> 16);
456 *x++ = y & 0xffff;
457#endif
458 }
459 while(++i < wds);
460 if (a) {
461 if (wds >= b->maxwds) {
462 b1 = Balloc(b->k+1);
463 Bcopy(b1, b);
464 Bfree(b);
465 b = b1;
466 }
467 b->x[wds++] = a;
468 b->wds = wds;
469 }
470 return b;
471 }
472
473 static Bigint *
474s2b
475#ifdef KR_headers
476 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
477#else
478 (CONST char *s, int nd0, int nd, ULong y9)
479#endif
480{
481 Bigint *b;
482 int i, k;
483 Long x, y;
484
485 x = (nd + 8) / 9;
486 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
487#ifdef Pack_32
488 b = Balloc(k);
489 b->x[0] = y9;
490 b->wds = 1;
491#else
492 b = Balloc(k+1);
493 b->x[0] = y9 & 0xffff;
494 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
495#endif
496
497 i = 9;
498 if (9 < nd0) {
499 s += 9;
500 do b = multadd(b, 10, *s++ - '0');
501 while(++i < nd0);
502 s++;
503 }
504 else
505 s += 10;
506 for(; i < nd; i++)
507 b = multadd(b, 10, *s++ - '0');
508 return b;
509 }
510
511 static int
512hi0bits
513#ifdef KR_headers
514 (x) register ULong x;
515#else
516 (register ULong x)
517#endif
518{
519 register int k = 0;
520
521 if (!(x & 0xffff0000)) {
522 k = 16;
523 x <<= 16;
524 }
525 if (!(x & 0xff000000)) {
526 k += 8;
527 x <<= 8;
528 }
529 if (!(x & 0xf0000000)) {
530 k += 4;
531 x <<= 4;
532 }
533 if (!(x & 0xc0000000)) {
534 k += 2;
535 x <<= 2;
536 }
537 if (!(x & 0x80000000)) {
538 k++;
539 if (!(x & 0x40000000))
540 return 32;
541 }
542 return k;
543 }
544
545 static int
546lo0bits
547#ifdef KR_headers
548 (y) ULong *y;
549#else
550 (ULong *y)
551#endif
552{
553 register int k;
554 register ULong x = *y;
555
556 if (x & 7) {
557 if (x & 1)
558 return 0;
559 if (x & 2) {
560 *y = x >> 1;
561 return 1;
562 }
563 *y = x >> 2;
564 return 2;
565 }
566 k = 0;
567 if (!(x & 0xffff)) {
568 k = 16;
569 x >>= 16;
570 }
571 if (!(x & 0xff)) {
572 k += 8;
573 x >>= 8;
574 }
575 if (!(x & 0xf)) {
576 k += 4;
577 x >>= 4;
578 }
579 if (!(x & 0x3)) {
580 k += 2;
581 x >>= 2;
582 }
583 if (!(x & 1)) {
584 k++;
585 x >>= 1;
586 if (!x & 1)
587 return 32;
588 }
589 *y = x;
590 return k;
591 }
592
593 static Bigint *
594i2b
595#ifdef KR_headers
596 (i) int i;
597#else
598 (int i)
599#endif
600{
601 Bigint *b;
602
603 b = Balloc(1);
604 b->x[0] = i;
605 b->wds = 1;
606 return b;
607 }
608
609 static Bigint *
610mult
611#ifdef KR_headers
612 (a, b) Bigint *a, *b;
613#else
614 (Bigint *a, Bigint *b)
615#endif
616{
617 Bigint *c;
618 int k, wa, wb, wc;
619 ULong carry, y, z;
620 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
621#ifdef Pack_32
622 ULong z2;
623#endif
624
625 if (a->wds < b->wds) {
626 c = a;
627 a = b;
628 b = c;
629 }
630 k = a->k;
631 wa = a->wds;
632 wb = b->wds;
633 wc = wa + wb;
634 if (wc > a->maxwds)
635 k++;
636 c = Balloc(k);
637 for(x = c->x, xa = x + wc; x < xa; x++)
638 *x = 0;
639 xa = a->x;
640 xae = xa + wa;
641 xb = b->x;
642 xbe = xb + wb;
643 xc0 = c->x;
644#ifdef Pack_32
645 for(; xb < xbe; xb++, xc0++) {
646 if (y = *xb & 0xffff) {
647 x = xa;
648 xc = xc0;
649 carry = 0;
650 do {
651 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
652 carry = z >> 16;
653 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
654 carry = z2 >> 16;
655 Storeinc(xc, z2, z);
656 }
657 while(x < xae);
658 *xc = carry;
659 }
660 if (y = *xb >> 16) {
661 x = xa;
662 xc = xc0;
663 carry = 0;
664 z2 = *xc;
665 do {
666 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
667 carry = z >> 16;
668 Storeinc(xc, z, z2);
669 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
670 carry = z2 >> 16;
671 }
672 while(x < xae);
673 *xc = z2;
674 }
675 }
676#else
677 for(; xb < xbe; xc0++) {
678 if (y = *xb++) {
679 x = xa;
680 xc = xc0;
681 carry = 0;
682 do {
683 z = *x++ * y + *xc + carry;
684 carry = z >> 16;
685 *xc++ = z & 0xffff;
686 }
687 while(x < xae);
688 *xc = carry;
689 }
690 }
691#endif
692 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
693 c->wds = wc;
694 return c;
695 }
696
697 static Bigint *p5s;
698
699 static Bigint *
700pow5mult
701#ifdef KR_headers
702 (b, k) Bigint *b; int k;
703#else
704 (Bigint *b, int k)
705#endif
706{
707 Bigint *b1, *p5, *p51;
708 int i;
709 static int p05[3] = { 5, 25, 125 };
710
711 if (i = k & 3)
712 b = multadd(b, p05[i-1], 0);
713
714 if (!(k >>= 2))
715 return b;
716 if (!(p5 = p5s)) {
717 /* first time */
718 p5 = p5s = i2b(625);
719 p5->next = 0;
720 }
721 for(;;) {
722 if (k & 1) {
723 b1 = mult(b, p5);
724 Bfree(b);
725 b = b1;
726 }
727 if (!(k >>= 1))
728 break;
729 if (!(p51 = p5->next)) {
730 p51 = p5->next = mult(p5,p5);
731 p51->next = 0;
732 }
733 p5 = p51;
734 }
735 return b;
736 }
737
738 static Bigint *
739lshift
740#ifdef KR_headers
741 (b, k) Bigint *b; int k;
742#else
743 (Bigint *b, int k)
744#endif
745{
746 int i, k1, n, n1;
747 Bigint *b1;
748 ULong *x, *x1, *xe, z;
749
750#ifdef Pack_32
751 n = k >> 5;
752#else
753 n = k >> 4;
754#endif
755 k1 = b->k;
756 n1 = n + b->wds + 1;
757 for(i = b->maxwds; n1 > i; i <<= 1)
758 k1++;
759 b1 = Balloc(k1);
760 x1 = b1->x;
761 for(i = 0; i < n; i++)
762 *x1++ = 0;
763 x = b->x;
764 xe = x + b->wds;
765#ifdef Pack_32
766 if (k &= 0x1f) {
767 k1 = 32 - k;
768 z = 0;
769 do {
770 *x1++ = *x << k | z;
771 z = *x++ >> k1;
772 }
773 while(x < xe);
774 if (*x1 = z)
775 ++n1;
776 }
777#else
778 if (k &= 0xf) {
779 k1 = 16 - k;
780 z = 0;
781 do {
782 *x1++ = *x << k & 0xffff | z;
783 z = *x++ >> k1;
784 }
785 while(x < xe);
786 if (*x1 = z)
787 ++n1;
788 }
789#endif
790 else do
791 *x1++ = *x++;
792 while(x < xe);
793 b1->wds = n1 - 1;
794 Bfree(b);
795 return b1;
796 }
797
798 static int
799cmp
800#ifdef KR_headers
801 (a, b) Bigint *a, *b;
802#else
803 (Bigint *a, Bigint *b)
804#endif
805{
806 ULong *xa, *xa0, *xb, *xb0;
807 int i, j;
808
809 i = a->wds;
810 j = b->wds;
811#ifdef DEBUG
812 if (i > 1 && !a->x[i-1])
813 Bug("cmp called with a->x[a->wds-1] == 0");
814 if (j > 1 && !b->x[j-1])
815 Bug("cmp called with b->x[b->wds-1] == 0");
816#endif
817 if (i -= j)
818 return i;
819 xa0 = a->x;
820 xa = xa0 + j;
821 xb0 = b->x;
822 xb = xb0 + j;
823 for(;;) {
824 if (*--xa != *--xb)
825 return *xa < *xb ? -1 : 1;
826 if (xa <= xa0)
827 break;
828 }
829 return 0;
830 }
831
832 static Bigint *
833diff
834#ifdef KR_headers
835 (a, b) Bigint *a, *b;
836#else
837 (Bigint *a, Bigint *b)
838#endif
839{
840 Bigint *c;
841 int i, wa, wb;
842 Long borrow, y; /* We need signed shifts here. */
843 ULong *xa, *xae, *xb, *xbe, *xc;
844#ifdef Pack_32
845 Long z;
846#endif
847
848 i = cmp(a,b);
849 if (!i) {
850 c = Balloc(0);
851 c->wds = 1;
852 c->x[0] = 0;
853 return c;
854 }
855 if (i < 0) {
856 c = a;
857 a = b;
858 b = c;
859 i = 1;
860 }
861 else
862 i = 0;
863 c = Balloc(a->k);
864 c->sign = i;
865 wa = a->wds;
866 xa = a->x;
867 xae = xa + wa;
868 wb = b->wds;
869 xb = b->x;
870 xbe = xb + wb;
871 xc = c->x;
872 borrow = 0;
873#ifdef Pack_32
874 do {
875 y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
876 borrow = y >> 16;
877 Sign_Extend(borrow, y);
878 z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
879 borrow = z >> 16;
880 Sign_Extend(borrow, z);
881 Storeinc(xc, z, y);
882 }
883 while(xb < xbe);
884 while(xa < xae) {
885 y = (*xa & 0xffff) + borrow;
886 borrow = y >> 16;
887 Sign_Extend(borrow, y);
888 z = (*xa++ >> 16) + borrow;
889 borrow = z >> 16;
890 Sign_Extend(borrow, z);
891 Storeinc(xc, z, y);
892 }
893#else
894 do {
895 y = *xa++ - *xb++ + borrow;
896 borrow = y >> 16;
897 Sign_Extend(borrow, y);
898 *xc++ = y & 0xffff;
899 }
900 while(xb < xbe);
901 while(xa < xae) {
902 y = *xa++ + borrow;
903 borrow = y >> 16;
904 Sign_Extend(borrow, y);
905 *xc++ = y & 0xffff;
906 }
907#endif
908 while(!*--xc)
909 wa--;
910 c->wds = wa;
911 return c;
912 }
913
914 static double
915ulp
916#ifdef KR_headers
917 (_x) double _x;
918#else
919 (double _x)
920#endif
921{
922 _double x;
923 register Long L;
924 _double a;
925
926 value(x) = _x;
927 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
928#ifndef Sudden_Underflow
929 if (L > 0) {
930#endif
931#ifdef IBM
932 L |= Exp_msk1 >> 4;
933#endif
934 word0(a) = L;
935 word1(a) = 0;
936#ifndef Sudden_Underflow
937 }
938 else {
939 L = -L >> Exp_shift;
940 if (L < Exp_shift) {
941 word0(a) = 0x80000 >> L;
942 word1(a) = 0;
943 }
944 else {
945 word0(a) = 0;
946 L -= Exp_shift;
947 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
948 }
949 }
950#endif
951 return value(a);
952 }
953
954 static double
955b2d
956#ifdef KR_headers
957 (a, e) Bigint *a; int *e;
958#else
959 (Bigint *a, int *e)
960#endif
961{
962 ULong *xa, *xa0, w, y, z;
963 int k;
964 _double d;
965#ifdef VAX
966 ULong d0, d1;
967#else
968#define d0 word0(d)
969#define d1 word1(d)
970#endif
971
972 xa0 = a->x;
973 xa = xa0 + a->wds;
974 y = *--xa;
975#ifdef DEBUG
976 if (!y) Bug("zero y in b2d");
977#endif
978 k = hi0bits(y);
979 *e = 32 - k;
980#ifdef Pack_32
981 if (k < Ebits) {
982 d0 = Exp_1 | y >> Ebits - k;
983 w = xa > xa0 ? *--xa : 0;
984 d1 = y << (32-Ebits) + k | w >> Ebits - k;
985 goto ret_d;
986 }
987 z = xa > xa0 ? *--xa : 0;
988 if (k -= Ebits) {
989 d0 = Exp_1 | y << k | z >> 32 - k;
990 y = xa > xa0 ? *--xa : 0;
991 d1 = z << k | y >> 32 - k;
992 }
993 else {
994 d0 = Exp_1 | y;
995 d1 = z;
996 }
997#else
998 if (k < Ebits + 16) {
999 z = xa > xa0 ? *--xa : 0;
1000 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1001 w = xa > xa0 ? *--xa : 0;
1002 y = xa > xa0 ? *--xa : 0;
1003 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1004 goto ret_d;
1005 }
1006 z = xa > xa0 ? *--xa : 0;
1007 w = xa > xa0 ? *--xa : 0;
1008 k -= Ebits + 16;
1009 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1010 y = xa > xa0 ? *--xa : 0;
1011 d1 = w << k + 16 | y << k;
1012#endif
1013 ret_d:
1014#ifdef VAX
1015 word0(d) = d0 >> 16 | d0 << 16;
1016 word1(d) = d1 >> 16 | d1 << 16;
1017#else
1018#undef d0
1019#undef d1
1020#endif
1021 return value(d);
1022 }
1023
1024 static Bigint *
1025d2b
1026#ifdef KR_headers
1027 (_d, e, bits) double d; int *e, *bits;
1028#else
1029 (double _d, int *e, int *bits)
1030#endif
1031{
1032 Bigint *b;
1033 int de, i, k;
1034 ULong *x, y, z;
1035 _double d;
1036#ifdef VAX
1037 ULong d0, d1;
1038#endif
1039
1040 value(d) = _d;
1041#ifdef VAX
1042 d0 = word0(d) >> 16 | word0(d) << 16;
1043 d1 = word1(d) >> 16 | word1(d) << 16;
1044#else
1045#define d0 word0(d)
1046#define d1 word1(d)
1047#endif
1048
1049#ifdef Pack_32
1050 b = Balloc(1);
1051#else
1052 b = Balloc(2);
1053#endif
1054 x = b->x;
1055
1056 z = d0 & Frac_mask;
1057 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
1058#ifdef Sudden_Underflow
1059 de = (int)(d0 >> Exp_shift);
1060#ifndef IBM
1061 z |= Exp_msk11;
1062#endif
1063#else
1064 if (de = (int)(d0 >> Exp_shift))
1065 z |= Exp_msk1;
1066#endif
1067#ifdef Pack_32
1068 if (y = d1) {
1069 if (k = lo0bits(&y)) {
1070 x[0] = y | z << 32 - k;
1071 z >>= k;
1072 }
1073 else
1074 x[0] = y;
1075 i = b->wds = (x[1] = z) ? 2 : 1;
1076 }
1077 else {
1078#ifdef DEBUG
1079 if (!z)
1080 Bug("Zero passed to d2b");
1081#endif
1082 k = lo0bits(&z);
1083 x[0] = z;
1084 i = b->wds = 1;
1085 k += 32;
1086 }
1087#else
1088 if (y = d1) {
1089 if (k = lo0bits(&y))
1090 if (k >= 16) {
1091 x[0] = y | z << 32 - k & 0xffff;
1092 x[1] = z >> k - 16 & 0xffff;
1093 x[2] = z >> k;
1094 i = 2;
1095 }
1096 else {
1097 x[0] = y & 0xffff;
1098 x[1] = y >> 16 | z << 16 - k & 0xffff;
1099 x[2] = z >> k & 0xffff;
1100 x[3] = z >> k+16;
1101 i = 3;
1102 }
1103 else {
1104 x[0] = y & 0xffff;
1105 x[1] = y >> 16;
1106 x[2] = z & 0xffff;
1107 x[3] = z >> 16;
1108 i = 3;
1109 }
1110 }
1111 else {
1112#ifdef DEBUG
1113 if (!z)
1114 Bug("Zero passed to d2b");
1115#endif
1116 k = lo0bits(&z);
1117 if (k >= 16) {
1118 x[0] = z;
1119 i = 0;
1120 }
1121 else {
1122 x[0] = z & 0xffff;
1123 x[1] = z >> 16;
1124 i = 1;
1125 }
1126 k += 32;
1127 }
1128 while(!x[i])
1129 --i;
1130 b->wds = i + 1;
1131#endif
1132#ifndef Sudden_Underflow
1133 if (de) {
1134#endif
1135#ifdef IBM
1136 *e = (de - Bias - (P-1) << 2) + k;
1137 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1138#else
1139 *e = de - Bias - (P-1) + k;
1140 *bits = P - k;
1141#endif
1142#ifndef Sudden_Underflow
1143 }
1144 else {
1145 *e = de - Bias - (P-1) + 1 + k;
1146#ifdef Pack_32
1147 *bits = 32*i - hi0bits(x[i-1]);
1148#else
1149 *bits = (i+2)*16 - hi0bits(x[i]);
1150#endif
1151 }
1152#endif
1153 return b;
1154 }
1155#undef d0
1156#undef d1
1157
1158 static double
1159ratio
1160#ifdef KR_headers
1161 (a, b) Bigint *a, *b;
1162#else
1163 (Bigint *a, Bigint *b)
1164#endif
1165{
1166 _double da, db;
1167 int k, ka, kb;
1168
1169 value(da) = b2d(a, &ka);
1170 value(db) = b2d(b, &kb);
1171#ifdef Pack_32
1172 k = ka - kb + 32*(a->wds - b->wds);
1173#else
1174 k = ka - kb + 16*(a->wds - b->wds);
1175#endif
1176#ifdef IBM
1177 if (k > 0) {
1178 word0(da) += (k >> 2)*Exp_msk1;
1179 if (k &= 3)
1180 da *= 1 << k;
1181 }
1182 else {
1183 k = -k;
1184 word0(db) += (k >> 2)*Exp_msk1;
1185 if (k &= 3)
1186 db *= 1 << k;
1187 }
1188#else
1189 if (k > 0)
1190 word0(da) += k*Exp_msk1;
1191 else {
1192 k = -k;
1193 word0(db) += k*Exp_msk1;
1194 }
1195#endif
1196 return value(da) / value(db);
1197 }
1198
1199static CONST double
1200tens[] = {
1201 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1202 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1203 1e20, 1e21, 1e22
1204#ifdef VAX
1205 , 1e23, 1e24
1206#endif
1207 };
1208
1209#ifdef IEEE_Arith
1210static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1211static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
1212#define n_bigtens 5
1213#else
1214#ifdef IBM
1215static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
1216static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1217#define n_bigtens 3
1218#else
1219static CONST double bigtens[] = { 1e16, 1e32 };
1220static CONST double tinytens[] = { 1e-16, 1e-32 };
1221#define n_bigtens 2
1222#endif
1223#endif
1224
1225 double
1226strtod
1227#ifdef KR_headers
1228 (s00, se) CONST char *s00; char **se;
1229#else
1230 (CONST char *s00, char **se)
1231#endif
1232{
1233 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1234 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1235 CONST char *s, *s0, *s1;
1236 double aadj, aadj1, adj;
1237 _double rv, rv0;
1238 Long L;
1239 ULong y, z;
1240 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1241
1242#ifndef KR_headers
1243 CONST char decimal_point = localeconv()->decimal_point[0];
1244#else
1245 CONST char decimal_point = '.';
1246#endif
1247
1248 sign = nz0 = nz = 0;
1249 value(rv) = 0.;
1250
1251
1252 for(s = s00; isspace((unsigned char) *s); s++)
1253 ;
1254
1255 if (*s == '-') {
1256 sign = 1;
1257 s++;
1258 } else if (*s == '+') {
1259 s++;
1260 }
1261
1262 if (*s == '\0') {
1263 s = s00;
1264 goto ret;
1265 }
1266
1267 if (*s == '0') {
1268 nz0 = 1;
1269 while(*++s == '0') ;
1270 if (!*s)
1271 goto ret;
1272 }
1273 s0 = s;
1274 y = z = 0;
1275 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
1276 if (nd < 9)
1277 y = 10*y + c - '0';
1278 else if (nd < 16)
1279 z = 10*z + c - '0';
1280 nd0 = nd;
1281 if (c == decimal_point) {
1282 c = *++s;
1283 if (!nd) {
1284 for(; c == '0'; c = *++s)
1285 nz++;
1286 if (c > '0' && c <= '9') {
1287 s0 = s;
1288 nf += nz;
1289 nz = 0;
1290 goto have_dig;
1291 }
1292 goto dig_done;
1293 }
1294 for(; c >= '0' && c <= '9'; c = *++s) {
1295 have_dig:
1296 nz++;
1297 if (c -= '0') {
1298 nf += nz;
1299 for(i = 1; i < nz; i++)
1300 if (nd++ < 9)
1301 y *= 10;
1302 else if (nd <= DBL_DIG + 1)
1303 z *= 10;
1304 if (nd++ < 9)
1305 y = 10*y + c;
1306 else if (nd <= DBL_DIG + 1)
1307 z = 10*z + c;
1308 nz = 0;
1309 }
1310 }
1311 }
1312 dig_done:
1313 e = 0;
1314 if (c == 'e' || c == 'E') {
1315 if (!nd && !nz && !nz0) {
1316 s = s00;
1317 goto ret;
1318 }
1319 s00 = s;
1320 esign = 0;
1321 switch(c = *++s) {
1322 case '-':
1323 esign = 1;
1324 case '+':
1325 c = *++s;
1326 }
1327 if (c >= '0' && c <= '9') {
1328 while(c == '0')
1329 c = *++s;
1330 if (c > '0' && c <= '9') {
1331 L = c - '0';
1332 s1 = s;
1333 while((c = *++s) >= '0' && c <= '9')
1334 L = 10*L + c - '0';
1335 if (s - s1 > 8 || L > 19999)
1336 /* Avoid confusion from exponents
1337 * so large that e might overflow.
1338 */
1339 e = 19999; /* safe for 16 bit ints */
1340 else
1341 e = (int)L;
1342 if (esign)
1343 e = -e;
1344 }
1345 else
1346 e = 0;
1347 }
1348 else
1349 s = s00;
1350 }
1351 if (!nd) {
1352 if (!nz && !nz0)
1353 s = s00;
1354 goto ret;
1355 }
1356 e1 = e -= nf;
1357
1358 /* Now we have nd0 digits, starting at s0, followed by a
1359 * decimal point, followed by nd-nd0 digits. The number we're
1360 * after is the integer represented by those digits times
1361 * 10**e */
1362
1363 if (!nd0)
1364 nd0 = nd;
1365 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1366 value(rv) = y;
1367 if (k > 9)
1368 value(rv) = tens[k - 9] * value(rv) + z;
1369 bd0 = 0;
1370 if (nd <= DBL_DIG
1371#ifndef RND_PRODQUOT
1372 && FLT_ROUNDS == 1
1373#endif
1374 ) {
1375 if (!e)
1376 goto ret;
1377 if (e > 0) {
1378 if (e <= Ten_pmax) {
1379#ifdef VAX
1380 goto vax_ovfl_check;
1381#else
1382 /* value(rv) = */ rounded_product(value(rv),
1383 tens[e]);
1384 goto ret;
1385#endif
1386 }
1387 i = DBL_DIG - nd;
1388 if (e <= Ten_pmax + i) {
1389 /* A fancier test would sometimes let us do
1390 * this for larger i values.
1391 */
1392 e -= i;
1393 value(rv) *= tens[i];
1394#ifdef VAX
1395 /* VAX exponent range is so narrow we must
1396 * worry about overflow here...
1397 */
1398 vax_ovfl_check:
1399 word0(rv) -= P*Exp_msk1;
1400 /* value(rv) = */ rounded_product(value(rv),
1401 tens[e]);
1402 if ((word0(rv) & Exp_mask)
1403 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1404 goto ovfl;
1405 word0(rv) += P*Exp_msk1;
1406#else
1407 /* value(rv) = */ rounded_product(value(rv),
1408 tens[e]);
1409#endif
1410 goto ret;
1411 }
1412 }
1413#ifndef Inaccurate_Divide
1414 else if (e >= -Ten_pmax) {
1415 /* value(rv) = */ rounded_quotient(value(rv),
1416 tens[-e]);
1417 goto ret;
1418 }
1419#endif
1420 }
1421 e1 += nd - k;
1422
1423 /* Get starting approximation = rv * 10**e1 */
1424
1425 if (e1 > 0) {
1426 if (i = e1 & 15)
1427 value(rv) *= tens[i];
1428 if (e1 &= ~15) {
1429 if (e1 > DBL_MAX_10_EXP) {
1430 ovfl:
1431 errno = ERANGE;
1432#ifdef __STDC__
1433 value(rv) = HUGE_VAL;
1434#else
1435 /* Can't trust HUGE_VAL */
1436#ifdef IEEE_Arith
1437 word0(rv) = Exp_mask;
1438 word1(rv) = 0;
1439#else
1440 word0(rv) = Big0;
1441 word1(rv) = Big1;
1442#endif
1443#endif
1444 if (bd0)
1445 goto retfree;
1446 goto ret;
1447 }
1448 if (e1 >>= 4) {
1449 for(j = 0; e1 > 1; j++, e1 >>= 1)
1450 if (e1 & 1)
1451 value(rv) *= bigtens[j];
1452 /* The last multiplication could overflow. */
1453 word0(rv) -= P*Exp_msk1;
1454 value(rv) *= bigtens[j];
1455 if ((z = word0(rv) & Exp_mask)
1456 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1457 goto ovfl;
1458 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1459 /* set to largest number */
1460 /* (Can't trust DBL_MAX) */
1461 word0(rv) = Big0;
1462 word1(rv) = Big1;
1463 }
1464 else
1465 word0(rv) += P*Exp_msk1;
1466 }
1467
1468 }
1469 }
1470 else if (e1 < 0) {
1471 e1 = -e1;
1472 if (i = e1 & 15)
1473 value(rv) /= tens[i];
1474 if (e1 &= ~15) {
1475 e1 >>= 4;
1476 if (e1 >= 1 << n_bigtens)
1477 goto undfl;
1478 for(j = 0; e1 > 1; j++, e1 >>= 1)
1479 if (e1 & 1)
1480 value(rv) *= tinytens[j];
1481 /* The last multiplication could underflow. */
1482 value(rv0) = value(rv);
1483 value(rv) *= tinytens[j];
1484 if (!value(rv)) {
1485 value(rv) = 2.*value(rv0);
1486 value(rv) *= tinytens[j];
1487 if (!value(rv)) {
1488 undfl:
1489 value(rv) = 0.;
1490 errno = ERANGE;
1491 if (bd0)
1492 goto retfree;
1493 goto ret;
1494 }
1495 word0(rv) = Tiny0;
1496 word1(rv) = Tiny1;
1497 /* The refinement below will clean
1498 * this approximation up.
1499 */
1500 }
1501 }
1502 }
1503
1504 /* Now the hard part -- adjusting rv to the correct value.*/
1505
1506 /* Put digits into bd: true value = bd * 10^e */
1507
1508 bd0 = s2b(s0, nd0, nd, y);
1509
1510 for(;;) {
1511 bd = Balloc(bd0->k);
1512 Bcopy(bd, bd0);
1513 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1514 bs = i2b(1);
1515
1516 if (e >= 0) {
1517 bb2 = bb5 = 0;
1518 bd2 = bd5 = e;
1519 }
1520 else {
1521 bb2 = bb5 = -e;
1522 bd2 = bd5 = 0;
1523 }
1524 if (bbe >= 0)
1525 bb2 += bbe;
1526 else
1527 bd2 -= bbe;
1528 bs2 = bb2;
1529#ifdef Sudden_Underflow
1530#ifdef IBM
1531 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
1532#else
1533 j = P + 1 - bbbits;
1534#endif
1535#else
1536 i = bbe + bbbits - 1; /* logb(rv) */
1537 if (i < Emin) /* denormal */
1538 j = bbe + (P-Emin);
1539 else
1540 j = P + 1 - bbbits;
1541#endif
1542 bb2 += j;
1543 bd2 += j;
1544 i = bb2 < bd2 ? bb2 : bd2;
1545 if (i > bs2)
1546 i = bs2;
1547 if (i > 0) {
1548 bb2 -= i;
1549 bd2 -= i;
1550 bs2 -= i;
1551 }
1552 if (bb5 > 0) {
1553 bs = pow5mult(bs, bb5);
1554 bb1 = mult(bs, bb);
1555 Bfree(bb);
1556 bb = bb1;
1557 }
1558 if (bb2 > 0)
1559 bb = lshift(bb, bb2);
1560 if (bd5 > 0)
1561 bd = pow5mult(bd, bd5);
1562 if (bd2 > 0)
1563 bd = lshift(bd, bd2);
1564 if (bs2 > 0)
1565 bs = lshift(bs, bs2);
1566 delta = diff(bb, bd);
1567 dsign = delta->sign;
1568 delta->sign = 0;
1569 i = cmp(delta, bs);
1570 if (i < 0) {
1571 /* Error is less than half an ulp -- check for
1572 * special case of mantissa a power of two.
1573 */
1574 if (dsign || word1(rv) || word0(rv) & Bndry_mask)
1575 break;
1576 delta = lshift(delta,Log2P);
1577 if (cmp(delta, bs) > 0)
1578 goto drop_down;
1579 break;
1580 }
1581 if (i == 0) {
1582 /* exactly half-way between */
1583 if (dsign) {
1584 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
1585 && word1(rv) == 0xffffffff) {
1586 /*boundary case -- increment exponent*/
1587 word0(rv) = (word0(rv) & Exp_mask)
1588 + Exp_msk1
1589#ifdef IBM
1590 | Exp_msk1 >> 4
1591#endif
1592 ;
1593 word1(rv) = 0;
1594 break;
1595 }
1596 }
1597 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
1598 drop_down:
1599 /* boundary case -- decrement exponent */
1600#ifdef Sudden_Underflow
1601 L = word0(rv) & Exp_mask;
1602#ifdef IBM
1603 if (L < Exp_msk1)
1604#else
1605 if (L <= Exp_msk1)
1606#endif
1607 goto undfl;
1608 L -= Exp_msk1;
1609#else
1610 L = (word0(rv) & Exp_mask) - Exp_msk1;
1611#endif
1612 word0(rv) = L | Bndry_mask1;
1613 word1(rv) = 0xffffffff;
1614#ifdef IBM
1615 goto cont;
1616#else
1617 break;
1618#endif
1619 }
1620#ifndef ROUND_BIASED
1621 if (!(word1(rv) & LSB))
1622 break;
1623#endif
1624 if (dsign)
1625 value(rv) += ulp(value(rv));
1626#ifndef ROUND_BIASED
1627 else {
1628 value(rv) -= ulp(value(rv));
1629#ifndef Sudden_Underflow
1630 if (!value(rv))
1631 goto undfl;
1632#endif
1633 }
1634#endif
1635 break;
1636 }
1637 if ((aadj = ratio(delta, bs)) <= 2.) {
1638 if (dsign)
1639 aadj = aadj1 = 1.;
1640 else if (word1(rv) || word0(rv) & Bndry_mask) {
1641#ifndef Sudden_Underflow
1642 if (word1(rv) == Tiny1 && !word0(rv))
1643 goto undfl;
1644#endif
1645 aadj = 1.;
1646 aadj1 = -1.;
1647 }
1648 else {
1649 /* special case -- power of FLT_RADIX to be */
1650 /* rounded down... */
1651
1652 if (aadj < 2./FLT_RADIX)
1653 aadj = 1./FLT_RADIX;
1654 else
1655 aadj *= 0.5;
1656 aadj1 = -aadj;
1657 }
1658 }
1659 else {
1660 aadj *= 0.5;
1661 aadj1 = dsign ? aadj : -aadj;
1662#ifdef Check_FLT_ROUNDS
1663 switch(FLT_ROUNDS) {
1664 case 2: /* towards +infinity */
1665 aadj1 -= 0.5;
1666 break;
1667 case 0: /* towards 0 */
1668 case 3: /* towards -infinity */
1669 aadj1 += 0.5;
1670 }
1671#else
1672 if (FLT_ROUNDS == 0)
1673 aadj1 += 0.5;
1674#endif
1675 }
1676 y = word0(rv) & Exp_mask;
1677
1678 /* Check for overflow */
1679
1680 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1681 value(rv0) = value(rv);
1682 word0(rv) -= P*Exp_msk1;
1683 adj = aadj1 * ulp(value(rv));
1684 value(rv) += adj;
1685 if ((word0(rv) & Exp_mask) >=
1686 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1687 if (word0(rv0) == Big0 && word1(rv0) == Big1)
1688 goto ovfl;
1689 word0(rv) = Big0;
1690 word1(rv) = Big1;
1691 goto cont;
1692 }
1693 else
1694 word0(rv) += P*Exp_msk1;
1695 }
1696 else {
1697#ifdef Sudden_Underflow
1698 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1699 value(rv0) = value(rv);
1700 word0(rv) += P*Exp_msk1;
1701 adj = aadj1 * ulp(value(rv));
1702 value(rv) += adj;
1703#ifdef IBM
1704 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1705#else
1706 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
1707#endif
1708 {
1709 if (word0(rv0) == Tiny0
1710 && word1(rv0) == Tiny1)
1711 goto undfl;
1712 word0(rv) = Tiny0;
1713 word1(rv) = Tiny1;
1714 goto cont;
1715 }
1716 else
1717 word0(rv) -= P*Exp_msk1;
1718 }
1719 else {
1720 adj = aadj1 * ulp(value(rv));
1721 value(rv) += adj;
1722 }
1723#else
1724 /* Compute adj so that the IEEE rounding rules will
1725 * correctly round rv + adj in some half-way cases.
1726 * If rv * ulp(rv) is denormalized (i.e.,
1727 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1728 * trouble from bits lost to denormalization;
1729 * example: 1.2e-307 .
1730 */
1731 if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
1732 aadj1 = (double)(int)(aadj + 0.5);
1733 if (!dsign)
1734 aadj1 = -aadj1;
1735 }
1736 adj = aadj1 * ulp(value(rv));
1737 value(rv) += adj;
1738#endif
1739 }
1740 z = word0(rv) & Exp_mask;
1741 if (y == z) {
1742 /* Can we stop now? */
1743 L = aadj;
1744 aadj -= L;
1745 /* The tolerances below are conservative. */
1746 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
1747 if (aadj < .4999999 || aadj > .5000001)
1748 break;
1749 }
1750 else if (aadj < .4999999/FLT_RADIX)
1751 break;
1752 }
1753 cont:
1754 Bfree(bb);
1755 Bfree(bd);
1756 Bfree(bs);
1757 Bfree(delta);
1758 }
1759 retfree:
1760 Bfree(bb);
1761 Bfree(bd);
1762 Bfree(bs);
1763 Bfree(bd0);
1764 Bfree(delta);
1765 ret:
1766 if (se)
1767 *se = (char *)s;
1768 return sign ? -value(rv) : value(rv);
1769 }
1770
1771 static int
1772quorem
1773#ifdef KR_headers
1774 (b, S) Bigint *b, *S;
1775#else
1776 (Bigint *b, Bigint *S)
1777#endif
1778{
1779 int n;
1780 Long borrow, y;
1781 ULong carry, q, ys;
1782 ULong *bx, *bxe, *sx, *sxe;
1783#ifdef Pack_32
1784 Long z;
1785 ULong si, zs;
1786#endif
1787
1788 n = S->wds;
1789#ifdef DEBUG
1790 /*debug*/ if (b->wds > n)
1791 /*debug*/ Bug("oversize b in quorem");
1792#endif
1793 if (b->wds < n)
1794 return 0;
1795 sx = S->x;
1796 sxe = sx + --n;
1797 bx = b->x;
1798 bxe = bx + n;
1799 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1800#ifdef DEBUG
1801 /*debug*/ if (q > 9)
1802 /*debug*/ Bug("oversized quotient in quorem");
1803#endif
1804 if (q) {
1805 borrow = 0;
1806 carry = 0;
1807 do {
1808#ifdef Pack_32
1809 si = *sx++;
1810 ys = (si & 0xffff) * q + carry;
1811 zs = (si >> 16) * q + (ys >> 16);
1812 carry = zs >> 16;
1813 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1814 borrow = y >> 16;
1815 Sign_Extend(borrow, y);
1816 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1817 borrow = z >> 16;
1818 Sign_Extend(borrow, z);
1819 Storeinc(bx, z, y);
1820#else
1821 ys = *sx++ * q + carry;
1822 carry = ys >> 16;
1823 y = *bx - (ys & 0xffff) + borrow;
1824 borrow = y >> 16;
1825 Sign_Extend(borrow, y);
1826 *bx++ = y & 0xffff;
1827#endif
1828 }
1829 while(sx <= sxe);
1830 if (!*bxe) {
1831 bx = b->x;
1832 while(--bxe > bx && !*bxe)
1833 --n;
1834 b->wds = n;
1835 }
1836 }
1837 if (cmp(b, S) >= 0) {
1838 q++;
1839 borrow = 0;
1840 carry = 0;
1841 bx = b->x;
1842 sx = S->x;
1843 do {
1844#ifdef Pack_32
1845 si = *sx++;
1846 ys = (si & 0xffff) + carry;
1847 zs = (si >> 16) + (ys >> 16);
1848 carry = zs >> 16;
1849 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1850 borrow = y >> 16;
1851 Sign_Extend(borrow, y);
1852 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1853 borrow = z >> 16;
1854 Sign_Extend(borrow, z);
1855 Storeinc(bx, z, y);
1856#else
1857 ys = *sx++ + carry;
1858 carry = ys >> 16;
1859 y = *bx - (ys & 0xffff) + borrow;
1860 borrow = y >> 16;
1861 Sign_Extend(borrow, y);
1862 *bx++ = y & 0xffff;
1863#endif
1864 }
1865 while(sx <= sxe);
1866 bx = b->x;
1867 bxe = bx + n;
1868 if (!*bxe) {
1869 while(--bxe > bx && !*bxe)
1870 --n;
1871 b->wds = n;
1872 }
1873 }
1874 return q;
1875 }
1876
1877/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
1878 *
1879 * Inspired by "How to Print Floating-Point Numbers Accurately" by
1880 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
1881 *
1882 * Modifications:
1883 * 1. Rather than iterating, we use a simple numeric overestimate
1884 * to determine k = floor(log10(d)). We scale relevant
1885 * quantities using O(log2(k)) rather than O(k) multiplications.
1886 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
1887 * try to generate digits strictly left to right. Instead, we
1888 * compute with fewer bits and propagate the carry if necessary
1889 * when rounding the final digit up. This is often faster.
1890 * 3. Under the assumption that input will be rounded nearest,
1891 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
1892 * That is, we allow equality in stopping tests when the
1893 * round-nearest rule will give the same floating-point value
1894 * as would satisfaction of the stopping test with strict
1895 * inequality.
1896 * 4. We remove common factors of powers of 2 from relevant
1897 * quantities.
1898 * 5. When converting floating-point integers less than 1e16,
1899 * we use floating-point arithmetic rather than resorting
1900 * to multiple-precision integers.
1901 * 6. When asked to produce fewer than 15 digits, we first try
1902 * to get by with floating-point arithmetic; we resort to
1903 * multiple-precision integer arithmetic only if we cannot
1904 * guarantee that the floating-point calculation has given
1905 * the correctly rounded result. For k requested digits and
1906 * "uniformly" distributed input, the probability is
1907 * something like 10^(k-15) that we must resort to the Long
1908 * calculation.
1909 */
1910
1911 char *
1912__dtoa
1913#ifdef KR_headers
1914 (_d, mode, ndigits, decpt, sign, rve)
1915 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1916#else
1917 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1918#endif
1919{
1920 /* Arguments ndigits, decpt, sign are similar to those
1921 of ecvt and fcvt; trailing zeros are suppressed from
1922 the returned string. If not null, *rve is set to point
1923 to the end of the return value. If d is +-Infinity or NaN,
1924 then *decpt is set to 9999.
1925
1926 mode:
1927 0 ==> shortest string that yields d when read in
1928 and rounded to nearest.
1929 1 ==> like 0, but with Steele & White stopping rule;
1930 e.g. with IEEE P754 arithmetic , mode 0 gives
1931 1e23 whereas mode 1 gives 9.999999999999999e22.
1932 2 ==> max(1,ndigits) significant digits. This gives a
1933 return value similar to that of ecvt, except
1934 that trailing zeros are suppressed.
1935 3 ==> through ndigits past the decimal point. This
1936 gives a return value similar to that from fcvt,
1937 except that trailing zeros are suppressed, and
1938 ndigits can be negative.
1939 4-9 should give the same return values as 2-3, i.e.,
1940 4 <= mode <= 9 ==> same return as mode
1941 2 + (mode & 1). These modes are mainly for
1942 debugging; often they run slower but sometimes
1943 faster than modes 2-3.
1944 4,5,8,9 ==> left-to-right digit generation.
1945 6-9 ==> don't try fast floating-point estimate
1946 (if applicable).
1947
1948 Values of mode other than 0-9 are treated as mode 0.
1949
1950 Sufficient space is allocated to the return value
1951 to hold the suppressed trailing zeros.
1952 */
1953
1954 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1955 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1956 spec_case, try_quick;
1957 Long L;
1958#ifndef Sudden_Underflow
1959 int denorm;
1960 ULong x;
1961#endif
1962 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1963 double ds;
1964 char *s, *s0;
1965 static Bigint *result;
1966 static int result_k;
1967 _double d, d2, eps;
1968
1969 value(d) = _d;
1970 if (result) {
1971 result->k = result_k;
1972 result->maxwds = 1 << result_k;
1973 Bfree(result);
1974 result = 0;
1975 }
1976
1977 if (word0(d) & Sign_bit) {
1978 /* set sign for everything, including 0's and NaNs */
1979 *sign = 1;
1980 word0(d) &= ~Sign_bit; /* clear sign bit */
1981 }
1982 else
1983 *sign = 0;
1984
1985#if defined(IEEE_Arith) + defined(VAX)
1986#ifdef IEEE_Arith
1987 if ((word0(d) & Exp_mask) == Exp_mask)
1988#else
1989 if (word0(d) == 0x8000)
1990#endif
1991 {
1992 /* Infinity or NaN */
1993 *decpt = 9999;
1994 s =
1995#ifdef IEEE_Arith
1996 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
1997#endif
1998 "NaN";
1999 if (rve)
2000 *rve =
2001#ifdef IEEE_Arith
2002 s[3] ? s + 8 :
2003#endif
2004 s + 3;
2005 return s;
2006 }
2007#endif
2008#ifdef IBM
2009 value(d) += 0; /* normalize */
2010#endif
2011 if (!value(d)) {
2012 *decpt = 1;
2013 s = "0";
2014 if (rve)
2015 *rve = s + 1;
2016 return s;
2017 }
2018
2019 b = d2b(value(d), &be, &bbits);
2020#ifdef Sudden_Underflow
2021 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2022#else
2023 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
2024#endif
2025 value(d2) = value(d);
2026 word0(d2) &= Frac_mask1;
2027 word0(d2) |= Exp_11;
2028#ifdef IBM
2029 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2030 value(d2) /= 1 << j;
2031#endif
2032
2033 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2034 * log10(x) = log(x) / log(10)
2035 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2036 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2037 *
2038 * This suggests computing an approximation k to log10(d) by
2039 *
2040 * k = (i - Bias)*0.301029995663981
2041 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2042 *
2043 * We want k to be too large rather than too small.
2044 * The error in the first-order Taylor series approximation
2045 * is in our favor, so we just round up the constant enough
2046 * to compensate for any error in the multiplication of
2047 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2048 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2049 * adding 1e-13 to the constant term more than suffices.
2050 * Hence we adjust the constant term to 0.1760912590558.
2051 * (We could get a more accurate k by invoking log10,
2052 * but this is probably not worthwhile.)
2053 */
2054
2055 i -= Bias;
2056#ifdef IBM
2057 i <<= 2;
2058 i += j;
2059#endif
2060#ifndef Sudden_Underflow
2061 denorm = 0;
2062 }
2063 else {
2064 /* d is denormalized */
2065
2066 i = bbits + be + (Bias + (P-1) - 1);
2067 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2068 : word1(d) << 32 - i;
2069 value(d2) = x;
2070 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2071 i -= (Bias + (P-1) - 1) + 1;
2072 denorm = 1;
2073 }
2074#endif
2075 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2076 i*0.301029995663981;
2077 k = (int)ds;
2078 if (ds < 0. && ds != k)
2079 k--; /* want k = floor(ds) */
2080 k_check = 1;
2081 if (k >= 0 && k <= Ten_pmax) {
2082 if (value(d) < tens[k])
2083 k--;
2084 k_check = 0;
2085 }
2086 j = bbits - i - 1;
2087 if (j >= 0) {
2088 b2 = 0;
2089 s2 = j;
2090 }
2091 else {
2092 b2 = -j;
2093 s2 = 0;
2094 }
2095 if (k >= 0) {
2096 b5 = 0;
2097 s5 = k;
2098 s2 += k;
2099 }
2100 else {
2101 b2 -= k;
2102 b5 = -k;
2103 s5 = 0;
2104 }
2105 if (mode < 0 || mode > 9)
2106 mode = 0;
2107 try_quick = 1;
2108 if (mode > 5) {
2109 mode -= 4;
2110 try_quick = 0;
2111 }
2112 leftright = 1;
2113 switch(mode) {
2114 case 0:
2115 case 1:
2116 ilim = ilim1 = -1;
2117 i = 18;
2118 ndigits = 0;
2119 break;
2120 case 2:
2121 leftright = 0;
2122 /* no break */
2123 case 4:
2124 if (ndigits <= 0)
2125 ndigits = 1;
2126 ilim = ilim1 = i = ndigits;
2127 break;
2128 case 3:
2129 leftright = 0;
2130 /* no break */
2131 case 5:
2132 i = ndigits + k + 1;
2133 ilim = i;
2134 ilim1 = i - 1;
2135 if (i <= 0)
2136 i = 1;
2137 }
2138 j = sizeof(ULong);
2139 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2140 j <<= 1) result_k++;
2141 result = Balloc(result_k);
2142 s = s0 = (char *)result;
2143
2144 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2145
2146 /* Try to get by with floating-point arithmetic. */
2147
2148 i = 0;
2149 value(d2) = value(d);
2150 k0 = k;
2151 ilim0 = ilim;
2152 ieps = 2; /* conservative */
2153 if (k > 0) {
2154 ds = tens[k&0xf];
2155 j = k >> 4;
2156 if (j & Bletch) {
2157 /* prevent overflows */
2158 j &= Bletch - 1;
2159 value(d) /= bigtens[n_bigtens-1];
2160 ieps++;
2161 }
2162 for(; j; j >>= 1, i++)
2163 if (j & 1) {
2164 ieps++;
2165 ds *= bigtens[i];
2166 }
2167 value(d) /= ds;
2168 }
2169 else if (j1 = -k) {
2170 value(d) *= tens[j1 & 0xf];
2171 for(j = j1 >> 4; j; j >>= 1, i++)
2172 if (j & 1) {
2173 ieps++;
2174 value(d) *= bigtens[i];
2175 }
2176 }
2177 if (k_check && value(d) < 1. && ilim > 0) {
2178 if (ilim1 <= 0)
2179 goto fast_failed;
2180 ilim = ilim1;
2181 k--;
2182 value(d) *= 10.;
2183 ieps++;
2184 }
2185 value(eps) = ieps*value(d) + 7.;
2186 word0(eps) -= (P-1)*Exp_msk1;
2187 if (ilim == 0) {
2188 S = mhi = 0;
2189 value(d) -= 5.;
2190 if (value(d) > value(eps))
2191 goto one_digit;
2192 if (value(d) < -value(eps))
2193 goto no_digits;
2194 goto fast_failed;
2195 }
2196#ifndef No_leftright
2197 if (leftright) {
2198 /* Use Steele & White method of only
2199 * generating digits needed.
2200 */
2201 value(eps) = 0.5/tens[ilim-1] - value(eps);
2202 for(i = 0;;) {
2203 L = value(d);
2204 value(d) -= L;
2205 *s++ = '0' + (int)L;
2206 if (value(d) < value(eps))
2207 goto ret1;
2208 if (1. - value(d) < value(eps))
2209 goto bump_up;
2210 if (++i >= ilim)
2211 break;
2212 value(eps) *= 10.;
2213 value(d) *= 10.;
2214 }
2215 }
2216 else {
2217#endif
2218 /* Generate ilim digits, then fix them up. */
2219 value(eps) *= tens[ilim-1];
2220 for(i = 1;; i++, value(d) *= 10.) {
2221 L = value(d);
2222 value(d) -= L;
2223 *s++ = '0' + (int)L;
2224 if (i == ilim) {
2225 if (value(d) > 0.5 + value(eps))
2226 goto bump_up;
2227 else if (value(d) < 0.5 - value(eps)) {
2228 while(*--s == '0');
2229 s++;
2230 goto ret1;
2231 }
2232 break;
2233 }
2234 }
2235#ifndef No_leftright
2236 }
2237#endif
2238 fast_failed:
2239 s = s0;
2240 value(d) = value(d2);
2241 k = k0;
2242 ilim = ilim0;
2243 }
2244
2245 /* Do we have a "small" integer? */
2246
2247 if (be >= 0 && k <= Int_max) {
2248 /* Yes. */
2249 ds = tens[k];
2250 if (ndigits < 0 && ilim <= 0) {
2251 S = mhi = 0;
2252 if (ilim < 0 || value(d) <= 5*ds)
2253 goto no_digits;
2254 goto one_digit;
2255 }
2256 for(i = 1;; i++) {
2257 L = value(d) / ds;
2258 value(d) -= L*ds;
2259#ifdef Check_FLT_ROUNDS
2260 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2261 if (value(d) < 0) {
2262 L--;
2263 value(d) += ds;
2264 }
2265#endif
2266 *s++ = '0' + (int)L;
2267 if (i == ilim) {
2268 value(d) += value(d);
2269 if (value(d) > ds || value(d) == ds && L & 1) {
2270 bump_up:
2271 while(*--s == '9')
2272 if (s == s0) {
2273 k++;
2274 *s = '0';
2275 break;
2276 }
2277 ++*s++;
2278 }
2279 break;
2280 }
2281 if (!(value(d) *= 10.))
2282 break;
2283 }
2284 goto ret1;
2285 }
2286
2287 m2 = b2;
2288 m5 = b5;
2289 mhi = mlo = 0;
2290 if (leftright) {
2291 if (mode < 2) {
2292 i =
2293#ifndef Sudden_Underflow
2294 denorm ? be + (Bias + (P-1) - 1 + 1) :
2295#endif
2296#ifdef IBM
2297 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
2298#else
2299 1 + P - bbits;
2300#endif
2301 }
2302 else {
2303 j = ilim - 1;
2304 if (m5 >= j)
2305 m5 -= j;
2306 else {
2307 s5 += j -= m5;
2308 b5 += j;
2309 m5 = 0;
2310 }
2311 if ((i = ilim) < 0) {
2312 m2 -= i;
2313 i = 0;
2314 }
2315 }
2316 b2 += i;
2317 s2 += i;
2318 mhi = i2b(1);
2319 }
2320 if (m2 > 0 && s2 > 0) {
2321 i = m2 < s2 ? m2 : s2;
2322 b2 -= i;
2323 m2 -= i;
2324 s2 -= i;
2325 }
2326 if (b5 > 0) {
2327 if (leftright) {
2328 if (m5 > 0) {
2329 mhi = pow5mult(mhi, m5);
2330 b1 = mult(mhi, b);
2331 Bfree(b);
2332 b = b1;
2333 }
2334 if (j = b5 - m5)
2335 b = pow5mult(b, j);
2336 }
2337 else
2338 b = pow5mult(b, b5);
2339 }
2340 S = i2b(1);
2341 if (s5 > 0)
2342 S = pow5mult(S, s5);
2343
2344 /* Check for special case that d is a normalized power of 2. */
2345
2346 if (mode < 2) {
2347 if (!word1(d) && !(word0(d) & Bndry_mask)
2348#ifndef Sudden_Underflow
2349 && word0(d) & Exp_mask
2350#endif
2351 ) {
2352 /* The special case */
2353 b2 += Log2P;
2354 s2 += Log2P;
2355 spec_case = 1;
2356 }
2357 else
2358 spec_case = 0;
2359 }
2360
2361 /* Arrange for convenient computation of quotients:
2362 * shift left if necessary so divisor has 4 leading 0 bits.
2363 *
2364 * Perhaps we should just compute leading 28 bits of S once
2365 * and for all and pass them and a shift to quorem, so it
2366 * can do shifts and ors to compute the numerator for q.
2367 */
2368#ifdef Pack_32
2369 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
2370 i = 32 - i;
2371#else
2372 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
2373 i = 16 - i;
2374#endif
2375 if (i > 4) {
2376 i -= 4;
2377 b2 += i;
2378 m2 += i;
2379 s2 += i;
2380 }
2381 else if (i < 4) {
2382 i += 28;
2383 b2 += i;
2384 m2 += i;
2385 s2 += i;
2386 }
2387 if (b2 > 0)
2388 b = lshift(b, b2);
2389 if (s2 > 0)
2390 S = lshift(S, s2);
2391 if (k_check) {
2392 if (cmp(b,S) < 0) {
2393 k--;
2394 b = multadd(b, 10, 0); /* we botched the k estimate */
2395 if (leftright)
2396 mhi = multadd(mhi, 10, 0);
2397 ilim = ilim1;
2398 }
2399 }
2400 if (ilim <= 0 && mode > 2) {
2401 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
2402 /* no digits, fcvt style */
2403 no_digits:
2404 k = -1 - ndigits;
2405 goto ret;
2406 }
2407 one_digit:
2408 *s++ = '1';
2409 k++;
2410 goto ret;
2411 }
2412 if (leftright) {
2413 if (m2 > 0)
2414 mhi = lshift(mhi, m2);
2415
2416 /* Compute mlo -- check for special case
2417 * that d is a normalized power of 2.
2418 */
2419
2420 mlo = mhi;
2421 if (spec_case) {
2422 mhi = Balloc(mhi->k);
2423 Bcopy(mhi, mlo);
2424 mhi = lshift(mhi, Log2P);
2425 }
2426
2427 for(i = 1;;i++) {
2428 dig = quorem(b,S) + '0';
2429 /* Do we yet have the shortest decimal string
2430 * that will round to d?
2431 */
2432 j = cmp(b, mlo);
2433 delta = diff(S, mhi);
2434 j1 = delta->sign ? 1 : cmp(b, delta);
2435 Bfree(delta);
2436#ifndef ROUND_BIASED
2437 if (j1 == 0 && !mode && !(word1(d) & 1)) {
2438 if (dig == '9')
2439 goto round_9_up;
2440 if (j > 0)
2441 dig++;
2442 *s++ = dig;
2443 goto ret;
2444 }
2445#endif
2446 if (j < 0 || j == 0 && !mode
2447#ifndef ROUND_BIASED
2448 && !(word1(d) & 1)
2449#endif
2450 ) {
2451 if (j1 > 0) {
2452 b = lshift(b, 1);
2453 j1 = cmp(b, S);
2454 if ((j1 > 0 || j1 == 0 && dig & 1)
2455 && dig++ == '9')
2456 goto round_9_up;
2457 }
2458 *s++ = dig;
2459 goto ret;
2460 }
2461 if (j1 > 0) {
2462 if (dig == '9') { /* possible if i == 1 */
2463 round_9_up:
2464 *s++ = '9';
2465 goto roundoff;
2466 }
2467 *s++ = dig + 1;
2468 goto ret;
2469 }
2470 *s++ = dig;
2471 if (i == ilim)
2472 break;
2473 b = multadd(b, 10, 0);
2474 if (mlo == mhi)
2475 mlo = mhi = multadd(mhi, 10, 0);
2476 else {
2477 mlo = multadd(mlo, 10, 0);
2478 mhi = multadd(mhi, 10, 0);
2479 }
2480 }
2481 }
2482 else
2483 for(i = 1;; i++) {
2484 *s++ = dig = quorem(b,S) + '0';
2485 if (i >= ilim)
2486 break;
2487 b = multadd(b, 10, 0);
2488 }
2489
2490 /* Round off last digit */
2491
2492 b = lshift(b, 1);
2493 j = cmp(b, S);
2494 if (j > 0 || j == 0 && dig & 1) {
2495 roundoff:
2496 while(*--s == '9')
2497 if (s == s0) {
2498 k++;
2499 *s++ = '1';
2500 goto ret;
2501 }
2502 ++*s++;
2503 }
2504 else {
2505 while(*--s == '0');
2506 s++;
2507 }
2508 ret:
2509 Bfree(S);
2510 if (mhi) {
2511 if (mlo && mlo != mhi)
2512 Bfree(mlo);
2513 Bfree(mhi);
2514 }
2515 ret1:
2516 Bfree(b);
2517 if (s == s0) { /* don't return empty string */
2518 *s++ = '0';
2519 k = 0;
2520 }
2521 *s = 0;
2522 *decpt = k + 1;
2523 if (rve)
2524 *rve = s;
2525 return s0;
2526 }
2527#ifdef __cplusplus
2528}
2529#endif
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
new file mode 100644
index 0000000000..b7d2cd1225
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.3
@@ -0,0 +1,168 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information 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.\" $OpenBSD: strtol.3,v 1.3 1996/08/19 08:33:51 tholo Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOL 3
40.Os
41.Sh NAME
42.Nm strtol, strtoq
43.Nd convert string value to a long or quad_t integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Fd #include <limits.h>
47.Ft long
48.Fn strtol "const char *nptr" "char **endptr" "int base"
49
50.Fd #include <sys/types.h>
51.Fd #include <stdlib.h>
52.Fd #include <limits.h>
53.Ft quad_t
54.Fn strtoq "const char *nptr" "char **endptr" "int base"
55.Sh DESCRIPTION
56The
57.Fn strtol
58function
59converts the string in
60.Fa nptr
61to a
62.Em long
63value.
64The
65.Fn strtoq
66function
67converts the string in
68.Fa nptr
69to a
70.Em quad_t
71value.
72The conversion is done according to the given
73.Fa base ,
74which must be between 2 and 36 inclusive,
75or be the special value 0.
76.Pp
77The string may begin with an arbitrary amount of white space
78(as determined by
79.Xr isspace 3 )
80followed by a single optional
81.Ql +
82or
83.Ql -
84sign.
85If
86.Fa base
87is zero or 16,
88the string may then include a
89.Ql 0x
90prefix,
91and the number will be read in base 16; otherwise, a zero
92.Fa base
93is taken as 10 (decimal) unless the next character is
94.Ql 0 ,
95in which case it is taken as 8 (octal).
96.Pp
97The remainder of the string is converted to a
98.Em long
99value in the obvious manner,
100stopping at the first character which is not a valid digit
101in the given base.
102(In bases above 10, the letter
103.Ql A
104in either upper or lower case
105represents 10,
106.Ql B
107represents 11, and so forth, with
108.Ql Z
109representing 35.)
110.Pp
111If
112.Fa endptr
113is non nil,
114.Fn strtol
115stores the address of the first invalid character in
116.Fa *endptr .
117If there were no digits at all, however,
118.Fn strtol
119stores the original value of
120.Fa nptr
121in
122.Fa *endptr .
123(Thus, if
124.Fa *nptr
125is not
126.Ql \e0
127but
128.Fa **endptr
129is
130.Ql \e0
131on return, the entire string was valid.)
132.Sh RETURN VALUES
133The
134.Fn strtol
135function
136returns the result of the conversion,
137unless the value would underflow or overflow.
138If an underflow occurs,
139.Fn strtol
140returns
141.Dv LONG_MIN .
142If an overflow occurs,
143.Fn strtol
144returns
145.Dv LONG_MAX .
146In both cases,
147.Va errno
148is set to
149.Er ERANGE .
150.Sh ERRORS
151.Bl -tag -width Er
152.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped.
154.El
155.Sh SEE ALSO
156.Xr atof 3 ,
157.Xr atoi 3 ,
158.Xr atol 3 ,
159.Xr strtod 3 ,
160.Xr strtoul 3
161.Sh STANDARDS
162The
163.Fn strtol
164function
165conforms to
166.St -ansiC .
167.Sh BUGS
168Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000000..e4ad557fd5
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.c
@@ -0,0 +1,150 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtol.c,v 1.4 1996/08/19 08:33:51 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43
44/*
45 * Convert a string to a long integer.
46 *
47 * Ignores `locale' stuff. Assumes that the upper and lower case
48 * alphabets and digits are each contiguous.
49 */
50long
51strtol(nptr, endptr, base)
52 const char *nptr;
53 char **endptr;
54 register int base;
55{
56 register const char *s;
57 register long acc, cutoff;
58 register int c;
59 register int neg, any, cutlim;
60
61 /*
62 * Skip white space and pick up leading +/- sign if any.
63 * If base is 0, allow 0x for hex and 0 for octal, else
64 * assume decimal; if base is already 16, allow 0x.
65 */
66 s = nptr;
67 do {
68 c = (unsigned char) *s++;
69 } while (isspace(c));
70 if (c == '-') {
71 neg = 1;
72 c = *s++;
73 } else {
74 neg = 0;
75 if (c == '+')
76 c = *s++;
77 }
78 if ((base == 0 || base == 16) &&
79 c == '0' && (*s == 'x' || *s == 'X')) {
80 c = s[1];
81 s += 2;
82 base = 16;
83 }
84 if (base == 0)
85 base = c == '0' ? 8 : 10;
86
87 /*
88 * Compute the cutoff value between legal numbers and illegal
89 * numbers. That is the largest legal value, divided by the
90 * base. An input number that is greater than this value, if
91 * followed by a legal input character, is too big. One that
92 * is equal to this value may be valid or not; the limit
93 * between valid and invalid numbers is then based on the last
94 * digit. For instance, if the range for longs is
95 * [-2147483648..2147483647] and the input base is 10,
96 * cutoff will be set to 214748364 and cutlim to either
97 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
98 * a value > 214748364, or equal but the next digit is > 7 (or 8),
99 * the number is too big, and we will return a range error.
100 *
101 * Set any if any `digits' consumed; make it negative to indicate
102 * overflow.
103 */
104 cutoff = neg ? LONG_MIN : LONG_MAX;
105 cutlim = cutoff % base;
106 cutoff /= base;
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++) {
115 if (isdigit(c))
116 c -= '0';
117 else if (isalpha(c))
118 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
119 else
120 break;
121 if (c >= base)
122 break;
123 if (any < 0)
124 continue;
125 if (neg) {
126 if (acc < cutoff || acc == cutoff && c > cutlim) {
127 any = -1;
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 }
145 }
146 }
147 if (endptr != 0)
148 *endptr = (char *) (any ? s - 1 : nptr);
149 return (acc);
150}
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoq.c
new file mode 100644
index 0000000000..44aabd73f0
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoq.c
@@ -0,0 +1,152 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: strtoq.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to a quad integer.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51quad_t
52strtoq(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{
57 register const char *s;
58 register quad_t acc, cutoff;
59 register int c;
60 register int neg, any, cutlim;
61
62 /*
63 * Skip white space and pick up leading +/- sign if any.
64 * If base is 0, allow 0x for hex and 0 for octal, else
65 * assume decimal; if base is already 16, allow 0x.
66 */
67 s = nptr;
68 do {
69 c = (unsigned char) *s++;
70 } while (isspace(c));
71 if (c == '-') {
72 neg = 1;
73 c = *s++;
74 } else {
75 neg = 0;
76 if (c == '+')
77 c = *s++;
78 }
79 if ((base == 0 || base == 16) &&
80 c == '0' && (*s == 'x' || *s == 'X')) {
81 c = s[1];
82 s += 2;
83 base = 16;
84 }
85 if (base == 0)
86 base = c == '0' ? 8 : 10;
87
88 /*
89 * Compute the cutoff value between legal numbers and illegal
90 * numbers. That is the largest legal value, divided by the
91 * base. An input number that is greater than this value, if
92 * followed by a legal input character, is too big. One that
93 * is equal to this value may be valid or not; the limit
94 * between valid and invalid numbers is then based on the last
95 * digit. For instance, if the range for quads is
96 * [-9223372036854775808..9223372036854775807] and the input base
97 * is 10, cutoff will be set to 922337203685477580 and cutlim to
98 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
99 * accumulated a value > 922337203685477580, or equal but the
100 * next digit is > 7 (or 8), the number is too big, and we will
101 * return a range error.
102 *
103 * Set any if any `digits' consumed; make it negative to indicate
104 * overflow.
105 */
106 cutoff = neg ? QUAD_MIN : QUAD_MAX;
107 cutlim = cutoff % base;
108 cutoff /= base;
109 if (neg) {
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++) {
117 if (isdigit(c))
118 c -= '0';
119 else if (isalpha(c))
120 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
121 else
122 break;
123 if (c >= base)
124 break;
125 if (any < 0)
126 continue;
127 if (neg) {
128 if (acc < cutoff || acc == cutoff && c > cutlim) {
129 any = -1;
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 }
147 }
148 }
149 if (endptr != 0)
150 *endptr = (char *) (any ? s - 1 : nptr);
151 return (acc);
152}
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000000..b8234122a2
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,163 @@
1.\" Copyright (c) 1990, 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.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information 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.\" $OpenBSD: strtoul.3,v 1.2 1996/08/19 08:33:52 tholo Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOUL 3
40.Os
41.Sh NAME
42.Nm strtoul, strtouq
43.Nd convert a string to an unsigned long or uquad_t integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Fd #include <limits.h>
47.Ft unsigned long
48.Fn strtoul "const char *nptr" "char **endptr" "int base"
49
50.Fd #include <sys/types.h>
51.Fd #include <stdlib.h>
52.Fd #include <limits.h>
53.Ft u_quad_t
54.Fn strtouq "const char *nptr" "char **endptr" "int base"
55.Sh DESCRIPTION
56The
57.Fn strtoul
58function
59converts the string in
60.Fa nptr
61to an
62.Em unsigned long
63value.
64The
65.Fn strtouq
66function
67converts the string in
68.Fa nptr
69to a
70.Em u_quad_t
71value.
72The conversion is done according to the given
73.Fa base ,
74which must be between 2 and 36 inclusive,
75or be the special value 0.
76.Pp
77The string may begin with an arbitrary amount of white space
78(as determined by
79.Xr isspace 3 )
80followed by a single optional
81.Ql +
82or
83.Ql -
84sign.
85If
86.Fa base
87is zero or 16,
88the string may then include a
89.Ql 0x
90prefix,
91and the number will be read in base 16; otherwise, a zero
92.Fa base
93is taken as 10 (decimal) unless the next character is
94.Ql 0 ,
95in which case it is taken as 8 (octal).
96.Pp
97The remainder of the string is converted to an
98.Em unsigned long
99value in the obvious manner,
100stopping at the end of the string
101or at the first character that does not produce a valid digit
102in the given base.
103(In bases above 10, the letter
104.Ql A
105in either upper or lower case
106represents 10,
107.Ql B
108represents 11, and so forth, with
109.Ql Z
110representing 35.)
111.Pp
112If
113.Fa endptr
114is non nil,
115.Fn strtoul
116stores the address of the first invalid character in
117.Fa *endptr .
118If there were no digits at all, however,
119.Fn strtoul
120stores the original value of
121.Fa nptr
122in
123.Fa *endptr .
124(Thus, if
125.Fa *nptr
126is not
127.Ql \e0
128but
129.Fa **endptr
130is
131.Ql \e0
132on return, the entire string was valid.)
133.Sh RETURN VALUES
134The
135.Fn strtoul
136function
137returns either the result of the conversion
138or, if there was a leading minus sign,
139the negation of the result of the conversion,
140unless the original (non-negated) value would overflow;
141in the latter case,
142.Fn strtoul
143returns
144.Dv ULONG_MAX
145and sets the global variable
146.Va errno
147to
148.Er ERANGE .
149.Sh ERRORS
150.Bl -tag -width Er
151.It Bq Er ERANGE
152The given string was out of range; the value converted has been clamped.
153.El
154.Sh SEE ALSO
155.Xr strtol 3
156.Sh STANDARDS
157The
158.Fn strtoul
159function
160conforms to
161.St -ansiC .
162.Sh BUGS
163Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
new file mode 100644
index 0000000000..d3b363fa04
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtoul.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43/*
44 * Convert a string to an unsigned long integer.
45 *
46 * Ignores `locale' stuff. Assumes that the upper and lower case
47 * alphabets and digits are each contiguous.
48 */
49unsigned long
50strtoul(nptr, endptr, base)
51 const char *nptr;
52 char **endptr;
53 register int base;
54{
55 register const char *s;
56 register unsigned long acc, cutoff;
57 register int c;
58 register int neg, any, cutlim;
59
60 /*
61 * See strtol for comments as to the logic used.
62 */
63 s = nptr;
64 do {
65 c = (unsigned char) *s++;
66 } while (isspace(c));
67 if (c == '-') {
68 neg = 1;
69 c = *s++;
70 } else {
71 neg = 0;
72 if (c == '+')
73 c = *s++;
74 }
75 if ((base == 0 || base == 16) &&
76 c == '0' && (*s == 'x' || *s == 'X')) {
77 c = s[1];
78 s += 2;
79 base = 16;
80 }
81 if (base == 0)
82 base = c == '0' ? 8 : 10;
83
84 cutoff = ULONG_MAX / (unsigned long)base;
85 cutlim = ULONG_MAX % (unsigned long)base;
86 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
87 if (isdigit(c))
88 c -= '0';
89 else if (isalpha(c))
90 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
91 else
92 break;
93 if (c >= base)
94 break;
95 if (any < 0)
96 continue;
97 if (acc > cutoff || acc == cutoff && c > cutlim) {
98 any = -1;
99 acc = ULONG_MAX;
100 errno = ERANGE;
101 } else {
102 any = 1;
103 acc *= (unsigned long)base;
104 acc += c;
105 }
106 }
107 if (neg && any > 0)
108 acc = -acc;
109 if (endptr != 0)
110 *endptr = (char *) (any ? s - 1 : nptr);
111 return (acc);
112}
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtouq.c
new file mode 100644
index 0000000000..1f29a22f33
--- /dev/null
+++ b/src/lib/libc/stdlib/strtouq.c
@@ -0,0 +1,114 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: strtouq.c,v 1.4 1996/08/19 08:33:53 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to an unsigned quad integer.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51u_quad_t
52strtouq(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{
57 register const char *s;
58 register u_quad_t acc, cutoff;
59 register int c;
60 register int neg, any, cutlim;
61
62 /*
63 * See strtoq for comments as to the logic used.
64 */
65 s = nptr;
66 do {
67 c = (unsigned char) *s++;
68 } while (isspace(c));
69 if (c == '-') {
70 neg = 1;
71 c = *s++;
72 } else {
73 neg = 0;
74 if (c == '+')
75 c = *s++;
76 }
77 if ((base == 0 || base == 16) &&
78 c == '0' && (*s == 'x' || *s == 'X')) {
79 c = s[1];
80 s += 2;
81 base = 16;
82 }
83 if (base == 0)
84 base = c == '0' ? 8 : 10;
85
86 cutoff = UQUAD_MAX / (u_quad_t)base;
87 cutlim = UQUAD_MAX % (u_quad_t)base;
88 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
89 if (isdigit(c))
90 c -= '0';
91 else if (isalpha(c))
92 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
93 else
94 break;
95 if (c >= base)
96 break;
97 if (any < 0)
98 continue;
99 if (acc > cutoff || acc == cutoff && c > cutlim) {
100 any = -1;
101 acc = UQUAD_MAX;
102 errno = ERANGE;
103 } else {
104 any = 1;
105 acc *= (u_quad_t)base;
106 acc += c;
107 }
108 }
109 if (neg && any > 0)
110 acc = -acc;
111 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc);
114}
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
new file mode 100644
index 0000000000..985adb07de
--- /dev/null
+++ b/src/lib/libc/stdlib/system.3
@@ -0,0 +1,98 @@
1.\" Copyright (c) 1990, 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.\" $OpenBSD: system.3,v 1.5 1996/12/11 23:09:53 tholo Exp $
37.\"
38.Dd June 29, 1991
39.Dt SYSTEM 3
40.Os
41.Sh NAME
42.Nm system
43.Nd pass a command to the shell
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn system "const char *string"
48.Sh DESCRIPTION
49The
50.Fn system
51function
52hands the argument
53.Fa string
54to the command interpreter
55.Xr sh 1 .
56The calling process waits for the shell to finish executing the command,
57ignoring
58.Dv SIGINT
59and
60.Dv SIGQUIT ,
61and blocking
62.Dv SIGCHLD .
63.Pp
64If
65.Fa string
66is a
67.Dv NULL
68pointer,
69.Fn system
70will return non-zero.
71Otherwise,
72.Fn system
73returns the termination status of the shell in the format specified by
74.Xr waitpid 2 .
75.Sh RETURN VALUES
76If a child process cannot be created, or the termination status of
77the shell cannot be obtained,
78.Fn system
79returns -1 and sets
80.Va errno
81to indicate the error.
82If execution of the shell fails,
83.Fn system
84returns the termination status for a program that terminates with a call of
85.Fn exit 127 .
86.Sh SEE ALSO
87.Xr sh 1 ,
88.Xr execve 2 ,
89.Xr waitpid 2 ,
90.Xr popen 3
91.Sh STANDARDS
92The
93.Fn system
94function
95conforms to
96.St -ansiC
97and
98.St -p1003.2-92 .
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
new file mode 100644
index 0000000000..3e1b047393
--- /dev/null
+++ b/src/lib/libc/stdlib/system.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
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. 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 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: system.c,v 1.3 1996/09/15 09:31:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/wait.h>
40#include <signal.h>
41#include <stdlib.h>
42#include <unistd.h>
43#include <paths.h>
44
45extern char **environ;
46
47int
48system(command)
49 const char *command;
50{
51 pid_t pid;
52 sig_t intsave, quitsave;
53 int omask;
54 int pstat;
55 char *argp[] = {"sh", "-c", NULL, NULL};
56
57 if (!command) /* just checking... */
58 return(1);
59
60 argp[2] = (char *)command;
61
62 omask = sigblock(sigmask(SIGCHLD));
63 switch(pid = vfork()) {
64 case -1: /* error */
65 (void)sigsetmask(omask);
66 return(-1);
67 case 0: /* child */
68 (void)sigsetmask(omask);
69 execve(_PATH_BSHELL, argp, environ);
70 _exit(127);
71 }
72
73 intsave = signal(SIGINT, SIG_IGN);
74 quitsave = signal(SIGQUIT, SIG_IGN);
75 pid = waitpid(pid, (int *)&pstat, 0);
76 (void)sigsetmask(omask);
77 (void)signal(SIGINT, intsave);
78 (void)signal(SIGQUIT, quitsave);
79 return(pid == -1 ? -1 : pstat);
80}
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}