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.inc56
-rw-r--r--src/lib/libc/stdlib/_rand48.c50
-rw-r--r--src/lib/libc/stdlib/a64l.3144
-rw-r--r--src/lib/libc/stdlib/a64l.c46
-rw-r--r--src/lib/libc/stdlib/abort.367
-rw-r--r--src/lib/libc/stdlib/abort.c86
-rw-r--r--src/lib/libc/stdlib/abs.369
-rw-r--r--src/lib/libc/stdlib/abs.c45
-rw-r--r--src/lib/libc/stdlib/alloca.384
-rw-r--r--src/lib/libc/stdlib/atexit.375
-rw-r--r--src/lib/libc/stdlib/atexit.c83
-rw-r--r--src/lib/libc/stdlib/atexit.h41
-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.385
-rw-r--r--src/lib/libc/stdlib/atoi.c45
-rw-r--r--src/lib/libc/stdlib/atol.373
-rw-r--r--src/lib/libc/stdlib/atol.c45
-rw-r--r--src/lib/libc/stdlib/bsearch.388
-rw-r--r--src/lib/libc/stdlib/bsearch.c79
-rw-r--r--src/lib/libc/stdlib/calloc.c59
-rw-r--r--src/lib/libc/stdlib/cfree.c49
-rw-r--r--src/lib/libc/stdlib/div.367
-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.392
-rw-r--r--src/lib/libc/stdlib/exit.c79
-rw-r--r--src/lib/libc/stdlib/getenv.3146
-rw-r--r--src/lib/libc/stdlib/getenv.c89
-rw-r--r--src/lib/libc/stdlib/getopt.3254
-rw-r--r--src/lib/libc/stdlib/getopt.c117
-rw-r--r--src/lib/libc/stdlib/getsubopt.3147
-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.364
-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.369
-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.3419
-rw-r--r--src/lib/libc/stdlib/malloc.c1305
-rw-r--r--src/lib/libc/stdlib/memory.369
-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.c124
-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.360
-rw-r--r--src/lib/libc/stdlib/qabs.c45
-rw-r--r--src/lib/libc/stdlib/qdiv.364
-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.3156
-rw-r--r--src/lib/libc/stdlib/radixsort.c317
-rw-r--r--src/lib/libc/stdlib/rand.3102
-rw-r--r--src/lib/libc/stdlib/rand.c65
-rw-r--r--src/lib/libc/stdlib/rand48.3165
-rw-r--r--src/lib/libc/stdlib/rand48.h32
-rw-r--r--src/lib/libc/stdlib/random.3190
-rw-r--r--src/lib/libc/stdlib/random.c417
-rw-r--r--src/lib/libc/stdlib/realpath.3124
-rw-r--r--src/lib/libc/stdlib/realpath.c166
-rw-r--r--src/lib/libc/stdlib/seed48.c40
-rw-r--r--src/lib/libc/stdlib/setenv.c121
-rw-r--r--src/lib/libc/stdlib/srand48.c34
-rw-r--r--src/lib/libc/stdlib/strtod.3117
-rw-r--r--src/lib/libc/stdlib/strtod.c2528
-rw-r--r--src/lib/libc/stdlib/strtol.3243
-rw-r--r--src/lib/libc/stdlib/strtol.c150
-rw-r--r--src/lib/libc/stdlib/strtoll.c166
-rw-r--r--src/lib/libc/stdlib/strtoul.3225
-rw-r--r--src/lib/libc/stdlib/strtoul.c112
-rw-r--r--src/lib/libc/stdlib/strtoull.c128
-rw-r--r--src/lib/libc/stdlib/system.3103
-rw-r--r--src/lib/libc/stdlib/system.c82
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3127
-rw-r--r--src/lib/libc/stdlib/tsearch.c126
83 files changed, 12353 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..4b4c88b9af
--- /dev/null
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,56 @@
1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2
3# stdlib sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/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 strtoll.c strtoul.c \
10 strtoull.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 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 malloc.3 calloc.3
42MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
43MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
44MLINKS+=radixsort.3 sradixsort.3
45MLINKS+=rand.3 srand.3 rand.3 rand_r.3
46MLINKS+=random.3 initstate.3 random.3 setstate.3
47MLINKS+=random.3 srandom.3 random.3 srandomdev.3
48MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
49MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
50MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
51MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3
52MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3
53MLINKS+=tsearch.3 tfind.3
54MLINKS+=tsearch.3 tdelete.3
55MLINKS+=tsearch.3 twalk.3
56MLINKS+=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..787634303c
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,144 @@
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: a64l.3,v 1.5 2000/04/20 13:50:01 aaron Exp $
27.\"
28.Dd August 17, 1997
29.Dt A64L 3
30.Os
31.Sh NAME
32.Nm a64l ,
33.Nm l64a
34.Nd convert between 32-bit integer and radix-64 ASCII string
35.Sh SYNOPSIS
36.Fd #include <stdlib.h>
37.Ft long
38.Fn a64l "const char *s"
39.Ft char *
40.Fn l64a "long l"
41.Sh DESCRIPTION
42The
43.Fn a64l
44and
45.Fn l64a
46functions are used to maintain numbers stored in radix-64
47.Tn ASCII
48characters.
49This is a notation by which 32-bit integers
50can be represented by up to six characters; each character represents a
51.Dq digit
52in a radix-64 notation.
53.Pp
54The characters used to represent digits are
55.Ql \&.
56for 0,
57.Ql /
58for 1,
59.Ql 0
60through
61.Ql 9
62for 2-11,
63.Ql A
64through
65.Ql Z
66for 12-37, and
67.Ql a
68through
69.Ql z
70for 38-63.
71.Pp
72The
73.Fn a64l
74function takes a pointer to a null-terminated radix-64 representation
75and returns a corresponding 32-bit value.
76If the string pointed to by
77.Fa s
78contains more than six characters,
79.Fn a64l
80will use the first six.
81.Fn a64l
82scans the character string from left to right, decoding
83each character as a 6-bit radix-64 number.
84If a long integer is
85larger than 32 bits, the return value will be sign-extended.
86.Pp
87.Fn l64a
88takes a long integer argument
89.Fa l
90and returns a pointer to the corresponding radix-64 representation.
91.Sh RETURN VALUES
92On success,
93.Fn a64l
94returns a 32-bit representation of
95.Fa s .
96If
97.Fa s
98is a null pointer or if it contains digits other than those described above.
99.Fn a64l
100returns \-1 and sets the global variable
101.Va errno
102to
103.Er EINVAL .
104.Pp
105On success,
106.Fn l64a
107returns a pointer to a string containing the radix-64 representation of
108.Fa l .
109If
110.Fa l
111is 0,
112.Fn l64a
113returns a pointer to the empty string.
114If
115.Fa l
116is negative,
117.Fn l64a
118returns a null pointer and sets the global variable
119.Va errno
120to
121.Er EINVAL .
122.Sh WARNINGS
123The value returned by
124.Fn l64a
125is a pointer into a static buffer, the contents of which
126will be overwritten by subsequent calls.
127.Pp
128The value returned by
129.Fn a64l
130may be incorrect if the value is too large; for that reason, only strings
131that resulted from a call to
132.Fn l64a
133should be used to call
134.Fn a64l .
135.Pp
136If a long integer is larger than 32 bits, only the low-order
13732 bits are used.
138.Sh STANDARDS
139The
140.Fn a64l
141and
142.Fn l64a
143functions conform to
144.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..743d42dd8a
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.3
@@ -0,0 +1,67 @@
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.6 2000/04/20 13:50:01 aaron 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 signal
52.Dv SIGABRT
53is being caught and the signal handler does not return.
54.Pp
55Any open streams are flushed and closed.
56.Sh RETURN VALUES
57The
58.Fn abort
59function never returns.
60.Sh SEE ALSO
61.Xr sigaction 2 ,
62.Xr exit 3
63.Sh STANDARDS
64The
65.Fn abort
66function conforms to
67.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..41a9f0f48b
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.c
@@ -0,0 +1,86 @@
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.7 2001/08/12 12:03:01 heko Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <signal.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include "thread_private.h"
42
43void (*__cleanup)();
44
45void
46abort()
47{
48 static int cleanup_called = 0;
49 sigset_t mask;
50
51
52 sigfillset(&mask);
53 /*
54 * don't block SIGABRT to give any handler a chance; we ignore
55 * any errors -- X311J doesn't allow abort to return anyway.
56 */
57 sigdelset(&mask, SIGABRT);
58#ifdef _THREAD_SAFE
59 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
60#else /* _THREAD_SAFE */
61 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
62#endif /* _THREAD_SAFE */
63
64 /*
65 * POSIX requires we flush stdio buffers on abort
66 */
67 if (cleanup_called == 0 && __cleanup != NULL) {
68 cleanup_called = 1;
69 (*__cleanup)();
70 }
71
72 (void)kill(getpid(), SIGABRT);
73
74 /*
75 * if SIGABRT ignored, or caught and the handler returns, do
76 * it again, only harder.
77 */
78 (void)signal(SIGABRT, SIG_DFL);
79#ifdef _THREAD_SAFE
80 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
81#else /* _THREAD_SAFE */
82 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
83#endif /* _THREAD_SAFE */
84 (void)kill(getpid(), SIGABRT);
85 exit(1);
86}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000000..0f7c097ade
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.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.\" 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.5 2000/04/20 13:50:01 aaron 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 computes the absolute value of the integer
52.Fa j .
53.Sh RETURN VALUES
54The
55.Fn abs
56function returns the absolute value.
57.Sh SEE ALSO
58.Xr cabs 3 ,
59.Xr floor 3 ,
60.Xr hypot 3 ,
61.Xr labs 3 ,
62.Xr math 3
63.Sh STANDARDS
64The
65.Fn abs
66function conforms to
67.St -ansiC .
68.Sh BUGS
69The 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..431443a6e6
--- /dev/null
+++ b/src/lib/libc/stdlib/alloca.3
@@ -0,0 +1,84 @@
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.9 2001/12/06 04:21:27 deraadt Exp $
33.\"
34.Dd May 2, 1991
35.Dt ALLOCA 3
36.Os
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 allocates
48.Fa size
49bytes of space in the stack frame of the caller.
50This temporary space is automatically freed on return.
51.Sh RETURN VALUES
52The
53.Fn alloca
54function returns a pointer to the beginning of the allocated space.
55.Sh SEE ALSO
56.Xr pagesize 1 ,
57.Xr brk 2 ,
58.Xr calloc 3 ,
59.Xr malloc 3 ,
60.Xr realloc 3
61.Sh BUGS
62The
63.Fn alloca
64function is machine dependent; its use is discouraged.
65.\" .Sh HISTORY
66.\" The
67.\" .Fn alloca
68.\" function appeared in
69.\" .Bx ?? .
70.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
71.\" The first man page (or link to a man page that I can find at the
72.\" moment is 4.3...
73.Pp
74The
75.Fn alloca
76function is slightly unsafe because it cannot ensure that the pointer
77returned points to a valid and usable block of memory.
78The allocation made may exceed the bounds of the stack, or even go
79further into other objects in memory, and
80.Fn alloca
81cannot determine such an error.
82Avoid
83.Fn alloca
84with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000000..5d79ede649
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.3
@@ -0,0 +1,75 @@
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.4 2000/04/20 13:50:01 aaron 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 registers the given
52.Fa function
53to be called at program exit, whether via
54.Xr exit 3
55or via return from the program's
56.Fn main .
57Functions so registered are called in reverse order;
58no arguments are passed.
59At least 32 functions can always be registered,
60and more are allowed as long as sufficient memory can be allocated.
61.Sh RETURN VALUES
62.Rv -std atexit
63.Sh ERRORS
64.Bl -tag -width Er
65.It Bq Er ENOMEM
66No memory was available to add the function to the list.
67The existing list of functions is unmodified.
68.El
69.Sh SEE ALSO
70.Xr exit 3
71.Sh STANDARDS
72The
73.Fn atexit
74function conforms to
75.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000000..92c4884f28
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2002 Daniel Hartmeier
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: atexit.c,v 1.5 2002/08/30 07:58:07 dhartmei Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <sys/types.h>
36#include <sys/mman.h>
37#include <stdlib.h>
38#include "atexit.h"
39
40int __atexit_invalid = 1;
41struct atexit *__atexit;
42
43/*
44 * Register a function to be performed at exit.
45 */
46int
47atexit(fn)
48 void (*fn)();
49{
50 register struct atexit *p = __atexit;
51 register int pgsize = getpagesize();
52
53 if (pgsize < sizeof(*p))
54 return (-1);
55 if (p != NULL) {
56 if (p->ind + 1 >= p->max)
57 p = NULL;
58 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
59 return (-1);
60 }
61 if (p == NULL) {
62 if (__atexit_invalid) {
63 /* malloc.c wants the first mmap() for sbrk()
64 games ('nice hack'), so enforce
65 malloc_init() with a dummy call. */
66 free(malloc(1));
67 __atexit_invalid = 0;
68 }
69 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
70 MAP_ANON | MAP_PRIVATE, -1, 0);
71 if (p == MAP_FAILED)
72 return (-1);
73 p->ind = 0;
74 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
75 sizeof(p->fns[0]);
76 p->next = __atexit;
77 __atexit = p;
78 }
79 p->fns[p->ind++] = fn;
80 if (mprotect(p, pgsize, PROT_READ))
81 return (-1);
82 return (0);
83}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000000..28bf3a7f27
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.h
@@ -0,0 +1,41 @@
1/* $OpenBSD: atexit.h,v 1.5 2002/08/30 07:58:07 dhartmei Exp $ */
2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
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 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33struct atexit {
34 struct atexit *next; /* next in list */
35 int ind; /* next index in this table */
36 int max; /* max entries >= ATEXIT_SIZE */
37 void (*fns[1])(); /* the table itself */
38};
39
40extern int __atexit_invalid;
41extern 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..0bd85dbe82
--- /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.3 1999/06/29 18:36:18 aaron 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.Fa nptr
55to
56.Li 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..69b94be70c
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.3
@@ -0,0 +1,85 @@
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.5 2000/04/20 13:50:01 aaron 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.Fa nptr
55to
56.Li integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61(int)strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh CAVEATS
64.Nm
65does no overflow checking, handles unsigned numbers poorly,
66and handles strings containing trailing extra characters
67(like
68.Dq "123abc" Ns )
69poorly.
70Careful use of
71.Xr strtol 3
72and
73.Xr strtoul 3
74can alleviate these problems.
75.Sh SEE ALSO
76.Xr atof 3 ,
77.Xr atol 3 ,
78.Xr strtod 3 ,
79.Xr strtol 3 ,
80.Xr strtoul 3
81.Sh STANDARDS
82The
83.Fn atoi
84function conforms to
85.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..53a518997f
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.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: atol.3,v 1.4 2000/04/20 13:50:01 aaron 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.Fa nptr
55to
56.Li 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 conforms to
73.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..9bb9d4ece4
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,88 @@
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.5 2000/04/20 13:50:01 aaron 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 is expected to have two arguments which point to the
67.Fa key
68object and to an array member, in that order, and should return an integer
69less than, equal to, or greater than zero if the
70.Fa key
71object is found, respectively, to be less than, to match, or be
72greater than the array member.
73.Sh RETURN VALUES
74The
75.Fn bsearch
76function returns a pointer to a matching member of the array, or a null
77pointer if no match is found.
78If two members compare as equal, which member is matched is unspecified.
79.Sh SEE ALSO
80.Xr db 3 ,
81.Xr lsearch 3 ,
82.Xr qsort 3 ,
83.Xr tsearch 3
84.Sh STANDARDS
85The
86.Fn bsearch
87function conforms to
88.St -ansiC .
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000000..1903202b6c
--- /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.3 2002/02/16 21:27:24 millert 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)(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.c b/src/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000000..c75b256d14
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.c
@@ -0,0 +1,59 @@
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.7 2002/07/31 09:19:04 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40#include <limits.h>
41#include <errno.h>
42
43void *
44calloc(num, size)
45 size_t num;
46 register size_t size;
47{
48 register void *p;
49
50 if (num && size && SIZE_T_MAX / num < size) {
51 errno = ENOMEM;
52 return NULL;
53 }
54 size *= num;
55 p = malloc(size);
56 if (p)
57 memset(p, 0, size);
58 return(p);
59}
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..1f651d7fd3
--- /dev/null
+++ b/src/lib/libc/stdlib/div.3
@@ -0,0 +1,67 @@
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.5 2000/04/20 13:50:02 aaron 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 computes the value
50.Fa num Ns No / Ns Fa denom
51and returns the quotient and remainder in a structure named
52.Fa div_t
53that contains two
54.Li int
55members named
56.Fa quot
57and
58.Fa rem .
59.Sh SEE ALSO
60.Xr ldiv 3 ,
61.Xr math 3 ,
62.Xr qdiv 3
63.Sh STANDARDS
64The
65.Fn div
66function conforms to
67.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..bcfdfd38f5
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.3
@@ -0,0 +1,92 @@
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.6 2001/07/27 23:48:12 mpech 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
49The
50.Fn exit
51function terminates a process.
52.Pp
53Before termination it performs the following functions in the
54order listed:
55.Bl -enum -offset indent
56.It
57Call the functions registered with the
58.Xr atexit 3
59function, in the reverse order of their registration.
60.It
61Flush all open output streams.
62.It
63Close all open streams.
64.It
65Unlink all files created with the
66.Xr tmpfile 3
67function.
68.El
69Following this,
70.Fn exit
71calls
72.Xr _exit 2 .
73Note that typically
74.Xr exit 2
75only passes the lower 8 bits of
76.Fa status
77on to the parent, thus negative values have less meaning.
78.Sh RETURN VALUES
79The
80.Fn exit
81function never returns.
82.Sh SEE ALSO
83.Xr _exit 2 ,
84.Xr atexit 3 ,
85.Xr intro 3 ,
86.Xr sysexits 3 ,
87.Xr tmpfile 3
88.Sh STANDARDS
89The
90.Fn exit
91function conforms to
92.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000000..c69639125e
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.c
@@ -0,0 +1,79 @@
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.7 2002/08/30 07:58:07 dhartmei Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/mman.h>
40#include <stdlib.h>
41#include <unistd.h>
42#include "atexit.h"
43#include "thread_private.h"
44
45void (*__cleanup)();
46
47/*
48 * This variable is zero until a process has created a thread.
49 * It is used to avoid calling locking functions in libc when they
50 * are not required. By default, libc is intended to be(come)
51 * thread-safe, but without a (significant) penalty to non-threaded
52 * processes.
53 */
54int __isthreaded = 0;
55
56/*
57 * Exit, flushing stdio buffers if necessary.
58 */
59void
60exit(status)
61 int status;
62{
63 register struct atexit *p, *q;
64 register int n, pgsize = getpagesize();
65
66 if (!__atexit_invalid) {
67 p = __atexit;
68 while (p != NULL) {
69 for (n = p->ind; --n >= 0;)
70 (*p->fns[n])();
71 q = p;
72 p = p->next;
73 munmap(q, pgsize);
74 }
75 }
76 if (__cleanup)
77 (*__cleanup)();
78 _exit(status);
79}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000000..b2aa0080d6
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.3
@@ -0,0 +1,146 @@
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.7 2000/04/20 13:50:02 aaron 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 host
59.Em environment list .
60For compatibility with differing environment conventions, the given arguments
61.Fa name
62and
63.Fa value
64may be appended and prepended, respectively, with an equal sign
65.Dq Li \&= .
66.Pp
67The
68.Fn getenv
69function obtains the current value of the environment variable,
70.Fa name .
71If the variable
72.Fa name
73is not in the current environment, a null pointer is returned.
74.Pp
75The
76.Fn setenv
77function inserts or resets the environment variable
78.Fa name
79in the current environment list.
80If the variable
81.Fa name
82does not exist in the list, it is inserted with the given
83.Fa value .
84If the variable does exist, the argument
85.Fa overwrite
86is tested; if
87.Fa overwrite
88is zero, the variable is not reset, otherwise it is reset to the given
89.Fa value .
90.Pp
91The
92.Fn putenv
93function takes an argument of the form
94.Ar name Ns No = Ns Ar value
95and is equivalent to:
96.Bd -literal -offset indent
97setenv(name, value, 1);
98.Ed
99.Pp
100The
101.Fn unsetenv
102function deletes all instances of the variable name pointed to by
103.Fa name
104from the list.
105.Sh RETURN VALUES
106The functions
107.Fn setenv
108and
109.Fn putenv
110return zero if successful; otherwise the global variable
111.Va errno
112is set to indicate the error and \-1 is returned.
113.Pp
114If
115.Fn getenv
116is successful, the string returned should be considered read-only.
117.Sh ERRORS
118.Bl -tag -width [ENOMEM]
119.It Bq Er ENOMEM
120The function
121.Fn setenv
122or
123.Fn putenv
124failed because they were unable to allocate memory for the environment.
125.El
126.Sh SEE ALSO
127.Xr csh 1 ,
128.Xr sh 1 ,
129.Xr execve 2 ,
130.Xr environ 7
131.Sh STANDARDS
132The
133.Fn getenv
134function conforms to
135.St -ansiC .
136.Sh HISTORY
137The functions
138.Fn setenv
139and
140.Fn unsetenv
141appeared in
142.At v7 .
143The
144.Fn putenv
145function appeared in
146.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..4acbe69606
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.3
@@ -0,0 +1,254 @@
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.17 2002/08/19 22:29:52 miod Exp $
33.\"
34.Dd April 19, 1994
35.Dt GETOPT 3
36.Os
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 known option character.
55An option character is
56.Dq known
57if it has been specified in the string of accepted option characters,
58.Fa optstring .
59.Pp
60The option string
61.Fa optstring
62may contain the following elements: individual characters and
63characters followed by a colon to indicate an option argument
64is to follow.
65For example, an option string
66.Qq x
67recognizes an option
68.Fl x ,
69and an option string
70.Qq Li x:
71recognizes an option and argument
72.Fl x Ar argument .
73It does not matter to
74.Fn getopt
75if a following argument has leading whitespace.
76.Pp
77On return from
78.Fn getopt ,
79.Va optarg
80points to an option argument, if it is anticipated,
81and the variable
82.Va optind
83contains the index to the next
84.Fa argv
85argument for a subsequent call
86to
87.Fn getopt .
88The variable
89.Va optopt
90saves the last known option character returned by
91.Fn getopt .
92.Pp
93The variables
94.Va opterr
95and
96.Va optind
97are both initialized to 1.
98The
99.Va optind
100variable may be set to another value before a set of calls to
101.Fn getopt
102in order to skip over more or less argv entries.
103.Pp
104In order to use
105.Fn getopt
106to evaluate multiple sets of arguments, or to evaluate a single set of
107arguments multiple times,
108the variable
109.Va optreset
110must be set to 1 before the second and each additional set of calls to
111.Fn getopt ,
112and the variable
113.Va optind
114must be reinitialized.
115.Pp
116The
117.Fn getopt
118function returns \-1 when the argument list is exhausted.
119The interpretation of options in the argument list may be cancelled
120by the option
121.Ql --
122(double dash) which causes
123.Fn getopt
124to signal the end of argument processing and returns \-1.
125When all options have been processed (i.e., up to the first non-option
126argument),
127.Fn getopt
128returns \-1.
129.Sh EXAMPLES
130.Bd -literal -compact
131int bflag, ch, fd;
132
133bflag = 0;
134while ((ch = getopt(argc, argv, "bf:")) != -1) {
135 switch (ch) {
136 case 'b':
137 bflag = 1;
138 break;
139 case 'f':
140 if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
141 (void)fprintf(stderr,
142 "myname: %s: %s\en", optarg, strerror(errno));
143 exit(1);
144 }
145 break;
146 case '?':
147 default:
148 usage();
149 }
150}
151argc -= optind;
152argv += optind;
153.Ed
154.Sh SEE ALSO
155.Xr getopt 1 ,
156.Xr getsubopt 3
157.Sh DIAGNOSTICS
158If the
159.Fn getopt
160function encounters a character not found in the string
161.Va optstring
162or detects
163a missing option argument it writes an error message to
164.Em stderr
165and returns
166.Ql ? .
167Setting
168.Va opterr
169to a zero will disable these error messages.
170If
171.Va optstring
172has a leading
173.Ql \&:
174then a missing option argument causes a
175.Ql \&:
176to be returned in addition to suppressing any error messages.
177.Pp
178Option arguments are allowed to begin with
179.Ql - ;
180this is reasonable but reduces the amount of error checking possible.
181.Sh EXTENSIONS
182The
183.Va optreset
184variable was added to make it possible to call the
185.Fn getopt
186function multiple times.
187This is an extension to the
188.St -p1003.2
189specification.
190.Sh HISTORY
191The
192.Fn getopt
193function appeared in
194.Bx 4.3 .
195.Sh BUGS
196The
197.Fn getopt
198function was once specified to return
199.Dv EOF
200instead of \-1.
201This was changed by
202.St -p1003.2-92
203to decouple
204.Fn getopt
205from
206.Pa <stdio.h> .
207.Pp
208A single dash
209.Pq Ql -
210may be specified as a character in
211.Fa optstring ,
212however it should
213.Em never
214have an argument associated with it.
215This allows
216.Fn getopt
217to be used with programs that expect
218.Ql -
219as an option flag.
220This practice is wrong, and should not be used in any current development.
221It is provided for backward compatibility
222.Em only .
223By default, a single dash causes
224.Fn getopt
225to return \-1.
226This is, we believe, compatible with System V.
227.Pp
228It is also possible to handle digits as option letters.
229This allows
230.Fn getopt
231to be used with programs that expect a number
232.Pq Dq Li \&-\&3
233as an option.
234This practice is wrong, and should not be used in any current development.
235It is provided for backward compatibility
236.Em only .
237The following code fragment works in most cases.
238.Bd -literal -offset indent
239long length;
240char *p;
241
242while ((c = getopt(argc, argv, "0123456789")) != -1) {
243 switch (c) {
244 case '0': case '1': case '2': case '3': case '4':
245 case '5': case '6': case '7': case '8': case '9':
246 p = argv[optind - 1];
247 if (p[0] == '-' && p[1] == ch && !p[2])
248 length = ch - '0';
249 else
250 length = strtol(argv[optind] + 1, NULL, 10);
251 break;
252 }
253}
254.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..8a17da4ea5
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,147 @@
1.\" $OpenBSD: getsubopt.3,v 1.5 2000/12/15 14:31:17 aaron 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 parses a string containing tokens delimited by one or more
51tab, space or comma
52.Pq Ql \&,
53characters.
54It is intended for use in parsing groups of option arguments provided
55as part of a utility command line.
56.Pp
57The argument
58.Fa optionp
59is a pointer to a pointer to the string.
60The argument
61.Fa tokens
62is a pointer to a null-terminated array of pointers to strings.
63.Pp
64The
65.Fn getsubopt
66function returns the zero-based offset of the pointer in the
67.Fa tokens
68array referencing a string which matches the first token
69in the string, or, \-1 if the string contains no tokens or
70.Fa tokens
71does not contain a matching string.
72.Pp
73If the token is of the form
74.Ar name Ns No = Ns Ar value ,
75the location referenced by
76.Fa valuep
77will be set to point to the start of the
78.Dq value
79portion 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 tokens were present.
91The argument
92.Fa valuep
93will be set to point to the value portion of the token, or
94.Dv NULL
95if no value portion was present.
96.Sh EXAMPLES
97.Bd -literal -compact
98char *tokens[] = {
99 #define ONE 0
100 "one",
101 #define TWO 1
102 "two",
103 NULL
104};
105
106\&...
107
108extern char *optarg, *suboptarg;
109char *options, *value;
110
111while ((ch = getopt(argc, argv, "ab:")) != \-1) {
112 switch(ch) {
113 case 'a':
114 /* process ``a'' option */
115 break;
116 case 'b':
117 options = optarg;
118 while (*options) {
119 switch(getsubopt(&options, tokens, &value)) {
120 case ONE:
121 /* process ``one'' sub option */
122 break;
123 case TWO:
124 /* process ``two'' sub option */
125 if (!value)
126 error("no value for two");
127 i = atoi(value);
128 break;
129 case \-1:
130 if (suboptarg)
131 error("illegal sub option %s",
132 suboptarg);
133 else
134 error("missing sub option");
135 break;
136 }
137 break;
138 }
139.Ed
140.Sh SEE ALSO
141.Xr getopt 3 ,
142.Xr strsep 3
143.Sh HISTORY
144The
145.Fn getsubopt
146function first appeared in
147.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..2770e5b977
--- /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.3 2002/02/16 21:27:24 millert 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)(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..fe39ca24dc
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.3
@@ -0,0 +1,64 @@
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.5 2000/04/20 13:50:02 aaron 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 returns the absolute value of the long integer
52.Fa j .
53.Sh SEE ALSO
54.Xr abs 3 ,
55.Xr cabs 3 ,
56.Xr floor 3 ,
57.Xr math 3
58.Sh STANDARDS
59The
60.Fn labs
61function conforms to
62.St -ansiC .
63.Sh BUGS
64The 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..b5301b1b21
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.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 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.5 2000/04/20 13:50:02 aaron 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 computes the value
52.Fa num Ns No / Ns Fa denom
53and returns the quotient and remainder in a structure named
54.Li ldiv_t
55that contains two
56.Li long integer
57members named
58.Fa quot
59and
60.Fa rem .
61.Sh SEE ALSO
62.Xr div 3 ,
63.Xr math 3 ,
64.Xr qdiv 3
65.Sh STANDARDS
66The
67.Fn ldiv
68function conforms to
69.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..8f05c38e86
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.3
@@ -0,0 +1,419 @@
1.\"
2.\" Copyright (c) 1980, 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.\" the American National Standards Committee X3, on Information
7.\" Processing Systems.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.\" $OpenBSD: malloc.3,v 1.24 2001/12/05 09:49:39 deraadt Exp $
38.\"
39.Dd August 27, 1996
40.Dt MALLOC 3
41.Os
42.Sh NAME
43.Nm malloc ,
44.Nm calloc ,
45.Nm realloc ,
46.Nm free ,
47.Nm cfree
48.Nd memory allocation and deallocation
49.Sh SYNOPSIS
50.Fd #include <stdlib.h>
51.Ft void *
52.Fn malloc "size_t size"
53.Ft void *
54.Fn calloc "size_t nmemb" "size_t size"
55.Ft void *
56.Fn realloc "void *ptr" "size_t size"
57.Ft void
58.Fn free "void *ptr"
59.Ft void
60.Fn cfree "void *ptr"
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.
77If the space is of
78.Em pagesize
79or larger, the memory returned will be page-aligned.
80.Pp
81Allocation of a zero size object returns a pointer to a zero size object.
82This zero size object is access protected, so any access to it will
83generate an exception (SIGSEGV).
84Many zero-sized objects can be placed consecutively in shared
85protected pages.
86The minimum size of the protection on each object is suitably aligned and
87sized as previously stated, but the protection may extend further depending
88on where in a protected zone the object lands.
89.Pp
90The
91.Fn calloc
92function allocates space for an array of
93.Fa nmemb
94objects, each of whose size is
95.Fa size .
96The space is initialized to all bits zero.
97.Pp
98The
99.Fn free
100function causes the space pointed to by
101.Fa ptr
102to be deallocated, that is, at least made available for further allocation,
103but if possible, it will passed back to the kernel with
104.Xr sbrk 2 .
105If
106.Fa ptr
107is a null pointer, no action occurs.
108.Pp
109A
110.Fn cfree
111function is also provided for compatibility with old systems and other
112.Nm malloc
113libraries; it is simply an alias for
114.Fn free .
115.Pp
116The
117.Fn realloc
118function changes the size of the object pointed to by
119.Fa ptr
120to
121.Fa size
122bytes and returns a pointer to the (possibly moved) object.
123The contents of the object are unchanged up to the lesser
124of the new and old sizes.
125If the new size is larger, the value of the newly allocated portion
126of the object is indeterminate and uninitialized.
127If
128.Fa ptr
129is a null pointer, the
130.Fn realloc
131function behaves like the
132.Fn malloc
133function for the specified size.
134If the space cannot be allocated, the object
135pointed to by
136.Fa ptr
137is unchanged.
138If
139.Fa size
140is zero and
141.Fa ptr
142is not a null pointer, the object it points to is freed and a new zero size
143object is returned.
144.Pp
145When using
146.Fn realloc
147one must be careful to avoid the following idiom:
148.Pp
149.Bd -literal -offset indent
150if ((p = realloc(p, nsize)) == NULL)
151 return NULL;
152.Ed
153.Pp
154In most cases, this will result in a leak of memory.
155As stated earlier, a return value of
156.Dv NULL
157indicates that the old object still remains allocated.
158Better code looks like this:
159.Bd -literal -offset indent
160if ((p2 = realloc(p, nsize)) == NULL) {
161 if (p)
162 free(p);
163 p = NULL;
164 return NULL;
165}
166p = p2;
167.Ed
168.Pp
169Malloc will first look for a symbolic link called
170.Pa /etc/malloc.conf
171and next check the environment for a variable called
172.Ev MALLOC_OPTIONS
173and finally for the global variable
174.Va malloc_options
175and scan them for flags in that order.
176Flags are single letters, uppercase means on, lowercase means off.
177.Bl -tag -width indent
178.It Cm A
179.Dq Abort .
180.Fn malloc
181will coredump the process, rather than tolerate failure.
182This is a very handy debugging aid, since the core file will represent the
183time of failure, rather than when the null pointer was accessed.
184.Pp
185.It Cm D
186.Dq Dump .
187.Fn malloc
188will dump statistics in a file called
189.Pa malloc.out
190at exit.
191This option requires the library to have been compiled with -DMALLOC_STATS in
192order to have any effect.
193.Pp
194.It Cm J
195.Dq Junk .
196Fill some junk into the area allocated.
197Currently junk is bytes of 0xd0; this is pronounced
198.Dq Duh .
199\&:-)
200.Pp
201.It Cm H
202.Dq Hint .
203Pass a hint to the kernel about pages we don't use.
204If the machine is paging a lot this may help a bit.
205.Pp
206.It Cm N
207Do not output warning messages when encountering possible corruption
208or bad pointers.
209.Pp
210.It Cm R
211.Dq realloc .
212Always reallocate when
213.Fn realloc
214is called, even if the initial allocation was big enough.
215This can substantially aid in compacting memory.
216.\".Pp
217.\".It Cm U
218.\".Dq utrace .
219.\"Generate entries for
220.\".Xr ktrace 1
221.\"for all operations.
222.\"Consult the source for this one.
223.Pp
224.It Cm X
225.Dq xmalloc .
226rather than return failure,
227.Xr abort 3
228the program with a diagnostic message on stderr.
229It is the intention that this option be set at compile time by
230including in the source:
231.Bd -literal -offset indent
232extern char *malloc_options;
233malloc_options = "X";
234.Ed
235.Pp
236.It Cm Z
237.Dq Zero .
238Fill some junk into the area allocated (see
239.Cm J ) ,
240except for the exact length the user asked for, which is zeroed.
241.Pp
242.It Cm <
243.Dq Half the cache size .
244Reduce the size of the cache by a factor of two.
245.Pp
246.It Cm >
247.Dq Double the cache size .
248Double the size of the cache by a factor of two.
249.El
250.Pp
251So to set a systemwide reduction of cache size and coredumps on problems
252one would:
253.Li ln -s 'A<' /etc/malloc.conf
254.Pp
255The
256.Cm J
257and
258.Cm Z
259is mostly for testing and debugging.
260If a program changes behavior if either of these options are used,
261it is buggy.
262.Pp
263The default cache size is 16 pages.
264.Sh ENVIRONMENT
265See above.
266.Sh RETURN VALUES
267The
268.Fn malloc
269and
270.Fn calloc
271functions return a pointer to the allocated space if successful; otherwise,
272a null pointer is returned and
273.Va errno
274is set to
275.Er ENOMEM .
276.Pp
277The
278.Fn free
279and
280.Fn cfree
281functions return no value.
282.Pp
283The
284.Fn realloc
285function returns a pointer to the (possibly moved) allocated space
286if successful; otherwise, a null pointer is returned and
287.Va errno
288is set to
289.Er ENOMEM .
290.Sh DIAGNOSTICS
291If
292.Fn malloc ,
293.Fn calloc ,
294.Fn realloc ,
295or
296.Fn free
297detect an error or warning condition,
298a message will be printed to file descriptor
2992 (not using stdio).
300Errors will always result in the process being
301.Xr abort 3 'ed.
302If the
303.Cm A
304option has been specified, warnings will also
305.Xr abort 3
306the process.
307.Pp
308Here is a brief description of the error messages and what they mean:
309.Bl -tag -width Fl
310.It Dq (ES): mumble mumble mumble
311.Fn malloc
312has been compiled with
313.Dv \&-DEXTRA_SANITY
314and something looks fishy in there.
315Consult sources and/or wizards.
316.It Dq allocation failed
317If the
318.Cm A
319option is specified it is an error for
320.Fn malloc ,
321.Fn calloc ,
322or
323.Fn realloc
324to return
325.Dv NULL .
326.It Dq mmap(2) failed, check limits.
327This is a rather weird condition that is most likely to indicate a
328seriously overloaded system or a
329.Xr ulimit 1
330restriction.
331.It Dq freelist is destroyed.
332.Fn malloc Ns 's
333internal freelist has been stomped on.
334.El
335.Pp
336Here is a brief description of the warning messages and what they mean:
337.Bl -tag -width Fl
338.It Dq chunk/page is already free.
339A pointer to a free chunk is attempted freed again.
340.It Dq junk pointer, too high to make sense.
341The pointer doesn't make sense.
342It's above the area of memory that
343.Fn malloc
344knows something about.
345This could be a pointer from some
346.Xr mmap 2 'ed
347memory.
348.It Dq junk pointer, too low to make sense.
349The pointer doesn't make sense.
350It's below the area of memory that
351.Fn malloc
352knows something about.
353This pointer probably came from your data or bss segments.
354.It Dq malloc() has never been called.
355Nothing has ever been allocated, yet something is being freed or
356realloc'ed.
357.It Dq modified (chunk-/page-) pointer.
358The pointer passed to free or realloc has been modified.
359.It Dq pointer to wrong page.
360The pointer that
361.Fn malloc
362is trying to free is not pointing to
363a sensible page.
364.It Dq recursive call.
365An attempt was made to call recursively into these functions, i.e., from a
366signal handler.
367This behavior is not supported.
368In particular, signal handlers should
369.Em not
370use any of the
371.Fn malloc
372functions nor utilize any other functions which may call
373.Fn malloc
374(e.g.,
375.Xr stdio 3
376routines).
377.It Dq unknown char in MALLOC_OPTIONS
378We found something we didn't understand.
379.El
380.Sh FILES
381.Bl -tag -width "/etc/malloc.conf"
382.It Pa /etc/malloc.conf
383symbolic link to filename containing option flags
384.El
385.Sh SEE ALSO
386.Xr brk 2 ,
387.Xr alloca 3 ,
388.Xr getpagesize 3 ,
389.Xr memory 3
390.Pa /usr/share/doc/papers/malloc.ascii.gz
391.Sh STANDARDS
392The
393.Fn malloc
394function conforms to
395.St -ansiC .
396.Sh HISTORY
397The present implementation of
398.Fn malloc
399started out as a filesystem on a drum
400attached to a 20-bit binary challenged computer built with discrete germanium
401transistors, and it has since graduated to handle primary storage rather than
402secondary.
403.Pp
404The main difference from other
405.Fn malloc
406implementations are believed to be that
407the free pages are not accessed until allocated.
408Most
409.Fn malloc
410implementations will store a data structure containing a,
411possibly double-, linked list in the free chunks of memory, used to tie
412all the free memory together.
413That is a quite suboptimal thing to do.
414Every time the free-list is traversed, all the otherwise unused, and very
415likely paged out, pages get faulted into primary memory, just to see what
416lies after them in the list.
417.Pp
418On systems which are paging, this can make a factor five in difference on the
419page-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..4e90ce402e
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1305 @@
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.48 2002/05/27 03:13:23 deraadt 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 <sys/types.h>
41#include <sys/param.h>
42#include <sys/mman.h>
43#include <sys/uio.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <unistd.h>
48#include <fcntl.h>
49#include <errno.h>
50
51/*
52 * The basic parameters you can tweak.
53 *
54 * malloc_pageshift pagesize = 1 << malloc_pageshift
55 * It's probably best if this is the native
56 * page size, but it shouldn't have to be.
57 *
58 * malloc_minsize minimum size of an allocation in bytes.
59 * If this is too small it's too much work
60 * to manage them. This is also the smallest
61 * unit of alignment used for the storage
62 * returned by malloc/realloc.
63 *
64 */
65
66#if defined(__OpenBSD__) && defined(__sparc__)
67# define malloc_pageshift 13U
68#endif /* __OpenBSD__ */
69
70#ifdef _THREAD_SAFE
71# include "thread_private.h"
72# if 0
73 /* kernel threads */
74# include <pthread.h>
75 static pthread_mutex_t malloc_lock;
76# define THREAD_LOCK() pthread_mutex_lock(&malloc_lock)
77# define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock)
78# define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0);
79# else
80 /* user threads */
81# include "spinlock.h"
82 static spinlock_t malloc_lock = _SPINLOCK_INITIALIZER;
83# define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&malloc_lock)
84# define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&malloc_lock)
85# define THREAD_LOCK_INIT()
86 /*
87 * Malloc can't use the wrapped write() if it fails very early, so
88 * we use the unwrapped syscall _thread_sys_write()
89 */
90# define write _thread_sys_write
91 ssize_t write(int, const void *, size_t);
92# undef malloc
93# undef realloc
94# undef free
95# endif
96#else
97 /* no threads */
98# define THREAD_LOCK()
99# define THREAD_UNLOCK()
100# define THREAD_LOCK_INIT()
101#endif
102
103/*
104 * No user serviceable parts behind this point.
105 *
106 * This structure describes a page worth of chunks.
107 */
108
109struct pginfo {
110 struct pginfo *next; /* next on the free list */
111 void *page; /* Pointer to the page */
112 u_short size; /* size of this page's chunks */
113 u_short shift; /* How far to shift for this size chunks */
114 u_short free; /* How many free chunks */
115 u_short total; /* How many chunk */
116 u_long bits[1]; /* Which chunks are free */
117};
118
119/*
120 * This structure describes a number of free pages.
121 */
122
123struct pgfree {
124 struct pgfree *next; /* next run of free pages */
125 struct pgfree *prev; /* prev run of free pages */
126 void *page; /* pointer to free pages */
127 void *end; /* pointer to end of free pages */
128 u_long size; /* number of bytes free */
129};
130
131/*
132 * How many bits per u_long in the bitmap.
133 * Change only if not 8 bits/byte
134 */
135#define MALLOC_BITS (8*sizeof(u_long))
136
137/*
138 * Magic values to put in the page_directory
139 */
140#define MALLOC_NOT_MINE ((struct pginfo*) 0)
141#define MALLOC_FREE ((struct pginfo*) 1)
142#define MALLOC_FIRST ((struct pginfo*) 2)
143#define MALLOC_FOLLOW ((struct pginfo*) 3)
144#define MALLOC_MAGIC ((struct pginfo*) 4)
145
146#ifndef malloc_pageshift
147#define malloc_pageshift (PGSHIFT)
148#endif
149
150#ifndef malloc_minsize
151#define malloc_minsize 16U
152#endif
153
154#ifndef malloc_pageshift
155#error "malloc_pageshift undefined"
156#endif
157
158#if !defined(malloc_pagesize)
159#define malloc_pagesize (1UL<<malloc_pageshift)
160#endif
161
162#if ((1UL<<malloc_pageshift) != malloc_pagesize)
163#error "(1UL<<malloc_pageshift) != malloc_pagesize"
164#endif
165
166#ifndef malloc_maxsize
167#define malloc_maxsize ((malloc_pagesize)>>1)
168#endif
169
170/* A mask for the offset inside a page. */
171#define malloc_pagemask ((malloc_pagesize)-1)
172
173#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
174#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
175
176/* fd of /dev/zero */
177#ifdef USE_DEV_ZERO
178static int fdzero;
179#define MMAP_FD fdzero
180#define INIT_MMAP() \
181 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
182 wrterror("open of /dev/zero"); }
183#else
184#define MMAP_FD (-1)
185#define INIT_MMAP()
186#endif
187
188/* Set when initialization has been done */
189static unsigned int malloc_started;
190
191/* Number of free pages we cache */
192static unsigned int malloc_cache = 16;
193
194/* The offset from pagenumber to index into the page directory */
195static u_long malloc_origo;
196
197/* The last index in the page directory we care about */
198static u_long last_index;
199
200/* Pointer to page directory. Allocated "as if with" malloc */
201static struct pginfo **page_dir;
202
203/* How many slots in the page directory */
204static size_t malloc_ninfo;
205
206/* Free pages line up here */
207static struct pgfree free_list;
208
209/* Abort(), user doesn't handle problems. */
210static int malloc_abort;
211
212/* Are we trying to die ? */
213static int suicide;
214
215#ifdef MALLOC_STATS
216/* dump statistics */
217static int malloc_stats;
218#endif
219
220/* avoid outputting warnings? */
221static int malloc_silent;
222
223/* always realloc ? */
224static int malloc_realloc;
225
226#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
227/* pass the kernel a hint on free pages ? */
228static int malloc_hint;
229#endif
230
231/* xmalloc behaviour ? */
232static int malloc_xmalloc;
233
234/* zero fill ? */
235static int malloc_zero;
236
237/* junk fill ? */
238static int malloc_junk;
239
240#ifdef __FreeBSD__
241/* utrace ? */
242static int malloc_utrace;
243
244struct ut { void *p; size_t s; void *r; };
245
246void utrace(struct ut *, int);
247
248#define UTRACE(a, b, c) \
249 if (malloc_utrace) \
250 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
251#else /* !__FreeBSD__ */
252#define UTRACE(a,b,c)
253#endif
254
255/* my last break. */
256static void *malloc_brk;
257
258/* one location cache for free-list holders */
259static struct pgfree *px;
260
261/* compile-time options */
262char *malloc_options;
263
264/* Name of the current public function */
265static char *malloc_func;
266
267/* Macro for mmap */
268#define MMAP(size) \
269 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
270 MMAP_FD, (off_t)0);
271
272/*
273 * Necessary function declarations
274 */
275static int extend_pgdir(u_long index);
276static void *imalloc(size_t size);
277static void ifree(void *ptr);
278static void *irealloc(void *ptr, size_t size);
279static void *malloc_bytes(size_t size);
280
281#ifdef MALLOC_STATS
282void
283malloc_dump(fd)
284 FILE *fd;
285{
286 struct pginfo **pd;
287 struct pgfree *pf;
288 int j;
289
290 pd = page_dir;
291
292 /* print out all the pages */
293 for(j=0;j<=last_index;j++) {
294 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
295 if (pd[j] == MALLOC_NOT_MINE) {
296 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
297 ;
298 j--;
299 fprintf(fd, ".. %5d not mine\n", j);
300 } else if (pd[j] == MALLOC_FREE) {
301 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
302 ;
303 j--;
304 fprintf(fd, ".. %5d free\n", j);
305 } else if (pd[j] == MALLOC_FIRST) {
306 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
307 ;
308 j--;
309 fprintf(fd, ".. %5d in use\n", j);
310 } else if (pd[j] < MALLOC_MAGIC) {
311 fprintf(fd, "(%p)\n", pd[j]);
312 } else {
313 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
314 pd[j], pd[j]->free, pd[j]->total,
315 pd[j]->size, pd[j]->page, pd[j]->next);
316 }
317 }
318
319 for(pf=free_list.next; pf; pf=pf->next) {
320 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
321 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
322 if (pf == pf->next) {
323 fprintf(fd, "Free_list loops.\n");
324 break;
325 }
326 }
327
328 /* print out various info */
329 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
330 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
331 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
332 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
333 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
334 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
335 (last_index + malloc_pageshift) << malloc_pageshift);
336 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
337}
338#endif /* MALLOC_STATS */
339
340extern char *__progname;
341
342static void
343wrterror(p)
344 char *p;
345{
346 char *q = " error: ";
347 struct iovec iov[4];
348
349 iov[0].iov_base = __progname;
350 iov[0].iov_len = strlen(__progname);
351 iov[1].iov_base = malloc_func;
352 iov[1].iov_len = strlen(malloc_func);
353 iov[2].iov_base = q;
354 iov[2].iov_len = strlen(q);
355 iov[3].iov_base = p;
356 iov[3].iov_len = strlen(p);
357 writev(STDERR_FILENO, iov, 4);
358
359 suicide = 1;
360#ifdef MALLOC_STATS
361 if (malloc_stats)
362 malloc_dump(stderr);
363#endif /* MALLOC_STATS */
364 abort();
365}
366
367static void
368wrtwarning(p)
369 char *p;
370{
371 char *q = " warning: ";
372 struct iovec iov[4];
373
374 if (malloc_abort)
375 wrterror(p);
376 else if (malloc_silent)
377 return;
378
379 iov[0].iov_base = __progname;
380 iov[0].iov_len = strlen(__progname);
381 iov[1].iov_base = malloc_func;
382 iov[1].iov_len = strlen(malloc_func);
383 iov[2].iov_base = q;
384 iov[2].iov_len = strlen(q);
385 iov[3].iov_base = p;
386 iov[3].iov_len = strlen(p);
387 writev(STDERR_FILENO, iov, 4);
388}
389
390#ifdef MALLOC_STATS
391static void
392malloc_exit()
393{
394 FILE *fd = fopen("malloc.out", "a");
395 char *q = "malloc() warning: Couldn't dump stats.\n";
396 if (fd) {
397 malloc_dump(fd);
398 fclose(fd);
399 } else
400 write(2, q, strlen(q));
401}
402#endif /* MALLOC_STATS */
403
404
405/*
406 * Allocate a number of pages from the OS
407 */
408static void *
409map_pages(pages)
410 int pages;
411{
412 caddr_t result, tail;
413
414 result = (caddr_t)pageround((u_long)sbrk(0));
415 tail = result + (pages << malloc_pageshift);
416
417 if (brk(tail)) {
418#ifdef MALLOC_EXTRA_SANITY
419 wrterror("(ES): map_pages fails\n");
420#endif /* MALLOC_EXTRA_SANITY */
421 return 0;
422 }
423
424 last_index = ptr2index(tail) - 1;
425 malloc_brk = tail;
426
427 if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
428 return 0;
429
430 return result;
431}
432
433/*
434 * Extend page directory
435 */
436static int
437extend_pgdir(index)
438 u_long index;
439{
440 struct pginfo **new, **old;
441 size_t i, oldlen;
442
443 /* Make it this many pages */
444 i = index * sizeof *page_dir;
445 i /= malloc_pagesize;
446 i += 2;
447
448 /* remember the old mapping size */
449 oldlen = malloc_ninfo * sizeof *page_dir;
450
451 /*
452 * NOTE: we allocate new pages and copy the directory rather than tempt
453 * fate by trying to "grow" the region.. There is nothing to prevent
454 * us from accidently re-mapping space that's been allocated by our caller
455 * via dlopen() or other mmap().
456 *
457 * The copy problem is not too bad, as there is 4K of page index per
458 * 4MB of malloc arena.
459 *
460 * We can totally avoid the copy if we open a file descriptor to associate
461 * the anon mappings with. Then, when we remap the pages at the new
462 * address, the old pages will be "magically" remapped.. But this means
463 * keeping open a "secret" file descriptor.....
464 */
465
466 /* Get new pages */
467 new = (struct pginfo**) MMAP(i * malloc_pagesize);
468 if (new == MAP_FAILED)
469 return 0;
470
471 /* Copy the old stuff */
472 memcpy(new, page_dir,
473 malloc_ninfo * sizeof *page_dir);
474
475 /* register the new size */
476 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
477
478 /* swap the pointers */
479 old = page_dir;
480 page_dir = new;
481
482 /* Now free the old stuff */
483 munmap(old, oldlen);
484 return 1;
485}
486
487/*
488 * Initialize the world
489 */
490static void
491malloc_init ()
492{
493 char *p, b[64];
494 int i, j;
495 int save_errno = errno;
496
497 THREAD_LOCK_INIT();
498
499 INIT_MMAP();
500
501#ifdef MALLOC_EXTRA_SANITY
502 malloc_junk = 1;
503#endif /* MALLOC_EXTRA_SANITY */
504
505 for (i = 0; i < 3; i++) {
506 if (i == 0) {
507 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
508 if (j <= 0)
509 continue;
510 b[j] = '\0';
511 p = b;
512 } else if (i == 1) {
513 if (issetugid() == 0)
514 p = getenv("MALLOC_OPTIONS");
515 else
516 continue;
517 } else if (i == 2) {
518 p = malloc_options;
519 }
520 for (; p && *p; p++) {
521 switch (*p) {
522 case '>': malloc_cache <<= 1; break;
523 case '<': malloc_cache >>= 1; break;
524 case 'a': malloc_abort = 0; break;
525 case 'A': malloc_abort = 1; break;
526#ifdef MALLOC_STATS
527 case 'd': malloc_stats = 0; break;
528 case 'D': malloc_stats = 1; break;
529#endif /* MALLOC_STATS */
530#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
531 case 'h': malloc_hint = 0; break;
532 case 'H': malloc_hint = 1; break;
533#endif /* __FreeBSD__ */
534 case 'r': malloc_realloc = 0; break;
535 case 'R': malloc_realloc = 1; break;
536 case 'j': malloc_junk = 0; break;
537 case 'J': malloc_junk = 1; break;
538 case 'n': malloc_silent = 0; break;
539 case 'N': malloc_silent = 1; break;
540#ifdef __FreeBSD__
541 case 'u': malloc_utrace = 0; break;
542 case 'U': malloc_utrace = 1; break;
543#endif /* __FreeBSD__ */
544 case 'x': malloc_xmalloc = 0; break;
545 case 'X': malloc_xmalloc = 1; break;
546 case 'z': malloc_zero = 0; break;
547 case 'Z': malloc_zero = 1; break;
548 default:
549 j = malloc_abort;
550 malloc_abort = 0;
551 wrtwarning("unknown char in MALLOC_OPTIONS\n");
552 malloc_abort = j;
553 break;
554 }
555 }
556 }
557
558 UTRACE(0, 0, 0);
559
560 /*
561 * We want junk in the entire allocation, and zero only in the part
562 * the user asked for.
563 */
564 if (malloc_zero)
565 malloc_junk=1;
566
567#ifdef MALLOC_STATS
568 if (malloc_stats)
569 atexit(malloc_exit);
570#endif /* MALLOC_STATS */
571
572 /* Allocate one page for the page directory */
573 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
574
575 if (page_dir == MAP_FAILED)
576 wrterror("mmap(2) failed, check limits.\n");
577
578 /*
579 * We need a maximum of malloc_pageshift buckets, steal these from the
580 * front of the page_directory;
581 */
582 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
583 malloc_origo -= malloc_pageshift;
584
585 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
586
587 /* Been here, done that */
588 malloc_started++;
589
590 /* Recalculate the cache size in bytes, and make sure it's nonzero */
591
592 if (!malloc_cache)
593 malloc_cache++;
594
595 malloc_cache <<= malloc_pageshift;
596
597 /*
598 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
599 * We can sbrk(2) further back when we keep this on a low address.
600 */
601 px = (struct pgfree *) imalloc (sizeof *px);
602 errno = save_errno;
603}
604
605/*
606 * Allocate a number of complete pages
607 */
608static void *
609malloc_pages(size)
610 size_t size;
611{
612 void *p, *delay_free = 0;
613 int i;
614 struct pgfree *pf;
615 u_long index;
616
617 size = pageround(size);
618
619 p = 0;
620 /* Look for free pages before asking for more */
621 for(pf = free_list.next; pf; pf = pf->next) {
622
623#ifdef MALLOC_EXTRA_SANITY
624 if (pf->size & malloc_pagemask)
625 wrterror("(ES): junk length entry on free_list\n");
626 if (!pf->size)
627 wrterror("(ES): zero length entry on free_list\n");
628 if (pf->page == pf->end)
629 wrterror("(ES): zero entry on free_list\n");
630 if (pf->page > pf->end)
631 wrterror("(ES): sick entry on free_list\n");
632 if ((void*)pf->page >= (void*)sbrk(0))
633 wrterror("(ES): entry on free_list past brk\n");
634 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
635 wrterror("(ES): non-free first page on free-list\n");
636 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
637 wrterror("(ES): non-free last page on free-list\n");
638#endif /* MALLOC_EXTRA_SANITY */
639
640 if (pf->size < size)
641 continue;
642
643 if (pf->size == size) {
644 p = pf->page;
645 if (pf->next)
646 pf->next->prev = pf->prev;
647 pf->prev->next = pf->next;
648 delay_free = pf;
649 break;
650 }
651
652 p = pf->page;
653 pf->page = (char *)pf->page + size;
654 pf->size -= size;
655 break;
656 }
657
658#ifdef MALLOC_EXTRA_SANITY
659 if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
660 wrterror("(ES): allocated non-free page on free-list\n");
661#endif /* MALLOC_EXTRA_SANITY */
662
663 size >>= malloc_pageshift;
664
665 /* Map new pages */
666 if (!p)
667 p = map_pages(size);
668
669 if (p) {
670
671 index = ptr2index(p);
672 page_dir[index] = MALLOC_FIRST;
673 for (i=1;i<size;i++)
674 page_dir[index+i] = MALLOC_FOLLOW;
675
676 if (malloc_junk)
677 memset(p, SOME_JUNK, size << malloc_pageshift);
678 }
679
680 if (delay_free) {
681 if (!px)
682 px = delay_free;
683 else
684 ifree(delay_free);
685 }
686
687 return p;
688}
689
690/*
691 * Allocate a page of fragments
692 */
693
694static __inline__ int
695malloc_make_chunks(bits)
696 int bits;
697{
698 struct pginfo *bp;
699 void *pp;
700 int i, k, l;
701
702 /* Allocate a new bucket */
703 pp = malloc_pages((size_t)malloc_pagesize);
704 if (!pp)
705 return 0;
706
707 /* Find length of admin structure */
708 l = sizeof *bp - sizeof(u_long);
709 l += sizeof(u_long) *
710 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
711
712 /* Don't waste more than two chunks on this */
713 /*
714 * If we are to allocate a memory protected page for the malloc(0)
715 * case (when bits=0), it must be from a different page than the
716 * pginfo page.
717 * --> Treat it like the big chunk alloc, get a second data page.
718 */
719 if (bits != 0 && (1UL<<(bits)) <= l+l) {
720 bp = (struct pginfo *)pp;
721 } else {
722 bp = (struct pginfo *)imalloc(l);
723 if (!bp) {
724 ifree(pp);
725 return 0;
726 }
727 }
728
729 /* memory protect the page allocated in the malloc(0) case */
730 if (bits == 0) {
731
732 bp->size = 0;
733 bp->shift = 1;
734 i = malloc_minsize-1;
735 while (i >>= 1)
736 bp->shift++;
737 bp->total = bp->free = malloc_pagesize >> bp->shift;
738 bp->page = pp;
739
740 k = mprotect(pp, malloc_pagesize, PROT_NONE);
741 if (k < 0) {
742 ifree(pp);
743 ifree(bp);
744 return 0;
745 }
746 } else {
747 bp->size = (1UL<<bits);
748 bp->shift = bits;
749 bp->total = bp->free = malloc_pagesize >> bits;
750 bp->page = pp;
751 }
752
753 /* set all valid bits in the bitmap */
754 k = bp->total;
755 i = 0;
756
757 /* Do a bunch at a time */
758 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
759 bp->bits[i / MALLOC_BITS] = ~0UL;
760
761 for(; i < k; i++)
762 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
763
764 if (bp == bp->page) {
765 /* Mark the ones we stole for ourselves */
766 for(i=0;l > 0;i++) {
767 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
768 bp->free--;
769 bp->total--;
770 l -= (1 << bits);
771 }
772 }
773
774 /* MALLOC_LOCK */
775
776 page_dir[ptr2index(pp)] = bp;
777
778 bp->next = page_dir[bits];
779 page_dir[bits] = bp;
780
781 /* MALLOC_UNLOCK */
782
783 return 1;
784}
785
786/*
787 * Allocate a fragment
788 */
789static void *
790malloc_bytes(size)
791 size_t size;
792{
793 int i,j;
794 u_long u;
795 struct pginfo *bp;
796 int k;
797 u_long *lp;
798
799 /* Don't bother with anything less than this */
800 /* unless we have a malloc(0) requests */
801 if (size != 0 && size < malloc_minsize)
802 size = malloc_minsize;
803
804 /* Find the right bucket */
805 if (size == 0)
806 j=0;
807 else {
808 j = 1;
809 i = size-1;
810 while (i >>= 1)
811 j++;
812 }
813
814 /* If it's empty, make a page more of that size chunks */
815 if (!page_dir[j] && !malloc_make_chunks(j))
816 return 0;
817
818 bp = page_dir[j];
819
820 /* Find first word of bitmap which isn't empty */
821 for (lp = bp->bits; !*lp; lp++)
822 ;
823
824 /* Find that bit, and tweak it */
825 u = 1;
826 k = 0;
827 while (!(*lp & u)) {
828 u += u;
829 k++;
830 }
831 *lp ^= u;
832
833 /* If there are no more free, remove from free-list */
834 if (!--bp->free) {
835 page_dir[j] = bp->next;
836 bp->next = 0;
837 }
838
839 /* Adjust to the real offset of that chunk */
840 k += (lp-bp->bits)*MALLOC_BITS;
841 k <<= bp->shift;
842
843 if (malloc_junk && bp->size != 0)
844 memset((char *)bp->page + k, SOME_JUNK, bp->size);
845
846 return (u_char *)bp->page + k;
847}
848
849/*
850 * Allocate a piece of memory
851 */
852static void *
853imalloc(size)
854 size_t size;
855{
856 void *result;
857
858 if (!malloc_started)
859 malloc_init();
860
861 if (suicide)
862 abort();
863
864 if ((size + malloc_pagesize) < size) /* Check for overflow */
865 result = 0;
866 else if (size <= malloc_maxsize)
867 result = malloc_bytes(size);
868 else
869 result = malloc_pages(size);
870
871 if (malloc_abort && !result)
872 wrterror("allocation failed.\n");
873
874 if (malloc_zero && result)
875 memset(result, 0, size);
876
877 return result;
878}
879
880/*
881 * Change the size of an allocation.
882 */
883static void *
884irealloc(ptr, size)
885 void *ptr;
886 size_t size;
887{
888 void *p;
889 u_long osize, index;
890 struct pginfo **mp;
891 int i;
892
893 if (suicide)
894 abort();
895
896 if (!malloc_started) {
897 wrtwarning("malloc() has never been called.\n");
898 return 0;
899 }
900
901 index = ptr2index(ptr);
902
903 if (index < malloc_pageshift) {
904 wrtwarning("junk pointer, too low to make sense.\n");
905 return 0;
906 }
907
908 if (index > last_index) {
909 wrtwarning("junk pointer, too high to make sense.\n");
910 return 0;
911 }
912
913 mp = &page_dir[index];
914
915 if (*mp == MALLOC_FIRST) { /* Page allocation */
916
917 /* Check the pointer */
918 if ((u_long)ptr & malloc_pagemask) {
919 wrtwarning("modified (page-) pointer.\n");
920 return 0;
921 }
922
923 /* Find the size in bytes */
924 for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
925 osize += malloc_pagesize;
926
927 if (!malloc_realloc && /* unless we have to, */
928 size <= osize && /* .. or are too small, */
929 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
930 return ptr; /* don't do anything. */
931 }
932
933 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
934
935 /* Check the pointer for sane values */
936 if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) {
937 wrtwarning("modified (chunk-) pointer.\n");
938 return 0;
939 }
940
941 /* Find the chunk index in the page */
942 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
943
944 /* Verify that it isn't a free chunk already */
945 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
946 wrtwarning("chunk is already free.\n");
947 return 0;
948 }
949
950 osize = (*mp)->size;
951
952 if (!malloc_realloc && /* Unless we have to, */
953 size < osize && /* ..or are too small, */
954 (size > osize/2 || /* ..or could use a smaller size, */
955 osize == malloc_minsize)) { /* ..(if there is one) */
956 return ptr; /* ..Don't do anything */
957 }
958
959 } else {
960 wrtwarning("pointer to wrong page.\n");
961 return 0;
962 }
963
964 p = imalloc(size);
965
966 if (p) {
967 /* copy the lesser of the two sizes, and free the old one */
968 /* Don't move from/to 0 sized region !!! */
969 if (osize != 0 && size != 0) {
970 if (osize < size)
971 memcpy(p, ptr, osize);
972 else
973 memcpy(p, ptr, size);
974 }
975 ifree(ptr);
976 }
977 return p;
978}
979
980/*
981 * Free a sequence of pages
982 */
983
984static __inline__ void
985free_pages(ptr, index, info)
986 void *ptr;
987 int index;
988 struct pginfo *info;
989{
990 int i;
991 struct pgfree *pf, *pt=0;
992 u_long l;
993 void *tail;
994
995 if (info == MALLOC_FREE) {
996 wrtwarning("page is already free.\n");
997 return;
998 }
999
1000 if (info != MALLOC_FIRST) {
1001 wrtwarning("pointer to wrong page.\n");
1002 return;
1003 }
1004
1005 if ((u_long)ptr & malloc_pagemask) {
1006 wrtwarning("modified (page-) pointer.\n");
1007 return;
1008 }
1009
1010 /* Count how many pages and mark them free at the same time */
1011 page_dir[index] = MALLOC_FREE;
1012 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
1013 page_dir[index + i] = MALLOC_FREE;
1014
1015 l = i << malloc_pageshift;
1016
1017 if (malloc_junk)
1018 memset(ptr, SOME_JUNK, l);
1019
1020#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
1021 if (malloc_hint)
1022 madvise(ptr, l, MADV_FREE);
1023#endif
1024
1025 tail = (char *)ptr+l;
1026
1027 /* add to free-list */
1028 if (!px)
1029 px = imalloc(sizeof *px); /* This cannot fail... */
1030 px->page = ptr;
1031 px->end = tail;
1032 px->size = l;
1033 if (!free_list.next) {
1034
1035 /* Nothing on free list, put this at head */
1036 px->next = free_list.next;
1037 px->prev = &free_list;
1038 free_list.next = px;
1039 pf = px;
1040 px = 0;
1041
1042 } else {
1043
1044 /* Find the right spot, leave pf pointing to the modified entry. */
1045 tail = (char *)ptr+l;
1046
1047 for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
1048 ; /* Race ahead here */
1049
1050 if (pf->page > tail) {
1051 /* Insert before entry */
1052 px->next = pf;
1053 px->prev = pf->prev;
1054 pf->prev = px;
1055 px->prev->next = px;
1056 pf = px;
1057 px = 0;
1058 } else if (pf->end == ptr ) {
1059 /* Append to the previous entry */
1060 pf->end = (char *)pf->end + l;
1061 pf->size += l;
1062 if (pf->next && pf->end == pf->next->page ) {
1063 /* And collapse the next too. */
1064 pt = pf->next;
1065 pf->end = pt->end;
1066 pf->size += pt->size;
1067 pf->next = pt->next;
1068 if (pf->next)
1069 pf->next->prev = pf;
1070 }
1071 } else if (pf->page == tail) {
1072 /* Prepend to entry */
1073 pf->size += l;
1074 pf->page = ptr;
1075 } else if (!pf->next) {
1076 /* Append at tail of chain */
1077 px->next = 0;
1078 px->prev = pf;
1079 pf->next = px;
1080 pf = px;
1081 px = 0;
1082 } else {
1083 wrterror("freelist is destroyed.\n");
1084 }
1085 }
1086
1087 /* Return something to OS ? */
1088 if (!pf->next && /* If we're the last one, */
1089 pf->size > malloc_cache && /* ..and the cache is full, */
1090 pf->end == malloc_brk && /* ..and none behind us, */
1091 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1092
1093 /*
1094 * Keep the cache intact. Notice that the '>' above guarantees that
1095 * the pf will always have at least one page afterwards.
1096 */
1097 pf->end = (char *)pf->page + malloc_cache;
1098 pf->size = malloc_cache;
1099
1100 brk(pf->end);
1101 malloc_brk = pf->end;
1102
1103 index = ptr2index(pf->end);
1104 last_index = index - 1;
1105
1106 for(i=index;i <= last_index;)
1107 page_dir[i++] = MALLOC_NOT_MINE;
1108
1109 /* XXX: We could realloc/shrink the pagedir here I guess. */
1110 }
1111 if (pt)
1112 ifree(pt);
1113}
1114
1115/*
1116 * Free a chunk, and possibly the page it's on, if the page becomes empty.
1117 */
1118
1119/* ARGSUSED */
1120static __inline__ void
1121free_bytes(ptr, index, info)
1122 void *ptr;
1123 int index;
1124 struct pginfo *info;
1125{
1126 int i;
1127 struct pginfo **mp;
1128 void *vp;
1129
1130 /* Find the chunk number on the page */
1131 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
1132
1133 if ((u_long)ptr & ((1UL<<(info->shift))-1)) {
1134 wrtwarning("modified (chunk-) pointer.\n");
1135 return;
1136 }
1137
1138 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
1139 wrtwarning("chunk is already free.\n");
1140 return;
1141 }
1142
1143 if (malloc_junk && info->size != 0)
1144 memset(ptr, SOME_JUNK, info->size);
1145
1146 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
1147 info->free++;
1148
1149 if (info->size != 0)
1150 mp = page_dir + info->shift;
1151 else
1152 mp = page_dir;
1153
1154 if (info->free == 1) {
1155
1156 /* Page became non-full */
1157
1158 /* Insert in address order */
1159 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
1160 mp = &(*mp)->next;
1161 info->next = *mp;
1162 *mp = info;
1163 return;
1164 }
1165
1166 if (info->free != info->total)
1167 return;
1168
1169 /* Find & remove this page in the queue */
1170 while (*mp != info) {
1171 mp = &((*mp)->next);
1172#ifdef MALLOC_EXTRA_SANITY
1173 if (!*mp)
1174 wrterror("(ES): Not on queue\n");
1175#endif /* MALLOC_EXTRA_SANITY */
1176 }
1177 *mp = info->next;
1178
1179 /* Free the page & the info structure if need be */
1180 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
1181
1182 /* If the page was mprotected, unprotect it before releasing it */
1183 if (info->size == 0) {
1184 mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
1185 /* Do we have to care if mprotect succeeds here ? */
1186 }
1187
1188 vp = info->page; /* Order is important ! */
1189 if(vp != (void*)info)
1190 ifree(info);
1191 ifree(vp);
1192}
1193
1194static void
1195ifree(ptr)
1196 void *ptr;
1197{
1198 struct pginfo *info;
1199 int index;
1200
1201 /* This is legal */
1202 if (!ptr)
1203 return;
1204
1205 if (!malloc_started) {
1206 wrtwarning("malloc() has never been called.\n");
1207 return;
1208 }
1209
1210 /* If we're already sinking, don't make matters any worse. */
1211 if (suicide)
1212 return;
1213
1214 index = ptr2index(ptr);
1215
1216 if (index < malloc_pageshift) {
1217 wrtwarning("junk pointer, too low to make sense.\n");
1218 return;
1219 }
1220
1221 if (index > last_index) {
1222 wrtwarning("junk pointer, too high to make sense.\n");
1223 return;
1224 }
1225
1226 info = page_dir[index];
1227
1228 if (info < MALLOC_MAGIC)
1229 free_pages(ptr, index, info);
1230 else
1231 free_bytes(ptr, index, info);
1232 return;
1233}
1234
1235/*
1236 * These are the public exported interface routines.
1237 */
1238
1239static int malloc_active;
1240
1241void *
1242malloc(size_t size)
1243{
1244 register void *r;
1245
1246 malloc_func = " in malloc():";
1247 THREAD_LOCK();
1248 if (malloc_active++) {
1249 wrtwarning("recursive call.\n");
1250 malloc_active--;
1251 THREAD_UNLOCK();
1252 return (0);
1253 }
1254 r = imalloc(size);
1255 UTRACE(0, size, r);
1256 malloc_active--;
1257 THREAD_UNLOCK();
1258 if (malloc_xmalloc && !r)
1259 wrterror("out of memory.\n");
1260 return (r);
1261}
1262
1263void
1264free(void *ptr)
1265{
1266 malloc_func = " in free():";
1267 THREAD_LOCK();
1268 if (malloc_active++) {
1269 wrtwarning("recursive call.\n");
1270 malloc_active--;
1271 THREAD_UNLOCK();
1272 return;
1273 }
1274 ifree(ptr);
1275 UTRACE(ptr, 0, 0);
1276 malloc_active--;
1277 THREAD_UNLOCK();
1278 return;
1279}
1280
1281void *
1282realloc(void *ptr, size_t size)
1283{
1284 register void *r;
1285
1286 malloc_func = " in realloc():";
1287 THREAD_LOCK();
1288 if (malloc_active++) {
1289 wrtwarning("recursive call.\n");
1290 malloc_active--;
1291 THREAD_UNLOCK();
1292 return (0);
1293 }
1294 if (!ptr) {
1295 r = imalloc(size);
1296 } else {
1297 r = irealloc(ptr, size);
1298 }
1299 UTRACE(ptr, size, r);
1300 malloc_active--;
1301 THREAD_UNLOCK();
1302 if (malloc_xmalloc && !r)
1303 wrterror("out of memory.\n");
1304 return (r);
1305}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000000..959a173a03
--- /dev/null
+++ b/src/lib/libc/stdlib/memory.3
@@ -0,0 +1,69 @@
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.5 2000/04/20 13:50:02 aaron Exp $
33.\"
34.Dd May 2, 1991
35.Dt MEMORY 3
36.Os
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 individual man pages.
59.Sh SEE ALSO
60.Xr alloca 3 ,
61.Xr calloc 3 ,
62.Xr free 3 ,
63.Xr malloc 3 ,
64.Xr realloc 3
65.Sh STANDARDS
66These functions, with the exception of
67.Fn alloca ,
68conform to
69.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000000..4ae6488af2
--- /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.5 2002/02/17 19:42:24 millert 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(u_char *, u_char *, size_t, size_t, int (*)());
62static void insertionsort(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)(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)(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)(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..6f08bbe342
--- /dev/null
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -0,0 +1,124 @@
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.3 2002/02/19 19:39:37 millert 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
76wctomb(char *s, wchar_t wchar)
77{
78 if (s == NULL)
79 return 0;
80
81 *s = (char) wchar;
82 return 1;
83}
84
85/*ARGSUSED*/
86size_t
87mbstowcs(pwcs, s, n)
88 wchar_t *pwcs;
89 const char *s;
90 size_t n;
91{
92 int count = 0;
93
94 if (n != 0) {
95 do {
96 if ((*pwcs++ = (wchar_t) *s++) == 0)
97 break;
98 count++;
99 } while (--n != 0);
100 }
101
102 return count;
103}
104
105/*ARGSUSED*/
106size_t
107wcstombs(s, pwcs, n)
108 char *s;
109 const wchar_t *pwcs;
110 size_t n;
111{
112 int count = 0;
113
114 if (n != 0) {
115 do {
116 if ((*s++ = (char) *pwcs++) == 0)
117 break;
118 count++;
119 } while (--n != 0);
120 }
121
122 return count;
123}
124
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..ef0307ab25
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.3
@@ -0,0 +1,60 @@
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.5 2000/04/20 13:50:02 aaron 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 returns the absolute value of the quad integer
52.Fa j .
53.Sh SEE ALSO
54.Xr abs 3 ,
55.Xr cabs 3 ,
56.Xr floor 3 ,
57.Xr labs 3 ,
58.Xr math 3
59.Sh BUGS
60The 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..4db47d9b4a
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -0,0 +1,64 @@
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.4 2000/12/24 00:31:00 aaron 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 computes the value
52.Fa num Ns No / Ns Fa denom
53and returns the quotient and remainder in a structure named
54.Li qdiv_t
55that contains two
56.Li quad integer
57members named
58.Fa quot
59and
60.Fa rem .
61.Sh SEE ALSO
62.Xr div 3 ,
63.Xr ldiv 3 ,
64.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..6c4eba46bf
--- /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.9 2002/02/23 19:51:46 miod Exp $
37.\"
38.Dd June 4, 1993
39.Dt QSORT 3
40.Os
41.Sh NAME
42.Nm qsort ,
43.Nm heapsort ,
44.Nm mergesort
45.Nd sort functions
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft void
49.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
50.Ft int
51.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
52.Ft int
53.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
54.Sh DESCRIPTION
55The
56.Fn qsort
57function is a modified partition-exchange sort, or quicksort.
58The
59.Fn heapsort
60function is a modified selection sort.
61The
62.Fn mergesort
63function is a modified merge sort with exponential search
64intended for sorting data with pre-existing order.
65.Pp
66The
67.Fn qsort
68and
69.Fn heapsort
70functions sort an array of
71.Fa nmemb
72objects, the initial member of which is pointed to by
73.Fa base .
74The size of each object is specified by
75.Fa size .
76.Fn mergesort
77behaves similarly, but
78.Em requires
79that
80.Fa size
81be greater than
82.Dq "sizeof(void *) / 2" .
83.Pp
84The contents of the array
85.Fa base
86are sorted in ascending order according to
87a comparison function pointed to by
88.Fa compar ,
89which requires two arguments pointing to the objects being
90compared.
91.Pp
92The comparison function must return an integer less than, equal to, or
93greater than zero if the first argument is considered to be respectively
94less than, equal to, or greater than the second.
95.Pp
96The functions
97.Fn qsort
98and
99.Fn heapsort
100are
101.Em not
102stable, that is, if two members compare as equal, their order in
103the sorted array is undefined.
104The function
105.Fn mergesort
106is stable.
107.Pp
108The
109.Fn qsort
110function is an implementation of C.A.R. Hoare's
111.Dq quicksort
112algorithm,
113a variant of partition-exchange sorting; in particular, see D.E. Knuth's
114Algorithm Q.
115.Fn qsort
116takes O N lg N average time.
117This implementation uses median selection to avoid its
118O N**2 worst-case behavior.
119.Pp
120The
121.Fn heapsort
122function is an implementation of J.W.J. William's
123.Dq heapsort
124algorithm,
125a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
126.Fn heapsort
127takes O N lg N worst-case time.
128This implementation of
129.Fn qsort
130is implemented without recursive function calls.
131.Pp
132The function
133.Fn mergesort
134requires additional memory of size
135.Fa nmemb *
136.Fa size
137bytes; it should be used only when space is not at a premium.
138.Fn mergesort
139is optimized for data with pre-existing order; its worst case
140time is O N lg N; its best case is O N.
141.Pp
142Normally,
143.Fn qsort
144is faster than
145.Fn mergesort ,
146which is faster than
147.Fn heapsort .
148Memory availability and pre-existing order in the data can make this untrue.
149.Sh RETURN VALUES
150The
151.Fn qsort
152function returns 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
165and
166.Fn mergesort
167functions succeed unless:
168.Bl -tag -width Er
169.It Bq Er EINVAL
170The
171.Fa size
172argument is zero, or the
173.Fa size
174argument to
175.Fn mergesort
176is less than
177.Dq "sizeof(void *) / 2" .
178.It Bq Er ENOMEM
179.Fn heapsort
180or
181.Fn mergesort
182were unable to allocate memory.
183.El
184.Sh COMPATIBILITY
185Previous versions of
186.Fn qsort
187did not permit the comparison routine itself to call
188.Fn qsort 3 .
189This is no longer true.
190.Sh SEE ALSO
191.Xr sort 1 ,
192.Xr radixsort 3
193.Rs
194.%A Hoare, C.A.R.
195.%D 1962
196.%T "Quicksort"
197.%J "The Computer Journal"
198.%V 5:1
199.%P pp. 10-15
200.Re
201.Rs
202.%A Williams, J.W.J
203.%D 1964
204.%T "Heapsort"
205.%J "Communications of the ACM"
206.%V 7:1
207.%P pp. 347-348
208.Re
209.Rs
210.%A Knuth, D.E.
211.%D 1968
212.%B "The Art of Computer Programming"
213.%V Vol. 3
214.%T "Sorting and Searching"
215.%P pp. 114-123, 145-149
216.Re
217.Rs
218.%A Mcilroy, P.M.
219.%T "Optimistic Sorting and Information Theoretic Complexity"
220.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
221.%V January 1992
222.Re
223.Rs
224.%A Bentley, J.L.
225.%T "Engineering a Sort Function"
226.%J "bentley@research.att.com"
227.%V January 1992
228.Re
229.Sh STANDARDS
230The
231.Fn qsort
232function conforms 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..9b8bb5801b
--- /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.7 2002/02/17 19:42:24 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static __inline char *med3(char *, char *, char *, int (*)());
42static __inline void swapfunc(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..f70990fa8e
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,156 @@
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.7 2001/08/06 10:42:26 mpech 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 are implementations of radix sort.
53.Pp
54These functions sort an array of pointers to byte strings, the initial
55member of which is referenced by
56.Fa base .
57The byte strings may contain any values; the end of each string
58is denoted by the user-specified value
59.Fa endbyte .
60.Pp
61Applications may specify a sort order by providing the
62.Fa table
63argument.
64If non-null,
65.Fa table
66must reference an array of
67.Dv UCHAR_MAX
68+ 1 bytes which contains the sort weight of each possible byte value.
69The end-of-string byte must have a sort weight of 0 or 255
70(for sorting in reverse order).
71More than one byte may have the same sort weight.
72The
73.Fa table
74argument is useful for applications which wish to sort different characters
75equally, for example, providing a table with the same weights
76for A-Z as for a-z will result in a case-insensitive sort.
77If
78.Fa table
79is
80.Dv NULL ,
81the contents of the array are sorted in ascending order according to the
82.Tn ASCII
83order of the byte strings they reference and
84.Fa endbyte
85has a sorting weight of 0.
86.Pp
87The
88.Fn sradixsort
89function is stable, that is, if two elements compare as equal, their
90order in the sorted array is unchanged.
91The
92.Fn sradixsort
93function uses additional memory sufficient to hold
94.Fa nmemb
95pointers.
96.Pp
97The
98.Fn radixsort
99function is not stable, but uses no additional memory.
100.Pp
101These functions are variants of most-significant-byte radix sorting; in
102particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
103They take linear time relative to the number of bytes in the strings.
104.Sh RETURN VALUES
105Upon successful completion 0 is returned.
106Otherwise, \-1 is returned and the global variable
107.Va errno
108is set to indicate the error.
109.Sh ERRORS
110.Bl -tag -width Er
111.It Bq Er EINVAL
112The value of the
113.Fa endbyte
114element of
115.Fa table
116is not 0 or 255.
117.El
118.Pp
119Additionally, the
120.Fn sradixsort
121function may fail and set
122.Va errno
123for any of the errors specified for the library routine
124.Xr malloc 3 .
125.Sh SEE ALSO
126.Xr sort 1 ,
127.Xr qsort 3
128.Rs
129.%A Knuth, D.E.
130.%D 1968
131.%B "The Art of Computer Programming"
132.%T "Sorting and Searching"
133.%V Vol. 3
134.%P pp. 170-178
135.Re
136.Rs
137.%A Paige, R.
138.%D 1987
139.%T "Three Partition Refinement Algorithms"
140.%J "SIAM J. Comput."
141.%V Vol. 16
142.%N No. 6
143.Re
144.Rs
145.%A McIlroy, P.
146.%D 1993
147.%B "Engineering Radix Sort"
148.%T "Computing Systems"
149.%V Vol. 6:1
150.%P pp. 5-27
151.Re
152.Sh HISTORY
153The
154.Fn radixsort
155function first appeared in
156.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..e03b479715
--- /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.5 2002/02/17 19:42:24 millert 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(const u_char **, int, int, const u_char *, u_int);
65static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
66static void r_sort_b(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..8899c2e104
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.3
@@ -0,0 +1,102 @@
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.8 2001/05/13 23:38:02 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 int seed"
49.Ft int
50.Fn rand void
51.Ft int
52.Fn rand_r "unsigned int *seed"
53.Sh DESCRIPTION
54.Bf -symbolic
55These interfaces are obsoleted by
56.Xr random 3 .
57.Ef
58.Pp
59The
60.Fn rand
61function computes a sequence of pseudo-random integers in the range
62of 0 to
63.Dv RAND_MAX
64(as defined by the header file
65.Aq Pa stdlib.h ) .
66.Pp
67The
68.Fn srand
69function sets its argument as the seed for a new sequence of
70pseudo-random numbers to be returned by
71.Fn rand .
72These sequences are repeatable by calling
73.Fn srand
74with the same seed value.
75.Pp
76If no seed value is provided, the functions are automatically
77seeded with a value of 1.
78.Pp
79The
80.Fn rand_r
81is a thread-safe version of
82.Fn rand .
83Storage for the seed must be provided through the
84.Fa seed
85argument, and needs to have been initialized by the caller.
86.Sh SEE ALSO
87.Xr arc4random 3 ,
88.Xr rand48 3 ,
89.Xr random 3
90.Sh STANDARDS
91The
92.Fn rand
93and
94.Fn srand
95functions conform to
96.St -ansiC .
97.Pp
98The
99.Fn rand_r
100function conforms to ISO/IEC 9945-1 ANSI/IEEE
101.Pq Dq Tn POSIX
102Std 1003.1c Draft 10.
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000000..bb180886c0
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.c
@@ -0,0 +1,65 @@
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.6 1998/12/07 21:47:22 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static u_int next = 1;
42
43int
44rand_r(seed)
45u_int *seed;
46{
47
48 *seed = *seed * 1103515245 + 12345;
49 return (*seed % ((u_int)RAND_MAX + 1));
50}
51
52int
53rand()
54{
55
56 return (rand_r(&next));
57}
58
59void
60srand(seed)
61u_int seed;
62{
63
64 next = seed;
65}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
new file mode 100644
index 0000000000..31a4fdf4dd
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.3
@@ -0,0 +1,165 @@
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.8 2001/08/06 10:42:26 mpech 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.
53The particular 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.
58The modulus is always fixed at m = 2 ** 48.
59r(n) is called the seed of the random number generator.
60.Pp
61For all the six generator routines described next, the first
62computational step is to perform a single iteration of the algorithm.
63.Pp
64.Fn drand48
65and
66.Fn erand48
67return values of type double.
68The full 48 bits of r(n+1) are
69loaded into the mantissa of the returned value, with the exponent set
70such that the values produced lie in the interval [0.0, 1.0).
71.Pp
72.Fn lrand48
73and
74.Fn nrand48
75return values of type long in the range
76[0, 2**31-1].
77The high-order (31) bits of
78r(n+1) are loaded into the lower bits of the returned value, with
79the topmost (sign) bit set to zero.
80.Pp
81.Fn mrand48
82and
83.Fn jrand48
84return values of type long in the range
85[-2**31, 2**31-1].
86The high-order (32) bits of r(n+1) are loaded into the returned value.
87.Pp
88.Fn drand48 ,
89.Fn lrand48 ,
90and
91.Fn mrand48
92use an internal buffer to store r(n).
93For these functions
94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
95.Pp
96On the other hand,
97.Fn erand48 ,
98.Fn nrand48 ,
99and
100.Fn jrand48
101use a user-supplied buffer to store the seed r(n),
102which consists of an array of 3 shorts, where the zeroth member
103holds the least significant bits.
104.Pp
105All functions share the same multiplicand and addend.
106.Pp
107.Fn srand48
108is used to initialize the internal buffer r(n) of
109.Fn drand48 ,
110.Fn lrand48 ,
111and
112.Fn mrand48
113such that the 32 bits of the seed value are copied into the upper 32 bits
114of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
115Additionally, the constant multiplicand and addend of the algorithm are
116reset to the default values given above.
117.Pp
118.Fn seed48
119also initializes the internal buffer r(n) of
120.Fn drand48 ,
121.Fn lrand48 ,
122and
123.Fn mrand48 ,
124but here all 48 bits of the seed can be specified in an array of 3 shorts,
125where the zeroth member specifies the lowest bits.
126Again, the constant multiplicand and addend of the algorithm are
127reset to the default values given above.
128.Fn seed48
129returns a pointer to an array of 3 shorts which contains the old seed.
130This array is statically allocated, so its contents are lost after
131each new call to
132.Fn seed48 .
133.Pp
134Finally,
135.Fn lcong48
136allows full control over the multiplicand and addend used in
137.Fn drand48 ,
138.Fn erand48 ,
139.Fn lrand48 ,
140.Fn nrand48 ,
141.Fn mrand48 ,
142and
143.Fn jrand48 ,
144and the seed used in
145.Fn drand48 ,
146.Fn lrand48 ,
147and
148.Fn mrand48 .
149An array of 7 shorts is passed as parameter; the first three shorts are
150used to initialize the seed; the second three are used to initialize the
151multiplicand; and the last short is used to initialize the addend.
152It is thus not possible to use values greater than 0xffff as the addend.
153.Pp
154Note that all three methods of seeding the random number generator
155always also set the multiplicand and addend for any of the six
156generator calls.
157.Pp
158For a more powerful random number generator, see
159.Xr random 3
160.Sh AUTHORS
161Martin Birgmeier
162.Sh SEE ALSO
163.Xr arc4random 3 ,
164.Xr rand 3 ,
165.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..afa49f65f3
--- /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.3 2002/02/16 21:27:24 millert Exp $
14 */
15
16#ifndef _RAND48_H_
17#define _RAND48_H_
18
19#include <math.h>
20#include <stdlib.h>
21
22void __dorand48(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..3d4545651b
--- /dev/null
+++ b/src/lib/libc/stdlib/random.3
@@ -0,0 +1,190 @@
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.14 2001/09/06 15:04:34 mpech Exp $
33.\"
34.Dd April 19, 1991
35.Dt RANDOM 3
36.Os
37.Sh NAME
38.Nm random ,
39.Nm srandom ,
40.Nm srandomdev ,
41.Nm initstate ,
42.Nm setstate
43.Nd better random number generator; routines for changing generators
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft long
47.Fn random void
48.Ft void
49.Fn srandom "unsigned int seed"
50.Ft void
51.Fn srandomdev void
52.Ft char *
53.Fn initstate "unsigned int seed" "char *state" "size_t n"
54.Ft char *
55.Fn setstate "const char *state"
56.Sh DESCRIPTION
57The
58.Fn random
59function uses a non-linear additive feedback random number generator employing
60a default table of size 31 long integers to return successive pseudo-random
61numbers in the range from 0 to (2**31)\-1.
62The period of this random number generator is very large, approximately
6316*((2**31)\-1.
64.Pp
65The
66.Fn random
67and
68.Fn srandom
69functions have (almost) the same calling sequence and initialization
70properties as
71.Xr rand 3 Ns / Xr srand 3 .
72The difference is that
73.Xr rand
74produces a much less random sequence \(em in fact, the low dozen bits
75generated by rand go through a cyclic pattern.
76All the bits generated by
77.Fn random
78are usable.
79For example,
80.Sq Li random()&01
81will produce a random binary
82value.
83.Pp
84Like
85.Xr rand 3 ,
86.Fn random
87will by default produce a sequence of numbers that can be duplicated
88by calling
89.Fn srandom
90with
91.Ql 1
92as the seed.
93.Pp
94The
95.Fn srandomdev
96routine initialize a state array using the
97.Xr arandom 4
98random number device which returns good random numbers,
99suitable for cryptographic use.
100Note that this particular seeding procedure can generate
101states which are impossible to reproduce by calling
102.Fn srandom
103with any value, since the succeeding terms in the
104state buffer are no longer derived from the LC algorithm applied to
105a fixed seed.
106.Pp
107The
108.Fn initstate
109routine allows a state array, passed in as an argument, to be initialized
110for future use.
111The size of the state array (in bytes) is used by
112.Fn initstate
113to decide how sophisticated a random number generator it should use \(em the
114more state, the better the random numbers will be.
115(Current "optimal" values for the amount of state information are
1168, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
117the nearest known amount.
118Using less than 8 bytes will cause an error.)
119The seed for the initialization (which specifies a starting point for
120the random number sequence, and provides for restarting at the same
121point) is also an argument.
122The
123.Fn initstate
124function returns a pointer to the previous state information array.
125.Pp
126Once a state has been initialized, the
127.Fn setstate
128routine provides for rapid switching between states.
129The
130.Fn setstate
131function returns a pointer to the previous state array; its
132argument state array is used for further random number generation
133until the next call to
134.Fn initstate
135or
136.Fn setstate .
137.Pp
138Once a state array has been initialized, it may be restarted at a
139different point either by calling
140.Fn initstate
141(with the desired seed, the state array, and its size) or by calling
142both
143.Fn setstate
144(with the state array) and
145.Fn srandom
146(with the desired seed).
147The advantage of calling both
148.Fn setstate
149and
150.Fn srandom
151is that the size of the state array does not have to be remembered after
152it is initialized.
153.Pp
154With 256 bytes of state information, the period of the random number
155generator is greater than 2**69
156which should be sufficient for most purposes.
157.Sh AUTHORS
158.An Earl T. Cohen
159.Sh DIAGNOSTICS
160If
161.Fn initstate
162is called with less than 8 bytes of state information, or if
163.Fn setstate
164detects that the state information has been garbled, error
165messages are printed on the standard error output.
166.Sh SEE ALSO
167.Xr arc4random 3 ,
168.Xr drand48 3 ,
169.Xr rand 3 ,
170.Xr random 4
171.Sh STANDARDS
172The
173.Fn random ,
174.Fn srandom ,
175.Fn initstate ,
176and
177.Fn setstate
178functions conform to
179.St -xpg4.2 .
180.Pp
181The
182.Fn srandomdev
183function is an extension.
184.Sh HISTORY
185These
186functions appeared in
187.Bx 4.2 .
188.Sh BUGS
189About 2/3 the speed of
190.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..5ce7c90ee9
--- /dev/null
+++ b/src/lib/libc/stdlib/random.c
@@ -0,0 +1,417 @@
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.9 2000/04/04 14:27:00 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/time.h>
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44
45/*
46 * random.c:
47 *
48 * An improved random number generation package. In addition to the standard
49 * rand()/srand() like interface, this package also has a special state info
50 * interface. The initstate() routine is called with a seed, an array of
51 * bytes, and a count of how many bytes are being passed in; this array is
52 * then initialized to contain information for random number generation with
53 * that much state information. Good sizes for the amount of state
54 * information are 32, 64, 128, and 256 bytes. The state can be switched by
55 * calling the setstate() routine with the same array as was initiallized
56 * with initstate(). By default, the package runs with 128 bytes of state
57 * information and generates far better random numbers than a linear
58 * congruential generator. If the amount of state information is less than
59 * 32 bytes, a simple linear congruential R.N.G. is used.
60 *
61 * Internally, the state information is treated as an array of longs; the
62 * zeroeth element of the array is the type of R.N.G. being used (small
63 * integer); the remainder of the array is the state information for the
64 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
65 * state information, which will allow a degree seven polynomial. (Note:
66 * the zeroeth word of state information also has some other information
67 * stored in it -- see setstate() for details).
68 *
69 * The random number generation technique is a linear feedback shift register
70 * approach, employing trinomials (since there are fewer terms to sum up that
71 * way). In this approach, the least significant bit of all the numbers in
72 * the state table will act as a linear feedback shift register, and will
73 * have period 2^deg - 1 (where deg is the degree of the polynomial being
74 * used, assuming that the polynomial is irreducible and primitive). The
75 * higher order bits will have longer periods, since their values are also
76 * influenced by pseudo-random carries out of the lower bits. The total
77 * period of the generator is approximately deg*(2**deg - 1); thus doubling
78 * the amount of state information has a vast influence on the period of the
79 * generator. Note: the deg*(2**deg - 1) is an approximation only good for
80 * large deg, when the period of the shift register is the dominant factor.
81 * With deg equal to seven, the period is actually much longer than the
82 * 7*(2**7 - 1) predicted by this formula.
83 */
84
85/*
86 * For each of the currently supported random number generators, we have a
87 * break value on the amount of state information (you need at least this
88 * many bytes of state info to support this random number generator), a degree
89 * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
90 * the separation between the two lower order coefficients of the trinomial.
91 */
92#define TYPE_0 0 /* linear congruential */
93#define BREAK_0 8
94#define DEG_0 0
95#define SEP_0 0
96
97#define TYPE_1 1 /* x**7 + x**3 + 1 */
98#define BREAK_1 32
99#define DEG_1 7
100#define SEP_1 3
101
102#define TYPE_2 2 /* x**15 + x + 1 */
103#define BREAK_2 64
104#define DEG_2 15
105#define SEP_2 1
106
107#define TYPE_3 3 /* x**31 + x**3 + 1 */
108#define BREAK_3 128
109#define DEG_3 31
110#define SEP_3 3
111
112#define TYPE_4 4 /* x**63 + x + 1 */
113#define BREAK_4 256
114#define DEG_4 63
115#define SEP_4 1
116
117/*
118 * Array versions of the above information to make code run faster --
119 * relies on fact that TYPE_i == i.
120 */
121#define MAX_TYPES 5 /* max number of types above */
122
123static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
124static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
125
126/*
127 * Initially, everything is set up as if from:
128 *
129 * initstate(1, &randtbl, 128);
130 *
131 * Note that this initialization takes advantage of the fact that srandom()
132 * advances the front and rear pointers 10*rand_deg times, and hence the
133 * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
134 * element of the state information, which contains info about the current
135 * position of the rear pointer is just
136 *
137 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
138 */
139
140static long randtbl[DEG_3 + 1] = {
141 TYPE_3,
142 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
143 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
144 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
145 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
146 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
147 0xf3bec5da,
148};
149
150/*
151 * fptr and rptr are two pointers into the state info, a front and a rear
152 * pointer. These two pointers are always rand_sep places aparts, as they
153 * cycle cyclically through the state information. (Yes, this does mean we
154 * could get away with just one pointer, but the code for random() is more
155 * efficient this way). The pointers are left positioned as they would be
156 * from the call
157 *
158 * initstate(1, randtbl, 128);
159 *
160 * (The position of the rear pointer, rptr, is really 0 (as explained above
161 * in the initialization of randtbl) because the state table pointer is set
162 * to point to randtbl[1] (as explained below).
163 */
164static long *fptr = &randtbl[SEP_3 + 1];
165static long *rptr = &randtbl[1];
166
167/*
168 * The following things are the pointer to the state information table, the
169 * type of the current generator, the degree of the current polynomial being
170 * used, and the separation between the two pointers. Note that for efficiency
171 * of random(), we remember the first location of the state information, not
172 * the zeroeth. Hence it is valid to access state[-1], which is used to
173 * store the type of the R.N.G. Also, we remember the last location, since
174 * this is more efficient than indexing every time to find the address of
175 * the last element to see if the front and rear pointers have wrapped.
176 */
177static long *state = &randtbl[1];
178static int rand_type = TYPE_3;
179static int rand_deg = DEG_3;
180static int rand_sep = SEP_3;
181static long *end_ptr = &randtbl[DEG_3 + 1];
182
183/*
184 * srandom:
185 *
186 * Initialize the random number generator based on the given seed. If the
187 * type is the trivial no-state-information type, just remember the seed.
188 * Otherwise, initializes state[] based on the given "seed" via a linear
189 * congruential generator. Then, the pointers are set to known locations
190 * that are exactly rand_sep places apart. Lastly, it cycles the state
191 * information a given number of times to get rid of any initial dependencies
192 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
193 * for default usage relies on values produced by this routine.
194 */
195void
196srandom(x)
197 u_int x;
198{
199 register long int test;
200 register int i;
201 ldiv_t val;
202
203 if (rand_type == TYPE_0)
204 state[0] = x;
205 else {
206 state[0] = x;
207 for (i = 1; i < rand_deg; i++) {
208 /*
209 * Implement the following, without overflowing 31 bits:
210 *
211 * state[i] = (16807 * state[i - 1]) % 2147483647;
212 *
213 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
214 */
215 val = ldiv(state[i-1], 127773);
216 test = 16807 * val.rem - 2836 * val.quot;
217 state[i] = test + (test < 0 ? 2147483647 : 0);
218 }
219 fptr = &state[rand_sep];
220 rptr = &state[0];
221 for (i = 0; i < 10 * rand_deg; i++)
222 (void)random();
223 }
224}
225
226/*
227 * srandomdev:
228 *
229 * Many programs choose the seed value in a totally predictable manner.
230 * This often causes problems. We seed the generator using the much more
231 * secure arandom(4) interface. Note that this particular seeding
232 * procedure can generate states which are impossible to reproduce by
233 * calling srandom() with any value, since the succeeding terms in the
234 * state buffer are no longer derived from the LC algorithm applied to
235 * a fixed seed.
236 */
237void
238srandomdev()
239{
240 int fd;
241 size_t len;
242
243 if (rand_type == TYPE_0)
244 len = sizeof(state[0]);
245 else
246 len = rand_deg * sizeof(state[0]);
247
248 if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
249 read(fd, (void *) state, len) == (ssize_t) len) {
250 close(fd);
251 } else {
252 struct timeval tv;
253 u_int junk;
254
255 /* XXX - this could be better */
256 gettimeofday(&tv, NULL);
257 srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
258 if (fd != -1)
259 close(fd);
260 return;
261 }
262
263 if (rand_type != TYPE_0) {
264 fptr = &state[rand_sep];
265 rptr = &state[0];
266 }
267}
268
269/*
270 * initstate:
271 *
272 * Initialize the state information in the given array of n bytes for future
273 * random number generation. Based on the number of bytes we are given, and
274 * the break values for the different R.N.G.'s, we choose the best (largest)
275 * one we can and set things up for it. srandom() is then called to
276 * initialize the state information.
277 *
278 * Note that on return from srandom(), we set state[-1] to be the type
279 * multiplexed with the current value of the rear pointer; this is so
280 * successive calls to initstate() won't lose this information and will be
281 * able to restart with setstate().
282 *
283 * Note: the first thing we do is save the current state, if any, just like
284 * setstate() so that it doesn't matter when initstate is called.
285 *
286 * Returns a pointer to the old state.
287 */
288char *
289initstate(seed, arg_state, n)
290 u_int seed; /* seed for R.N.G. */
291 char *arg_state; /* pointer to state array */
292 size_t n; /* # bytes of state info */
293{
294 register char *ostate = (char *)(&state[-1]);
295
296 if (rand_type == TYPE_0)
297 state[-1] = rand_type;
298 else
299 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
300 if (n < BREAK_0)
301 return(NULL);
302 if (n < BREAK_1) {
303 rand_type = TYPE_0;
304 rand_deg = DEG_0;
305 rand_sep = SEP_0;
306 } else if (n < BREAK_2) {
307 rand_type = TYPE_1;
308 rand_deg = DEG_1;
309 rand_sep = SEP_1;
310 } else if (n < BREAK_3) {
311 rand_type = TYPE_2;
312 rand_deg = DEG_2;
313 rand_sep = SEP_2;
314 } else if (n < BREAK_4) {
315 rand_type = TYPE_3;
316 rand_deg = DEG_3;
317 rand_sep = SEP_3;
318 } else {
319 rand_type = TYPE_4;
320 rand_deg = DEG_4;
321 rand_sep = SEP_4;
322 }
323 state = &(((long *)arg_state)[1]); /* first location */
324 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
325 srandom(seed);
326 if (rand_type == TYPE_0)
327 state[-1] = rand_type;
328 else
329 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
330 return(ostate);
331}
332
333/*
334 * setstate:
335 *
336 * Restore the state from the given state array.
337 *
338 * Note: it is important that we also remember the locations of the pointers
339 * in the current state information, and restore the locations of the pointers
340 * from the old state information. This is done by multiplexing the pointer
341 * location into the zeroeth word of the state information.
342 *
343 * Note that due to the order in which things are done, it is OK to call
344 * setstate() with the same state as the current state.
345 *
346 * Returns a pointer to the old state information.
347 */
348char *
349setstate(arg_state)
350 const char *arg_state;
351{
352 register long *new_state = (long *)arg_state;
353 register int type = new_state[0] % MAX_TYPES;
354 register int rear = new_state[0] / MAX_TYPES;
355 char *ostate = (char *)(&state[-1]);
356
357 if (rand_type == TYPE_0)
358 state[-1] = rand_type;
359 else
360 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
361 switch(type) {
362 case TYPE_0:
363 case TYPE_1:
364 case TYPE_2:
365 case TYPE_3:
366 case TYPE_4:
367 rand_type = type;
368 rand_deg = degrees[type];
369 rand_sep = seps[type];
370 break;
371 default:
372 return(NULL);
373 }
374 state = &new_state[1];
375 if (rand_type != TYPE_0) {
376 rptr = &state[rear];
377 fptr = &state[(rear + rand_sep) % rand_deg];
378 }
379 end_ptr = &state[rand_deg]; /* set end_ptr too */
380 return(ostate);
381}
382
383/*
384 * random:
385 *
386 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
387 * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
388 * the same in all the other cases due to all the global variables that have
389 * been set up. The basic operation is to add the number at the rear pointer
390 * into the one at the front pointer. Then both pointers are advanced to
391 * the next location cyclically in the table. The value returned is the sum
392 * generated, reduced to 31 bits by throwing away the "least random" low bit.
393 *
394 * Note: the code takes advantage of the fact that both the front and
395 * rear pointers can't wrap on the same call by not testing the rear
396 * pointer if the front one has wrapped.
397 *
398 * Returns a 31-bit random number.
399 */
400long
401random()
402{
403 long i;
404
405 if (rand_type == TYPE_0)
406 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
407 else {
408 *fptr += *rptr;
409 i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
410 if (++fptr >= end_ptr) {
411 fptr = state;
412 ++rptr;
413 } else if (++rptr >= end_ptr)
414 rptr = state;
415 }
416 return(i);
417}
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000000..56fbea9ede
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.3
@@ -0,0 +1,124 @@
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.8 2001/04/23 15:30:25 aaron 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 the memory referenced by
60.Fa resolvedname .
61The
62.Fa resolvedname
63argument
64.Em must
65refer to a buffer capable of storing at least
66.Dv MAXPATHLEN
67characters.
68.Pp
69The
70.Fn realpath
71function will resolve both absolute and relative paths
72and return the absolute pathname corresponding to
73.Fa pathname .
74All but the last component of
75.Fa pathname
76must exist when
77.Fn realpath
78is called.
79.Sh "RETURN VALUES"
80The
81.Fn realpath
82function returns
83.Fa resolvedname
84on success.
85If an error occurs,
86.Fn realpath
87returns
88.Dv NULL ,
89and
90.Fa resolvedname
91contains the pathname which caused the problem.
92.Sh ERRORS
93The function
94.Fn realpath
95may fail and set the external variable
96.Va errno
97for any of the errors specified for the library functions
98.Xr chdir 2 ,
99.Xr close 2 ,
100.Xr fchdir 2 ,
101.Xr lstat 2 ,
102.Xr open 2 ,
103.Xr readlink 2 ,
104and
105.Xr getcwd 3 .
106.Sh CAVEATS
107This implementation of
108.Fn realpath
109differs slightly from the Solaris implementation.
110The
111.Bx 4.4
112version always returns absolute pathnames,
113whereas the Solaris implementation will,
114under certain circumstances, return a relative
115.Fa resolvedname
116when given a relative
117.Fa pathname .
118.Sh SEE ALSO
119.Xr getcwd 3
120.Sh HISTORY
121The
122.Fn realpath
123function call first appeared in
124.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..d01b19e0f2
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.c
@@ -0,0 +1,166 @@
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.7 2002/05/24 21:22:37 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)strlcpy(resolved, ".", MAXPATHLEN);
70 return (NULL);
71 }
72
73 /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
74 if (path[0] == '.' && path[1] == '\0')
75 path = "";
76
77 /*
78 * Find the dirname and basename from the path to be resolved.
79 * Change directory to the dirname component.
80 * lstat the basename part.
81 * if it is a symlink, read in the value and loop.
82 * if it is a directory, then change to that directory.
83 * get the current directory name and append the basename.
84 */
85 strlcpy(resolved, path, MAXPATHLEN);
86loop:
87 q = strrchr(resolved, '/');
88 if (q != NULL) {
89 p = q + 1;
90 if (q == resolved)
91 q = "/";
92 else {
93 do {
94 --q;
95 } while (q > resolved && *q == '/');
96 q[1] = '\0';
97 q = resolved;
98 }
99 if (chdir(q) < 0)
100 goto err1;
101 } else
102 p = resolved;
103
104 /* Deal with the last component. */
105 if (*p != '\0' && lstat(p, &sb) == 0) {
106 if (S_ISLNK(sb.st_mode)) {
107 if (++symlinks > MAXSYMLINKS) {
108 errno = ELOOP;
109 goto err1;
110 }
111 n = readlink(p, resolved, MAXPATHLEN-1);
112 if (n < 0)
113 goto err1;
114 resolved[n] = '\0';
115 goto loop;
116 }
117 if (S_ISDIR(sb.st_mode)) {
118 if (chdir(p) < 0)
119 goto err1;
120 p = "";
121 }
122 }
123
124 /*
125 * Save the last component name and get the full pathname of
126 * the current directory.
127 */
128 (void)strlcpy(wbuf, p, sizeof wbuf);
129 if (getcwd(resolved, MAXPATHLEN) == 0)
130 goto err1;
131
132 /*
133 * Join the two strings together, ensuring that the right thing
134 * happens if the last component is empty, or the dirname is root.
135 */
136 if (resolved[0] == '/' && resolved[1] == '\0')
137 rootd = 1;
138 else
139 rootd = 0;
140
141 if (*wbuf) {
142 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
143 errno = ENAMETOOLONG;
144 goto err1;
145 }
146 if (rootd == 0)
147 (void)strcat(resolved, "/");
148 (void)strcat(resolved, wbuf);
149 }
150
151 /* Go back to where we came from. */
152 if (fchdir(fd) < 0) {
153 serrno = errno;
154 goto err2;
155 }
156
157 /* It's okay if the close fails, what's an fd more or less? */
158 (void)close(fd);
159 return (resolved);
160
161err1: serrno = errno;
162 (void)fchdir(fd);
163err2: (void)close(fd);
164 errno = serrno;
165 return (NULL);
166}
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..fc7c67a5db
--- /dev/null
+++ b/src/lib/libc/stdlib/setenv.c
@@ -0,0 +1,121 @@
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.4 2001/07/09 06:57:45 deraadt 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 ;
67 return (0);
68 }
69 } else { /* create new slot */
70 register int cnt;
71 register char **P;
72
73 for (P = environ, cnt = 0; *P; ++P, ++cnt);
74 if (alloced) { /* just increase size */
75 P = (char **)realloc((void *)environ,
76 (size_t)(sizeof(char *) * (cnt + 2)));
77 if (!P)
78 return (-1);
79 environ = P;
80 }
81 else { /* get new space */
82 alloced = 1; /* copy old entries into it */
83 P = (char **)malloc((size_t)(sizeof(char *) *
84 (cnt + 2)));
85 if (!P)
86 return (-1);
87 bcopy(environ, P, cnt * sizeof(char *));
88 environ = P;
89 }
90 environ[cnt + 1] = NULL;
91 offset = cnt;
92 }
93 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
94 if (!(environ[offset] = /* name + `=' + value */
95 malloc((size_t)((int)(C - name) + l_value + 2))))
96 return (-1);
97 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
98 ;
99 for (*C++ = '='; (*C++ = *value++); )
100 ;
101 return (0);
102}
103
104/*
105 * unsetenv(name) --
106 * Delete environmental variable "name".
107 */
108void
109unsetenv(name)
110 const char *name;
111{
112 extern char **environ;
113 register char **P;
114 int offset;
115 char *__findenv();
116
117 while (__findenv(name, &offset)) /* if set multiple times */
118 for (P = &environ[offset];; ++P)
119 if (!(*P = *(P + 1)))
120 break;
121}
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..4e04f6738e
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.3
@@ -0,0 +1,117 @@
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.7 2000/04/20 13:50:03 aaron 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 pointed to by
54.Fa nptr
55to
56.Li double
57representation.
58.Pp
59The expected form of the string is an optional plus
60.Pq Ql +
61or minus sign
62.Pq Ql -
63followed by a sequence of digits optionally containing
64a decimal-point character, optionally followed by an exponent.
65An exponent consists of an
66.Sq E
67or
68.Sq e ,
69followed by an optional plus or minus sign, followed by a sequence of digits.
70.Pp
71Leading whitespace characters in the string (as defined by the
72.Xr isspace 3
73function) are skipped.
74.Sh RETURN VALUES
75The
76.Fn strtod
77function returns the converted value, if any.
78.Pp
79If
80.Fa endptr
81is not
82.Dv NULL ,
83a pointer to the character after the last character used
84in the conversion is stored in the location referenced by
85.Fa endptr .
86.Pp
87If no conversion is performed, zero is returned and the value of
88.Fa nptr
89is stored in the location referenced by
90.Fa endptr .
91.Pp
92If the correct value would cause overflow, plus or minus
93.Dv HUGE_VAL
94is returned (according to the sign of the value), and
95.Er ERANGE
96is stored in
97.Va errno .
98If the correct value would cause underflow, zero is returned and
99.Er ERANGE
100is stored in
101.Va errno .
102.Sh ERRORS
103.Bl -tag -width Er
104.It Bq Er ERANGE
105Overflow or underflow occurred.
106.El
107.Sh SEE ALSO
108.Xr atof 3 ,
109.Xr atoi 3 ,
110.Xr atol 3 ,
111.Xr strtol 3 ,
112.Xr strtoul 3
113.Sh STANDARDS
114The
115.Fn strtod
116function conforms to
117.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
new file mode 100644
index 0000000000..ce7ce9fe56
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.c
@@ -0,0 +1,2528 @@
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.15 2002/02/19 19:39:37 millert 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#ifdef IEEE_BIG_ENDIAN
157#define IEEE_ARITHMETIC
158#endif
159#ifdef IEEE_LITTLE_ENDIAN
160#define IEEE_ARITHMETIC
161#endif
162
163#ifdef IEEE_ARITHMETIC
164#define DBL_DIG 15
165#define DBL_MAX_10_EXP 308
166#define DBL_MAX_EXP 1024
167#define FLT_RADIX 2
168#define FLT_ROUNDS 1
169#define DBL_MAX 1.7976931348623157e+308
170#endif
171
172#ifdef IBM
173#define DBL_DIG 16
174#define DBL_MAX_10_EXP 75
175#define DBL_MAX_EXP 63
176#define FLT_RADIX 16
177#define FLT_ROUNDS 0
178#define DBL_MAX 7.2370055773322621e+75
179#endif
180
181#ifdef VAX
182#define DBL_DIG 16
183#define DBL_MAX_10_EXP 38
184#define DBL_MAX_EXP 127
185#define FLT_RADIX 2
186#define FLT_ROUNDS 1
187#define DBL_MAX 1.7014118346046923e+38
188#endif
189
190#ifndef LONG_MAX
191#define LONG_MAX 2147483647
192#endif
193#else
194#include "float.h"
195#endif
196#ifndef __MATH_H__
197#include "math.h"
198#endif
199
200#ifdef __cplusplus
201extern "C" {
202#endif
203
204#ifndef CONST
205#ifdef KR_headers
206#define CONST /* blank */
207#else
208#define CONST const
209#endif
210#endif
211
212#ifdef Unsigned_Shifts
213#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
214#else
215#define Sign_Extend(a,b) /*no-op*/
216#endif
217
218#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
219 defined(IBM) != 1
220Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
221IBM should be defined.
222#endif
223
224typedef union {
225 double d;
226 ULong ul[2];
227} _double;
228#define value(x) ((x).d)
229#ifdef IEEE_LITTLE_ENDIAN
230#define word0(x) ((x).ul[1])
231#define word1(x) ((x).ul[0])
232#else
233#define word0(x) ((x).ul[0])
234#define word1(x) ((x).ul[1])
235#endif
236
237/* The following definition of Storeinc is appropriate for MIPS processors.
238 * An alternative that might be better on some machines is
239 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
240 */
241#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
242#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
243((unsigned short *)a)[0] = (unsigned short)c, a++)
244#else
245#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
246((unsigned short *)a)[1] = (unsigned short)c, a++)
247#endif
248
249/* #define P DBL_MANT_DIG */
250/* Ten_pmax = floor(P*log(2)/log(5)) */
251/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
252/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
253/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
254
255#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
256#define Exp_shift 20
257#define Exp_shift1 20
258#define Exp_msk1 0x100000
259#define Exp_msk11 0x100000
260#define Exp_mask 0x7ff00000
261#define P 53
262#define Bias 1023
263#define IEEE_Arith
264#define Emin (-1022)
265#define Exp_1 0x3ff00000
266#define Exp_11 0x3ff00000
267#define Ebits 11
268#define Frac_mask 0xfffff
269#define Frac_mask1 0xfffff
270#define Ten_pmax 22
271#define Bletch 0x10
272#define Bndry_mask 0xfffff
273#define Bndry_mask1 0xfffff
274#define LSB 1
275#define Sign_bit 0x80000000
276#define Log2P 1
277#define Tiny0 0
278#define Tiny1 1
279#define Quick_max 14
280#define Int_max 14
281#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
282#else
283#undef Sudden_Underflow
284#define Sudden_Underflow
285#ifdef IBM
286#define Exp_shift 24
287#define Exp_shift1 24
288#define Exp_msk1 0x1000000
289#define Exp_msk11 0x1000000
290#define Exp_mask 0x7f000000
291#define P 14
292#define Bias 65
293#define Exp_1 0x41000000
294#define Exp_11 0x41000000
295#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
296#define Frac_mask 0xffffff
297#define Frac_mask1 0xffffff
298#define Bletch 4
299#define Ten_pmax 22
300#define Bndry_mask 0xefffff
301#define Bndry_mask1 0xffffff
302#define LSB 1
303#define Sign_bit 0x80000000
304#define Log2P 4
305#define Tiny0 0x100000
306#define Tiny1 0
307#define Quick_max 14
308#define Int_max 15
309#else /* VAX */
310#define Exp_shift 23
311#define Exp_shift1 7
312#define Exp_msk1 0x80
313#define Exp_msk11 0x800000
314#define Exp_mask 0x7f80
315#define P 56
316#define Bias 129
317#define Exp_1 0x40800000
318#define Exp_11 0x4080
319#define Ebits 8
320#define Frac_mask 0x7fffff
321#define Frac_mask1 0xffff007f
322#define Ten_pmax 24
323#define Bletch 2
324#define Bndry_mask 0xffff007f
325#define Bndry_mask1 0xffff007f
326#define LSB 0x10000
327#define Sign_bit 0x8000
328#define Log2P 1
329#define Tiny0 0x80
330#define Tiny1 0
331#define Quick_max 15
332#define Int_max 15
333#endif
334#endif
335
336#ifndef IEEE_Arith
337#define ROUND_BIASED
338#endif
339
340#ifdef RND_PRODQUOT
341#define rounded_product(a,b) a = rnd_prod(a, b)
342#define rounded_quotient(a,b) a = rnd_quot(a, b)
343#ifdef KR_headers
344extern double rnd_prod(), rnd_quot();
345#else
346extern double rnd_prod(double, double), rnd_quot(double, double);
347#endif
348#else
349#define rounded_product(a,b) a *= b
350#define rounded_quotient(a,b) a /= b
351#endif
352
353#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
354#define Big1 0xffffffff
355
356#ifndef Just_16
357/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
358 * This makes some inner loops simpler and sometimes saves work
359 * during multiplications, but it often seems to make things slightly
360 * slower. Hence the default is now to store 32 bits per Long.
361 */
362#ifndef Pack_32
363#define Pack_32
364#endif
365#endif
366
367#define Kmax 15
368
369#ifdef __cplusplus
370extern "C" double strtod(const char *s00, char **se);
371extern "C" char *__dtoa(double d, int mode, int ndigits,
372 int *decpt, int *sign, char **rve);
373#endif
374
375 struct
376Bigint {
377 struct Bigint *next;
378 int k, maxwds, sign, wds;
379 ULong x[1];
380 };
381
382 typedef struct Bigint Bigint;
383
384 static Bigint *freelist[Kmax+1];
385
386 static Bigint *
387Balloc
388#ifdef KR_headers
389 (k) int k;
390#else
391 (int k)
392#endif
393{
394 int x;
395 Bigint *rv;
396
397 if ((rv = freelist[k])) {
398 freelist[k] = rv->next;
399 }
400 else {
401 x = 1 << k;
402 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
403 rv->k = k;
404 rv->maxwds = x;
405 }
406 rv->sign = rv->wds = 0;
407 return rv;
408 }
409
410 static void
411Bfree
412#ifdef KR_headers
413 (v) Bigint *v;
414#else
415 (Bigint *v)
416#endif
417{
418 if (v) {
419 v->next = freelist[v->k];
420 freelist[v->k] = v;
421 }
422 }
423
424#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
425y->wds*sizeof(Long) + 2*sizeof(int))
426
427 static Bigint *
428multadd
429#ifdef KR_headers
430 (b, m, a) Bigint *b; int m, a;
431#else
432 (Bigint *b, int m, int a) /* multiply by m and add a */
433#endif
434{
435 int i, wds;
436 ULong *x, y;
437#ifdef Pack_32
438 ULong xi, z;
439#endif
440 Bigint *b1;
441
442 wds = b->wds;
443 x = b->x;
444 i = 0;
445 do {
446#ifdef Pack_32
447 xi = *x;
448 y = (xi & 0xffff) * m + a;
449 z = (xi >> 16) * m + (y >> 16);
450 a = (int)(z >> 16);
451 *x++ = (z << 16) + (y & 0xffff);
452#else
453 y = *x * m + a;
454 a = (int)(y >> 16);
455 *x++ = y & 0xffff;
456#endif
457 }
458 while(++i < wds);
459 if (a) {
460 if (wds >= b->maxwds) {
461 b1 = Balloc(b->k+1);
462 Bcopy(b1, b);
463 Bfree(b);
464 b = b1;
465 }
466 b->x[wds++] = a;
467 b->wds = wds;
468 }
469 return b;
470 }
471
472 static Bigint *
473s2b
474#ifdef KR_headers
475 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
476#else
477 (CONST char *s, int nd0, int nd, ULong y9)
478#endif
479{
480 Bigint *b;
481 int i, k;
482 Long x, y;
483
484 x = (nd + 8) / 9;
485 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
486#ifdef Pack_32
487 b = Balloc(k);
488 b->x[0] = y9;
489 b->wds = 1;
490#else
491 b = Balloc(k+1);
492 b->x[0] = y9 & 0xffff;
493 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
494#endif
495
496 i = 9;
497 if (9 < nd0) {
498 s += 9;
499 do b = multadd(b, 10, *s++ - '0');
500 while(++i < nd0);
501 s++;
502 }
503 else
504 s += 10;
505 for(; i < nd; i++)
506 b = multadd(b, 10, *s++ - '0');
507 return b;
508 }
509
510 static int
511hi0bits
512#ifdef KR_headers
513 (x) register ULong x;
514#else
515 (register ULong x)
516#endif
517{
518 register int k = 0;
519
520 if (!(x & 0xffff0000)) {
521 k = 16;
522 x <<= 16;
523 }
524 if (!(x & 0xff000000)) {
525 k += 8;
526 x <<= 8;
527 }
528 if (!(x & 0xf0000000)) {
529 k += 4;
530 x <<= 4;
531 }
532 if (!(x & 0xc0000000)) {
533 k += 2;
534 x <<= 2;
535 }
536 if (!(x & 0x80000000)) {
537 k++;
538 if (!(x & 0x40000000))
539 return 32;
540 }
541 return k;
542 }
543
544 static int
545lo0bits
546#ifdef KR_headers
547 (y) ULong *y;
548#else
549 (ULong *y)
550#endif
551{
552 register int k;
553 register ULong x = *y;
554
555 if (x & 7) {
556 if (x & 1)
557 return 0;
558 if (x & 2) {
559 *y = x >> 1;
560 return 1;
561 }
562 *y = x >> 2;
563 return 2;
564 }
565 k = 0;
566 if (!(x & 0xffff)) {
567 k = 16;
568 x >>= 16;
569 }
570 if (!(x & 0xff)) {
571 k += 8;
572 x >>= 8;
573 }
574 if (!(x & 0xf)) {
575 k += 4;
576 x >>= 4;
577 }
578 if (!(x & 0x3)) {
579 k += 2;
580 x >>= 2;
581 }
582 if (!(x & 1)) {
583 k++;
584 x >>= 1;
585 if (!x & 1)
586 return 32;
587 }
588 *y = x;
589 return k;
590 }
591
592 static Bigint *
593i2b
594#ifdef KR_headers
595 (i) int i;
596#else
597 (int i)
598#endif
599{
600 Bigint *b;
601
602 b = Balloc(1);
603 b->x[0] = i;
604 b->wds = 1;
605 return b;
606 }
607
608 static Bigint *
609mult
610#ifdef KR_headers
611 (a, b) Bigint *a, *b;
612#else
613 (Bigint *a, Bigint *b)
614#endif
615{
616 Bigint *c;
617 int k, wa, wb, wc;
618 ULong carry, y, z;
619 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
620#ifdef Pack_32
621 ULong z2;
622#endif
623
624 if (a->wds < b->wds) {
625 c = a;
626 a = b;
627 b = c;
628 }
629 k = a->k;
630 wa = a->wds;
631 wb = b->wds;
632 wc = wa + wb;
633 if (wc > a->maxwds)
634 k++;
635 c = Balloc(k);
636 for(x = c->x, xa = x + wc; x < xa; x++)
637 *x = 0;
638 xa = a->x;
639 xae = xa + wa;
640 xb = b->x;
641 xbe = xb + wb;
642 xc0 = c->x;
643#ifdef Pack_32
644 for(; xb < xbe; xb++, xc0++) {
645 if ((y = *xb & 0xffff)) {
646 x = xa;
647 xc = xc0;
648 carry = 0;
649 do {
650 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
651 carry = z >> 16;
652 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
653 carry = z2 >> 16;
654 Storeinc(xc, z2, z);
655 }
656 while(x < xae);
657 *xc = carry;
658 }
659 if ((y = *xb >> 16)) {
660 x = xa;
661 xc = xc0;
662 carry = 0;
663 z2 = *xc;
664 do {
665 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
666 carry = z >> 16;
667 Storeinc(xc, z, z2);
668 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
669 carry = z2 >> 16;
670 }
671 while(x < xae);
672 *xc = z2;
673 }
674 }
675#else
676 for(; xb < xbe; xc0++) {
677 if (y = *xb++) {
678 x = xa;
679 xc = xc0;
680 carry = 0;
681 do {
682 z = *x++ * y + *xc + carry;
683 carry = z >> 16;
684 *xc++ = z & 0xffff;
685 }
686 while(x < xae);
687 *xc = carry;
688 }
689 }
690#endif
691 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
692 c->wds = wc;
693 return c;
694 }
695
696 static Bigint *p5s;
697
698 static Bigint *
699pow5mult
700#ifdef KR_headers
701 (b, k) Bigint *b; int k;
702#else
703 (Bigint *b, int k)
704#endif
705{
706 Bigint *b1, *p5, *p51;
707 int i;
708 static int p05[3] = { 5, 25, 125 };
709
710 if ((i = k & 3))
711 b = multadd(b, p05[i-1], 0);
712
713 if (!(k >>= 2))
714 return b;
715 if (!(p5 = p5s)) {
716 /* first time */
717 p5 = p5s = i2b(625);
718 p5->next = 0;
719 }
720 for(;;) {
721 if (k & 1) {
722 b1 = mult(b, p5);
723 Bfree(b);
724 b = b1;
725 }
726 if (!(k >>= 1))
727 break;
728 if (!(p51 = p5->next)) {
729 p51 = p5->next = mult(p5,p5);
730 p51->next = 0;
731 }
732 p5 = p51;
733 }
734 return b;
735 }
736
737 static Bigint *
738lshift
739#ifdef KR_headers
740 (b, k) Bigint *b; int k;
741#else
742 (Bigint *b, int k)
743#endif
744{
745 int i, k1, n, n1;
746 Bigint *b1;
747 ULong *x, *x1, *xe, z;
748
749#ifdef Pack_32
750 n = k >> 5;
751#else
752 n = k >> 4;
753#endif
754 k1 = b->k;
755 n1 = n + b->wds + 1;
756 for(i = b->maxwds; n1 > i; i <<= 1)
757 k1++;
758 b1 = Balloc(k1);
759 x1 = b1->x;
760 for(i = 0; i < n; i++)
761 *x1++ = 0;
762 x = b->x;
763 xe = x + b->wds;
764#ifdef Pack_32
765 if (k &= 0x1f) {
766 k1 = 32 - k;
767 z = 0;
768 do {
769 *x1++ = *x << k | z;
770 z = *x++ >> k1;
771 }
772 while(x < xe);
773 if ((*x1 = z))
774 ++n1;
775 }
776#else
777 if (k &= 0xf) {
778 k1 = 16 - k;
779 z = 0;
780 do {
781 *x1++ = *x << k & 0xffff | z;
782 z = *x++ >> k1;
783 }
784 while(x < xe);
785 if (*x1 = z)
786 ++n1;
787 }
788#endif
789 else do
790 *x1++ = *x++;
791 while(x < xe);
792 b1->wds = n1 - 1;
793 Bfree(b);
794 return b1;
795 }
796
797 static int
798cmp
799#ifdef KR_headers
800 (a, b) Bigint *a, *b;
801#else
802 (Bigint *a, Bigint *b)
803#endif
804{
805 ULong *xa, *xa0, *xb, *xb0;
806 int i, j;
807
808 i = a->wds;
809 j = b->wds;
810#ifdef DEBUG
811 if (i > 1 && !a->x[i-1])
812 Bug("cmp called with a->x[a->wds-1] == 0");
813 if (j > 1 && !b->x[j-1])
814 Bug("cmp called with b->x[b->wds-1] == 0");
815#endif
816 if (i -= j)
817 return i;
818 xa0 = a->x;
819 xa = xa0 + j;
820 xb0 = b->x;
821 xb = xb0 + j;
822 for(;;) {
823 if (*--xa != *--xb)
824 return *xa < *xb ? -1 : 1;
825 if (xa <= xa0)
826 break;
827 }
828 return 0;
829 }
830
831 static Bigint *
832diff
833#ifdef KR_headers
834 (a, b) Bigint *a, *b;
835#else
836 (Bigint *a, Bigint *b)
837#endif
838{
839 Bigint *c;
840 int i, wa, wb;
841 Long borrow, y; /* We need signed shifts here. */
842 ULong *xa, *xae, *xb, *xbe, *xc;
843#ifdef Pack_32
844 Long z;
845#endif
846
847 i = cmp(a,b);
848 if (!i) {
849 c = Balloc(0);
850 c->wds = 1;
851 c->x[0] = 0;
852 return c;
853 }
854 if (i < 0) {
855 c = a;
856 a = b;
857 b = c;
858 i = 1;
859 }
860 else
861 i = 0;
862 c = Balloc(a->k);
863 c->sign = i;
864 wa = a->wds;
865 xa = a->x;
866 xae = xa + wa;
867 wb = b->wds;
868 xb = b->x;
869 xbe = xb + wb;
870 xc = c->x;
871 borrow = 0;
872#ifdef Pack_32
873 do {
874 y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
875 borrow = y >> 16;
876 Sign_Extend(borrow, y);
877 z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
878 borrow = z >> 16;
879 Sign_Extend(borrow, z);
880 Storeinc(xc, z, y);
881 }
882 while(xb < xbe);
883 while(xa < xae) {
884 y = (*xa & 0xffff) + borrow;
885 borrow = y >> 16;
886 Sign_Extend(borrow, y);
887 z = (*xa++ >> 16) + borrow;
888 borrow = z >> 16;
889 Sign_Extend(borrow, z);
890 Storeinc(xc, z, y);
891 }
892#else
893 do {
894 y = *xa++ - *xb++ + borrow;
895 borrow = y >> 16;
896 Sign_Extend(borrow, y);
897 *xc++ = y & 0xffff;
898 }
899 while(xb < xbe);
900 while(xa < xae) {
901 y = *xa++ + borrow;
902 borrow = y >> 16;
903 Sign_Extend(borrow, y);
904 *xc++ = y & 0xffff;
905 }
906#endif
907 while(!*--xc)
908 wa--;
909 c->wds = wa;
910 return c;
911 }
912
913 static double
914ulp
915#ifdef KR_headers
916 (_x) double _x;
917#else
918 (double _x)
919#endif
920{
921 _double x;
922 register Long L;
923 _double a;
924
925 value(x) = _x;
926 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
927#ifndef Sudden_Underflow
928 if (L > 0) {
929#endif
930#ifdef IBM
931 L |= Exp_msk1 >> 4;
932#endif
933 word0(a) = L;
934 word1(a) = 0;
935#ifndef Sudden_Underflow
936 }
937 else {
938 L = -L >> Exp_shift;
939 if (L < Exp_shift) {
940 word0(a) = 0x80000 >> L;
941 word1(a) = 0;
942 }
943 else {
944 word0(a) = 0;
945 L -= Exp_shift;
946 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
947 }
948 }
949#endif
950 return value(a);
951 }
952
953 static double
954b2d
955#ifdef KR_headers
956 (a, e) Bigint *a; int *e;
957#else
958 (Bigint *a, int *e)
959#endif
960{
961 ULong *xa, *xa0, w, y, z;
962 int k;
963 _double d;
964#ifdef VAX
965 ULong d0, d1;
966#else
967#define d0 word0(d)
968#define d1 word1(d)
969#endif
970
971 xa0 = a->x;
972 xa = xa0 + a->wds;
973 y = *--xa;
974#ifdef DEBUG
975 if (!y) Bug("zero y in b2d");
976#endif
977 k = hi0bits(y);
978 *e = 32 - k;
979#ifdef Pack_32
980 if (k < Ebits) {
981 d0 = Exp_1 | y >> Ebits - k;
982 w = xa > xa0 ? *--xa : 0;
983 d1 = y << (32-Ebits) + k | w >> Ebits - k;
984 goto ret_d;
985 }
986 z = xa > xa0 ? *--xa : 0;
987 if (k -= Ebits) {
988 d0 = Exp_1 | y << k | z >> 32 - k;
989 y = xa > xa0 ? *--xa : 0;
990 d1 = z << k | y >> 32 - k;
991 }
992 else {
993 d0 = Exp_1 | y;
994 d1 = z;
995 }
996#else
997 if (k < Ebits + 16) {
998 z = xa > xa0 ? *--xa : 0;
999 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1000 w = xa > xa0 ? *--xa : 0;
1001 y = xa > xa0 ? *--xa : 0;
1002 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1003 goto ret_d;
1004 }
1005 z = xa > xa0 ? *--xa : 0;
1006 w = xa > xa0 ? *--xa : 0;
1007 k -= Ebits + 16;
1008 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1009 y = xa > xa0 ? *--xa : 0;
1010 d1 = w << k + 16 | y << k;
1011#endif
1012 ret_d:
1013#ifdef VAX
1014 word0(d) = d0 >> 16 | d0 << 16;
1015 word1(d) = d1 >> 16 | d1 << 16;
1016#else
1017#undef d0
1018#undef d1
1019#endif
1020 return value(d);
1021 }
1022
1023 static Bigint *
1024d2b
1025#ifdef KR_headers
1026 (_d, e, bits) double d; int *e, *bits;
1027#else
1028 (double _d, int *e, int *bits)
1029#endif
1030{
1031 Bigint *b;
1032 int de, i, k;
1033 ULong *x, y, z;
1034 _double d;
1035#ifdef VAX
1036 ULong d0, d1;
1037#endif
1038
1039 value(d) = _d;
1040#ifdef VAX
1041 d0 = word0(d) >> 16 | word0(d) << 16;
1042 d1 = word1(d) >> 16 | word1(d) << 16;
1043#else
1044#define d0 word0(d)
1045#define d1 word1(d)
1046#endif
1047
1048#ifdef Pack_32
1049 b = Balloc(1);
1050#else
1051 b = Balloc(2);
1052#endif
1053 x = b->x;
1054
1055 z = d0 & Frac_mask;
1056 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
1057#ifdef Sudden_Underflow
1058 de = (int)(d0 >> Exp_shift);
1059#ifndef IBM
1060 z |= Exp_msk11;
1061#endif
1062#else
1063 if (de = (int)(d0 >> Exp_shift))
1064 z |= Exp_msk1;
1065#endif
1066#ifdef Pack_32
1067 if (y = d1) {
1068 if (k = lo0bits(&y)) {
1069 x[0] = y | z << 32 - k;
1070 z >>= k;
1071 }
1072 else
1073 x[0] = y;
1074 i = b->wds = (x[1] = z) ? 2 : 1;
1075 }
1076 else {
1077#ifdef DEBUG
1078 if (!z)
1079 Bug("Zero passed to d2b");
1080#endif
1081 k = lo0bits(&z);
1082 x[0] = z;
1083 i = b->wds = 1;
1084 k += 32;
1085 }
1086#else
1087 if (y = d1) {
1088 if (k = lo0bits(&y))
1089 if (k >= 16) {
1090 x[0] = y | z << 32 - k & 0xffff;
1091 x[1] = z >> k - 16 & 0xffff;
1092 x[2] = z >> k;
1093 i = 2;
1094 }
1095 else {
1096 x[0] = y & 0xffff;
1097 x[1] = y >> 16 | z << 16 - k & 0xffff;
1098 x[2] = z >> k & 0xffff;
1099 x[3] = z >> k+16;
1100 i = 3;
1101 }
1102 else {
1103 x[0] = y & 0xffff;
1104 x[1] = y >> 16;
1105 x[2] = z & 0xffff;
1106 x[3] = z >> 16;
1107 i = 3;
1108 }
1109 }
1110 else {
1111#ifdef DEBUG
1112 if (!z)
1113 Bug("Zero passed to d2b");
1114#endif
1115 k = lo0bits(&z);
1116 if (k >= 16) {
1117 x[0] = z;
1118 i = 0;
1119 }
1120 else {
1121 x[0] = z & 0xffff;
1122 x[1] = z >> 16;
1123 i = 1;
1124 }
1125 k += 32;
1126 }
1127 while(!x[i])
1128 --i;
1129 b->wds = i + 1;
1130#endif
1131#ifndef Sudden_Underflow
1132 if (de) {
1133#endif
1134#ifdef IBM
1135 *e = (de - Bias - (P-1) << 2) + k;
1136 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1137#else
1138 *e = de - Bias - (P-1) + k;
1139 *bits = P - k;
1140#endif
1141#ifndef Sudden_Underflow
1142 }
1143 else {
1144 *e = de - Bias - (P-1) + 1 + k;
1145#ifdef Pack_32
1146 *bits = 32*i - hi0bits(x[i-1]);
1147#else
1148 *bits = (i+2)*16 - hi0bits(x[i]);
1149#endif
1150 }
1151#endif
1152 return b;
1153 }
1154#undef d0
1155#undef d1
1156
1157 static double
1158ratio
1159#ifdef KR_headers
1160 (a, b) Bigint *a, *b;
1161#else
1162 (Bigint *a, Bigint *b)
1163#endif
1164{
1165 _double da, db;
1166 int k, ka, kb;
1167
1168 value(da) = b2d(a, &ka);
1169 value(db) = b2d(b, &kb);
1170#ifdef Pack_32
1171 k = ka - kb + 32*(a->wds - b->wds);
1172#else
1173 k = ka - kb + 16*(a->wds - b->wds);
1174#endif
1175#ifdef IBM
1176 if (k > 0) {
1177 word0(da) += (k >> 2)*Exp_msk1;
1178 if (k &= 3)
1179 da *= 1 << k;
1180 }
1181 else {
1182 k = -k;
1183 word0(db) += (k >> 2)*Exp_msk1;
1184 if (k &= 3)
1185 db *= 1 << k;
1186 }
1187#else
1188 if (k > 0)
1189 word0(da) += k*Exp_msk1;
1190 else {
1191 k = -k;
1192 word0(db) += k*Exp_msk1;
1193 }
1194#endif
1195 return value(da) / value(db);
1196 }
1197
1198static CONST double
1199tens[] = {
1200 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1201 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1202 1e20, 1e21, 1e22
1203#ifdef VAX
1204 , 1e23, 1e24
1205#endif
1206 };
1207
1208#ifdef IEEE_Arith
1209static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1210static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
1211#define n_bigtens 5
1212#else
1213#ifdef IBM
1214static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
1215static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1216#define n_bigtens 3
1217#else
1218static CONST double bigtens[] = { 1e16, 1e32 };
1219static CONST double tinytens[] = { 1e-16, 1e-32 };
1220#define n_bigtens 2
1221#endif
1222#endif
1223
1224 double
1225strtod
1226#ifdef KR_headers
1227 (s00, se) CONST char *s00; char **se;
1228#else
1229 (CONST char *s00, char **se)
1230#endif
1231{
1232 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1233 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1234 CONST char *s, *s0, *s1;
1235 double aadj, aadj1, adj;
1236 _double rv, rv0;
1237 Long L;
1238 ULong y, z;
1239 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1240
1241#ifndef KR_headers
1242 CONST char decimal_point = localeconv()->decimal_point[0];
1243#else
1244 CONST char decimal_point = '.';
1245#endif
1246
1247 sign = nz0 = nz = 0;
1248 value(rv) = 0.;
1249
1250
1251 for(s = s00; isspace((unsigned char) *s); s++)
1252 ;
1253
1254 if (*s == '-') {
1255 sign = 1;
1256 s++;
1257 } else if (*s == '+') {
1258 s++;
1259 }
1260
1261 if (*s == '\0') {
1262 s = s00;
1263 goto ret;
1264 }
1265
1266 if (*s == '0') {
1267 nz0 = 1;
1268 while(*++s == '0') ;
1269 if (!*s)
1270 goto ret;
1271 }
1272 s0 = s;
1273 y = z = 0;
1274 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
1275 if (nd < 9)
1276 y = 10*y + c - '0';
1277 else if (nd < 16)
1278 z = 10*z + c - '0';
1279 nd0 = nd;
1280 if (c == decimal_point) {
1281 c = *++s;
1282 if (!nd) {
1283 for(; c == '0'; c = *++s)
1284 nz++;
1285 if (c > '0' && c <= '9') {
1286 s0 = s;
1287 nf += nz;
1288 nz = 0;
1289 goto have_dig;
1290 }
1291 goto dig_done;
1292 }
1293 for(; c >= '0' && c <= '9'; c = *++s) {
1294 have_dig:
1295 nz++;
1296 if (c -= '0') {
1297 nf += nz;
1298 for(i = 1; i < nz; i++)
1299 if (nd++ < 9)
1300 y *= 10;
1301 else if (nd <= DBL_DIG + 1)
1302 z *= 10;
1303 if (nd++ < 9)
1304 y = 10*y + c;
1305 else if (nd <= DBL_DIG + 1)
1306 z = 10*z + c;
1307 nz = 0;
1308 }
1309 }
1310 }
1311 dig_done:
1312 e = 0;
1313 if (c == 'e' || c == 'E') {
1314 if (!nd && !nz && !nz0) {
1315 s = s00;
1316 goto ret;
1317 }
1318 s00 = s;
1319 esign = 0;
1320 switch(c = *++s) {
1321 case '-':
1322 esign = 1;
1323 case '+':
1324 c = *++s;
1325 }
1326 if (c >= '0' && c <= '9') {
1327 while(c == '0')
1328 c = *++s;
1329 if (c > '0' && c <= '9') {
1330 L = c - '0';
1331 s1 = s;
1332 while((c = *++s) >= '0' && c <= '9')
1333 L = 10*L + c - '0';
1334 if (s - s1 > 8 || L > 19999)
1335 /* Avoid confusion from exponents
1336 * so large that e might overflow.
1337 */
1338 e = 19999; /* safe for 16 bit ints */
1339 else
1340 e = (int)L;
1341 if (esign)
1342 e = -e;
1343 }
1344 else
1345 e = 0;
1346 }
1347 else
1348 s = s00;
1349 }
1350 if (!nd) {
1351 if (!nz && !nz0)
1352 s = s00;
1353 goto ret;
1354 }
1355 e1 = e -= nf;
1356
1357 /* Now we have nd0 digits, starting at s0, followed by a
1358 * decimal point, followed by nd-nd0 digits. The number we're
1359 * after is the integer represented by those digits times
1360 * 10**e */
1361
1362 if (!nd0)
1363 nd0 = nd;
1364 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1365 value(rv) = y;
1366 if (k > 9)
1367 value(rv) = tens[k - 9] * value(rv) + z;
1368 bd0 = 0;
1369 if (nd <= DBL_DIG
1370#ifndef RND_PRODQUOT
1371 && FLT_ROUNDS == 1
1372#endif
1373 ) {
1374 if (!e)
1375 goto ret;
1376 if (e > 0) {
1377 if (e <= Ten_pmax) {
1378#ifdef VAX
1379 goto vax_ovfl_check;
1380#else
1381 /* value(rv) = */ rounded_product(value(rv),
1382 tens[e]);
1383 goto ret;
1384#endif
1385 }
1386 i = DBL_DIG - nd;
1387 if (e <= Ten_pmax + i) {
1388 /* A fancier test would sometimes let us do
1389 * this for larger i values.
1390 */
1391 e -= i;
1392 value(rv) *= tens[i];
1393#ifdef VAX
1394 /* VAX exponent range is so narrow we must
1395 * worry about overflow here...
1396 */
1397 vax_ovfl_check:
1398 word0(rv) -= P*Exp_msk1;
1399 /* value(rv) = */ rounded_product(value(rv),
1400 tens[e]);
1401 if ((word0(rv) & Exp_mask)
1402 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1403 goto ovfl;
1404 word0(rv) += P*Exp_msk1;
1405#else
1406 /* value(rv) = */ rounded_product(value(rv),
1407 tens[e]);
1408#endif
1409 goto ret;
1410 }
1411 }
1412#ifndef Inaccurate_Divide
1413 else if (e >= -Ten_pmax) {
1414 /* value(rv) = */ rounded_quotient(value(rv),
1415 tens[-e]);
1416 goto ret;
1417 }
1418#endif
1419 }
1420 e1 += nd - k;
1421
1422 /* Get starting approximation = rv * 10**e1 */
1423
1424 if (e1 > 0) {
1425 if (i = e1 & 15)
1426 value(rv) *= tens[i];
1427 if (e1 &= ~15) {
1428 if (e1 > DBL_MAX_10_EXP) {
1429 ovfl:
1430 errno = ERANGE;
1431#ifndef Bad_float_h
1432 value(rv) = HUGE_VAL;
1433#else
1434 /* Can't trust HUGE_VAL */
1435#ifdef IEEE_Arith
1436 word0(rv) = Exp_mask;
1437 word1(rv) = 0;
1438#else
1439 word0(rv) = Big0;
1440 word1(rv) = Big1;
1441#endif
1442#endif
1443 if (bd0)
1444 goto retfree;
1445 goto ret;
1446 }
1447 if (e1 >>= 4) {
1448 for(j = 0; e1 > 1; j++, e1 >>= 1)
1449 if (e1 & 1)
1450 value(rv) *= bigtens[j];
1451 /* The last multiplication could overflow. */
1452 word0(rv) -= P*Exp_msk1;
1453 value(rv) *= bigtens[j];
1454 if ((z = word0(rv) & Exp_mask)
1455 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1456 goto ovfl;
1457 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1458 /* set to largest number */
1459 /* (Can't trust DBL_MAX) */
1460 word0(rv) = Big0;
1461 word1(rv) = Big1;
1462 }
1463 else
1464 word0(rv) += P*Exp_msk1;
1465 }
1466
1467 }
1468 }
1469 else if (e1 < 0) {
1470 e1 = -e1;
1471 if (i = e1 & 15)
1472 value(rv) /= tens[i];
1473 if (e1 &= ~15) {
1474 e1 >>= 4;
1475 if (e1 >= 1 << n_bigtens)
1476 goto undfl;
1477 for(j = 0; e1 > 1; j++, e1 >>= 1)
1478 if (e1 & 1)
1479 value(rv) *= tinytens[j];
1480 /* The last multiplication could underflow. */
1481 value(rv0) = value(rv);
1482 value(rv) *= tinytens[j];
1483 if (!value(rv)) {
1484 value(rv) = 2.*value(rv0);
1485 value(rv) *= tinytens[j];
1486 if (!value(rv)) {
1487 undfl:
1488 value(rv) = 0.;
1489 errno = ERANGE;
1490 if (bd0)
1491 goto retfree;
1492 goto ret;
1493 }
1494 word0(rv) = Tiny0;
1495 word1(rv) = Tiny1;
1496 /* The refinement below will clean
1497 * this approximation up.
1498 */
1499 }
1500 }
1501 }
1502
1503 /* Now the hard part -- adjusting rv to the correct value.*/
1504
1505 /* Put digits into bd: true value = bd * 10^e */
1506
1507 bd0 = s2b(s0, nd0, nd, y);
1508
1509 for(;;) {
1510 bd = Balloc(bd0->k);
1511 Bcopy(bd, bd0);
1512 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1513 bs = i2b(1);
1514
1515 if (e >= 0) {
1516 bb2 = bb5 = 0;
1517 bd2 = bd5 = e;
1518 }
1519 else {
1520 bb2 = bb5 = -e;
1521 bd2 = bd5 = 0;
1522 }
1523 if (bbe >= 0)
1524 bb2 += bbe;
1525 else
1526 bd2 -= bbe;
1527 bs2 = bb2;
1528#ifdef Sudden_Underflow
1529#ifdef IBM
1530 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
1531#else
1532 j = P + 1 - bbbits;
1533#endif
1534#else
1535 i = bbe + bbbits - 1; /* logb(rv) */
1536 if (i < Emin) /* denormal */
1537 j = bbe + (P-Emin);
1538 else
1539 j = P + 1 - bbbits;
1540#endif
1541 bb2 += j;
1542 bd2 += j;
1543 i = bb2 < bd2 ? bb2 : bd2;
1544 if (i > bs2)
1545 i = bs2;
1546 if (i > 0) {
1547 bb2 -= i;
1548 bd2 -= i;
1549 bs2 -= i;
1550 }
1551 if (bb5 > 0) {
1552 bs = pow5mult(bs, bb5);
1553 bb1 = mult(bs, bb);
1554 Bfree(bb);
1555 bb = bb1;
1556 }
1557 if (bb2 > 0)
1558 bb = lshift(bb, bb2);
1559 if (bd5 > 0)
1560 bd = pow5mult(bd, bd5);
1561 if (bd2 > 0)
1562 bd = lshift(bd, bd2);
1563 if (bs2 > 0)
1564 bs = lshift(bs, bs2);
1565 delta = diff(bb, bd);
1566 dsign = delta->sign;
1567 delta->sign = 0;
1568 i = cmp(delta, bs);
1569 if (i < 0) {
1570 /* Error is less than half an ulp -- check for
1571 * special case of mantissa a power of two.
1572 */
1573 if (dsign || word1(rv) || word0(rv) & Bndry_mask)
1574 break;
1575 delta = lshift(delta,Log2P);
1576 if (cmp(delta, bs) > 0)
1577 goto drop_down;
1578 break;
1579 }
1580 if (i == 0) {
1581 /* exactly half-way between */
1582 if (dsign) {
1583 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
1584 && word1(rv) == 0xffffffff) {
1585 /*boundary case -- increment exponent*/
1586 word0(rv) = (word0(rv) & Exp_mask)
1587 + Exp_msk1
1588#ifdef IBM
1589 | Exp_msk1 >> 4
1590#endif
1591 ;
1592 word1(rv) = 0;
1593 break;
1594 }
1595 }
1596 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
1597 drop_down:
1598 /* boundary case -- decrement exponent */
1599#ifdef Sudden_Underflow
1600 L = word0(rv) & Exp_mask;
1601#ifdef IBM
1602 if (L < Exp_msk1)
1603#else
1604 if (L <= Exp_msk1)
1605#endif
1606 goto undfl;
1607 L -= Exp_msk1;
1608#else
1609 L = (word0(rv) & Exp_mask) - Exp_msk1;
1610#endif
1611 word0(rv) = L | Bndry_mask1;
1612 word1(rv) = 0xffffffff;
1613#ifdef IBM
1614 goto cont;
1615#else
1616 break;
1617#endif
1618 }
1619#ifndef ROUND_BIASED
1620 if (!(word1(rv) & LSB))
1621 break;
1622#endif
1623 if (dsign)
1624 value(rv) += ulp(value(rv));
1625#ifndef ROUND_BIASED
1626 else {
1627 value(rv) -= ulp(value(rv));
1628#ifndef Sudden_Underflow
1629 if (!value(rv))
1630 goto undfl;
1631#endif
1632 }
1633#endif
1634 break;
1635 }
1636 if ((aadj = ratio(delta, bs)) <= 2.) {
1637 if (dsign)
1638 aadj = aadj1 = 1.;
1639 else if (word1(rv) || word0(rv) & Bndry_mask) {
1640#ifndef Sudden_Underflow
1641 if (word1(rv) == Tiny1 && !word0(rv))
1642 goto undfl;
1643#endif
1644 aadj = 1.;
1645 aadj1 = -1.;
1646 }
1647 else {
1648 /* special case -- power of FLT_RADIX to be */
1649 /* rounded down... */
1650
1651 if (aadj < 2./FLT_RADIX)
1652 aadj = 1./FLT_RADIX;
1653 else
1654 aadj *= 0.5;
1655 aadj1 = -aadj;
1656 }
1657 }
1658 else {
1659 aadj *= 0.5;
1660 aadj1 = dsign ? aadj : -aadj;
1661#ifdef Check_FLT_ROUNDS
1662 switch(FLT_ROUNDS) {
1663 case 2: /* towards +infinity */
1664 aadj1 -= 0.5;
1665 break;
1666 case 0: /* towards 0 */
1667 case 3: /* towards -infinity */
1668 aadj1 += 0.5;
1669 }
1670#else
1671 if (FLT_ROUNDS == 0)
1672 aadj1 += 0.5;
1673#endif
1674 }
1675 y = word0(rv) & Exp_mask;
1676
1677 /* Check for overflow */
1678
1679 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1680 value(rv0) = value(rv);
1681 word0(rv) -= P*Exp_msk1;
1682 adj = aadj1 * ulp(value(rv));
1683 value(rv) += adj;
1684 if ((word0(rv) & Exp_mask) >=
1685 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1686 if (word0(rv0) == Big0 && word1(rv0) == Big1)
1687 goto ovfl;
1688 word0(rv) = Big0;
1689 word1(rv) = Big1;
1690 goto cont;
1691 }
1692 else
1693 word0(rv) += P*Exp_msk1;
1694 }
1695 else {
1696#ifdef Sudden_Underflow
1697 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1698 value(rv0) = value(rv);
1699 word0(rv) += P*Exp_msk1;
1700 adj = aadj1 * ulp(value(rv));
1701 value(rv) += adj;
1702#ifdef IBM
1703 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1704#else
1705 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
1706#endif
1707 {
1708 if (word0(rv0) == Tiny0
1709 && word1(rv0) == Tiny1)
1710 goto undfl;
1711 word0(rv) = Tiny0;
1712 word1(rv) = Tiny1;
1713 goto cont;
1714 }
1715 else
1716 word0(rv) -= P*Exp_msk1;
1717 }
1718 else {
1719 adj = aadj1 * ulp(value(rv));
1720 value(rv) += adj;
1721 }
1722#else
1723 /* Compute adj so that the IEEE rounding rules will
1724 * correctly round rv + adj in some half-way cases.
1725 * If rv * ulp(rv) is denormalized (i.e.,
1726 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1727 * trouble from bits lost to denormalization;
1728 * example: 1.2e-307 .
1729 */
1730 if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
1731 aadj1 = (double)(int)(aadj + 0.5);
1732 if (!dsign)
1733 aadj1 = -aadj1;
1734 }
1735 adj = aadj1 * ulp(value(rv));
1736 value(rv) += adj;
1737#endif
1738 }
1739 z = word0(rv) & Exp_mask;
1740 if (y == z) {
1741 /* Can we stop now? */
1742 L = aadj;
1743 aadj -= L;
1744 /* The tolerances below are conservative. */
1745 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
1746 if (aadj < .4999999 || aadj > .5000001)
1747 break;
1748 }
1749 else if (aadj < .4999999/FLT_RADIX)
1750 break;
1751 }
1752 cont:
1753 Bfree(bb);
1754 Bfree(bd);
1755 Bfree(bs);
1756 Bfree(delta);
1757 }
1758 retfree:
1759 Bfree(bb);
1760 Bfree(bd);
1761 Bfree(bs);
1762 Bfree(bd0);
1763 Bfree(delta);
1764 ret:
1765 if (se)
1766 *se = (char *)s;
1767 return sign ? -value(rv) : value(rv);
1768 }
1769
1770 static int
1771quorem
1772#ifdef KR_headers
1773 (b, S) Bigint *b, *S;
1774#else
1775 (Bigint *b, Bigint *S)
1776#endif
1777{
1778 int n;
1779 Long borrow, y;
1780 ULong carry, q, ys;
1781 ULong *bx, *bxe, *sx, *sxe;
1782#ifdef Pack_32
1783 Long z;
1784 ULong si, zs;
1785#endif
1786
1787 n = S->wds;
1788#ifdef DEBUG
1789 /*debug*/ if (b->wds > n)
1790 /*debug*/ Bug("oversize b in quorem");
1791#endif
1792 if (b->wds < n)
1793 return 0;
1794 sx = S->x;
1795 sxe = sx + --n;
1796 bx = b->x;
1797 bxe = bx + n;
1798 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1799#ifdef DEBUG
1800 /*debug*/ if (q > 9)
1801 /*debug*/ Bug("oversized quotient in quorem");
1802#endif
1803 if (q) {
1804 borrow = 0;
1805 carry = 0;
1806 do {
1807#ifdef Pack_32
1808 si = *sx++;
1809 ys = (si & 0xffff) * q + carry;
1810 zs = (si >> 16) * q + (ys >> 16);
1811 carry = zs >> 16;
1812 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1813 borrow = y >> 16;
1814 Sign_Extend(borrow, y);
1815 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1816 borrow = z >> 16;
1817 Sign_Extend(borrow, z);
1818 Storeinc(bx, z, y);
1819#else
1820 ys = *sx++ * q + carry;
1821 carry = ys >> 16;
1822 y = *bx - (ys & 0xffff) + borrow;
1823 borrow = y >> 16;
1824 Sign_Extend(borrow, y);
1825 *bx++ = y & 0xffff;
1826#endif
1827 }
1828 while(sx <= sxe);
1829 if (!*bxe) {
1830 bx = b->x;
1831 while(--bxe > bx && !*bxe)
1832 --n;
1833 b->wds = n;
1834 }
1835 }
1836 if (cmp(b, S) >= 0) {
1837 q++;
1838 borrow = 0;
1839 carry = 0;
1840 bx = b->x;
1841 sx = S->x;
1842 do {
1843#ifdef Pack_32
1844 si = *sx++;
1845 ys = (si & 0xffff) + carry;
1846 zs = (si >> 16) + (ys >> 16);
1847 carry = zs >> 16;
1848 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1849 borrow = y >> 16;
1850 Sign_Extend(borrow, y);
1851 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1852 borrow = z >> 16;
1853 Sign_Extend(borrow, z);
1854 Storeinc(bx, z, y);
1855#else
1856 ys = *sx++ + carry;
1857 carry = ys >> 16;
1858 y = *bx - (ys & 0xffff) + borrow;
1859 borrow = y >> 16;
1860 Sign_Extend(borrow, y);
1861 *bx++ = y & 0xffff;
1862#endif
1863 }
1864 while(sx <= sxe);
1865 bx = b->x;
1866 bxe = bx + n;
1867 if (!*bxe) {
1868 while(--bxe > bx && !*bxe)
1869 --n;
1870 b->wds = n;
1871 }
1872 }
1873 return q;
1874 }
1875
1876/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
1877 *
1878 * Inspired by "How to Print Floating-Point Numbers Accurately" by
1879 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
1880 *
1881 * Modifications:
1882 * 1. Rather than iterating, we use a simple numeric overestimate
1883 * to determine k = floor(log10(d)). We scale relevant
1884 * quantities using O(log2(k)) rather than O(k) multiplications.
1885 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
1886 * try to generate digits strictly left to right. Instead, we
1887 * compute with fewer bits and propagate the carry if necessary
1888 * when rounding the final digit up. This is often faster.
1889 * 3. Under the assumption that input will be rounded nearest,
1890 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
1891 * That is, we allow equality in stopping tests when the
1892 * round-nearest rule will give the same floating-point value
1893 * as would satisfaction of the stopping test with strict
1894 * inequality.
1895 * 4. We remove common factors of powers of 2 from relevant
1896 * quantities.
1897 * 5. When converting floating-point integers less than 1e16,
1898 * we use floating-point arithmetic rather than resorting
1899 * to multiple-precision integers.
1900 * 6. When asked to produce fewer than 15 digits, we first try
1901 * to get by with floating-point arithmetic; we resort to
1902 * multiple-precision integer arithmetic only if we cannot
1903 * guarantee that the floating-point calculation has given
1904 * the correctly rounded result. For k requested digits and
1905 * "uniformly" distributed input, the probability is
1906 * something like 10^(k-15) that we must resort to the Long
1907 * calculation.
1908 */
1909
1910 char *
1911__dtoa
1912#ifdef KR_headers
1913 (_d, mode, ndigits, decpt, sign, rve)
1914 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1915#else
1916 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1917#endif
1918{
1919 /* Arguments ndigits, decpt, sign are similar to those
1920 of ecvt and fcvt; trailing zeros are suppressed from
1921 the returned string. If not null, *rve is set to point
1922 to the end of the return value. If d is +-Infinity or NaN,
1923 then *decpt is set to 9999.
1924
1925 mode:
1926 0 ==> shortest string that yields d when read in
1927 and rounded to nearest.
1928 1 ==> like 0, but with Steele & White stopping rule;
1929 e.g. with IEEE P754 arithmetic , mode 0 gives
1930 1e23 whereas mode 1 gives 9.999999999999999e22.
1931 2 ==> max(1,ndigits) significant digits. This gives a
1932 return value similar to that of ecvt, except
1933 that trailing zeros are suppressed.
1934 3 ==> through ndigits past the decimal point. This
1935 gives a return value similar to that from fcvt,
1936 except that trailing zeros are suppressed, and
1937 ndigits can be negative.
1938 4-9 should give the same return values as 2-3, i.e.,
1939 4 <= mode <= 9 ==> same return as mode
1940 2 + (mode & 1). These modes are mainly for
1941 debugging; often they run slower but sometimes
1942 faster than modes 2-3.
1943 4,5,8,9 ==> left-to-right digit generation.
1944 6-9 ==> don't try fast floating-point estimate
1945 (if applicable).
1946
1947 Values of mode other than 0-9 are treated as mode 0.
1948
1949 Sufficient space is allocated to the return value
1950 to hold the suppressed trailing zeros.
1951 */
1952
1953 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1954 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1955 spec_case, try_quick;
1956 Long L;
1957#ifndef Sudden_Underflow
1958 int denorm;
1959 ULong x;
1960#endif
1961 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1962 double ds;
1963 char *s, *s0;
1964 static Bigint *result;
1965 static int result_k;
1966 _double d, d2, eps;
1967
1968 value(d) = _d;
1969 if (result) {
1970 result->k = result_k;
1971 result->maxwds = 1 << result_k;
1972 Bfree(result);
1973 result = 0;
1974 }
1975
1976 if (word0(d) & Sign_bit) {
1977 /* set sign for everything, including 0's and NaNs */
1978 *sign = 1;
1979 word0(d) &= ~Sign_bit; /* clear sign bit */
1980 }
1981 else
1982 *sign = 0;
1983
1984#if defined(IEEE_Arith) + defined(VAX)
1985#ifdef IEEE_Arith
1986 if ((word0(d) & Exp_mask) == Exp_mask)
1987#else
1988 if (word0(d) == 0x8000)
1989#endif
1990 {
1991 /* Infinity or NaN */
1992 *decpt = 9999;
1993 s =
1994#ifdef IEEE_Arith
1995 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
1996#endif
1997 "NaN";
1998 if (rve)
1999 *rve =
2000#ifdef IEEE_Arith
2001 s[3] ? s + 8 :
2002#endif
2003 s + 3;
2004 return s;
2005 }
2006#endif
2007#ifdef IBM
2008 value(d) += 0; /* normalize */
2009#endif
2010 if (!value(d)) {
2011 *decpt = 1;
2012 s = "0";
2013 if (rve)
2014 *rve = s + 1;
2015 return s;
2016 }
2017
2018 b = d2b(value(d), &be, &bbits);
2019#ifdef Sudden_Underflow
2020 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2021#else
2022 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
2023#endif
2024 value(d2) = value(d);
2025 word0(d2) &= Frac_mask1;
2026 word0(d2) |= Exp_11;
2027#ifdef IBM
2028 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2029 value(d2) /= 1 << j;
2030#endif
2031
2032 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2033 * log10(x) = log(x) / log(10)
2034 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2035 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2036 *
2037 * This suggests computing an approximation k to log10(d) by
2038 *
2039 * k = (i - Bias)*0.301029995663981
2040 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2041 *
2042 * We want k to be too large rather than too small.
2043 * The error in the first-order Taylor series approximation
2044 * is in our favor, so we just round up the constant enough
2045 * to compensate for any error in the multiplication of
2046 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2047 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2048 * adding 1e-13 to the constant term more than suffices.
2049 * Hence we adjust the constant term to 0.1760912590558.
2050 * (We could get a more accurate k by invoking log10,
2051 * but this is probably not worthwhile.)
2052 */
2053
2054 i -= Bias;
2055#ifdef IBM
2056 i <<= 2;
2057 i += j;
2058#endif
2059#ifndef Sudden_Underflow
2060 denorm = 0;
2061 }
2062 else {
2063 /* d is denormalized */
2064
2065 i = bbits + be + (Bias + (P-1) - 1);
2066 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2067 : word1(d) << 32 - i;
2068 value(d2) = x;
2069 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2070 i -= (Bias + (P-1) - 1) + 1;
2071 denorm = 1;
2072 }
2073#endif
2074 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2075 i*0.301029995663981;
2076 k = (int)ds;
2077 if (ds < 0. && ds != k)
2078 k--; /* want k = floor(ds) */
2079 k_check = 1;
2080 if (k >= 0 && k <= Ten_pmax) {
2081 if (value(d) < tens[k])
2082 k--;
2083 k_check = 0;
2084 }
2085 j = bbits - i - 1;
2086 if (j >= 0) {
2087 b2 = 0;
2088 s2 = j;
2089 }
2090 else {
2091 b2 = -j;
2092 s2 = 0;
2093 }
2094 if (k >= 0) {
2095 b5 = 0;
2096 s5 = k;
2097 s2 += k;
2098 }
2099 else {
2100 b2 -= k;
2101 b5 = -k;
2102 s5 = 0;
2103 }
2104 if (mode < 0 || mode > 9)
2105 mode = 0;
2106 try_quick = 1;
2107 if (mode > 5) {
2108 mode -= 4;
2109 try_quick = 0;
2110 }
2111 leftright = 1;
2112 switch(mode) {
2113 case 0:
2114 case 1:
2115 ilim = ilim1 = -1;
2116 i = 18;
2117 ndigits = 0;
2118 break;
2119 case 2:
2120 leftright = 0;
2121 /* no break */
2122 case 4:
2123 if (ndigits <= 0)
2124 ndigits = 1;
2125 ilim = ilim1 = i = ndigits;
2126 break;
2127 case 3:
2128 leftright = 0;
2129 /* no break */
2130 case 5:
2131 i = ndigits + k + 1;
2132 ilim = i;
2133 ilim1 = i - 1;
2134 if (i <= 0)
2135 i = 1;
2136 }
2137 j = sizeof(ULong);
2138 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2139 j <<= 1) result_k++;
2140 result = Balloc(result_k);
2141 s = s0 = (char *)result;
2142
2143 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2144
2145 /* Try to get by with floating-point arithmetic. */
2146
2147 i = 0;
2148 value(d2) = value(d);
2149 k0 = k;
2150 ilim0 = ilim;
2151 ieps = 2; /* conservative */
2152 if (k > 0) {
2153 ds = tens[k&0xf];
2154 j = k >> 4;
2155 if (j & Bletch) {
2156 /* prevent overflows */
2157 j &= Bletch - 1;
2158 value(d) /= bigtens[n_bigtens-1];
2159 ieps++;
2160 }
2161 for(; j; j >>= 1, i++)
2162 if (j & 1) {
2163 ieps++;
2164 ds *= bigtens[i];
2165 }
2166 value(d) /= ds;
2167 }
2168 else if (j1 = -k) {
2169 value(d) *= tens[j1 & 0xf];
2170 for(j = j1 >> 4; j; j >>= 1, i++)
2171 if (j & 1) {
2172 ieps++;
2173 value(d) *= bigtens[i];
2174 }
2175 }
2176 if (k_check && value(d) < 1. && ilim > 0) {
2177 if (ilim1 <= 0)
2178 goto fast_failed;
2179 ilim = ilim1;
2180 k--;
2181 value(d) *= 10.;
2182 ieps++;
2183 }
2184 value(eps) = ieps*value(d) + 7.;
2185 word0(eps) -= (P-1)*Exp_msk1;
2186 if (ilim == 0) {
2187 S = mhi = 0;
2188 value(d) -= 5.;
2189 if (value(d) > value(eps))
2190 goto one_digit;
2191 if (value(d) < -value(eps))
2192 goto no_digits;
2193 goto fast_failed;
2194 }
2195#ifndef No_leftright
2196 if (leftright) {
2197 /* Use Steele & White method of only
2198 * generating digits needed.
2199 */
2200 value(eps) = 0.5/tens[ilim-1] - value(eps);
2201 for(i = 0;;) {
2202 L = value(d);
2203 value(d) -= L;
2204 *s++ = '0' + (int)L;
2205 if (value(d) < value(eps))
2206 goto ret1;
2207 if (1. - value(d) < value(eps))
2208 goto bump_up;
2209 if (++i >= ilim)
2210 break;
2211 value(eps) *= 10.;
2212 value(d) *= 10.;
2213 }
2214 }
2215 else {
2216#endif
2217 /* Generate ilim digits, then fix them up. */
2218 value(eps) *= tens[ilim-1];
2219 for(i = 1;; i++, value(d) *= 10.) {
2220 L = value(d);
2221 value(d) -= L;
2222 *s++ = '0' + (int)L;
2223 if (i == ilim) {
2224 if (value(d) > 0.5 + value(eps))
2225 goto bump_up;
2226 else if (value(d) < 0.5 - value(eps)) {
2227 while(*--s == '0');
2228 s++;
2229 goto ret1;
2230 }
2231 break;
2232 }
2233 }
2234#ifndef No_leftright
2235 }
2236#endif
2237 fast_failed:
2238 s = s0;
2239 value(d) = value(d2);
2240 k = k0;
2241 ilim = ilim0;
2242 }
2243
2244 /* Do we have a "small" integer? */
2245
2246 if (be >= 0 && k <= Int_max) {
2247 /* Yes. */
2248 ds = tens[k];
2249 if (ndigits < 0 && ilim <= 0) {
2250 S = mhi = 0;
2251 if (ilim < 0 || value(d) <= 5*ds)
2252 goto no_digits;
2253 goto one_digit;
2254 }
2255 for(i = 1;; i++) {
2256 L = value(d) / ds;
2257 value(d) -= L*ds;
2258#ifdef Check_FLT_ROUNDS
2259 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2260 if (value(d) < 0) {
2261 L--;
2262 value(d) += ds;
2263 }
2264#endif
2265 *s++ = '0' + (int)L;
2266 if (i == ilim) {
2267 value(d) += value(d);
2268 if (value(d) > ds || value(d) == ds && L & 1) {
2269 bump_up:
2270 while(*--s == '9')
2271 if (s == s0) {
2272 k++;
2273 *s = '0';
2274 break;
2275 }
2276 ++*s++;
2277 }
2278 break;
2279 }
2280 if (!(value(d) *= 10.))
2281 break;
2282 }
2283 goto ret1;
2284 }
2285
2286 m2 = b2;
2287 m5 = b5;
2288 mhi = mlo = 0;
2289 if (leftright) {
2290 if (mode < 2) {
2291 i =
2292#ifndef Sudden_Underflow
2293 denorm ? be + (Bias + (P-1) - 1 + 1) :
2294#endif
2295#ifdef IBM
2296 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
2297#else
2298 1 + P - bbits;
2299#endif
2300 }
2301 else {
2302 j = ilim - 1;
2303 if (m5 >= j)
2304 m5 -= j;
2305 else {
2306 s5 += j -= m5;
2307 b5 += j;
2308 m5 = 0;
2309 }
2310 if ((i = ilim) < 0) {
2311 m2 -= i;
2312 i = 0;
2313 }
2314 }
2315 b2 += i;
2316 s2 += i;
2317 mhi = i2b(1);
2318 }
2319 if (m2 > 0 && s2 > 0) {
2320 i = m2 < s2 ? m2 : s2;
2321 b2 -= i;
2322 m2 -= i;
2323 s2 -= i;
2324 }
2325 if (b5 > 0) {
2326 if (leftright) {
2327 if (m5 > 0) {
2328 mhi = pow5mult(mhi, m5);
2329 b1 = mult(mhi, b);
2330 Bfree(b);
2331 b = b1;
2332 }
2333 if (j = b5 - m5)
2334 b = pow5mult(b, j);
2335 }
2336 else
2337 b = pow5mult(b, b5);
2338 }
2339 S = i2b(1);
2340 if (s5 > 0)
2341 S = pow5mult(S, s5);
2342
2343 /* Check for special case that d is a normalized power of 2. */
2344
2345 if (mode < 2) {
2346 if (!word1(d) && !(word0(d) & Bndry_mask)
2347#ifndef Sudden_Underflow
2348 && word0(d) & Exp_mask
2349#endif
2350 ) {
2351 /* The special case */
2352 b2 += Log2P;
2353 s2 += Log2P;
2354 spec_case = 1;
2355 }
2356 else
2357 spec_case = 0;
2358 }
2359
2360 /* Arrange for convenient computation of quotients:
2361 * shift left if necessary so divisor has 4 leading 0 bits.
2362 *
2363 * Perhaps we should just compute leading 28 bits of S once
2364 * and for all and pass them and a shift to quorem, so it
2365 * can do shifts and ors to compute the numerator for q.
2366 */
2367#ifdef Pack_32
2368 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
2369 i = 32 - i;
2370#else
2371 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
2372 i = 16 - i;
2373#endif
2374 if (i > 4) {
2375 i -= 4;
2376 b2 += i;
2377 m2 += i;
2378 s2 += i;
2379 }
2380 else if (i < 4) {
2381 i += 28;
2382 b2 += i;
2383 m2 += i;
2384 s2 += i;
2385 }
2386 if (b2 > 0)
2387 b = lshift(b, b2);
2388 if (s2 > 0)
2389 S = lshift(S, s2);
2390 if (k_check) {
2391 if (cmp(b,S) < 0) {
2392 k--;
2393 b = multadd(b, 10, 0); /* we botched the k estimate */
2394 if (leftright)
2395 mhi = multadd(mhi, 10, 0);
2396 ilim = ilim1;
2397 }
2398 }
2399 if (ilim <= 0 && mode > 2) {
2400 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
2401 /* no digits, fcvt style */
2402 no_digits:
2403 k = -1 - ndigits;
2404 goto ret;
2405 }
2406 one_digit:
2407 *s++ = '1';
2408 k++;
2409 goto ret;
2410 }
2411 if (leftright) {
2412 if (m2 > 0)
2413 mhi = lshift(mhi, m2);
2414
2415 /* Compute mlo -- check for special case
2416 * that d is a normalized power of 2.
2417 */
2418
2419 mlo = mhi;
2420 if (spec_case) {
2421 mhi = Balloc(mhi->k);
2422 Bcopy(mhi, mlo);
2423 mhi = lshift(mhi, Log2P);
2424 }
2425
2426 for(i = 1;;i++) {
2427 dig = quorem(b,S) + '0';
2428 /* Do we yet have the shortest decimal string
2429 * that will round to d?
2430 */
2431 j = cmp(b, mlo);
2432 delta = diff(S, mhi);
2433 j1 = delta->sign ? 1 : cmp(b, delta);
2434 Bfree(delta);
2435#ifndef ROUND_BIASED
2436 if (j1 == 0 && !mode && !(word1(d) & 1)) {
2437 if (dig == '9')
2438 goto round_9_up;
2439 if (j > 0)
2440 dig++;
2441 *s++ = dig;
2442 goto ret;
2443 }
2444#endif
2445 if (j < 0 || j == 0 && !mode
2446#ifndef ROUND_BIASED
2447 && !(word1(d) & 1)
2448#endif
2449 ) {
2450 if (j1 > 0) {
2451 b = lshift(b, 1);
2452 j1 = cmp(b, S);
2453 if ((j1 > 0 || j1 == 0 && dig & 1)
2454 && dig++ == '9')
2455 goto round_9_up;
2456 }
2457 *s++ = dig;
2458 goto ret;
2459 }
2460 if (j1 > 0) {
2461 if (dig == '9') { /* possible if i == 1 */
2462 round_9_up:
2463 *s++ = '9';
2464 goto roundoff;
2465 }
2466 *s++ = dig + 1;
2467 goto ret;
2468 }
2469 *s++ = dig;
2470 if (i == ilim)
2471 break;
2472 b = multadd(b, 10, 0);
2473 if (mlo == mhi)
2474 mlo = mhi = multadd(mhi, 10, 0);
2475 else {
2476 mlo = multadd(mlo, 10, 0);
2477 mhi = multadd(mhi, 10, 0);
2478 }
2479 }
2480 }
2481 else
2482 for(i = 1;; i++) {
2483 *s++ = dig = quorem(b,S) + '0';
2484 if (i >= ilim)
2485 break;
2486 b = multadd(b, 10, 0);
2487 }
2488
2489 /* Round off last digit */
2490
2491 b = lshift(b, 1);
2492 j = cmp(b, S);
2493 if (j > 0 || j == 0 && dig & 1) {
2494 roundoff:
2495 while(*--s == '9')
2496 if (s == s0) {
2497 k++;
2498 *s++ = '1';
2499 goto ret;
2500 }
2501 ++*s++;
2502 }
2503 else {
2504 while(*--s == '0');
2505 s++;
2506 }
2507 ret:
2508 Bfree(S);
2509 if (mhi) {
2510 if (mlo && mlo != mhi)
2511 Bfree(mlo);
2512 Bfree(mhi);
2513 }
2514 ret1:
2515 Bfree(b);
2516 if (s == s0) { /* don't return empty string */
2517 *s++ = '0';
2518 k = 0;
2519 }
2520 *s = 0;
2521 *decpt = k + 1;
2522 if (rve)
2523 *rve = s;
2524 return s0;
2525 }
2526#ifdef __cplusplus
2527}
2528#endif
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
new file mode 100644
index 0000000000..a5bdff0b81
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.3
@@ -0,0 +1,243 @@
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.10 2002/06/29 00:20:11 millert Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOL 3
40.Os
41.Sh NAME
42.Nm strtol ,
43.Nm strtoll ,
44.Nm strtoq
45.Nd convert string value to a long or long long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Fd #include <limits.h>
49.Ft long
50.Fn strtol "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <stdlib.h>
53.Fd #include <limits.h>
54.Ft long long
55.Fn strtoll "const char *nptr" "char **endptr" "int base"
56.Pp
57.Fd #include <sys/types.h>
58.Fd #include <stdlib.h>
59.Fd #include <limits.h>
60.Ft quad_t
61.Fn strtoq "const char *nptr" "char **endptr" "int base"
62.Sh DESCRIPTION
63The
64.Fn strtol
65function converts the string in
66.Fa nptr
67to a
68.Li long
69value.
70The
71.Fn strtoll
72function converts the string in
73.Fa nptr
74to a
75.Li long long
76value.
77The
78.Fn strtoq
79function is a deprecated equivalent of
80.Fn strtoll
81and is provided for backwards compatibility with legacy programs.
82The conversion is done according to the given
83.Fa base ,
84which must be a number between 2 and 36 inclusive or the special value 0.
85.Pp
86The string may begin with an arbitrary amount of whitespace
87(as determined by
88.Xr isspace 3 )
89followed by a single optional
90.Ql +
91or
92.Ql -
93sign.
94If
95.Fa base
96is zero or 16, the string may then include a
97.Ql 0x
98prefix, and the number will be read in base 16; otherwise, a zero
99.Fa base
100is taken as 10 (decimal) unless the next character is
101.Ql 0 ,
102in which case it is taken as 8 (octal).
103.Pp
104The remainder of the string is converted to a
105.Li long
106value in the obvious manner,
107stopping at the first character which is not a valid digit
108in the given base.
109(In bases above 10, the letter
110.Ql A
111in either upper or lower case represents 10,
112.Ql B
113represents 11, and so forth, with
114.Ql Z
115representing 35.)
116.Pp
117If
118.Fa endptr
119is non-null,
120.Fn strtol
121stores the address of the first invalid character in
122.Fa *endptr .
123If there were no digits at all, however,
124.Fn strtol
125stores the original value of
126.Fa nptr
127in
128.Fa *endptr .
129(Thus, if
130.Fa *nptr
131is not
132.Ql \e0
133but
134.Fa **endptr
135is
136.Ql \e0
137on return, the entire string was valid.)
138.Sh RETURN VALUES
139The
140.Fn strtol
141function returns the result of the conversion,
142unless the value would underflow or overflow.
143If an underflow occurs,
144.Fn strtol
145returns
146.Dv LONG_MIN .
147If an overflow occurs,
148.Fn strtol
149returns
150.Dv LONG_MAX .
151In both cases,
152.Va errno
153is set to
154.Er ERANGE .
155.Pp
156The
157.Fn strtoll
158function has identical return values except that
159.Dv LLONG_MIN
160and
161.Dv LLONG_MAX
162are used to indicate underflow and overflow respectively.
163.Sh EXAMPLES
164Ensuring that a string is a valid number (i.e., in range and containing no
165trailing characters) requires clearing
166.Va errno
167beforehand explicitly since
168.Va errno
169is not changed on a successful call to
170.Fn strtol ,
171and the return value of
172.Fn strtol
173cannot be used unambiguously to signal an error:
174.Bd -literal -offset indent
175char *ep;
176long lval;
177
178\&...
179
180errno = 0;
181lval = strtol(buf, &ep, 10);
182if (buf[0] == '\e0' || *ep != '\e0')
183 goto not_a_number;
184if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
185 goto out_of_range;
186.Ed
187.Pp
188This example will accept
189.Dq 12
190but not
191.Dq 12foo
192or
193.Dq 12\en .
194If trailing whitespace is acceptable, further checks must be done on
195.Va *ep ;
196alternately, use
197.Xr sscanf 3 .
198.Pp
199If
200.Fn strtol
201is being used instead of
202.Xr atoi 3 ,
203error checking is further complicated because the desired return value is an
204.Li int
205rather than a
206.Li long ;
207however, on some architectures integers and long integers are the same size.
208Thus the following is necessary:
209.Bd -literal -offset indent
210char *ep;
211int ival;
212long lval;
213
214\&...
215
216errno = 0;
217lval = strtol(buf, &ep, 10);
218if (buf[0] == '\e0' || *ep != '\e0')
219 goto not_a_number;
220if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
221 (lval > INT_MAX || lval < INT_MIN))
222 goto out_of_range;
223ival = lval;
224.Ed
225.Sh ERRORS
226.Bl -tag -width Er
227.It Bq Er ERANGE
228The given string was out of range; the value converted has been clamped.
229.El
230.Sh SEE ALSO
231.Xr atof 3 ,
232.Xr atoi 3 ,
233.Xr atol 3 ,
234.Xr sscanf 3 ,
235.Xr strtod 3 ,
236.Xr strtoul 3
237.Sh STANDARDS
238The
239.Fn strtol
240function conforms to
241.St -ansiC .
242.Sh BUGS
243Ignores 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/strtoll.c b/src/lib/libc/stdlib/strtoll.c
new file mode 100644
index 0000000000..b0eb6d198c
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -0,0 +1,166 @@
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 const char rcsid[] = "$OpenBSD: strtoll.c,v 1.1 2002/06/29 00:20:11 millert 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 long long.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51long long
52strtoll(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 int base;
56{
57 const char *s;
58 long long acc, cutoff;
59 int c;
60 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 long longs 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 ? LLONG_MIN : LLONG_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 = LLONG_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 = LLONG_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}
153
154#ifdef __weak_alias
155__weak_alias(strtoq, strtoll);
156#else
157quad_t
158strtoq(nptr, endptr, base)
159 const char *nptr;
160 char **endptr;
161 int base;
162{
163
164 return ((quad_t)strtoll(nptr, endptr, base);
165}
166#endif
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000000..6d55de4d7a
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,225 @@
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.10 2002/06/29 00:20:11 millert Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOUL 3
40.Os
41.Sh NAME
42.Nm strtoul ,
43.Nm strtoull ,
44.Nm strtouq
45.Nd convert a string to an unsigned long or unsigned long long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Fd #include <limits.h>
49.Ft unsigned long
50.Fn strtoul "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <stdlib.h>
53.Fd #include <limits.h>
54.Ft unsigned long long
55.Fn strtoull "const char *nptr" "char **endptr" "int base"
56.Pp
57.Fd #include <sys/types.h>
58.Fd #include <stdlib.h>
59.Fd #include <limits.h>
60.Ft u_quad_t
61.Fn strtouq "const char *nptr" "char **endptr" "int base"
62.Sh DESCRIPTION
63The
64.Fn strtoul
65function converts the string in
66.Fa nptr
67to an
68.Li unsigned long
69value.
70The
71.Fn strtoull
72function converts the string in
73.Fa nptr
74to an
75.Li unsigned long long
76value.
77The
78.Fn strtouq
79function is a deprecated equivalent of
80.Fn strtoull
81and is provided for backwards compatibility with legacy programs.
82The conversion is done according to the given
83.Fa base ,
84which must be a number between 2 and 36 inclusive
85or the special value 0.
86.Pp
87The string may begin with an arbitrary amount of whitespace
88(as determined by
89.Xr isspace 3 )
90followed by a single optional
91.Ql +
92or
93.Ql -
94sign.
95If
96.Fa base
97is zero or 16, the string may then include a
98.Ql 0x
99prefix, and the number will be read in base 16; otherwise, a zero
100.Fa base
101is taken as 10 (decimal) unless the next character is
102.Ql 0 ,
103in which case it is taken as 8 (octal).
104.Pp
105The remainder of the string is converted to an
106.Li unsigned long
107value in the obvious manner, stopping at the end of the string
108or at the first character that does not produce a valid digit
109in the given base.
110(In bases above 10, the letter
111.Ql A
112in either upper or lower case represents 10,
113.Ql B
114represents 11, and so forth, with
115.Ql Z
116representing 35.)
117.Pp
118If
119.Fa endptr
120is non-null,
121.Fn strtoul
122stores the address of the first invalid character in
123.Fa *endptr .
124If there were no digits at all, however,
125.Fn strtoul
126stores the original value of
127.Fa nptr
128in
129.Fa *endptr .
130(Thus, if
131.Fa *nptr
132is not
133.Ql \e0
134but
135.Fa **endptr
136is
137.Ql \e0
138on return, the entire string was valid.)
139.Sh RETURN VALUES
140The
141.Fn strtoul
142function returns the result of the conversion,
143unless the value would overflow, in which case
144.Dv ULONG_MAX
145is returned and
146.Va errno
147is set to
148.Er ERANGE .
149If there was a leading minus sign,
150.Fn strtoul
151returns the (unsigned) negation of the absolute value of the number, unless
152the absolute value would overflow.
153In this case,
154.Fn strtoul
155returns
156.Dv ULONG_MAX
157and sets the global variable
158.Va errno
159to
160.Er ERANGE .
161.Pp
162The
163.Fn strtoull
164function has identical return values except that
165.Dv ULLONG_MIN
166and
167.Dv ULLONG_MAX
168are used to indicate underflow and overflow respectively.
169.Pp
170There is no way to determine if
171.Fn strtoul
172has processed a negative number (and returned an unsigned value) short of
173examining the string in
174.Fa nptr
175directly.
176.Sh EXAMPLES
177Ensuring that a string is a valid number (i.e., in range and containing no
178trailing characters) requires clearing
179.Va errno
180beforehand explicitly since
181.Va errno
182is not changed on a successful call to
183.Fn strtoul ,
184and the return value of
185.Fn strtoul
186cannot be used unambiguously to signal an error:
187.Bd -literal -offset indent
188char *ep;
189unsigned long ulval;
190
191\&...
192
193errno = 0;
194ulval = strtoul(buf, &ep, 10);
195if (buf[0] == '\e0' || *ep != '\e0')
196 goto not_a_number;
197if (errno == ERANGE && ulval == ULONG_MAX)
198 goto out_of_range;
199.Ed
200.Pp
201This example will accept
202.Dq 12
203but not
204.Dq 12foo
205or
206.Dq 12\en .
207If trailing whitespace is acceptable, further checks must be done on
208.Va *ep ;
209alternately, use
210.Xr sscanf 3 .
211.Sh ERRORS
212.Bl -tag -width Er
213.It Bq Er ERANGE
214The given string was out of range; the value converted has been clamped.
215.El
216.Sh SEE ALSO
217.Xr sscanf 3 ,
218.Xr strtol 3
219.Sh STANDARDS
220The
221.Fn strtoul
222function conforms to
223.St -ansiC .
224.Sh BUGS
225Ignores 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/strtoull.c b/src/lib/libc/stdlib/strtoull.c
new file mode 100644
index 0000000000..7b4dd56c01
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -0,0 +1,128 @@
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 const char rcsid[] = "$OpenBSD: strtoull.c,v 1.1 2002/06/29 00:20:11 millert 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 long long.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51unsigned long long
52strtoull(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 int base;
56{
57 const char *s;
58 unsigned long long acc, cutoff;
59 int c;
60 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 = ULLONG_MAX / (unsigned long long)base;
87 cutlim = ULLONG_MAX % (unsigned long long)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 = ULLONG_MAX;
102 errno = ERANGE;
103 } else {
104 any = 1;
105 acc *= (unsigned long long)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}
115
116#ifdef __weak_alias
117__weak_alias(strtouq, strtoull);
118#else
119u_quad_t
120strtouq(nptr, endptr, base)
121 const char *nptr;
122 char **endptr;
123 int base;
124{
125
126 return ((u_quad_t)strtoull(nptr, endptr, base);
127}
128#endif
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
new file mode 100644
index 0000000000..83c6de80e3
--- /dev/null
+++ b/src/lib/libc/stdlib/system.3
@@ -0,0 +1,103 @@
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.8 2000/10/06 04:17:51 aaron 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 hands the argument
52.Fa string
53to the command interpreter
54.Xr sh 1 .
55The calling process waits for the shell to finish executing the command,
56ignoring
57.Dv SIGINT
58and
59.Dv SIGQUIT ,
60and blocking
61.Dv SIGCHLD .
62.Pp
63If
64.Fa string
65is
66.Dv NULL ,
67.Fn system
68will return non-zero.
69Otherwise,
70.Fn system
71returns the termination status of the shell in the format specified by
72.Xr waitpid 2 .
73.Sh RETURN VALUES
74If a child process cannot be created, or the termination status of
75the shell cannot be obtained,
76.Fn system
77returns \-1 and sets
78.Va errno
79to indicate the error.
80If execution of the shell fails,
81.Fn system
82returns the termination status for a program that terminates with a call of
83.Fn exit 127 .
84.Sh SEE ALSO
85.Xr sh 1 ,
86.Xr execve 2 ,
87.Xr waitpid 2 ,
88.Xr popen 3
89.Sh STANDARDS
90The
91.Fn system
92function conforms to
93.St -ansiC
94and
95.St -p1003.2-92 .
96.Sh CAVEATS
97Never supply the
98.Fn system
99function with a command containing any part of an unsanitized user-supplied
100string.
101Shell meta-characters present will be honored by the
102.Xr sh 1
103command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
new file mode 100644
index 0000000000..636a9ebdff
--- /dev/null
+++ b/src/lib/libc/stdlib/system.c
@@ -0,0 +1,82 @@
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.5 2002/05/26 09:29:02 deraadt 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 sigset_t mask, 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 sigemptyset(&mask);
63 sigaddset(&mask, SIGCHLD);
64 sigprocmask(SIG_BLOCK, &mask, &omask);
65 switch (pid = vfork()) {
66 case -1: /* error */
67 sigprocmask(SIG_SETMASK, &omask, NULL);
68 return(-1);
69 case 0: /* child */
70 sigprocmask(SIG_SETMASK, &omask, NULL);
71 execve(_PATH_BSHELL, argp, environ);
72 _exit(127);
73 }
74
75 intsave = signal(SIGINT, SIG_IGN);
76 quitsave = signal(SIGQUIT, SIG_IGN);
77 pid = waitpid(pid, (int *)&pstat, 0);
78 sigprocmask(SIG_SETMASK, &omask, NULL);
79 (void)signal(SIGINT, intsave);
80 (void)signal(SIGQUIT, quitsave);
81 return (pid == -1 ? -1 : pstat);
82}
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..5c3b8c17f5
--- /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)(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..b000a0a8b1
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,127 @@
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.9 2000/08/09 15:51:21 aaron Exp $
27.\"
28.Dd June 15, 1997
29.Dt TSEARCH 3
30.Os
31.Sh NAME
32.Nm tsearch ,
33.Nm tfind ,
34.Nm tdelete ,
35.Nm twalk
36.Nd manipulate binary search trees
37.Sh SYNOPSIS
38.Fd #include <search.h>
39.Ft void *
40.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
41.Ft void *
42.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
43.Ft void *
44.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
45.Ft void
46.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
47.Sh DESCRIPTION
48The
49.Fn tdelete ,
50.Fn tfind ,
51.Fn tsearch ,
52and
53.Fn twalk
54functions manage binary search trees based on algorithms T and D
55from Knuth (6.2.2).
56The comparison function passed in by
57the user has the same style of return values as
58.Xr strcmp 3 .
59.Pp
60.Fn tfind
61searches for the datum matched by the argument
62.Fa key
63in the binary tree rooted at
64.Fa rootp ,
65returning a pointer to the datum if it is found and
66.Dv NULL
67if it is not.
68.Pp
69.Fn tsearch
70is identical to
71.Fn tfind
72except that if no match is found,
73.Fa key
74is inserted into the tree and a pointer to it is returned.
75If
76.Fa rootp
77points to a null value a new binary search tree is created.
78.Pp
79.Fn tdelete
80deletes a node from the specified binary search tree and returns
81a pointer to the parent of the node to be deleted.
82It takes the same arguments as
83.Fn tfind
84and
85.Fn tsearch .
86If the node to be deleted is the root of the binary search tree,
87.Fa rootp
88will be adjusted.
89.Pp
90.Fn twalk
91walks the binary search tree rooted in
92.Fa root
93and calls the function
94.Fa action
95on each node.
96.Fa action
97is called with three arguments: a pointer to the current node,
98a value from the enum
99.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
100specifying the traversal type, and a node level (where level
101zero is the root of the tree).
102.Sh SEE ALSO
103.Xr bsearch 3 ,
104.Xr lsearch 3
105.Sh RETURN VALUES
106The
107.Fn tsearch
108function returns
109.Dv NULL
110if allocation of a new node fails (usually
111due to a lack of free memory).
112.Pp
113.Fn tfind ,
114.Fn tsearch ,
115and
116.Fn tdelete
117return
118.Dv NULL
119if
120.Fa rootp
121is
122.Dv NULL
123or the datum cannot be found.
124.Pp
125The
126.Fn twalk
127function 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..0ad5866172
--- /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)(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)(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)(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}