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.inc57
-rw-r--r--src/lib/libc/stdlib/_rand48.c4
-rw-r--r--src/lib/libc/stdlib/a64l.3133
-rw-r--r--src/lib/libc/stdlib/a64l.c28
-rw-r--r--src/lib/libc/stdlib/abort.326
-rw-r--r--src/lib/libc/stdlib/abort.c35
-rw-r--r--src/lib/libc/stdlib/abs.323
-rw-r--r--src/lib/libc/stdlib/abs.c9
-rw-r--r--src/lib/libc/stdlib/alloca.341
-rw-r--r--src/lib/libc/stdlib/atexit.319
-rw-r--r--src/lib/libc/stdlib/atexit.c141
-rw-r--r--src/lib/libc/stdlib/atexit.h57
-rw-r--r--src/lib/libc/stdlib/atof.313
-rw-r--r--src/lib/libc/stdlib/atof.c9
-rw-r--r--src/lib/libc/stdlib/atoi.332
-rw-r--r--src/lib/libc/stdlib/atoi.c9
-rw-r--r--src/lib/libc/stdlib/atol.319
-rw-r--r--src/lib/libc/stdlib/atol.c9
-rw-r--r--src/lib/libc/stdlib/atoll.3 (renamed from src/lib/libc/stdlib/calloc.3)59
-rw-r--r--src/lib/libc/stdlib/atoll.c41
-rw-r--r--src/lib/libc/stdlib/bsearch.325
-rw-r--r--src/lib/libc/stdlib/bsearch.c11
-rw-r--r--src/lib/libc/stdlib/calloc.c20
-rw-r--r--src/lib/libc/stdlib/cfree.c45
-rw-r--r--src/lib/libc/stdlib/div.323
-rw-r--r--src/lib/libc/stdlib/div.c9
-rw-r--r--src/lib/libc/stdlib/drand48.c4
-rw-r--r--src/lib/libc/stdlib/ecvt.3165
-rw-r--r--src/lib/libc/stdlib/ecvt.c103
-rw-r--r--src/lib/libc/stdlib/erand48.c4
-rw-r--r--src/lib/libc/stdlib/exit.331
-rw-r--r--src/lib/libc/stdlib/exit.c42
-rw-r--r--src/lib/libc/stdlib/free.382
-rw-r--r--src/lib/libc/stdlib/gcvt.c99
-rw-r--r--src/lib/libc/stdlib/getenv.372
-rw-r--r--src/lib/libc/stdlib/getenv.c72
-rw-r--r--src/lib/libc/stdlib/getopt.3252
-rw-r--r--src/lib/libc/stdlib/getopt.c118
-rw-r--r--src/lib/libc/stdlib/getopt_long.3377
-rw-r--r--src/lib/libc/stdlib/getopt_long.c544
-rw-r--r--src/lib/libc/stdlib/getsubopt.3143
-rw-r--r--src/lib/libc/stdlib/getsubopt.c102
-rw-r--r--src/lib/libc/stdlib/heapsort.c17
-rw-r--r--src/lib/libc/stdlib/insque.3100
-rw-r--r--src/lib/libc/stdlib/insque.c52
-rw-r--r--src/lib/libc/stdlib/jrand48.c4
-rw-r--r--src/lib/libc/stdlib/l64a.c15
-rw-r--r--src/lib/libc/stdlib/labs.335
-rw-r--r--src/lib/libc/stdlib/labs.c9
-rw-r--r--src/lib/libc/stdlib/lcong48.c4
-rw-r--r--src/lib/libc/stdlib/ldiv.329
-rw-r--r--src/lib/libc/stdlib/ldiv.c9
-rw-r--r--src/lib/libc/stdlib/llabs.c45
-rw-r--r--src/lib/libc/stdlib/lrand48.c4
-rw-r--r--src/lib/libc/stdlib/lsearch.3103
-rw-r--r--src/lib/libc/stdlib/lsearch.c86
-rw-r--r--src/lib/libc/stdlib/malloc.3399
-rw-r--r--src/lib/libc/stdlib/malloc.c1610
-rw-r--r--src/lib/libc/stdlib/memory.371
-rw-r--r--src/lib/libc/stdlib/merge.c23
-rw-r--r--src/lib/libc/stdlib/mrand48.c4
-rw-r--r--src/lib/libc/stdlib/multibyte.c15
-rw-r--r--src/lib/libc/stdlib/nrand48.c4
-rw-r--r--src/lib/libc/stdlib/putenv.c25
-rw-r--r--src/lib/libc/stdlib/qabs.318
-rw-r--r--src/lib/libc/stdlib/qabs.c9
-rw-r--r--src/lib/libc/stdlib/qdiv.322
-rw-r--r--src/lib/libc/stdlib/qdiv.c9
-rw-r--r--src/lib/libc/stdlib/qsort.391
-rw-r--r--src/lib/libc/stdlib/qsort.c40
-rw-r--r--src/lib/libc/stdlib/radixsort.350
-rw-r--r--src/lib/libc/stdlib/radixsort.c21
-rw-r--r--src/lib/libc/stdlib/rand.335
-rw-r--r--src/lib/libc/stdlib/rand.c24
-rw-r--r--src/lib/libc/stdlib/rand48.345
-rw-r--r--src/lib/libc/stdlib/rand48.h4
-rw-r--r--src/lib/libc/stdlib/random.3113
-rw-r--r--src/lib/libc/stdlib/random.c148
-rw-r--r--src/lib/libc/stdlib/realloc.3100
-rw-r--r--src/lib/libc/stdlib/realpath.340
-rw-r--r--src/lib/libc/stdlib/realpath.c43
-rw-r--r--src/lib/libc/stdlib/remque.c48
-rw-r--r--src/lib/libc/stdlib/seed48.c4
-rw-r--r--src/lib/libc/stdlib/setenv.c22
-rw-r--r--src/lib/libc/stdlib/srand48.c4
-rw-r--r--src/lib/libc/stdlib/strtod.343
-rw-r--r--src/lib/libc/stdlib/strtod.c254
-rw-r--r--src/lib/libc/stdlib/strtol.3148
-rw-r--r--src/lib/libc/stdlib/strtol.c76
-rw-r--r--src/lib/libc/stdlib/strtoll.c (renamed from src/lib/libc/stdlib/strtoq.c)96
-rw-r--r--src/lib/libc/stdlib/strtoul.3147
-rw-r--r--src/lib/libc/stdlib/strtoul.c50
-rw-r--r--src/lib/libc/stdlib/strtoull.c (renamed from src/lib/libc/stdlib/strtouq.c)68
-rw-r--r--src/lib/libc/stdlib/system.350
-rw-r--r--src/lib/libc/stdlib/system.c29
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3116
-rw-r--r--src/lib/libc/stdlib/tsearch.c126
98 files changed, 5836 insertions, 2068 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index 782a4ab022..74f8ff5e7a 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,24 +1,28 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
3 2
4# stdlib sources 3# stdlib sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
6 5
7SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
8 exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ 7 calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
8 getsubopt.c heapsort.c l64a.c llabs.c lsearch.c malloc.c merge.c \
9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ 9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \
10 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ 10 setenv.c strtod.c strtol.c strtoll.c strtoul.c strtoull.c system.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 11 tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 12 lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13 13
14.if (${MACHINE_ARCH} == "m68k") 14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c 15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
16.elif (${MACHINE_ARCH} == "i386") 17.elif (${MACHINE_ARCH} == "i386")
17SRCS+= abs.S div.S labs.S ldiv.S 18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
18.elif (${MACHINE_ARCH} == "ns32k") 20.elif (${MACHINE_ARCH} == "ns32k")
19SRCS+= abs.S div.c labs.c ldiv.c 21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
20.elif (${MACHINE_ARCH} == "tahoe") 23.elif (${MACHINE_ARCH} == "tahoe")
21SRCS+= abs.S div.c labs.c ldiv.c 24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
22.elif (${MACHINE_ARCH} == "vax") 26.elif (${MACHINE_ARCH} == "vax")
23SRCS+= abs.c div.c labs.c ldiv.c 27SRCS+= abs.c div.c labs.c ldiv.c
24.elif (${MACHINE_ARCH} == "alpha") 28.elif (${MACHINE_ARCH} == "alpha")
@@ -28,18 +32,37 @@ SRCS+= abs.c div.c labs.c ldiv.c
28SRCS+= abs.c div.c labs.c ldiv.c 32SRCS+= abs.c div.c labs.c ldiv.c
29.endif 33.endif
30 34
31MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 35.if (${MACHINE_ARCH} == "vax") || (${MACHINE_ARCH} == "m68k")
32 calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ 36SRCS+= insque.S remque.S
33 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ 37.else
34 rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ 38SRCS+= insque.c remque.c
35 system.3 39.endif
40
41MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
42 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
43 getsubopt.3 insque.3 labs.3 ldiv.3 lsearch.3 malloc.3 qabs.3 \
44 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \
45 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
36 46
47MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
37MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 48MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
49MLINKS+=getopt_long.3 getopt_long_only.3
50MLINKS+=insque.3 remque.3
51MLINKS+=labs.3 llabs.3
52MLINKS+=lsearch.3 lfind.3
53MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
54MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
38MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 55MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
39MLINKS+=rand.3 srand.3 56MLINKS+=radixsort.3 sradixsort.3
40MLINKS+=strtol.3 strtoq.3 57MLINKS+=rand.3 srand.3 rand.3 rand_r.3
41MLINKS+=strtoul.3 strtouq.3 58MLINKS+=random.3 initstate.3 random.3 setstate.3
42MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 59MLINKS+=random.3 srandom.3 random.3 srandomdev.3
43MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 60MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
44MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 61MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
45MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 62MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
63MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3
64MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3
65MLINKS+=tsearch.3 tfind.3
66MLINKS+=tsearch.3 tdelete.3
67MLINKS+=tsearch.3 twalk.3
68MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
index 83ade4645a..fed7372f68 100644
--- a/src/lib/libc/stdlib/_rand48.c
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: _rand48.c,v 1.2 1996/08/19 08:33:19 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16unsigned short __rand48_seed[3] = { 20unsigned short __rand48_seed[3] = {
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..de70d0af71
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,133 @@
1.\" $OpenBSD: a64l.3,v 1.8 2003/06/17 21:56:24 millert Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd August 17, 1997
18.Dt A64L 3
19.Os
20.Sh NAME
21.Nm a64l ,
22.Nm l64a
23.Nd convert between 32-bit integer and radix-64 ASCII string
24.Sh SYNOPSIS
25.Fd #include <stdlib.h>
26.Ft long
27.Fn a64l "const char *s"
28.Ft char *
29.Fn l64a "long l"
30.Sh DESCRIPTION
31The
32.Fn a64l
33and
34.Fn l64a
35functions are used to maintain numbers stored in radix-64
36.Tn ASCII
37characters.
38This is a notation by which 32-bit integers
39can be represented by up to six characters; each character represents a
40.Dq digit
41in a radix-64 notation.
42.Pp
43The characters used to represent digits are
44.Ql \&.
45for 0,
46.Ql /
47for 1,
48.Ql 0
49through
50.Ql 9
51for 2-11,
52.Ql A
53through
54.Ql Z
55for 12-37, and
56.Ql a
57through
58.Ql z
59for 38-63.
60.Pp
61The
62.Fn a64l
63function takes a pointer to a null-terminated radix-64 representation
64and returns a corresponding 32-bit value.
65If the string pointed to by
66.Fa s
67contains more than six characters,
68.Fn a64l
69will use the first six.
70.Fn a64l
71scans the character string from left to right, decoding
72each character as a 6-bit radix-64 number.
73If a long integer is
74larger than 32 bits, the return value will be sign-extended.
75.Pp
76.Fn l64a
77takes a long integer argument
78.Fa l
79and returns a pointer to the corresponding radix-64 representation.
80.Sh RETURN VALUES
81On success,
82.Fn a64l
83returns a 32-bit representation of
84.Fa s .
85If
86.Fa s
87is a null pointer or if it contains digits other than those described above,
88.Fn a64l
89returns \-1 and sets the global variable
90.Va errno
91to
92.Er EINVAL .
93.Pp
94On success,
95.Fn l64a
96returns a pointer to a string containing the radix-64 representation of
97.Fa l .
98If
99.Fa l
100is 0,
101.Fn l64a
102returns a pointer to the empty string.
103If
104.Fa l
105is negative,
106.Fn l64a
107returns a null pointer and sets the global variable
108.Va errno
109to
110.Er EINVAL .
111.Sh WARNINGS
112The value returned by
113.Fn l64a
114is a pointer into a static buffer, the contents of which
115will be overwritten by subsequent calls.
116.Pp
117The value returned by
118.Fn a64l
119may be incorrect if the value is too large; for that reason, only strings
120that resulted from a call to
121.Fn l64a
122should be used to call
123.Fn a64l .
124.Pp
125If a long integer is larger than 32 bits, only the low-order
12632 bits are used.
127.Sh STANDARDS
128The
129.Fn a64l
130and
131.Fn l64a
132functions conform to
133.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
index 03fc77e034..a68f0a6dcd 100644
--- a/src/lib/libc/stdlib/a64l.c
+++ b/src/lib/libc/stdlib/a64l.c
@@ -4,8 +4,11 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; 7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
9 12
10long 13long
11a64l(s) 14a64l(s)
@@ -14,21 +17,30 @@ a64l(s)
14 long value, digit, shift; 17 long value, digit, shift;
15 int i; 18 int i;
16 19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
17 value = 0; 25 value = 0;
18 shift = 0; 26 shift = 0;
19 for (i = 0; *s && i < 6; i++, s++) { 27 for (i = 0; *s && i < 6; i++, s++) {
20 if (*s <= '/') 28 if (*s >= '.' && *s <= '/')
21 digit = *s - '.'; 29 digit = *s - '.';
22 else if (*s <= '9') 30 else if (*s >= '0' && *s <= '9')
23 digit = *s - '0' + 2; 31 digit = *s - '0' + 2;
24 else if (*s <= 'Z') 32 else if (*s >= 'A' && *s <= 'Z')
25 digit = *s - 'A' + 12; 33 digit = *s - 'A' + 12;
26 else 34 else if (*s >= 'a' && *s <= 'z')
27 digit = *s - 'a' + 38; 35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
28 40
29 value |= digit << shift; 41 value |= digit << shift;
30 shift += 6; 42 shift += 6;
31 } 43 }
32 44
33 return (long) value; 45 return(value);
34} 46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
index ab57327585..d411b859eb 100644
--- a/src/lib/libc/stdlib/abort.3
+++ b/src/lib/libc/stdlib/abort.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)abort.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: abort.3,v 1.7 2003/06/02 20:18:37 millert Exp $
37.\" $Id: abort.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ABORT 3 35.Dt ABORT 3
@@ -49,23 +44,20 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abort 46.Fn abort
52function causes abnormal program termination to occur, unless the 47function causes abnormal program termination to occur, unless the signal
53signal
54.Dv SIGABRT 48.Dv SIGABRT
55is being caught and the signal handler does not return. 49is being caught and the signal handler does not return.
56.Pp 50.Pp
57No open streams are closed or flushed. 51Any open streams are flushed and closed.
58.Sh RETURN VALUES 52.Sh RETURN VALUES
59The 53The
60.Nm abort 54.Fn abort
61function 55function never returns.
62never returns.
63.Sh SEE ALSO 56.Sh SEE ALSO
64.Xr sigaction 2 , 57.Xr sigaction 2 ,
65.Xr exit 2 58.Xr exit 3
66.Sh STANDARDS 59.Sh STANDARDS
67The 60The
68.Fn abort 61.Fn abort
69function 62function conforms to
70conforms to 63.St -p1003.1-90 .
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
index c298e016b4..2430c124f9 100644
--- a/src/lib/libc/stdlib/abort.c
+++ b/src/lib/libc/stdlib/abort.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,26 +28,43 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: abort.c,v 1.13 2004/01/20 19:35:17 millert Exp $";
36static char *rcsid = "$Id: abort.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <signal.h> 34#include <signal.h>
40#include <stdlib.h> 35#include <stdlib.h>
41#include <unistd.h> 36#include <unistd.h>
37#include "thread_private.h"
38#include "atexit.h"
42 39
43void 40void
44abort() 41abort(void)
45{ 42{
43 struct atexit *p = __atexit;
44 static int cleanup_called = 0;
46 sigset_t mask; 45 sigset_t mask;
47 46
47
48 sigfillset(&mask); 48 sigfillset(&mask);
49 /* 49 /*
50 * don't block SIGABRT to give any handler a chance; we ignore 50 * don't block SIGABRT to give any handler a chance; we ignore
51 * any errors -- X311J doesn't allow abort to return anyway. 51 * any errors -- X311J doesn't allow abort to return anyway.
52 */ 52 */
53 sigdelset(&mask, SIGABRT); 53 sigdelset(&mask, SIGABRT);
54 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 54 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
55
56 /*
57 * POSIX requires we flush stdio buffers on abort
58 */
59 if (cleanup_called == 0) {
60 while (p != NULL && p->next != NULL)
61 p = p->next;
62 if (p != NULL && p->fns[0] != NULL) {
63 cleanup_called = 1;
64 (*p->fns[0])();
65 }
66 }
67
55 (void)kill(getpid(), SIGABRT); 68 (void)kill(getpid(), SIGABRT);
56 69
57 /* 70 /*
@@ -59,7 +72,7 @@ abort()
59 * it again, only harder. 72 * it again, only harder.
60 */ 73 */
61 (void)signal(SIGABRT, SIG_DFL); 74 (void)signal(SIGABRT, SIG_DFL);
62 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 75 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
63 (void)kill(getpid(), SIGABRT); 76 (void)kill(getpid(), SIGABRT);
64 exit(1); 77 _exit(1);
65} 78}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
index 4748d89e77..f0a6b8a23a 100644
--- a/src/lib/libc/stdlib/abs.3
+++ b/src/lib/libc/stdlib/abs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)abs.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: abs.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: abs.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ABS 3 35.Dt ABS 3
@@ -49,21 +44,17 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abs 46.Fn abs
52function 47function computes the absolute value of the integer
53computes 48.Fa j .
54the absolute value of the integer
55.Ar j .
56.Sh RETURN VALUES 49.Sh RETURN VALUES
57The 50The
58.Fn abs 51.Fn abs
59function 52function returns the absolute value.
60returns
61the absolute value.
62.Sh SEE ALSO 53.Sh SEE ALSO
63.Xr floor 3 ,
64.Xr labs 3 ,
65.Xr cabs 3 , 54.Xr cabs 3 ,
55.Xr floor 3 ,
66.Xr hypot 3 , 56.Xr hypot 3 ,
57.Xr labs 3 ,
67.Xr math 3 58.Xr math 3
68.Sh STANDARDS 59.Sh STANDARDS
69The 60The
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
index 64468e0224..c67ad9494f 100644
--- a/src/lib/libc/stdlib/abs.c
+++ b/src/lib/libc/stdlib/abs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: abs.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: abs.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
index dcb97ab11c..4136dc405c 100644
--- a/src/lib/libc/stdlib/alloca.3
+++ b/src/lib/libc/stdlib/alloca.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,12 +25,11 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)alloca.3 5.1 (Berkeley) 5/2/91 28.\" $OpenBSD: alloca.3,v 1.10 2003/06/02 20:18:37 millert Exp $
33.\" $Id: alloca.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
34.\" 29.\"
35.Dd May 2, 1991 30.Dd May 2, 1991
36.Dt ALLOCA 3 31.Dt ALLOCA 3
37.Os BSD 4 32.Os
38.Sh NAME 33.Sh NAME
39.Nm alloca 34.Nm alloca
40.Nd memory allocator 35.Nd memory allocator
@@ -45,35 +40,41 @@
45.Sh DESCRIPTION 40.Sh DESCRIPTION
46The 41The
47.Fn alloca 42.Fn alloca
48function 43function allocates
49allocates
50.Fa size 44.Fa size
51bytes of space in the stack frame of the caller. 45bytes of space in the stack frame of the caller.
52This temporary space is automatically freed on 46This temporary space is automatically freed on return.
53return.
54.Sh RETURN VALUES 47.Sh RETURN VALUES
55The 48The
56.Fn alloca 49.Fn alloca
57function returns a pointer to the beginning of the allocated space. 50function returns a pointer to the beginning of the allocated space.
58If the allocation failed, a
59.Dv NULL
60pointer is returned.
61.Sh SEE ALSO 51.Sh SEE ALSO
52.Xr pagesize 1 ,
62.Xr brk 2 , 53.Xr brk 2 ,
63.Xr pagesize 2
64.Xr calloc 3 , 54.Xr calloc 3 ,
65.Xr malloc 3 , 55.Xr malloc 3 ,
66.Xr realloc 3 , 56.Xr realloc 3
67.Sh BUGS 57.Sh BUGS
68The 58The
69.Fn alloca 59.Fn alloca
70function 60function is machine dependent; its use is discouraged.
71is machine dependent; its use is discouraged.
72.\" .Sh HISTORY 61.\" .Sh HISTORY
73.\" The 62.\" The
74.\" .Fn alloca 63.\" .Fn alloca
75.\" function appeared in 64.\" function appeared in
76.\" .Bx ?? . 65.\" .Bx ?? .
77.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd 66.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
78.\" The first man page (or link to a man page that I can find at the 67.\" The first man page (or link to a man page that I can find at the
79.\" moment is 4.3... 68.\" moment is 4.3...
69.Pp
70The
71.Fn alloca
72function is slightly unsafe because it cannot ensure that the pointer
73returned points to a valid and usable block of memory.
74The allocation made may exceed the bounds of the stack, or even go
75further into other objects in memory, and
76.Fn alloca
77cannot determine such an error.
78Avoid
79.Fn alloca
80with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
index 07de054d3c..c8d4ce63d5 100644
--- a/src/lib/libc/stdlib/atexit.3
+++ b/src/lib/libc/stdlib/atexit.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atexit.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atexit.3,v 1.5 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atexit.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATEXIT 3 35.Dt ATEXIT 3
@@ -49,13 +44,12 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn atexit 46.Fn atexit
52function 47function registers the given
53registers the given 48.Fa function
54.Ar function
55to be called at program exit, whether via 49to be called at program exit, whether via
56.Xr exit 3 50.Xr exit 3
57or via return from the program's 51or via return from the program's
58.Em main . 52.Fn main .
59Functions so registered are called in reverse order; 53Functions so registered are called in reverse order;
60no arguments are passed. 54no arguments are passed.
61At least 32 functions can always be registered, 55At least 32 functions can always be registered,
@@ -73,6 +67,5 @@ The existing list of functions is unmodified.
73.Sh STANDARDS 67.Sh STANDARDS
74The 68The
75.Fn atexit 69.Fn atexit
76function 70function conforms to
77conforms to
78.St -ansiC . 71.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 4da1eb0d9c..98564d0dd3 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -1,68 +1,135 @@
1/*- 1/*
2 * Copyright (c) 1990 The Regents of the University of California. 2 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 3 * All rights reserved.
4 * 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 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
10 * are met: 7 * 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 * 8 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 9 * - Redistributions of source code must retain the above copyright
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 * notice, this list of conditions and the following disclaimer.
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11 * - Redistributions in binary form must reproduce the above
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 12 * copyright notice, this list of conditions and the following
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 * disclaimer in the documentation and/or other materials provided
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 14 * with the distribution.
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 15 *
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * SUCH DAMAGE. 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 *
35 */ 29 */
36 30
37#if defined(LIBC_SCCS) && !defined(lint) 31#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)atexit.c 5.2 (Berkeley) 11/14/90";*/ 32static char *rcsid = "$OpenBSD: atexit.c,v 1.7 2002/09/14 22:03:14 dhartmei Exp $";
39static char *rcsid = "$Id: atexit.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 33#endif /* LIBC_SCCS and not lint */
41 34
35#include <sys/types.h>
36#include <sys/mman.h>
42#include <stdlib.h> 37#include <stdlib.h>
38#include <unistd.h>
43#include "atexit.h" 39#include "atexit.h"
44 40
41int __atexit_invalid = 1;
45struct atexit *__atexit; 42struct atexit *__atexit;
46 43
47/* 44/*
45 * Function pointers are stored in a linked list of pages. The list
46 * is initially empty, and pages are allocated on demand. The first
47 * function pointer in the first allocated page (the last one in
48 * the linked list) is reserved for the cleanup function.
49 *
50 * Outside the following two functions, all pages are mprotect()'ed
51 * to prevent unintentional/malicious corruption.
52 *
53 * The free(malloc(1)) is a workaround causing malloc_init() to
54 * ensure that malloc.c gets the first mmap() call for its sbrk()
55 * games.
56 */
57
58/*
48 * Register a function to be performed at exit. 59 * Register a function to be performed at exit.
49 */ 60 */
50int 61int
51atexit(fn) 62atexit(fn)
52 void (*fn)(); 63 void (*fn)();
53{ 64{
54 static struct atexit __atexit0; /* one guaranteed table */ 65 register struct atexit *p = __atexit;
55 register struct atexit *p; 66 register int pgsize = getpagesize();
56 67
57 if ((p = __atexit) == NULL) 68 if (pgsize < sizeof(*p))
58 __atexit = p = &__atexit0; 69 return (-1);
59 else if (p->ind >= ATEXIT_SIZE) { 70 if (p != NULL) {
60 if ((p = malloc(sizeof(*p))) == NULL) 71 if (p->ind + 1 >= p->max)
72 p = NULL;
73 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
74 return (-1);
75 }
76 if (p == NULL) {
77 if (__atexit_invalid) {
78 free(malloc(1));
79 __atexit_invalid = 0;
80 }
81 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
82 MAP_ANON | MAP_PRIVATE, -1, 0);
83 if (p == MAP_FAILED)
61 return (-1); 84 return (-1);
62 p->ind = 0; 85 if (__atexit == NULL) {
86 p->fns[0] = NULL;
87 p->ind = 1;
88 } else
89 p->ind = 0;
90 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
91 sizeof(p->fns[0]);
63 p->next = __atexit; 92 p->next = __atexit;
64 __atexit = p; 93 __atexit = p;
65 } 94 }
66 p->fns[p->ind++] = fn; 95 p->fns[p->ind++] = fn;
96 if (mprotect(p, pgsize, PROT_READ))
97 return (-1);
67 return (0); 98 return (0);
68} 99}
100
101/*
102 * Register the cleanup function
103 */
104void
105__atexit_register_cleanup(fn)
106 void (*fn)();
107{
108 register struct atexit *p = __atexit;
109 register int pgsize = getpagesize();
110
111 if (pgsize < sizeof(*p))
112 return;
113 while (p != NULL && p->next != NULL)
114 p = p->next;
115 if (p == NULL) {
116 if (__atexit_invalid) {
117 free(malloc(1));
118 __atexit_invalid = 0;
119 }
120 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
121 MAP_ANON | MAP_PRIVATE, -1, 0);
122 if (p == MAP_FAILED)
123 return;
124 p->ind = 1;
125 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
126 sizeof(p->fns[0]);
127 p->next = NULL;
128 __atexit = p;
129 } else {
130 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
131 return;
132 }
133 p->fns[0] = fn;
134 mprotect(p, pgsize, PROT_READ);
135}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
index 8b756e8fe2..21b0c2e532 100644
--- a/src/lib/libc/stdlib/atexit.h
+++ b/src/lib/libc/stdlib/atexit.h
@@ -1,46 +1,41 @@
1/*- 1/* $OpenBSD: atexit.h,v 1.6 2003/07/31 07:08:42 deraadt Exp $ */
2 * Copyright (c) 1990 The Regents of the University of California. 2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 5 * All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
7 * are met: 9 * 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 * 10 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 11 * - Redistributions of source code must retain the above copyright
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12 * notice, this list of conditions and the following disclaimer.
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 13 * - Redistributions in binary form must reproduce the above
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 14 * copyright notice, this list of conditions and the following
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 15 * disclaimer in the documentation and/or other materials provided
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 16 * with the distribution.
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 17 *
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * SUCH DAMAGE. 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.
32 * 30 *
33 * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90
34 * $Id: atexit.h,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
35 */ 31 */
36 32
37/* must be at least 32 to guarantee ANSI conformance */
38#define ATEXIT_SIZE 32
39
40struct atexit { 33struct atexit {
41 struct atexit *next; /* next in list */ 34 struct atexit *next; /* next in list */
42 int ind; /* next index in this table */ 35 int ind; /* next index in this table */
43 void (*fns[ATEXIT_SIZE])(); /* the table itself */ 36 int max; /* max entries >= ATEXIT_SIZE */
37 void (*fns[1])(void); /* the table itself */
44}; 38};
45 39
40extern int __atexit_invalid;
46extern struct atexit *__atexit; /* points to head of LIFO stack */ 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
index 53e04f71c5..c60b9e9fd7 100644
--- a/src/lib/libc/stdlib/atof.3
+++ b/src/lib/libc/stdlib/atof.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atof.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: atof.3,v 1.4 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atof.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATOF 3 35.Dt ATOF 3
@@ -52,9 +47,9 @@ string to double
52The 47The
53.Fn atof 48.Fn atof
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Ar double 52.Li double
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
index 9202de50bb..dad2b77bfd 100644
--- a/src/lib/libc/stdlib/atof.c
+++ b/src/lib/libc/stdlib/atof.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/ 31static char *rcsid = "$OpenBSD: atof.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atof.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
index 219ba73c00..070344a810 100644
--- a/src/lib/libc/stdlib/atoi.3
+++ b/src/lib/libc/stdlib/atoi.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atoi.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atoi.3,v 1.7 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atoi.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 4, 1993
40.Dt ATOI 3 35.Dt ATOI 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -52,13 +47,12 @@ string to integer
52The 47The
53.Fn atoi 48.Fn atoi
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Em nptr 50.Fa nptr
56to 51to
57.Em integer 52.Li integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
61.Pp
62.Bd -literal -offset indent 56.Bd -literal -offset indent
63(int)strtol(nptr, (char **)NULL, 10); 57(int)strtol(nptr, (char **)NULL, 10);
64.Ed 58.Ed
@@ -73,3 +67,15 @@ The
73.Fn atoi 67.Fn atoi
74function conforms to 68function conforms to
75.St -ansiC . 69.St -ansiC .
70.Sh CAVEATS
71.Nm
72does no overflow checking, handles unsigned numbers poorly,
73and handles strings containing trailing extra characters
74(like
75.Dq "123abc" )
76poorly.
77Careful use of
78.Xr strtol 3
79and
80.Xr strtoul 3
81can alleviate these problems.
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
index df7845f90c..b1fe789fd5 100644
--- a/src/lib/libc/stdlib/atoi.c
+++ b/src/lib/libc/stdlib/atoi.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atoi.c 5.7 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: atoi.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atoi.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
index 86e3d324a3..80e54c892d 100644
--- a/src/lib/libc/stdlib/atol.3
+++ b/src/lib/libc/stdlib/atol.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)atol.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atol.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: atol.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt ATOL 3 35.Dt ATOL 3
@@ -52,9 +47,9 @@ string to long integer
52The 47The
53.Fn atol 48.Fn atol
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Em long integer 52.Li long integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
@@ -64,12 +59,12 @@ strtol(nptr, (char **)NULL, 10);
64.Sh SEE ALSO 59.Sh SEE ALSO
65.Xr atof 3 , 60.Xr atof 3 ,
66.Xr atoi 3 , 61.Xr atoi 3 ,
62.Xr atoll 3 ,
67.Xr strtod 3 , 63.Xr strtod 3 ,
68.Xr strtol 3 , 64.Xr strtol 3 ,
69.Xr strtoul 3 65.Xr strtoul 3
70.Sh STANDARDS 66.Sh STANDARDS
71The 67The
72.Fn atol 68.Fn atol
73function 69function conforms to
74conforms to 70.St -ansiC-99 .
75.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
index 31ed06298b..83adad3eae 100644
--- a/src/lib/libc/stdlib/atol.c
+++ b/src/lib/libc/stdlib/atol.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atol.c 5.7 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: atol.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: atol.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/atoll.3
index d0754b46a0..40584e9d47 100644
--- a/src/lib/libc/stdlib/calloc.3
+++ b/src/lib/libc/stdlib/atoll.3
@@ -1,4 +1,4 @@
1.\" Copyright (c) 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved. 2.\" All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,39 +29,42 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)calloc.3 5.2 (Berkeley) 6/29/91 32.\" $OpenBSD: atoll.3,v 1.3 2003/06/02 20:18:37 millert Exp $
37.\" $Id: calloc.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt CALLOC 3 35.Dt ATOLL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm calloc 38.Nm atoll
44.Nd allocate clean memory (zero initialized space) 39.Nd convert
40.Tn ASCII
41string to long long integer
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Ft void * 44.Ft long long
48.Fn calloc "size_t nmemb" "size_t size" 45.Fn atoll "const char *nptr"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn calloc 48.Fn atoll
52function allocates space for an array of 49function converts the initial portion of the string pointed to by
53.Fa nmemb 50.Fa nptr
54objects, each of whose size is 51to
55.Fa size . 52.Li long integer
56The space is initialized to all bits zero. 53representation.
57.Sh RETURN VALUES 54.Pp
58The 55It is equivalent to:
59.Fn calloc 56.Bd -literal -offset indent
60function returns 57strtoll(nptr, (char **)NULL, 10);
61a pointer to the 58.Ed
62the allocated space if successful; otherwise a null pointer is returned.
63.Sh SEE ALSO 59.Sh SEE ALSO
64.Xr malloc 3 , 60.Xr atof 3 ,
65.Xr realloc 3 , 61.Xr atoi 3 ,
66.Xr free 3 62.Xr atol 3 ,
63.Xr strtod 3 ,
64.Xr strtol 3 ,
65.Xr strtoul 3
67.Sh STANDARDS 66.Sh STANDARDS
68The 67The
69.Fn calloc 68.Fn atoll
70function conforms to 69function conforms to
71.St -ansiC . 70.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/atoll.c b/src/lib/libc/stdlib/atoll.c
new file mode 100644
index 0000000000..6786b62e1a
--- /dev/null
+++ b/src/lib/libc/stdlib/atoll.c
@@ -0,0 +1,41 @@
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. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: atoll.c,v 1.2 2003/06/02 20:18:37 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <stdlib.h>
35
36long long
37atoll(str)
38 const char *str;
39{
40 return(strtoll(str, (char **)NULL, 10));
41}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 1622c96c6b..d1dd9173db 100644
--- a/src/lib/libc/stdlib/bsearch.3
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)bsearch.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: bsearch.3,v 1.6 2003/06/02 20:18:37 millert Exp $
37.\" $Id: bsearch.3,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd April 19, 1994
40.Dt BSEARCH 3 35.Dt BSEARCH 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -51,12 +46,12 @@ The
51.Fn bsearch 46.Fn bsearch
52function searches an array of 47function searches an array of
53.Fa nmemb 48.Fa nmemb
54objects, the initial member of which is 49objects, the initial member of which is
55pointed to by 50pointed to by
56.Fa base , 51.Fa base ,
57for a member that matches the object pointed to by 52for a member that matches the object pointed to by
58.Fa key . 53.Fa key .
59The size of each member of the array is specified by 54The size of each member of the array is specified by
60.Fa size . 55.Fa size .
61.Pp 56.Pp
62The contents of the array should be in ascending sorted order according 57The contents of the array should be in ascending sorted order according
@@ -64,9 +59,7 @@ to the comparison function referenced by
64.Fa compar . 59.Fa compar .
65The 60The
66.Fa compar 61.Fa compar
67routine 62routine is expected to have two arguments which point to the
68is expected to have two
69two arguments which point to the
70.Fa key 63.Fa key
71object and to an array member, in that order, and should return an integer 64object and to an array member, in that order, and should return an integer
72less than, equal to, or greater than zero if the 65less than, equal to, or greater than zero if the
@@ -83,7 +76,7 @@ If two members compare as equal, which member is matched is unspecified.
83.Xr db 3 , 76.Xr db 3 ,
84.Xr lsearch 3 , 77.Xr lsearch 3 ,
85.Xr qsort 3 , 78.Xr qsort 3 ,
86.\" .Xr tsearch 3 79.Xr tsearch 3
87.Sh STANDARDS 80.Sh STANDARDS
88The 81The
89.Fn bsearch 82.Fn bsearch
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
index fac03f694f..9bfbf64256 100644
--- a/src/lib/libc/stdlib/bsearch.c
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bsearch.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: bsearch.c,v 1.4 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -60,7 +55,7 @@ bsearch(key, base0, nmemb, size, compar)
60 const void *base0; 55 const void *base0;
61 size_t nmemb; 56 size_t nmemb;
62 register size_t size; 57 register size_t size;
63 register int (*compar) __P((const void *, const void *)); 58 register int (*compar)(const void *, const void *);
64{ 59{
65 register const char *base = base0; 60 register const char *base = base0;
66 register int lim, cmp; 61 register int lim, cmp;
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
index 3353fab052..b0703cc884 100644
--- a/src/lib/libc/stdlib/calloc.c
+++ b/src/lib/libc/stdlib/calloc.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,12 +28,13 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)calloc.c 5.6 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: calloc.c,v 1.8 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: calloc.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
36#include <limits.h>
37#include <errno.h>
41 38
42void * 39void *
43calloc(num, size) 40calloc(num, size)
@@ -46,8 +43,13 @@ calloc(num, size)
46{ 43{
47 register void *p; 44 register void *p;
48 45
46 if (num && size && SIZE_T_MAX / num < size) {
47 errno = ENOMEM;
48 return NULL;
49 }
49 size *= num; 50 size *= num;
50 if (p = malloc(size)) 51 p = malloc(size);
51 memset(p, '\0', size); 52 if (p)
53 memset(p, 0, size);
52 return(p); 54 return(p);
53} 55}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..ecbc11d6c3
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,45 @@
1/* $OpenBSD: cfree.c,v 1.3 2003/07/18 23:05:13 david 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 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#if defined(LIBC_SCCS) && !defined(lint)
29static char rcsid[] = "$OpenBSD: cfree.c,v 1.3 2003/07/18 23:05:13 david Exp $";
30#endif /* LIBC_SCCS and not lint */
31
32#include <sys/cdefs.h>
33#include <stdlib.h>
34
35#ifdef __indr_reference
36__indr_reference(free, cfree);
37#else
38
39void
40cfree(p)
41 void *p;
42{
43 free(p);
44}
45#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
index a4730694a5..a75614310e 100644
--- a/src/lib/libc/stdlib/div.3
+++ b/src/lib/libc/stdlib/div.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
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 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,8 +27,7 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)div.3 5.2 (Berkeley) 4/19/91 30.\" $OpenBSD: div.3,v 1.7 2004/01/23 23:08:46 jmc Exp $
35.\" $Id: div.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd April 19, 1991
38.Dt DIV 3 33.Dt DIV 3
@@ -47,24 +42,22 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn div 44.Fn div
50function 45function computes the value
51computes the value 46.Fa num Ns / Ns Fa denom
52.Fa num/denom
53and returns the quotient and remainder in a structure named 47and returns the quotient and remainder in a structure named
54.Fa div_t 48.Fa div_t
55that contains two 49that contains two
56.Em int 50.Li int
57members named 51members named
58.Fa quot 52.Fa quot
59and 53and
60.Fa rem . 54.Fa rem .
61.Sh SEE ALSO 55.Sh SEE ALSO
62.Xr ldiv 3 , 56.Xr ldiv 3 ,
63.Xr qdiv 3 , 57.Xr math 3 ,
64.Xr math 3 58.Xr qdiv 3
65.Sh STANDARDS 59.Sh STANDARDS
66The 60The
67.Fn div 61.Fn div
68function 62function conforms to
69conforms to
70.St -ansiC . 63.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
index 122ac0deec..9e070dcd64 100644
--- a/src/lib/libc/stdlib/div.c
+++ b/src/lib/libc/stdlib/div.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)div.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: div.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
39static char *rcsid = "$Id: div.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* div_t */ 37#include <stdlib.h> /* div_t */
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
index ae1a8634dc..02886d5b62 100644
--- a/src/lib/libc/stdlib/drand48.c
+++ b/src/lib/libc/stdlib/drand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: drand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3
new file mode 100644
index 0000000000..689cb1c6f9
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: ecvt.3,v 1.7 2004/01/25 14:48:32 jmc Exp $
2.\"
3.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.\" Sponsored in part by the Defense Advanced Research Projects
18.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
19.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
20.\"
21.Dd December 1, 2002
22.Dt ECVT 3
23.Os
24.Sh NAME
25.Nm ecvt ,
26.Nm fcvt ,
27.Nm gcvt
28.Nd convert double to
29.Tn ASCII
30string
31.Sh SYNOPSIS
32.Fd #include <stdlib.h>
33.Ft char *
34.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
35.Ft char *
36.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
37.Ft char *
38.Fn gcvt "double value" "int ndigit" "char *buf"
39.Sh DESCRIPTION
40.Bf -symbolic
41These functions are provided for compatibility with legacy code.
42New code should use the
43.Xr snprintf 3
44function for improved safety and portability.
45.Ef
46.Pp
47The
48.Fn ecvt ,
49.Fn fcvt
50and
51.Fn gcvt
52functions convert the double precision floating-point number
53.Fa value
54to a NUL-terminated
55.Tn ASCII
56string.
57.Pp
58The
59.Fn ecvt
60function converts
61.Fa value
62to a NUL-terminated string of exactly
63.Fa ndigit
64digits and returns a pointer to that string.
65The result is padded with zeroes from left to right as needed.
66There are no leading zeroes unless
67.Fa value
68itself is 0.
69The least significant digit is rounded in an implementation-dependent manner.
70The position of the decimal point relative to the beginning of the string
71is stored in
72.Fa decpt .
73A negative value indicates that the decimal point is located
74to the left of the returned digits (this occurs when there is no
75whole number component to
76.Fa value ) .
77If
78.Fa value
79is zero, it is unspecified whether the integer pointed to by
80.Fa decpt
81will be 0 or 1.
82The decimal point itself is not included in the returned string.
83If the sign of the result is negative, the integer pointed to by
84.Fa sign
85is non-zero; otherwise, it is 0.
86.Pp
87If the converted value is out of range or is not representable,
88the contents of the returned string are unspecified.
89.Pp
90The
91.Fn fcvt
92function is identical to
93.Fn ecvt
94with the exception that
95.Fa ndigit
96specifies the number of digits after the decimal point (zero-padded as
97needed).
98.Pp
99The
100.Fn gcvt
101function converts
102.Fa value
103to a NUL-terminated string similar to the %g
104.Xr printf 3
105format specifier and stores the result in
106.Fa buf .
107It produces
108.Fa ndigit
109significant digits similar to the %f
110.Xr printf 3
111format specifier where possible.
112If
113.Fa ndigit
114does allow sufficient precision, the result is stored in
115exponential notation similar to the %e
116.Xr printf 3
117format specifier.
118If
119.Fa value
120is less than zero,
121.Fa buf
122will be prefixed with a minus sign.
123A decimal point is included in the returned string if
124.Fa value
125is not a whole number.
126Unlike the
127.Fn ecvt
128and
129.Fn fcvt
130functions,
131.Fa buf
132is not zero-padded.
133.Sh RETURN VALUES
134The
135.Fn ecvt ,
136.Fn fcvt
137and
138.Fn gcvt
139functions return a NUL-terminated string representation of
140.Fa value .
141.Sh WARNINGS
142The
143.Fn ecvt
144and
145.Fn fcvt
146functions return a pointer to internal storage space that will be
147overwritten by subsequent calls to either function.
148.Pp
149The maximum possible precision of the return value is limited by the
150precision of a double and may not be the same on all architectures.
151.Pp
152The
153.Xr snprintf 3
154function is preferred over these functions for new code.
155.Sh SEE ALSO
156.Xr printf 3 ,
157.Xr strtod 3
158.Sh STANDARDS
159The
160.Fn ecvt ,
161.Fn fcvt
162and
163.Fn gcvt
164functions conform to
165.St -p1003.1-2001 .
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c
new file mode 100644
index 0000000000..657c531808
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,103 @@
1/* $OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23#if defined(LIBC_SCCS) && !defined(lint)
24static char rcsid[] = "$OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $";
25#endif /* LIBC_SCCS and not lint */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31extern char *__dtoa(double, int, int, int *, int *, char **);
32static char *__cvt(double, int, int *, int *, int, int);
33
34static char *
35__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
36{
37 static char *s;
38 char *p, *rve;
39 size_t siz;
40
41 if (ndigit == 0) {
42 *sign = value < 0.0;
43 *decpt = 0;
44 return ("");
45 }
46
47 if (s) {
48 free(s);
49 s = NULL;
50 }
51
52 if (ndigit < 0)
53 siz = -ndigit + 1;
54 else
55 siz = ndigit + 1;
56
57
58 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
59 if (value == 0.0) {
60 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
61 *sign = 0;
62 if ((rve = s = (char *)malloc(siz)) == NULL)
63 return(NULL);
64 *rve++ = '0';
65 *rve = '\0';
66 } else {
67 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
68 if (*decpt == 9999) {
69 /* Nan or Infinity */
70 *decpt = 0;
71 return(p);
72 }
73 /* make a local copy and adjust rve to be in terms of s */
74 if (pad && fmode)
75 siz += *decpt;
76 if ((s = (char *)malloc(siz)) == NULL)
77 return(NULL);
78 (void) strlcpy(s, p, siz);
79 rve = s + (rve - p);
80 }
81
82 /* Add trailing zeros (unless we got NaN or Inf) */
83 if (pad && *decpt != 9999) {
84 siz -= rve - s;
85 while (--siz)
86 *rve++ = '0';
87 *rve = '\0';
88 }
89
90 return(s);
91}
92
93char *
94ecvt(double value, int ndigit, int *decpt, int *sign)
95{
96 return(__cvt(value, ndigit, decpt, sign, 0, 1));
97}
98
99char *
100fcvt(double value, int ndigit, int *decpt, int *sign)
101{
102 return(__cvt(value, ndigit, decpt, sign, 1, 1));
103}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
index cc9fbf770c..b92dacffcc 100644
--- a/src/lib/libc/stdlib/erand48.c
+++ b/src/lib/libc/stdlib/erand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: erand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16double 20double
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
index adb81ffcb4..8c4b2eed2c 100644
--- a/src/lib/libc/stdlib/exit.3
+++ b/src/lib/libc/stdlib/exit.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)exit.3 6.6 (Berkeley) 6/29/91 32.\" $OpenBSD: exit.3,v 1.9 2003/06/02 20:18:37 millert Exp $
37.\" $Id: exit.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt EXIT 3 35.Dt EXIT 3
@@ -47,8 +42,9 @@
47.Ft void 42.Ft void
48.Fn exit "int status" 43.Fn exit "int status"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50.Fn Exit 45The
51terminates a process. 46.Fn exit
47function terminates a process.
52.Pp 48.Pp
53Before termination it performs the following functions in the 49Before termination it performs the following functions in the
54order listed: 50order listed:
@@ -66,19 +62,28 @@ Unlink all files created with the
66.Xr tmpfile 3 62.Xr tmpfile 3
67function. 63function.
68.El 64.El
65.Pp
66Following this,
67.Fn exit
68calls
69.Xr _exit 2 .
70Note that typically
71.Xr _exit 2
72only passes the lower 8 bits of
73.Fa status
74on to the parent, thus negative values have less meaning.
69.Sh RETURN VALUES 75.Sh RETURN VALUES
70The 76The
71.Fn exit 77.Fn exit
72function 78function never returns.
73never returns.
74.Sh SEE ALSO 79.Sh SEE ALSO
75.Xr _exit 2 , 80.Xr _exit 2 ,
76.Xr atexit 3 , 81.Xr atexit 3 ,
77.Xr intro 3 , 82.Xr intro 3 ,
83.Xr sysexits 3 ,
78.Xr tmpfile 3 84.Xr tmpfile 3
79.Sh STANDARDS 85.Sh STANDARDS
80The 86The
81.Fn exit 87.Fn exit
82function 88function conforms to
83conforms to
84.St -ansiC . 89.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
index b1412f42bb..a75b32abeb 100644
--- a/src/lib/libc/stdlib/exit.c
+++ b/src/lib/libc/stdlib/exit.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,15 +28,24 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: exit.c,v 1.9 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: exit.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#include <sys/types.h>
35#include <sys/mman.h>
39#include <stdlib.h> 36#include <stdlib.h>
40#include <unistd.h> 37#include <unistd.h>
41#include "atexit.h" 38#include "atexit.h"
39#include "thread_private.h"
42 40
43void (*__cleanup)(); 41/*
42 * This variable is zero until a process has created a thread.
43 * It is used to avoid calling locking functions in libc when they
44 * are not required. By default, libc is intended to be(come)
45 * thread-safe, but without a (significant) penalty to non-threaded
46 * processes.
47 */
48int __isthreaded = 0;
44 49
45/* 50/*
46 * Exit, flushing stdio buffers if necessary. 51 * Exit, flushing stdio buffers if necessary.
@@ -49,13 +54,20 @@ void
49exit(status) 54exit(status)
50 int status; 55 int status;
51{ 56{
52 register struct atexit *p; 57 register struct atexit *p, *q;
53 register int n; 58 register int n, pgsize = getpagesize();
54 59
55 for (p = __atexit; p; p = p->next) 60 if (!__atexit_invalid) {
56 for (n = p->ind; --n >= 0;) 61 p = __atexit;
57 (*p->fns[n])(); 62 while (p != NULL) {
58 if (__cleanup) 63 for (n = p->ind; --n >= 0;)
59 (*__cleanup)(); 64 if (p->fns[n] != NULL)
65 (*p->fns[n])();
66 q = p;
67 p = p->next;
68 munmap(q, pgsize);
69 }
70 }
71 /* cleanup, if registered, was called through fns[0] in the last page */
60 _exit(status); 72 _exit(status);
61} 73}
diff --git a/src/lib/libc/stdlib/free.3 b/src/lib/libc/stdlib/free.3
deleted file mode 100644
index 3d0131d7de..0000000000
--- a/src/lib/libc/stdlib/free.3
+++ /dev/null
@@ -1,82 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" from: @(#)free.3 5.2 (Berkeley) 6/29/91
37.\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\"
39.Dd June 29, 1991
40.Dt FREE 3
41.Os
42.Sh NAME
43.Nm free
44.Nd free up memory allocated with malloc, calloc or realloc
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn free "void *ptr"
49.Sh DESCRIPTION
50The
51.Fn free
52function causes the space pointed to by
53.Fa ptr
54to be deallocated, that is, made available
55for further allocation.
56If
57.Fa ptr
58is a null pointer, no action occurs.
59Otherwise, if the argument does not match a pointer earlier
60returned by the
61.Xr calloc ,
62.Xr malloc ,
63or
64.Xr realloc
65function, or if the space has been deallocated by a call to
66.Fn free
67or
68.Xr realloc ,
69general havoc may occur.
70.Sh RETURN VALUES
71The
72.Fn free
73function returns no value.
74.Sh SEE ALSO
75.Xr calloc 3 ,
76.Xr malloc 3 ,
77.Xr realloc 3
78.Sh STANDARDS
79The
80.Fn free
81function conforms to
82.St -ansiC .
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..9fd664b346
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,99 @@
1/* $OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23#if defined(LIBC_SCCS) && !defined(lint)
24static char rcsid[] = "$OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $";
25#endif /* LIBC_SCCS and not lint */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31extern char *__dtoa(double, int, int, int *, int *, char **);
32
33char *
34gcvt(double value, int ndigit, char *buf)
35{
36 char *digits, *dst, *src;
37 int i, decpt, sign;
38
39 if (ndigit == 0) {
40 buf[0] = '\0';
41 return (buf);
42 }
43
44 digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
45 if (decpt == 9999) {
46 /* Infinity or NaN, assume buffer is at least ndigit long. */
47 strlcpy(buf, digits, ndigit + 1);
48 return (buf);
49 }
50
51 dst = buf;
52 if (sign)
53 *dst++ = '-';
54
55 if (decpt < 0 || decpt > ndigit) {
56 /* exponential format */
57 if (--decpt < 0) {
58 sign = 1;
59 decpt = -decpt;
60 } else
61 sign = 0;
62 for (src = digits; *src != '\0'; )
63 *dst++ = *src++;
64 *dst++ = 'e';
65 if (sign)
66 *dst++ = '-';
67 else
68 *dst++ = '+';
69 if (decpt < 10) {
70 *dst++ = '0';
71 *dst++ = '0' + decpt;
72 *dst = '\0';
73 } else {
74 /* XXX - optimize */
75 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
76 sign /= 10;
77 while (decpt != 0) {
78 dst[i--] = '0' + decpt % 10;
79 decpt /= 10;
80 }
81 }
82 } else {
83 /* standard format */
84 for (i = 0, src = digits; i < decpt; i++) {
85 if (*src != '\0')
86 *dst++ = *src++;
87 else
88 *dst++ = '0';
89 }
90 if (*src != '\0') {
91 *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */
92 for (i = decpt; digits[i] != '\0'; i++) {
93 *dst++ = digits[i];
94 }
95 }
96 *dst = '\0';
97 }
98 return (buf);
99}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
index 411eb35da4..054004e1d8 100644
--- a/src/lib/libc/stdlib/getenv.3
+++ b/src/lib/libc/stdlib/getenv.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1988, 1991 The Regents of the University of California. 1.\" Copyright (c) 1988, 1991, 1993
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)getenv.3 6.11 (Berkeley) 6/29/91 32.\" $OpenBSD: getenv.3,v 1.9 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: getenv.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd December 11, 1993
40.Dt GETENV 3 35.Dt GETENV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -56,59 +51,51 @@
56.Ft void 51.Ft void
57.Fn unsetenv "const char *name" 52.Fn unsetenv "const char *name"
58.Sh DESCRIPTION 53.Sh DESCRIPTION
59These functions set, unset and fetch environment variables from the 54These functions set, unset, and fetch environment variables from the host
60host
61.Em environment list . 55.Em environment list .
62For compatibility with differing environment conventions, 56For compatibility with differing environment conventions, the given arguments
63the given arguments 57.Fa name
64.Ar name
65and 58and
66.Ar value 59.Fa value
67may be appended and prepended, 60may be appended and prepended, respectively, with an equal sign
68respectively,
69with an equal sign
70.Dq Li \&= . 61.Dq Li \&= .
71.Pp 62.Pp
72The 63The
73.Fn getenv 64.Fn getenv
74function obtains the current value of the environment variable, 65function obtains the current value of the environment variable,
75.Ar name . 66.Fa name .
76If the variable 67If the variable
77.Ar name 68.Fa name
78is not in the current environment , 69is not in the current environment, a null pointer is returned.
79a null pointer is returned.
80.Pp 70.Pp
81The 71The
82.Fn setenv 72.Fn setenv
83function inserts or resets the environment variable 73function inserts or resets the environment variable
84.Ar name 74.Fa name
85in the current environment list. 75in the current environment list.
86If the variable 76If the variable
87.Ar name 77.Fa name
88does not exist in the list, 78does not exist in the list, it is inserted with the given
89it is inserted with the given 79.Fa value .
90.Ar value.
91If the variable does exist, the argument 80If the variable does exist, the argument
92.Ar overwrite 81.Fa overwrite
93is tested; if 82is tested; if
94.Ar overwrite is 83.Fa overwrite
95zero, the 84is zero, the variable is not reset, otherwise it is reset to the given
96variable is not reset, otherwise it is reset 85.Fa value .
97to the given
98.Ar value .
99.Pp 86.Pp
100The 87The
101.Fn putenv 88.Fn putenv
102function takes an argument of the form ``name=value'' and is 89function takes an argument of the form
103equivalent to: 90.Ar name Ns = Ns Ar value
91and is equivalent to:
104.Bd -literal -offset indent 92.Bd -literal -offset indent
105setenv(name, value, 1); 93setenv(name, value, 1);
106.Ed 94.Ed
107.Pp 95.Pp
108The 96The
109.Fn unsetenv 97.Fn unsetenv
110function 98function deletes all instances of the variable name pointed to by
111deletes all instances of the variable name pointed to by
112.Fa name 99.Fa name
113from the list. 100from the list.
114.Sh RETURN VALUES 101.Sh RETURN VALUES
@@ -118,10 +105,13 @@ and
118.Fn putenv 105.Fn putenv
119return zero if successful; otherwise the global variable 106return zero if successful; otherwise the global variable
120.Va errno 107.Va errno
121is set to indicate the error and a 108is set to indicate the error and \-1 is returned.
122\-1 is returned. 109.Pp
110If
111.Fn getenv
112is successful, the string returned should be considered read-only.
123.Sh ERRORS 113.Sh ERRORS
124.Bl -tag -width Er 114.Bl -tag -width [ENOMEM]
125.It Bq Er ENOMEM 115.It Bq Er ENOMEM
126The function 116The function
127.Fn setenv 117.Fn setenv
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 09d47f2149..c597e468a9 100644
--- a/src/lib/libc/stdlib/getenv.c
+++ b/src/lib/libc/stdlib/getenv.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 1987 Regents of the University of California. 2 * Copyright (c) 1987, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,26 +28,13 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)getenv.c 5.8 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: getenv.c,v 1.6 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: getenv.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
41 36
42/* 37char *__findenv(const char *name, int *offset);
43 * getenv --
44 * Returns ptr to value associated with name, if any, else NULL.
45 */
46char *
47getenv(name)
48 const char *name;
49{
50 int offset;
51 char *__findenv();
52
53 return(__findenv(name, &offset));
54}
55 38
56/* 39/*
57 * __findenv -- 40 * __findenv --
@@ -63,20 +46,39 @@ getenv(name)
63 * This routine *should* be a static; don't use it. 46 * This routine *should* be a static; don't use it.
64 */ 47 */
65char * 48char *
66__findenv(name, offset) 49__findenv(const char *name, int *offset)
67 register char *name;
68 int *offset;
69{ 50{
70 extern char **environ; 51 extern char **environ;
71 register int len; 52 register int len, i;
72 register char **P, *C; 53 register const char *np;
54 register char **p, *cp;
55
56 if (name == NULL || environ == NULL)
57 return (NULL);
58 for (np = name; *np && *np != '='; ++np)
59 ;
60 len = np - name;
61 for (p = environ; (cp = *p) != NULL; ++p) {
62 for (np = name, i = len; i && *cp; i--)
63 if (*cp++ != *np++)
64 break;
65 if (i == 0 && *cp++ == '=') {
66 *offset = p - environ;
67 return (cp);
68 }
69 }
70 return (NULL);
71}
72
73/*
74 * getenv --
75 * Returns ptr to value associated with name, if any, else NULL.
76 */
77char *
78getenv(name)
79 const char *name;
80{
81 int offset;
73 82
74 for (C = name, len = 0; *C && *C != '='; ++C, ++len); 83 return (__findenv(name, &offset));
75 for (P = environ; *P; ++P)
76 if (!strncmp(*P, name, len))
77 if (*(C = *P + len) == '=') {
78 *offset = P - environ;
79 return(++C);
80 }
81 return(NULL);
82} 84}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
index f843881afd..d210852c6b 100644
--- a/src/lib/libc/stdlib/getopt.3
+++ b/src/lib/libc/stdlib/getopt.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,11 +25,11 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" @(#)getopt.3 8.4 (Berkeley) 4/19/94 28.\" $OpenBSD: getopt.3,v 1.28 2003/09/22 23:47:26 millert Exp $
33.\" 29.\"
34.Dd April 19, 1994 30.Dd December 17, 2002
35.Dt GETOPT 3 31.Dt GETOPT 3
36.Os BSD 4.3 32.Os
37.Sh NAME 33.Sh NAME
38.Nm getopt 34.Nm getopt
39.Nd get option character from command line argument list 35.Nd get option character from command line argument list
@@ -61,20 +57,24 @@ if it has been specified in the string of accepted option characters,
61.Pp 57.Pp
62The option string 58The option string
63.Fa optstring 59.Fa optstring
64may contain the following elements: individual characters, and 60may contain the following elements: individual characters,
65characters followed by a colon to indicate an option argument 61characters followed by a colon, and characters followed by two colons.
66is to follow. 62A character followed by a single colon indicates that an argument
63is to follow the option on the command line.
64Two colons indicates that the argument is optional--this is an
65extension not covered by
66.Px .
67For example, an option string 67For example, an option string
68.Li "\&""x"" 68.Qq x
69recognizes an option 69recognizes an option
70.Dq Fl x , 70.Fl x ,
71and an option string 71and an option string
72.Li "\&""x:"" 72.Qq Li x:
73recognizes an option and argument 73recognizes an option and argument
74.Dq Fl x Ar argument . 74.Fl x Ar argument .
75It does not matter to 75It does not matter to
76.Fn getopt 76.Fn getopt
77if a following argument has leading white space. 77if a following argument has leading whitespace.
78.Pp 78.Pp
79On return from 79On return from
80.Fn getopt , 80.Fn getopt ,
@@ -87,14 +87,8 @@ contains the index to the next
87argument for a subsequent call 87argument for a subsequent call
88to 88to
89.Fn getopt . 89.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp 90.Pp
97The variable 91The variables
98.Va opterr 92.Va opterr
99and 93and
100.Va optind 94.Va optind
@@ -119,63 +113,62 @@ must be reinitialized.
119.Pp 113.Pp
120The 114The
121.Fn getopt 115.Fn getopt
122function 116function returns \-1 when the argument list is exhausted.
123returns \-1
124when the argument list is exhausted, or a non-recognized
125option is encountered.
126The interpretation of options in the argument list may be cancelled 117The interpretation of options in the argument list may be cancelled
127by the option 118by the option
128.Ql -- 119.Ql --
129(double dash) which causes 120(double dash) which causes
130.Fn getopt 121.Fn getopt
131to signal the end of argument processing and returns \-1. 122to signal the end of argument processing and return \-1.
132When all options have been processed (i.e., up to the first non-option 123When all options have been processed (i.e., up to the first non-option
133argument), 124argument),
134.Fn getopt 125.Fn getopt
135returns \-1. 126returns \-1.
136.Sh DIAGNOSTICS 127.Sh RETURN VALUES
137If the 128The
138.Fn getopt 129.Fn getopt
139function encounters a character not found in the string 130function returns the next known option character in
140.Va optarg 131.Fa optstring .
141or detects
142a missing option argument it writes an error message and returns
143.Ql ?
144to the
145.Em stderr .
146Setting
147.Va opterr
148to a zero will disable these error messages.
149If 132If
150.Va optstring 133.Fn getopt
151has a leading 134encounters a character not found in
152.Ql \&: 135.Fa optstring
153then a missing option argument causes a 136or if it detects a missing option argument,
154.Ql \&: 137it returns
155to be returned in addition to suppressing any error messages. 138.Sq \&?
156.Pp 139(question mark).
157Option arguments are allowed to begin with 140If
158.Dq Li \- ; 141.Fa optstring
159this is reasonable but 142has a leading
160reduces the amount of error checking possible. 143.Sq \&:
161.Sh EXTENSIONS 144then a missing option argument causes
145.Sq \&:
146to be returned instead of
147.Sq \&? .
148In either case, the variable
149.Va optopt
150is set to the character that caused the error.
162The 151The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt 152.Fn getopt
166function multiple times. 153function returns \-1 when the argument list is exhausted.
167This is an extension to the 154.Sh ENVIRONMENT
168.St -p1003.2 155.Bl -tag -width POSIXLY_CORRECTXX
169specification. 156.It Ev POSIXLY_CORRECT
170.Sh EXAMPLE 157If set, a leading
158.Sq -
159in
160.Ar optstring
161is ignored.
162.El
163.Sh EXAMPLES
171.Bd -literal -compact 164.Bd -literal -compact
172extern char *optarg; 165extern char *optarg;
173extern int optind; 166extern int optind;
174int bflag, ch, fd; 167int bflag, ch, fd;
175 168
176bflag = 0; 169bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) 170while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch(ch) { 171 switch (ch) {
179 case 'b': 172 case 'b':
180 bflag = 1; 173 bflag = 1;
181 break; 174 break;
@@ -189,31 +182,76 @@ while ((ch = getopt(argc, argv, "bf:")) != -1)
189 case '?': 182 case '?':
190 default: 183 default:
191 usage(); 184 usage();
185 }
192} 186}
193argc -= optind; 187argc -= optind;
194argv += optind; 188argv += optind;
195.Ed 189.Ed
196.Sh HISTORY 190.Sh DIAGNOSTICS
197The 191If the
198.Fn getopt 192.Fn getopt
199function appeared 193function encounters a character not found in the string
200.Bx 4.3 . 194.Fa optstring
201.Sh BUGS 195or detects
196a missing option argument it writes an error message to
197.Em stderr
198and returns
199.Ql \&? .
200Setting
201.Va opterr
202to a zero will disable these error messages.
203If
204.Fa optstring
205has a leading
206.Ql \&:
207then a missing option argument causes a
208.Ql \&:
209to be returned in addition to suppressing any error messages.
210.Pp
211Option arguments are allowed to begin with
212.Ql - ;
213this is reasonable but reduces the amount of error checking possible.
214.Sh SEE ALSO
215.Xr getopt 1 ,
216.Xr getopt_long 3 ,
217.Xr getsubopt 3
218.Sh STANDARDS
202The 219The
203.Fn getopt 220.Fn getopt
204function was once specified to return 221function implements a superset of the functionality specified by
205.Dv EOF 222.St -p1003.1 .
206instead of \-1.
207This was changed by
208.St -p1003.2-92
209to decouple
210.Fn getopt
211from
212.Pa <stdio.h> .
213.Pp 223.Pp
224The following extensions are supported:
225.Bl -tag -width "xxx"
226.It Li o
227The
228.Va optreset
229variable was added to make it possible to call the
230.Fn getopt
231function multiple times.
232.It Li o
233If the first character of
234.Fa optstring
235is a plus sign
236.Pq Ql + ,
237it will be ignored.
238This is for compatibility with
239.Tn GNU
240.Fn getopt .
241.It Li o
242If the first character of
243.Fa optstring
244is a dash
245.Pq Ql - ,
246non-options will be returned as arguments to the option character
247.Ql \e1 .
248This is for compatibility with
249.Tn GNU
250.Fn getopt .
251.It Li o
214A single dash 252A single dash
215.Dq Li - 253.Pq Ql -
216may be specified as an character in 254may be specified as a character in
217.Fa optstring , 255.Fa optstring ,
218however it should 256however it should
219.Em never 257.Em never
@@ -221,39 +259,81 @@ have an argument associated with it.
221This allows 259This allows
222.Fn getopt 260.Fn getopt
223to be used with programs that expect 261to be used with programs that expect
224.Dq Li - 262.Ql -
225as an option flag. 263as an option flag.
226This practice is wrong, and should not be used in any current development. 264This practice is wrong, and should not be used in any current development.
227It is provided for backward compatibility 265It is provided for backward compatibility
228.Em only . 266.Em only .
267Care should be taken not to use
268.Ql -
269as the first character in
270.Fa optstring
271to avoid a semantic conflict with
272.Tn GNU
273.Fn getopt
274semantics (see above).
229By default, a single dash causes 275By default, a single dash causes
230.Fn getopt 276.Fn getopt
231to return \-1. 277to return \-1.
232This is, we believe, compatible with System V. 278.El
279.Pp
280Unlike
281.Tn GNU
282.Fn getopt ,
283.Ox
284does not permute the argument vector to allow non-options to be
285interspersed with options on the command line.
286Programs requiring this behavior should use
287.Xr getopt_long 3
288instead.
289Because of this (and unlike
290.Tn GNU ) ,
291the
292.Ox
293.Fn getopt
294supports optional arguments separated by whitespace.
295.Sh HISTORY
296The
297.Fn getopt
298function appeared in
299.Bx 4.3 .
300.Sh BUGS
301The
302.Fn getopt
303function was once specified to return
304.Dv EOF
305instead of \-1.
306This was changed by
307.St -p1003.2-92
308to decouple
309.Fn getopt
310from
311.Aq Pa stdio.h .
233.Pp 312.Pp
234It is also possible to handle digits as option letters. 313It is possible to handle digits as option letters.
235This allows 314This allows
236.Fn getopt 315.Fn getopt
237to be used with programs that expect a number 316to be used with programs that expect a number
238.Pq Dq Li \&-\&3 317.Pq Dq Li \-3
239as an option. 318as an option.
240This practice is wrong, and should not be used in any current development. 319This practice is wrong, and should not be used in any current development.
241It is provided for backward compatibility 320It is provided for backward compatibility
242.Em only . 321.Em only .
243The following code fragment works in most cases. 322The following code fragment works in most cases.
244.Bd -literal -offset indent 323.Bd -literal -offset indent
245int length; 324int ch;
325long length;
246char *p; 326char *p;
247 327
248while ((c = getopt(argc, argv, "0123456789")) != -1) 328while ((ch = getopt(argc, argv, "0123456789")) != -1) {
249 switch (c) { 329 switch (ch) {
250 case '0': case '1': case '2': case '3': case '4': 330 case '0': case '1': case '2': case '3': case '4':
251 case '5': case '6': case '7': case '8': case '9': 331 case '5': case '6': case '7': case '8': case '9':
252 p = argv[optind - 1]; 332 p = argv[optind - 1];
253 if (p[0] == '-' && p[1] == ch && !p[2]) 333 if (p[0] == '-' && p[1] == ch && !p[2])
254 length = atoi(++p); 334 length = ch - '0';
255 else 335 else
256 length = atoi(argv[optind] + 1); 336 length = strtol(argv[optind] + 1, NULL, 10);
257 break; 337 break;
258 } 338 }
259} 339}
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
deleted file mode 100644
index 63c5e6a479..0000000000
--- a/src/lib/libc/stdlib/getopt.c
+++ /dev/null
@@ -1,118 +0,0 @@
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)
35/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */
36static char *rcsid = "$Id: getopt.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43int opterr = 1, /* if error message should be printed */
44 optind = 1, /* index into parent argv vector */
45 optopt, /* character checked for validity */
46 optreset; /* reset getopt */
47char *optarg; /* argument associated with option */
48
49#define BADCH (int)'?'
50#define BADARG (int)':'
51#define EMSG ""
52
53/*
54 * getopt --
55 * Parse argc/argv argument vector.
56 */
57int
58getopt(nargc, nargv, ostr)
59 int nargc;
60 char * const *nargv;
61 const char *ostr;
62{
63 extern char *__progname;
64 static char *place = EMSG; /* option letter processing */
65 char *oli; /* option letter list index */
66
67 if (optreset || !*place) { /* update scanning pointer */
68 optreset = 0;
69 if (optind >= nargc || *(place = nargv[optind]) != '-') {
70 place = EMSG;
71 return (-1);
72 }
73 if (place[1] && *++place == '-') { /* found "--" */
74 ++optind;
75 place = EMSG;
76 return (-1);
77 }
78 } /* option letter okay? */
79 if ((optopt = (int)*place++) == (int)':' ||
80 !(oli = strchr(ostr, optopt))) {
81 /*
82 * if the user didn't specify '-' as an option,
83 * assume it means -1.
84 */
85 if (optopt == (int)'-')
86 return (-1);
87 if (!*place)
88 ++optind;
89 if (opterr && *ostr != ':')
90 (void)fprintf(stderr,
91 "%s: illegal option -- %c\n", __progname, optopt);
92 return (BADCH);
93 }
94 if (*++oli != ':') { /* don't need argument */
95 optarg = NULL;
96 if (!*place)
97 ++optind;
98 }
99 else { /* need an argument */
100 if (*place) /* no white space */
101 optarg = place;
102 else if (nargc <= ++optind) { /* no arg */
103 place = EMSG;
104 if (*ostr == ':')
105 return (BADARG);
106 if (opterr)
107 (void)fprintf(stderr,
108 "%s: option requires an argument -- %c\n",
109 __progname, optopt);
110 return (BADCH);
111 }
112 else /* white space */
113 optarg = nargv[optind];
114 place = EMSG;
115 ++optind;
116 }
117 return (optopt); /* dump back option letter */
118}
diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3
new file mode 100644
index 0000000000..978583ef96
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.3
@@ -0,0 +1,377 @@
1.\" $OpenBSD: getopt_long.3,v 1.10 2004/01/06 23:44:28 fgsch Exp $
2.\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $
3.\"
4.\" Copyright (c) 1988, 1991, 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. Neither the name of the University nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95
32.\"
33.Dd April 1, 2000
34.Dt GETOPT_LONG 3
35.Os
36.Sh NAME
37.Nm getopt_long ,
38.Nm getopt_long_only
39.Nd get long options from command line argument list
40.Sh SYNOPSIS
41.Fd #include <getopt.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_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
49.Ft int
50.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
51.Sh DESCRIPTION
52The
53.Fn getopt_long
54function is similar to
55.Xr getopt 3
56but it accepts options in two forms: words and characters.
57The
58.Fn getopt_long
59function provides a superset of the functionality of
60.Xr getopt 3 .
61.Fn getopt_long
62can be used in two ways.
63In the first way, every long option understood by the program has a
64corresponding short option, and the option structure is only used to
65translate from long options to short options.
66When used in this fashion,
67.Fn getopt_long
68behaves identically to
69.Xr getopt 3 .
70This is a good way to add long option processing to an existing program
71with the minimum of rewriting.
72.Pp
73In the second mechanism, a long option sets a flag in the
74.Fa option
75structure passed, or will store a pointer to the command line argument
76in the
77.Fa option
78structure passed to it for options that take arguments.
79Additionally, the long option's argument may be specified as a single
80argument with an equal sign, e.g.
81.Bd -literal
82myprogram --myoption=somevalue
83.Ed
84.Pp
85When a long option is processed the call to
86.Fn getopt_long
87will return 0.
88For this reason, long option processing without
89shortcuts is not backwards compatible with
90.Xr getopt 3 .
91.Pp
92It is possible to combine these methods, providing for long options
93processing with short option equivalents for some options.
94Less frequently used options would be processed as long options only.
95.Pp
96The
97.Fn getopt_long
98call requires a structure to be initialized describing the long
99options.
100The structure is:
101.Bd -literal
102struct option {
103 char *name;
104 int has_arg;
105 int *flag;
106 int val;
107};
108.Ed
109.Pp
110The
111.Fa name
112field should contain the option name without the leading double dash.
113.Pp
114The
115.Fa has_arg
116field should be one of:
117.Bl -tag -width "optional_argument"
118.It Li no_argument
119no argument to the option is expect.
120.It Li required_argument
121an argument to the option is required.
122.It Li optional_argument
123an argument to the option may be presented.
124.El
125.Pp
126If
127.Fa flag
128is not
129.Dv NULL ,
130then the integer pointed to by it will be set to the value in the
131.Fa val
132field.
133If the
134.Fa flag
135field is
136.Dv NULL ,
137then the
138.Fa val
139field will be returned.
140Setting
141.Fa flag
142to
143.Dv NULL
144and setting
145.Fa val
146to the corresponding short option will make this function act just
147like
148.Xr getopt 3 .
149.Pp
150If the
151.Fa longindex
152field is not
153.Dv NULL ,
154then the integer pointed to by it will be set to the index of the long
155option relative to
156.Fa longopts .
157.Pp
158The last element of the
159.Fa longopts
160array has to be filled with zeroes.
161.Pp
162The
163.Fn getopt_long_only
164function behaves identically to
165.Fn getopt_long
166with the exception that long options may start with
167.Sq -
168in addition to
169.Sq -- .
170If an option starting with
171.Sq -
172does not match a long option but does match a single-character option,
173the single-character option is returned.
174.Sh RETURN VALUES
175If the
176.Fa flag
177field in
178.Li struct option
179is
180.Dv NULL ,
181.Fn getopt_long
182and
183.Fn getopt_long_only
184return the value specified in the
185.Fa val
186field, which is usually just the corresponding short option.
187If
188.Fa flag
189is not
190.Dv NULL ,
191these functions return 0 and store
192.Fa val
193in the location pointed to by
194.Fa flag .
195These functions return
196.Sq \:
197if there was a missing option argument,
198.Sq \&?
199if the user specified an unknown or ambiguous option, and
200\-1 when the argument list has been exhausted.
201.Sh EXAMPLES
202.Bd -literal -compact
203int bflag, ch, fd;
204int daggerset;
205
206/* options descriptor */
207static struct option longopts[] = {
208 { "buffy", no_argument, NULL, 'b' },
209 { "fluoride", required_argument, NULL, 'f' },
210 { "daggerset", no_argument, &daggerset, 1 },
211 { NULL, 0, NULL, 0 }
212};
213
214bflag = 0;
215while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
216 switch (ch) {
217 case 'b':
218 bflag = 1;
219 break;
220 case 'f':
221 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
222 err(1, "unable to open %s", optarg);
223 break;
224 case 0:
225 if (daggerset) {
226 fprintf(stderr,"Buffy will use her dagger to "
227 "apply fluoride to dracula's teeth\en");
228 }
229 break;
230 default:
231 usage();
232}
233argc -= optind;
234argv += optind;
235.Ed
236.Sh IMPLEMENTATION DIFFERENCES
237This section describes differences to the GNU implementation
238found in glibc-2.1.3:
239.Bl -tag -width "xxx"
240.It Li o
241handling of - as first char of option string in presence of
242environment variable POSIXLY_CORRECT:
243.Bl -tag -width "OpenBSD"
244.It Li GNU
245ignores POSIXLY_CORRECT and returns non-options as
246arguments to option '\e1'.
247.It Li OpenBSD
248honors POSIXLY_CORRECT and stops at the first non-option.
249.El
250.It Li o
251handling of - within the option string (not the first character):
252.Bl -tag -width "OpenBSD"
253.It Li GNU
254treats a
255.Ql -
256on the command line as a non-argument.
257.It Li OpenBSD
258a
259.Ql -
260within the option string matches a
261.Ql -
262(single dash) on the command line.
263This functionality is provided for backward compatibility with
264programs, such as
265.Xr su 1 ,
266that use
267.Ql -
268as an option flag.
269This practice is wrong, and should not be used in any current development.
270.El
271.It Li o
272handling of :: in options string in presence of POSIXLY_CORRECT:
273.Bl -tag -width "OpenBSD"
274.It Li Both
275GNU and OpenBSD ignore POSIXLY_CORRECT here and take :: to
276mean the preceding option takes an optional argument.
277.El
278.It Li o
279return value in case of missing argument if first character
280(after + or -) in option string is not ':':
281.Bl -tag -width "OpenBSD"
282.It Li GNU
283returns '?'
284.It OpenBSD
285returns ':' (since OpenBSD's getopt does).
286.El
287.It Li o
288handling of --a in getopt:
289.Bl -tag -width "OpenBSD"
290.It Li GNU
291parses this as option '-', option 'a'.
292.It Li OpenBSD
293parses this as '--', and returns \-1 (ignoring the a).
294(Because the original getopt does.)
295.El
296.It Li o
297setting of optopt for long options with flag !=
298.Dv NULL :
299.Bl -tag -width "OpenBSD"
300.It Li GNU
301sets optopt to val.
302.It Li OpenBSD
303sets optopt to 0 (since val would never be returned).
304.El
305.It Li o
306handling of -W with W; in option string in getopt (not getopt_long):
307.Bl -tag -width "OpenBSD"
308.It Li GNU
309causes a segfault.
310.It Li OpenBSD
311no special handling is done;
312.Dq W;
313is interpreted as two separate options, neither of which take an argument.
314.El
315.It Li o
316setting of optarg for long options without an argument that are
317invoked via -W (W; in option string):
318.Bl -tag -width "OpenBSD"
319.It Li GNU
320sets optarg to the option name (the argument of -W).
321.It Li OpenBSD
322sets optarg to
323.Dv NULL
324(the argument of the long option).
325.El
326.It Li o
327handling of -W with an argument that is not (a prefix to) a known
328long option (W; in option string):
329.Bl -tag -width "OpenBSD"
330.It Li GNU
331returns -W with optarg set to the unknown option.
332.It Li OpenBSD
333treats this as an error (unknown option) and returns '?' with
334optopt set to 0 and optarg set to
335.Dv NULL
336(as GNU's man page documents).
337.El
338.It Li o
339The error messages are different.
340.It Li o
341OpenBSD does not permute the argument vector at the same points in
342the calling sequence as GNU does.
343The aspects normally used by the caller
344(ordering after \-1 is returned, value of optind relative
345to current positions) are the same, though.
346(We do fewer variable swaps.)
347.El
348.Sh ENVIRONMENT
349.Bl -tag -width POSIXLY_CORRECT
350.It Ev POSIXLY_CORRECT
351If set, option processing stops when the first non-option is found and
352a leading
353.Sq -
354or
355.Sq +
356in the
357.Ar optstring
358is ignored.
359.El
360.Sh SEE ALSO
361.Xr getopt 3
362.Sh HISTORY
363The
364.Fn getopt_long
365and
366.Fn getopt_long_only
367functions first appeared in GNU libiberty.
368This implementation first appeared in
369.Ox 3.3 .
370.Sh BUGS
371The
372.Ar argv
373argument is not really
374.Dv const
375as its elements may be permuted (unless
376.Ev POSIXLY_CORRECT
377is set).
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c
new file mode 100644
index 0000000000..6079ce3503
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -0,0 +1,544 @@
1/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */
2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
3
4/*
5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Sponsored in part by the Defense Advanced Research Projects
20 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22 */
23/*-
24 * Copyright (c) 2000 The NetBSD Foundation, Inc.
25 * All rights reserved.
26 *
27 * This code is derived from software contributed to The NetBSD Foundation
28 * by Dieter Baron and Thomas Klausner.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the NetBSD
41 * Foundation, Inc. and its contributors.
42 * 4. Neither the name of The NetBSD Foundation nor the names of its
43 * contributors may be used to endorse or promote products derived
44 * from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 * POSSIBILITY OF SUCH DAMAGE.
57 */
58
59#if defined(LIBC_SCCS) && !defined(lint)
60static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $";
61#endif /* LIBC_SCCS and not lint */
62
63#include <err.h>
64#include <errno.h>
65#include <getopt.h>
66#include <stdlib.h>
67#include <string.h>
68
69#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
70
71#ifdef REPLACE_GETOPT
72int opterr = 1; /* if error message should be printed */
73int optind = 1; /* index into parent argv vector */
74int optopt = '?'; /* character checked for validity */
75int optreset; /* reset getopt */
76char *optarg; /* argument associated with option */
77#endif
78
79#define PRINT_ERROR ((opterr) && (*options != ':'))
80
81#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
82#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
83#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
84
85/* return values */
86#define BADCH (int)'?'
87#define BADARG ((*options == ':') ? (int)':' : (int)'?')
88#define INORDER (int)1
89
90#define EMSG ""
91
92static int getopt_internal(int, char * const *, const char *,
93 const struct option *, int *, int);
94static int parse_long_options(char * const *, const char *,
95 const struct option *, int *, int);
96static int gcd(int, int);
97static void permute_args(int, int, int, char * const *);
98
99static char *place = EMSG; /* option letter processing */
100
101/* XXX: set optreset to 1 rather than these two */
102static int nonopt_start = -1; /* first non option argument (for permute) */
103static int nonopt_end = -1; /* first option after non options (for permute) */
104
105/* Error messages */
106static const char recargchar[] = "option requires an argument -- %c";
107static const char recargstring[] = "option requires an argument -- %s";
108static const char ambig[] = "ambiguous option -- %.*s";
109static const char noarg[] = "option doesn't take an argument -- %.*s";
110static const char illoptchar[] = "unknown option -- %c";
111static const char illoptstring[] = "unknown option -- %s";
112
113/*
114 * Compute the greatest common divisor of a and b.
115 */
116static int
117gcd(int a, int b)
118{
119 int c;
120
121 c = a % b;
122 while (c != 0) {
123 a = b;
124 b = c;
125 c = a % b;
126 }
127
128 return (b);
129}
130
131/*
132 * Exchange the block from nonopt_start to nonopt_end with the block
133 * from nonopt_end to opt_end (keeping the same order of arguments
134 * in each block).
135 */
136static void
137permute_args(int panonopt_start, int panonopt_end, int opt_end,
138 char * const *nargv)
139{
140 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
141 char *swap;
142
143 /*
144 * compute lengths of blocks and number and size of cycles
145 */
146 nnonopts = panonopt_end - panonopt_start;
147 nopts = opt_end - panonopt_end;
148 ncycle = gcd(nnonopts, nopts);
149 cyclelen = (opt_end - panonopt_start) / ncycle;
150
151 for (i = 0; i < ncycle; i++) {
152 cstart = panonopt_end+i;
153 pos = cstart;
154 for (j = 0; j < cyclelen; j++) {
155 if (pos >= panonopt_end)
156 pos -= nnonopts;
157 else
158 pos += nopts;
159 swap = nargv[pos];
160 /* LINTED const cast */
161 ((char **) nargv)[pos] = nargv[cstart];
162 /* LINTED const cast */
163 ((char **)nargv)[cstart] = swap;
164 }
165 }
166}
167
168/*
169 * parse_long_options --
170 * Parse long options in argc/argv argument vector.
171 * Returns -1 if short_too is set and the option does not match long_options.
172 */
173static int
174parse_long_options(char * const *nargv, const char *options,
175 const struct option *long_options, int *idx, int short_too)
176{
177 char *current_argv, *has_equal;
178 size_t current_argv_len;
179 int i, match;
180
181 current_argv = place;
182 match = -1;
183
184 optind++;
185
186 if ((has_equal = strchr(current_argv, '=')) != NULL) {
187 /* argument found (--option=arg) */
188 current_argv_len = has_equal - current_argv;
189 has_equal++;
190 } else
191 current_argv_len = strlen(current_argv);
192
193 for (i = 0; long_options[i].name; i++) {
194 /* find matching long option */
195 if (strncmp(current_argv, long_options[i].name,
196 current_argv_len))
197 continue;
198
199 if (strlen(long_options[i].name) == current_argv_len) {
200 /* exact match */
201 match = i;
202 break;
203 }
204 /*
205 * If this is a known short option, don't allow
206 * a partial match of a single character.
207 */
208 if (short_too && current_argv_len == 1)
209 continue;
210
211 if (match == -1) /* partial match */
212 match = i;
213 else {
214 /* ambiguous abbreviation */
215 if (PRINT_ERROR)
216 warnx(ambig, (int)current_argv_len,
217 current_argv);
218 optopt = 0;
219 return (BADCH);
220 }
221 }
222 if (match != -1) { /* option found */
223 if (long_options[match].has_arg == no_argument
224 && has_equal) {
225 if (PRINT_ERROR)
226 warnx(noarg, (int)current_argv_len,
227 current_argv);
228 /*
229 * XXX: GNU sets optopt to val regardless of flag
230 */
231 if (long_options[match].flag == NULL)
232 optopt = long_options[match].val;
233 else
234 optopt = 0;
235 return (BADARG);
236 }
237 if (long_options[match].has_arg == required_argument ||
238 long_options[match].has_arg == optional_argument) {
239 if (has_equal)
240 optarg = has_equal;
241 else if (long_options[match].has_arg ==
242 required_argument) {
243 /*
244 * optional argument doesn't use next nargv
245 */
246 optarg = nargv[optind++];
247 }
248 }
249 if ((long_options[match].has_arg == required_argument)
250 && (optarg == NULL)) {
251 /*
252 * Missing argument; leading ':' indicates no error
253 * should be generated.
254 */
255 if (PRINT_ERROR)
256 warnx(recargstring,
257 current_argv);
258 /*
259 * XXX: GNU sets optopt to val regardless of flag
260 */
261 if (long_options[match].flag == NULL)
262 optopt = long_options[match].val;
263 else
264 optopt = 0;
265 --optind;
266 return (BADARG);
267 }
268 } else { /* unknown option */
269 if (short_too) {
270 --optind;
271 return (-1);
272 }
273 if (PRINT_ERROR)
274 warnx(illoptstring, current_argv);
275 optopt = 0;
276 return (BADCH);
277 }
278 if (idx)
279 *idx = match;
280 if (long_options[match].flag) {
281 *long_options[match].flag = long_options[match].val;
282 return (0);
283 } else
284 return (long_options[match].val);
285}
286
287/*
288 * getopt_internal --
289 * Parse argc/argv argument vector. Called by user level routines.
290 */
291static int
292getopt_internal(int nargc, char * const *nargv, const char *options,
293 const struct option *long_options, int *idx, int flags)
294{
295 char *oli; /* option letter list index */
296 int optchar, short_too;
297 static int posixly_correct = -1;
298
299 if (options == NULL)
300 return (-1);
301
302 /*
303 * Disable GNU extensions if POSIXLY_CORRECT is set or options
304 * string begins with a '+'.
305 */
306 if (posixly_correct == -1)
307 posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
308 if (posixly_correct || *options == '+')
309 flags &= ~FLAG_PERMUTE;
310 else if (*options == '-')
311 flags |= FLAG_ALLARGS;
312 if (*options == '+' || *options == '-')
313 options++;
314
315 /*
316 * XXX Some GNU programs (like cvs) set optind to 0 instead of
317 * XXX using optreset. Work around this braindamage.
318 */
319 if (optind == 0)
320 optind = optreset = 1;
321
322 optarg = NULL;
323 if (optreset)
324 nonopt_start = nonopt_end = -1;
325start:
326 if (optreset || !*place) { /* update scanning pointer */
327 optreset = 0;
328 if (optind >= nargc) { /* end of argument vector */
329 place = EMSG;
330 if (nonopt_end != -1) {
331 /* do permutation, if we have to */
332 permute_args(nonopt_start, nonopt_end,
333 optind, nargv);
334 optind -= nonopt_end - nonopt_start;
335 }
336 else if (nonopt_start != -1) {
337 /*
338 * If we skipped non-options, set optind
339 * to the first of them.
340 */
341 optind = nonopt_start;
342 }
343 nonopt_start = nonopt_end = -1;
344 return (-1);
345 }
346 if (*(place = nargv[optind]) != '-' ||
347 (place[1] == '\0' && strchr(options, '-') == NULL)) {
348 place = EMSG; /* found non-option */
349 if (flags & FLAG_ALLARGS) {
350 /*
351 * GNU extension:
352 * return non-option as argument to option 1
353 */
354 optarg = nargv[optind++];
355 return (INORDER);
356 }
357 if (!(flags & FLAG_PERMUTE)) {
358 /*
359 * If no permutation wanted, stop parsing
360 * at first non-option.
361 */
362 return (-1);
363 }
364 /* do permutation */
365 if (nonopt_start == -1)
366 nonopt_start = optind;
367 else if (nonopt_end != -1) {
368 permute_args(nonopt_start, nonopt_end,
369 optind, nargv);
370 nonopt_start = optind -
371 (nonopt_end - nonopt_start);
372 nonopt_end = -1;
373 }
374 optind++;
375 /* process next argument */
376 goto start;
377 }
378 if (nonopt_start != -1 && nonopt_end == -1)
379 nonopt_end = optind;
380
381 /*
382 * If we have "-" do nothing, if "--" we are done.
383 */
384 if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
385 optind++;
386 place = EMSG;
387 /*
388 * We found an option (--), so if we skipped
389 * non-options, we have to permute.
390 */
391 if (nonopt_end != -1) {
392 permute_args(nonopt_start, nonopt_end,
393 optind, nargv);
394 optind -= nonopt_end - nonopt_start;
395 }
396 nonopt_start = nonopt_end = -1;
397 return (-1);
398 }
399 }
400
401 /*
402 * Check long options if:
403 * 1) we were passed some
404 * 2) the arg is not just "-"
405 * 3) either the arg starts with -- we are getopt_long_only()
406 */
407 if (long_options != NULL && place != nargv[optind] &&
408 (*place == '-' || (flags & FLAG_LONGONLY))) {
409 short_too = 0;
410 if (*place == '-')
411 place++; /* --foo long option */
412 else if (*place != ':' && strchr(options, *place) != NULL)
413 short_too = 1; /* could be short option too */
414
415 optchar = parse_long_options(nargv, options, long_options,
416 idx, short_too);
417 if (optchar != -1) {
418 place = EMSG;
419 return (optchar);
420 }
421 }
422
423 if ((optchar = (int)*place++) == (int)':' ||
424 optchar == (int)'-' && *place != '\0' ||
425 (oli = strchr(options, optchar)) == NULL) {
426 /*
427 * If the user specified "-" and '-' isn't listed in
428 * options, return -1 (non-option) as per POSIX.
429 * Otherwise, it is an unknown option character (or ':').
430 */
431 if (optchar == (int)'-' && *place == '\0')
432 return (-1);
433 if (!*place)
434 ++optind;
435 if (PRINT_ERROR)
436 warnx(illoptchar, optchar);
437 optopt = optchar;
438 return (BADCH);
439 }
440 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
441 /* -W long-option */
442 if (*place) /* no space */
443 /* NOTHING */;
444 else if (++optind >= nargc) { /* no arg */
445 place = EMSG;
446 if (PRINT_ERROR)
447 warnx(recargchar, optchar);
448 optopt = optchar;
449 return (BADARG);
450 } else /* white space */
451 place = nargv[optind];
452 optchar = parse_long_options(nargv, options, long_options,
453 idx, 0);
454 place = EMSG;
455 return (optchar);
456 }
457 if (*++oli != ':') { /* doesn't take argument */
458 if (!*place)
459 ++optind;
460 } else { /* takes (optional) argument */
461 optarg = NULL;
462 if (*place) /* no white space */
463 optarg = place;
464 /* XXX: disable test for :: if PC? (GNU doesn't) */
465 else if (oli[1] != ':') { /* arg not optional */
466 if (++optind >= nargc) { /* no arg */
467 place = EMSG;
468 if (PRINT_ERROR)
469 warnx(recargchar, optchar);
470 optopt = optchar;
471 return (BADARG);
472 } else
473 optarg = nargv[optind];
474 } else if (!(flags & FLAG_PERMUTE)) {
475 /*
476 * If permutation is disabled, we can accept an
477 * optional arg separated by whitespace.
478 */
479 if (optind + 1 < nargc)
480 optarg = nargv[++optind];
481 }
482 place = EMSG;
483 ++optind;
484 }
485 /* dump back option letter */
486 return (optchar);
487}
488
489#ifdef REPLACE_GETOPT
490/*
491 * getopt --
492 * Parse argc/argv argument vector.
493 *
494 * [eventually this will replace the BSD getopt]
495 */
496int
497getopt(int nargc, char * const *nargv, const char *options)
498{
499
500 /*
501 * We dont' pass FLAG_PERMUTE to getopt_internal() since
502 * the BSD getopt(3) (unlike GNU) has never done this.
503 *
504 * Furthermore, since many privileged programs call getopt()
505 * before dropping privileges it makes sense to keep things
506 * as simple (and bug-free) as possible.
507 */
508 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
509}
510#endif /* REPLACE_GETOPT */
511
512/*
513 * getopt_long --
514 * Parse argc/argv argument vector.
515 */
516int
517getopt_long(nargc, nargv, options, long_options, idx)
518 int nargc;
519 char * const *nargv;
520 const char *options;
521 const struct option *long_options;
522 int *idx;
523{
524
525 return (getopt_internal(nargc, nargv, options, long_options, idx,
526 FLAG_PERMUTE));
527}
528
529/*
530 * getopt_long_only --
531 * Parse argc/argv argument vector.
532 */
533int
534getopt_long_only(nargc, nargv, options, long_options, idx)
535 int nargc;
536 char * const *nargv;
537 const char *options;
538 const struct option *long_options;
539 int *idx;
540{
541
542 return (getopt_internal(nargc, nargv, options, long_options, idx,
543 FLAG_PERMUTE|FLAG_LONGONLY));
544}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..8513cfb66a
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,143 @@
1.\" $OpenBSD: getsubopt.3,v 1.8 2004/01/23 23:08:46 jmc 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. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd June 9, 1993
33.Dt GETSUBOPT 3
34.Os
35.Sh NAME
36.Nm getsubopt
37.Nd get sub options from an argument
38.Sh SYNOPSIS
39.Fd #include <stdlib.h>
40.Vt extern char *suboptarg;
41.Ft int
42.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
43.Sh DESCRIPTION
44The
45.Fn getsubopt
46function parses a string containing tokens delimited by one or more
47tab, space or comma
48.Pq Ql \&,
49characters.
50It is intended for use in parsing groups of option arguments provided
51as part of a utility command line.
52.Pp
53The argument
54.Fa optionp
55is a pointer to a pointer to the string.
56The argument
57.Fa tokens
58is a pointer to a null-terminated array of pointers to strings.
59.Pp
60The
61.Fn getsubopt
62function returns the zero-based offset of the pointer in the
63.Fa tokens
64array referencing a string which matches the first token
65in the string, or \-1 if the string contains no tokens or
66.Fa tokens
67does not contain a matching string.
68.Pp
69If the token is of the form
70.Ar name Ns = Ns Ar value ,
71the location referenced by
72.Fa valuep
73will be set to point to the start of the
74.Dq value
75portion of the token.
76.Pp
77On return from
78.Fn getsubopt ,
79.Fa optionp
80will be set to point to the start of the next token in the string,
81or the null at the end of the string if no more tokens are present.
82The external variable
83.Fa suboptarg
84will be set to point to the start of the current token, or
85.Dv NULL
86if no tokens were present.
87The argument
88.Fa valuep
89will be set to point to the value portion of the token, or
90.Dv NULL
91if no value portion was present.
92.Sh EXAMPLES
93.Bd -literal -compact
94char *tokens[] = {
95 #define ONE 0
96 "one",
97 #define TWO 1
98 "two",
99 NULL
100};
101
102\&...
103
104extern char *optarg, *suboptarg;
105char *options, *value;
106
107while ((ch = getopt(argc, argv, "ab:")) != \-1) {
108 switch(ch) {
109 case 'a':
110 /* process ``a'' option */
111 break;
112 case 'b':
113 options = optarg;
114 while (*options) {
115 switch(getsubopt(&options, tokens, &value)) {
116 case ONE:
117 /* process ``one'' sub option */
118 break;
119 case TWO:
120 /* process ``two'' sub option */
121 if (!value)
122 error("no value for two");
123 i = atoi(value);
124 break;
125 case \-1:
126 if (suboptarg)
127 error("illegal sub option %s",
128 suboptarg);
129 else
130 error("missing sub option");
131 break;
132 }
133 break;
134 }
135.Ed
136.Sh SEE ALSO
137.Xr getopt 3 ,
138.Xr strsep 3
139.Sh HISTORY
140The
141.Fn getsubopt
142function first appeared in
143.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..308458ea75
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: getsubopt.c,v 1.2 2003/06/02 20:18:37 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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#ifndef lint
33#if 0
34static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
35#else
36static char rcsid[] = "$OpenBSD: getsubopt.c,v 1.2 2003/06/02 20:18:37 millert Exp $";
37#endif
38#endif /* not lint */
39
40#include <unistd.h>
41#include <stdlib.h>
42#include <string.h>
43
44/*
45 * The SVID interface to getsubopt provides no way of figuring out which
46 * part of the suboptions list wasn't matched. This makes error messages
47 * tricky... The extern variable suboptarg is a pointer to the token
48 * which didn't match.
49 */
50char *suboptarg;
51
52int
53getsubopt(optionp, tokens, valuep)
54 register char **optionp, **valuep;
55 register char * const *tokens;
56{
57 register int cnt;
58 register char *p;
59
60 suboptarg = *valuep = NULL;
61
62 if (!optionp || !*optionp)
63 return(-1);
64
65 /* skip leading white-space, commas */
66 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
67
68 if (!*p) {
69 *optionp = p;
70 return(-1);
71 }
72
73 /* save the start of the token, and skip the rest of the token. */
74 for (suboptarg = p;
75 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
76
77 if (*p) {
78 /*
79 * If there's an equals sign, set the value pointer, and
80 * skip over the value part of the token. Terminate the
81 * token.
82 */
83 if (*p == '=') {
84 *p = '\0';
85 for (*valuep = ++p;
86 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
87 if (*p)
88 *p++ = '\0';
89 } else
90 *p++ = '\0';
91 /* Skip any whitespace or commas after this token. */
92 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
93 }
94
95 /* set optionp for next round. */
96 *optionp = p;
97
98 for (cnt = 0; *tokens; ++tokens, ++cnt)
99 if (!strcmp(suboptarg, *tokens))
100 return(cnt);
101 return(-1);
102}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
index bd998fa357..f4aeeef7a3 100644
--- a/src/lib/libc/stdlib/heapsort.c
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";*/ 34static char *rcsid = "$OpenBSD: heapsort.c,v 1.6 2003/09/08 16:24:05 deraadt Exp $";
39static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <sys/types.h> 37#include <sys/types.h>
@@ -73,7 +68,7 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp
73 * Build the list into a heap, where a heap is defined such that for 68 * Build the list into a heap, where a heap is defined such that for
74 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. 69 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
75 * 70 *
76 * There two cases. If j == nmemb, select largest of Ki and Kj. If 71 * There are two cases. If j == nmemb, select largest of Ki and Kj. If
77 * j < nmemb, select largest of Ki, Kj and Kj+1. 72 * j < nmemb, select largest of Ki, Kj and Kj+1.
78 */ 73 */
79#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ 74#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
@@ -95,12 +90,12 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp
95 * Select the top of the heap and 'heapify'. Since by far the most expensive 90 * Select the top of the heap and 'heapify'. Since by far the most expensive
96 * action is the call to the compar function, a considerable optimization 91 * action is the call to the compar function, a considerable optimization
97 * in the average case can be achieved due to the fact that k, the displaced 92 * in the average case can be achieved due to the fact that k, the displaced
98 * elememt, is ususally quite small, so it would be preferable to first 93 * element, is usually quite small, so it would be preferable to first
99 * heapify, always maintaining the invariant that the larger child is copied 94 * heapify, always maintaining the invariant that the larger child is copied
100 * over its parent's record. 95 * over its parent's record.
101 * 96 *
102 * Then, starting from the *bottom* of the heap, finding k's correct place, 97 * Then, starting from the *bottom* of the heap, finding k's correct place,
103 * again maintianing the invariant. As a result of the invariant no element 98 * again maintaining the invariant. As a result of the invariant no element
104 * is 'lost' when k is assigned its correct place in the heap. 99 * is 'lost' when k is assigned its correct place in the heap.
105 * 100 *
106 * The time savings from this optimization are on the order of 15-20% for the 101 * The time savings from this optimization are on the order of 15-20% for the
@@ -142,7 +137,7 @@ int
142heapsort(vbase, nmemb, size, compar) 137heapsort(vbase, nmemb, size, compar)
143 void *vbase; 138 void *vbase;
144 size_t nmemb, size; 139 size_t nmemb, size;
145 int (*compar) __P((const void *, const void *)); 140 int (*compar)(const void *, const void *);
146{ 141{
147 register int cnt, i, j, l; 142 register int cnt, i, j, l;
148 register char tmp, *tmp1, *tmp2; 143 register char tmp, *tmp1, *tmp2;
diff --git a/src/lib/libc/stdlib/insque.3 b/src/lib/libc/stdlib/insque.3
new file mode 100644
index 0000000000..cd8110ed90
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.3
@@ -0,0 +1,100 @@
1.\" $OpenBSD: insque.3,v 1.3 2004/01/25 14:48:32 jmc Exp $
2.\" Copyright (c) 1993 John Brezak
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"
29.Dd August 12, 1993
30.Dt INSQUE 3
31.Os
32.Sh NAME
33.Nm insque ,
34.Nm remque
35.Nd insert/remove element from a queue
36.Sh SYNOPSIS
37.Fd #include <search.h>
38.Ft void
39.Fn insque "void *elem" "void *pred"
40.Ft void
41.Fn remque "void *elem"
42.Sh DESCRIPTION
43.Bf -symbolic
44These interfaces have been superceded by the
45.Xr queue 3
46macros and are provided for compatibility with legacy code.
47.Ef
48.Pp
49.Fn insque
50and
51.Fn remque
52manipulate queues built from doubly linked lists.
53The queue can be either circular or linear.
54Each element in the queue must be of the following form:
55.Bd -literal
56struct qelem {
57 struct qelem *q_forw;
58 struct qelem *q_back;
59 char q_data[];
60};
61.Ed
62.Pp
63The first two elements in the struct must be pointers of the
64same type that point to the previous and next elements in
65the queue respectively.
66Any subsequent data in the struct is application-dependent.
67.Pp
68The
69.Fn insque
70function inserts
71.Fa elem
72into a queue immediately after
73.Fa pred .
74.Pp
75The
76.Fn remque
77function removes
78.Fa elem
79from the queue.
80.Sh DIAGNOSTICS
81These functions are not atomic unless that machine architecture allows it.
82.Sh SEE ALSO
83.Xr queue 3
84.Sh STANDARDS
85The
86.Fn lsearch
87and
88.Fn lfind
89functions conform to the
90.St -p1003.1-2001
91and
92.St -xpg4.3 .
93specifications.
94.Sh HISTORY
95The
96.Fn insque
97and
98.Fn remque
99functions are derived from the insque and remque instructions on a
100.Tn VAX .
diff --git a/src/lib/libc/stdlib/insque.c b/src/lib/libc/stdlib/insque.c
new file mode 100644
index 0000000000..549246c71f
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.c
@@ -0,0 +1,52 @@
1/* $OpenBSD: insque.c,v 1.1 2003/05/08 23:26:30 millert Exp $ */
2
3/*
4 * Copyright (c) 1993 John Brezak
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. The name of the author may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: insque.c,v 1.1 2003/05/08 23:26:30 millert Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <search.h>
36
37struct qelem {
38 struct qelem *q_forw;
39 struct qelem *q_back;
40};
41
42void
43insque(void *entry, void *pred)
44{
45 struct qelem *e = (struct qelem *) entry;
46 struct qelem *p = (struct qelem *) pred;
47
48 e->q_forw = p->q_forw;
49 e->q_back = p;
50 p->q_forw->q_back = e;
51 p->q_forw = e;
52}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
index 205781e0ee..99cddb71e5 100644
--- a/src/lib/libc/stdlib/jrand48.c
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: jrand48.c,v 1.2 1996/08/19 08:33:33 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
index 3069b31bf6..4e99391254 100644
--- a/src/lib/libc/stdlib/l64a.c
+++ b/src/lib/libc/stdlib/l64a.c
@@ -4,13 +4,14 @@
4 */ 4 */
5 5
6#if defined(LIBC_SCCS) && !defined(lint) 6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$NetBSD: l64a.c,v 1.4 1995/05/11 23:04:52 jtc Exp $"; 7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif 8#endif /* LIBC_SCCS and not lint */
9 9
10#include <errno.h>
10#include <stdlib.h> 11#include <stdlib.h>
11 12
12char * 13char *
13l64a (value) 14l64a(value)
14 long value; 15 long value;
15{ 16{
16 static char buf[8]; 17 static char buf[8];
@@ -18,8 +19,10 @@ l64a (value)
18 int digit; 19 int digit;
19 int i; 20 int i;
20 21
21 if (!value) 22 if (value < 0) {
22 return NULL; 23 errno = EINVAL;
24 return(NULL);
25 }
23 26
24 for (i = 0; value != 0 && i < 6; i++) { 27 for (i = 0; value != 0 && i < 6; i++) {
25 digit = value & 0x3f; 28 digit = value & 0x3f;
@@ -39,5 +42,5 @@ l64a (value)
39 42
40 *s = '\0'; 43 *s = '\0';
41 44
42 return buf; 45 return(buf);
43} 46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
index 28e4d2053c..742f3eedba 100644
--- a/src/lib/libc/stdlib/labs.3
+++ b/src/lib/libc/stdlib/labs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,35 +29,40 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: labs.3,v 1.7 2003/07/21 20:20:04 millert Exp $
37.\" $Id: labs.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd May 14, 2003
40.Dt LABS 3 35.Dt LABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm labs 38.Nm labs, llabs
44.Nd return the absolute value of a long integer 39.Nd return the absolute value of a long integer
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft long 42.Ft long
48.Fn labs "long j" 43.Fn labs "long i"
44.Ft long long
45.Fn llabs "long long j"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn labs 48.Fn labs
52function 49function returns the absolute value of the long integer
53returns the absolute value of the long integer 50.Fa i .
54.Ar j . 51The
52.Fn llabs
53function returns the absolute value of the long long integer
54.Fa j .
55.Sh SEE ALSO 55.Sh SEE ALSO
56.Xr abs 3 , 56.Xr abs 3 ,
57.Xr floor 3 ,
58.Xr cabs 3 , 57.Xr cabs 3 ,
58.Xr floor 3 ,
59.Xr math 3 59.Xr math 3
60.Sh STANDARDS 60.Sh STANDARDS
61The 61The
62.Fn labs 62.Fn labs
63function 63and
64conforms to 64.Fn llabs
65.St -ansiC . 65functions conform to
66.St -ansiC-99 .
66.Sh BUGS 67.Sh BUGS
67The absolute value of the most negative integer remains negative. 68The 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
index ccf1415792..51ef490d97 100644
--- a/src/lib/libc/stdlib/labs.c
+++ b/src/lib/libc/stdlib/labs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: labs.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
36static char *rcsid = "$Id: labs.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
index 965d46b17a..44bd74e48a 100644
--- a/src/lib/libc/stdlib/lcong48.c
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lcong48.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
index a7b5ccf878..63e1f2165c 100644
--- a/src/lib/libc/stdlib/ldiv.3
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: ldiv.3,v 1.7 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: ldiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt LDIV 3 35.Dt LDIV 3
@@ -49,24 +44,22 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn ldiv 46.Fn ldiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar ldiv_t 50.Li ldiv_t
57that contains two 51that contains two
58.Em long integer 52.Li long integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
65.Xr qdiv 3 , 59.Xr math 3 ,
66.Xr math 3 60.Xr qdiv 3
67.Sh STANDARDS 61.Sh STANDARDS
68The 62The
69.Fn ldiv 63.Fn ldiv
70function 64function conforms to
71conforms to
72.St -ansiC . 65.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
index f7074507e5..e005ff77de 100644
--- a/src/lib/libc/stdlib/ldiv.c
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: ldiv.c,v 1.3 2003/06/02 20:18:37 millert Exp $";
39static char *rcsid = "$Id: ldiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* ldiv_t */ 37#include <stdlib.h> /* ldiv_t */
diff --git a/src/lib/libc/stdlib/llabs.c b/src/lib/libc/stdlib/llabs.c
new file mode 100644
index 0000000000..9611b5aefd
--- /dev/null
+++ b/src/lib/libc/stdlib/llabs.c
@@ -0,0 +1,45 @@
1/* $OpenBSD: llabs.c,v 1.1 2003/07/21 20:20:04 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
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 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#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: llabs.c,v 1.1 2003/07/21 20:20:04 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <stdlib.h>
41
42long long llabs(long long j)
43{
44 return (j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
index 8e7f26237f..6b7524a51b 100644
--- a/src/lib/libc/stdlib/lrand48.c
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lrand48.c,v 1.2 1996/08/19 08:33:36 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3
new file mode 100644
index 0000000000..2adc51096d
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.3
@@ -0,0 +1,103 @@
1.\" Copyright (c) 1989, 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. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93
29.\"
30.Dd June 4, 1993
31.Dt LSEARCH 3
32.Os
33.Sh NAME
34.Nm lsearch ,
35.Nm lfind
36.Nd linear searching routines
37.Sh SYNOPSIS
38.Ft char *
39.Fn lsearch "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
40.Ft char *
41.Fn lfind "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
42.Sh DESCRIPTION
43The functions
44.Fn lsearch ,
45and
46.Fn lfind
47provide basic linear searching functionality.
48.Pp
49.Fa base
50is the pointer to the beginning of an array.
51The argument
52.Fa nelp
53is the current number of elements in the array, where each element
54is
55.Fa width
56bytes long.
57The
58.Fa compar
59function
60is a comparison routine which is used to compare two elements.
61It takes two arguments which point to the
62.Fa key
63object and to an array member, in that order, and must return an integer
64less than, equivalent to, or greater than zero if the
65.Fa key
66object is considered, respectively, to be less than, equal to, or greater
67than the array member.
68.Pp
69The
70.Fn lsearch
71and
72.Fn lfind
73functions
74return a pointer into the array referenced by
75.Fa base
76where
77.Fa key
78is located.
79If
80.Fa key
81does not exist,
82.Fn lfind
83will return a null pointer and
84.Fn lsearch
85will add it to the array.
86When an element is added to the array by
87.Fn lsearch
88the location referenced by the argument
89.Fa nelp
90is incremented by one.
91.Sh SEE ALSO
92.Xr bsearch 3 ,
93.Xr db 3
94.Sh STANDARDS
95The
96.Fn lsearch
97and
98.Fn lfind
99functions conform to the
100.St -p1003.1-2001
101and
102.St -xpg4.3 .
103specifications.
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c
new file mode 100644
index 0000000000..82483d1c82
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 1989, 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 * Roger L. Snyder.
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. 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
33#if defined(LIBC_SCCS) && !defined(lint)
34static char sccsid[] = "@(#)lsearch.c 8.1 (Berkeley) 6/4/93";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/types.h>
38#include <string.h>
39#include <search.h>
40
41typedef int (*cmp_fn_t)(const void *, const void *);
42static void *linear_base(const void *, const void *, size_t *, size_t,
43 cmp_fn_t, int);
44
45void *
46lsearch(const void *key, const void *base, size_t *nelp, size_t width,
47 cmp_fn_t compar)
48{
49
50 return(linear_base(key, base, nelp, width, compar, 1));
51}
52
53void *
54lfind(const void *key, const void *base, size_t *nelp, size_t width,
55 cmp_fn_t compar)
56{
57 return(linear_base(key, base, nelp, width, compar, 0));
58}
59
60static void *
61linear_base(const void *key, const void *base, size_t *nelp, size_t width,
62 cmp_fn_t compar, int add_flag)
63{
64 const char *element, *end;
65
66 end = (const char *)base + *nelp * width;
67 for (element = base; element < end; element += width)
68 if (!compar(key, element)) /* key found */
69 return((void *)element);
70
71 if (!add_flag) /* key not found */
72 return(NULL);
73
74 /*
75 * The UNIX System User's Manual, 1986 edition claims that
76 * a NULL pointer is returned by lsearch with errno set
77 * appropriately, if there is not enough room in the table
78 * to add a new item. This can't be done as none of these
79 * routines have any method of determining the size of the
80 * table. This comment isn't in the 1986-87 System V
81 * manual.
82 */
83 ++*nelp;
84 memcpy((void *)end, key, width);
85 return((void *)end);
86}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index 3bbf2bf65e..1154537385 100644
--- a/src/lib/libc/stdlib/malloc.3
+++ b/src/lib/libc/stdlib/malloc.3
@@ -1,5 +1,6 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California. 1.\"
2.\" All rights reserved. 2.\" Copyright (c) 1980, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
3.\" 4.\"
4.\" This code is derived from software contributed to Berkeley by 5.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 6.\" the American National Standards Committee X3, on Information
@@ -13,11 +14,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
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 18.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 19.\" without specific prior written permission.
23.\" 20.\"
@@ -33,19 +30,32 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
35.\" 32.\"
36.\" from: @(#)malloc.3 6.7 (Berkeley) 6/29/91 33.\" $OpenBSD: malloc.3,v 1.36 2004/02/09 13:07:42 espie Exp $
37.\" $Id: malloc.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 34.\"
39.Dd June 29, 1991 35.Dd August 27, 1996
40.Dt MALLOC 3 36.Dt MALLOC 3
41.Os BSD 4 37.Os
42.Sh NAME 38.Sh NAME
43.Nm malloc 39.Nm malloc ,
44.Nd general memory allocation function 40.Nm calloc ,
41.Nm realloc ,
42.Nm free ,
43.Nm cfree
44.Nd memory allocation and deallocation
45.Sh SYNOPSIS 45.Sh SYNOPSIS
46.Fd #include <stdlib.h> 46.Fd #include <stdlib.h>
47.Ft void * 47.Ft void *
48.Fn malloc "size_t size" 48.Fn malloc "size_t size"
49.Ft void *
50.Fn calloc "size_t nmemb" "size_t size"
51.Ft void *
52.Fn realloc "void *ptr" "size_t size"
53.Ft void
54.Fn free "void *ptr"
55.Ft void
56.Fn cfree "void *ptr"
57.Ft char *
58.Va malloc_options ;
49.Sh DESCRIPTION 59.Sh DESCRIPTION
50The 60The
51.Fn malloc 61.Fn malloc
@@ -59,33 +69,364 @@ space from the appropriate list.
59.Pp 69.Pp
60The allocated space is 70The allocated space is
61suitably aligned (after possible pointer 71suitably aligned (after possible pointer
62coercion) for storage of any type of object. If the space is of 72coercion) for storage of any type of object.
73If the space is of
63.Em pagesize 74.Em pagesize
64or larger, the memory returned will be page-aligned. 75or larger, the memory returned will be page-aligned.
76.Pp
77Allocation of a zero size object returns a pointer to a zero size object.
78This zero size object is access protected, so any access to it will
79generate an exception (SIGSEGV).
80Many zero-sized objects can be placed consecutively in shared
81protected pages.
82The minimum size of the protection on each object is suitably aligned and
83sized as previously stated, but the protection may extend further depending
84on where in a protected zone the object lands.
85.Pp
86The
87.Fn calloc
88function allocates space for an array of
89.Fa nmemb
90objects, each of whose size is
91.Fa size .
92The space is initialized to all bits zero.
93.Pp
94The
95.Fn free
96function causes the space pointed to by
97.Fa ptr
98to be deallocated, that is, at least made available for further allocation,
99but if possible, it will passed back to the kernel with
100.Xr sbrk 2 .
101If
102.Fa ptr
103is a null pointer, no action occurs.
104.Pp
105A
106.Fn cfree
107function is also provided for compatibility with old systems and other
108.Nm malloc
109libraries; it is simply an alias for
110.Fn free .
111.Pp
112The
113.Fn realloc
114function changes the size of the object pointed to by
115.Fa ptr
116to
117.Fa size
118bytes and returns a pointer to the (possibly moved) object.
119The contents of the object are unchanged up to the lesser
120of the new and old sizes.
121If the new size is larger, the value of the newly allocated portion
122of the object is indeterminate and uninitialized.
123If
124.Fa ptr
125is a null pointer, the
126.Fn realloc
127function behaves like the
128.Fn malloc
129function for the specified size.
130If the space cannot be allocated, the object
131pointed to by
132.Fa ptr
133is unchanged.
134If
135.Fa size
136is zero and
137.Fa ptr
138is not a null pointer, the object it points to is freed and a new zero size
139object is returned.
140.Pp
141When using
142.Fn realloc
143one must be careful to avoid the following idiom:
144.Bd -literal -offset indent
145size += 50;
146if ((p = realloc(p, size)) == NULL)
147 return (NULL);
148.Ed
149.Pp
150Do not adjust the variable describing how much memory has been allocated
151until one knows the allocation has been successful.
152This can cause aberrant program behavior if the incorrect size value is used.
153In most cases, the above sample will also result in a leak of memory.
154As stated earlier, a return value of
155.Dv NULL
156indicates that the old object still remains allocated.
157Better code looks like this:
158.Bd -literal -offset indent
159newsize = size + 50;
160if ((newp = realloc(p, newsize)) == NULL) {
161 free(p);
162 p = NULL;
163 size = 0;
164 return (NULL);
165}
166p = newp;
167size = newsize;
168.Ed
169.Pp
170Malloc will first look for a symbolic link called
171.Pa /etc/malloc.conf
172and next check the environment for a variable called
173.Ev MALLOC_OPTIONS
174and finally for the global variable
175.Va malloc_options
176and scan them for flags in that order.
177Flags are single letters, uppercase means on, lowercase means off.
178.Bl -tag -width indent
179.It Cm A
180.Dq Abort .
181.Fn malloc
182will coredump the process, rather than tolerate failure.
183This is a very handy debugging aid, since the core file will represent the
184time of failure, rather than when the null pointer was accessed.
185.Pp
186.It Cm D
187.Dq Dump .
188.Fn malloc
189will dump statistics in a file called
190.Pa malloc.out
191at exit.
192This option requires the library to have been compiled with -DMALLOC_STATS in
193order to have any effect.
194.Pp
195.It Cm F
196.Dq Freeguard .
197Enable use after free protection.
198Unused pages on the freelist are read and write protected to
199cause a segmentation fault upon access.
200.Pp
201.It Cm G
202.Dq Guard .
203Enable guard pages and chunk randomization.
204Each page size or larger allocation is followed by a guard page that will
205cause a segmentation fault upon any access.
206Smaller than page size chunks are returned in a random order.
207.Pp
208.It Cm H
209.Dq Hint .
210Pass a hint to the kernel about pages we don't use.
211If the machine is paging a lot this may help a bit.
212.Pp
213.It Cm J
214.Dq Junk .
215Fill some junk into the area allocated.
216Currently junk is bytes of 0xd0; this is pronounced
217.Dq Duh .
218\&:-)
219.Pp
220.It Cm N
221Do not output warning messages when encountering possible corruption
222or bad pointers.
223.Pp
224.It Cm R
225.Dq realloc .
226Always reallocate when
227.Fn realloc
228is called, even if the initial allocation was big enough.
229This can substantially aid in compacting memory.
230.\".Pp
231.\".It Cm U
232.\".Dq utrace .
233.\"Generate entries for
234.\".Xr ktrace 1
235.\"for all operations.
236.\"Consult the source for this one.
237.Pp
238.It Cm X
239.Dq xmalloc .
240Rather than return failure,
241.Xr abort 3
242the program with a diagnostic message on stderr.
243It is the intention that this option be set at compile time by
244including in the source:
245.Bd -literal -offset indent
246extern char *malloc_options;
247malloc_options = "X";
248.Ed
249.Pp
250.It Cm Z
251.Dq Zero .
252Fill some junk into the area allocated (see
253.Cm J ) ,
254except for the exact length the user asked for, which is zeroed.
255.Pp
256.It Cm <
257.Dq Half the cache size .
258Reduce the size of the cache by a factor of two.
259.Pp
260.It Cm >
261.Dq Double the cache size .
262Double the size of the cache by a factor of two.
263.El
264.Pp
265So to set a systemwide reduction of cache size and coredumps on problems
266one would:
267.Li ln -s 'A<' /etc/malloc.conf
268.Pp
269The
270.Cm J
271and
272.Cm Z
273flags are mostly for testing and debugging.
274If a program changes behavior if either of these options are used,
275it is buggy.
276.Pp
277The default cache size is 16 pages.
65.Sh RETURN VALUES 278.Sh RETURN VALUES
66The 279The
67.Fn malloc 280.Fn malloc
68function returns 281and
69a pointer to the allocated space if successful; otherwise 282.Fn calloc
70a null pointer is returned. 283functions return a pointer to the allocated space if successful; otherwise,
284a null pointer is returned and
285.Va errno
286is set to
287.Er ENOMEM .
288.Pp
289The
290.Fn free
291and
292.Fn cfree
293functions return no value.
294.Pp
295The
296.Fn realloc
297function returns a pointer to the (possibly moved) allocated space
298if successful; otherwise, a null pointer is returned and
299.Va errno
300is set to
301.Er ENOMEM .
302.Sh ENVIRONMENT
303See above.
304.Sh FILES
305.Bl -tag -width "/etc/malloc.conf"
306.It Pa /etc/malloc.conf
307symbolic link to filename containing option flags
308.El
309.Sh DIAGNOSTICS
310If
311.Fn malloc ,
312.Fn calloc ,
313.Fn realloc ,
314or
315.Fn free
316detect an error or warning condition,
317a message will be printed to file descriptor
3182 (not using stdio).
319Errors will always result in the process being
320.Xr abort 3 'ed.
321If the
322.Cm A
323option has been specified, warnings will also
324.Xr abort 3
325the process.
326.Pp
327Here is a brief description of the error messages and what they mean:
328.Bl -tag -width Fl
329.It Dq (ES): mumble mumble mumble
330.Fn malloc
331has been compiled with
332.Dv \&-DEXTRA_SANITY
333and something looks fishy in there.
334Consult sources and/or wizards.
335.It Dq allocation failed
336If the
337.Cm A
338option is specified it is an error for
339.Fn malloc ,
340.Fn calloc ,
341or
342.Fn realloc
343to return
344.Dv NULL .
345.It Dq mmap(2) failed, check limits.
346This is a rather weird condition that is most likely to indicate a
347seriously overloaded system or a
348.Xr ulimit 1
349restriction.
350.It Dq freelist is destroyed.
351.Fn malloc Ns 's
352internal freelist has been stomped on.
353.El
354.Pp
355Here is a brief description of the warning messages and what they mean:
356.Bl -tag -width Fl
357.It Dq chunk/page is already free.
358There was an attempt to free a chunk that had already been freed.
359.It Dq junk pointer, too high to make sense.
360The pointer doesn't make sense.
361It's above the area of memory that
362.Fn malloc
363knows something about.
364This could be a pointer from some
365.Xr mmap 2 'ed
366memory.
367.It Dq junk pointer, too low to make sense.
368The pointer doesn't make sense.
369It's below the area of memory that
370.Fn malloc
371knows something about.
372This pointer probably came from your data or bss segments.
373.It Dq malloc() has never been called.
374Nothing has ever been allocated, yet something is being freed or
375realloc'ed.
376.It Dq modified (chunk-/page-) pointer.
377The pointer passed to free or realloc has been modified.
378.It Dq pointer to wrong page.
379The pointer that
380.Fn malloc
381is trying to free is not pointing to
382a sensible page.
383.It Dq recursive call.
384An attempt was made to call recursively into these functions, i.e., from a
385signal handler.
386This behavior is not supported.
387In particular, signal handlers should
388.Em not
389use any of the
390.Fn malloc
391functions nor utilize any other functions which may call
392.Fn malloc
393(e.g.,
394.Xr stdio 3
395routines).
396.It Dq unknown char in MALLOC_OPTIONS
397We found something we didn't understand.
398.El
71.Sh SEE ALSO 399.Sh SEE ALSO
72.Xr brk 2 , 400.Xr brk 2 ,
73.Xr getpagesize 2 ,
74.Xr free 3 ,
75.Xr calloc 3 ,
76.Xr alloca 3 , 401.Xr alloca 3 ,
77.Xr realloc 3 , 402.Xr getpagesize 3 ,
78.Xr memory 3 403.Xr memory 3
79.Sh STANDARDS 404.Sh STANDARDS
80The 405The
81.Fn malloc 406.Fn malloc
82function conforms to 407function conforms to
83.St -ansiC . 408.St -ansiC .
84.Sh BUGS 409.Sh HISTORY
85The current implementation of 410The present implementation of
86.Xr malloc 411.Fn malloc
87does not always fail gracefully when system 412started out as a filesystem on a drum
88memory limits are approached. 413attached to a 20-bit binary challenged computer built with discrete germanium
89It may fail to allocate memory when larger free blocks could be broken 414transistors, and it has since graduated to handle primary storage rather than
90up, or when limits are exceeded because the size is rounded up. 415secondary.
91It is optimized for sizes that are powers of two. 416.Pp
417The main difference from other
418.Fn malloc
419implementations are believed to be that
420the free pages are not accessed until allocated.
421Most
422.Fn malloc
423implementations will store a data structure containing a,
424possibly double-, linked list in the free chunks of memory, used to tie
425all the free memory together.
426That is a quite suboptimal thing to do.
427Every time the free-list is traversed, all the otherwise unused, and very
428likely paged out, pages get faulted into primary memory, just to see what
429lies after them in the list.
430.Pp
431On systems which are paging, this can increase the page-faults
432of a process by a factor of five.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 3c57fad024..f5704754a0 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,421 +1,1327 @@
1/* 1/*
2 * Copyright (c) 1983 Regents of the University of California. 2 * ----------------------------------------------------------------------------
3 * All rights reserved. 3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * Redistribution and use in source and binary forms, with or without 5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * modification, are permitted provided that the following conditions 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * are met: 7 * ----------------------------------------------------------------------------
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */ 8 */
33 9
34#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.66 2004/02/19 23:20:53 tdeval Exp $";
36static char *rcsid = "$Id: malloc.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
38 13
39/* 14/*
40 * malloc.c (Caltech) 2/21/82 15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
41 * Chris Kingsley, kingsley@cit-20. 16 * related to internal conditions and consistency in malloc.c. This has
42 * 17 * a noticeable runtime performance hit, and generally will not do you
43 * This is a very fast storage allocator. It allocates blocks of a small 18 * any good unless you fiddle with the internals of malloc or want
44 * number of different sizes, and keeps free lists of each size. Blocks that 19 * to catch random pointer corruption as early as possible.
45 * don't exactly fit are passed up to the next larger size. In this 20 */
46 * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. 21#ifndef MALLOC_EXTRA_SANITY
47 * This is designed for use in a virtual memory environment. 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.
48 */ 37 */
38#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
49 39
50#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/mman.h>
43#include <sys/uio.h>
44#include <stdio.h>
51#include <stdlib.h> 45#include <stdlib.h>
52#include <string.h> 46#include <string.h>
53#include <unistd.h> 47#include <unistd.h>
48#include <fcntl.h>
49#include <limits.h>
50#include <errno.h>
54 51
55#define NULL 0 52#include "thread_private.h"
56 53
57static void morecore(); 54/*
58static int findbucket(); 55 * The basic parameters you can tweak.
56 *
57 * malloc_pageshift pagesize = 1 << malloc_pageshift
58 * It's probably best if this is the native
59 * page size, but it shouldn't have to be.
60 *
61 * malloc_minsize minimum size of an allocation in bytes.
62 * If this is too small it's too much work
63 * to manage them. This is also the smallest
64 * unit of alignment used for the storage
65 * returned by malloc/realloc.
66 *
67 */
68
69#if defined(__OpenBSD__) && defined(__sparc__)
70# define malloc_pageshift 13U
71#endif /* __OpenBSD__ */
59 72
60/* 73/*
61 * The overhead on a block is at least 4 bytes. When free, this space 74 * No user serviceable parts behind this point.
62 * contains a pointer to the next free block, and the bottom two bits must 75 *
63 * be zero. When in use, the first byte is set to MAGIC, and the second 76 * This structure describes a page worth of chunks.
64 * byte is the size index. The remaining bytes are for alignment.
65 * If range checking is enabled then a second word holds the size of the
66 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
67 * The order of elements is critical: ov_magic must overlay the low order
68 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
69 */ 77 */
70union overhead { 78
71 union overhead *ov_next; /* when free */ 79struct pginfo {
72 struct { 80 struct pginfo *next; /* next on the free list */
73 u_char ovu_magic; /* magic number */ 81 void *page; /* Pointer to the page */
74 u_char ovu_index; /* bucket # */ 82 u_short size; /* size of this page's chunks */
75#ifdef RCHECK 83 u_short shift; /* How far to shift for this size chunks */
76 u_short ovu_rmagic; /* range magic number */ 84 u_short free; /* How many free chunks */
77 u_long ovu_size; /* actual block size */ 85 u_short total; /* How many chunk */
78#endif 86 u_long bits[1]; /* Which chunks are free */
79 } ovu;
80#define ov_magic ovu.ovu_magic
81#define ov_index ovu.ovu_index
82#define ov_rmagic ovu.ovu_rmagic
83#define ov_size ovu.ovu_size
84}; 87};
85 88
86#define MAGIC 0xef /* magic # on accounting info */ 89/*
87#define RMAGIC 0x5555 /* magic # on range info */ 90 * This structure describes a number of free pages.
91 */
92
93struct pgfree {
94 struct pgfree *next; /* next run of free pages */
95 struct pgfree *prev; /* prev run of free pages */
96 void *page; /* pointer to free pages */
97 void *end; /* pointer to end of free pages */
98 u_long size; /* number of bytes free */
99};
100
101/*
102 * How many bits per u_long in the bitmap.
103 * Change only if not 8 bits/byte
104 */
105#define MALLOC_BITS (8*sizeof(u_long))
106
107/*
108 * Magic values to put in the page_directory
109 */
110#define MALLOC_NOT_MINE ((struct pginfo*) 0)
111#define MALLOC_FREE ((struct pginfo*) 1)
112#define MALLOC_FIRST ((struct pginfo*) 2)
113#define MALLOC_FOLLOW ((struct pginfo*) 3)
114#define MALLOC_MAGIC ((struct pginfo*) 4)
115
116#ifndef malloc_pageshift
117#define malloc_pageshift (PGSHIFT)
118#endif
119
120#ifndef malloc_minsize
121#define malloc_minsize 16U
122#endif
123
124#ifndef malloc_pageshift
125#error "malloc_pageshift undefined"
126#endif
127
128#if !defined(malloc_pagesize)
129#define malloc_pagesize (1UL<<malloc_pageshift)
130#endif
131
132#if ((1UL<<malloc_pageshift) != malloc_pagesize)
133#error "(1UL<<malloc_pageshift) != malloc_pagesize"
134#endif
135
136#ifndef malloc_maxsize
137#define malloc_maxsize ((malloc_pagesize)>>1)
138#endif
139
140/* A mask for the offset inside a page. */
141#define malloc_pagemask ((malloc_pagesize)-1)
142
143#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
144#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
88 145
89#ifdef RCHECK 146/* fd of /dev/zero */
90#define RSLOP sizeof (u_short) 147#ifdef USE_DEV_ZERO
148static int fdzero;
149#define MMAP_FD fdzero
150#define INIT_MMAP() \
151 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
152 wrterror("open of /dev/zero\n"); }
91#else 153#else
92#define RSLOP 0 154#define MMAP_FD (-1)
155#define INIT_MMAP()
156#endif
157
158/* Set when initialization has been done */
159static unsigned int malloc_started;
160
161/* Number of free pages we cache */
162static unsigned int malloc_cache = 16;
163
164/* The offset from pagenumber to index into the page directory */
165static u_long malloc_origo;
166
167/* The last index in the page directory we care about */
168static u_long last_index;
169
170/* Pointer to page directory. Allocated "as if with" malloc */
171static struct pginfo **page_dir;
172
173/* How many slots in the page directory */
174static size_t malloc_ninfo;
175
176/* Free pages line up here */
177static struct pgfree free_list;
178
179/* Abort(), user doesn't handle problems. */
180static int malloc_abort = 2;
181
182/* Are we trying to die ? */
183static int suicide;
184
185#ifdef MALLOC_STATS
186/* dump statistics */
187static int malloc_stats;
93#endif 188#endif
94 189
190/* avoid outputting warnings? */
191static int malloc_silent;
192
193/* always realloc ? */
194static int malloc_realloc;
195
196/* mprotect free pages PROT_NONE? */
197static int malloc_freeprot;
198
199/* use guard pages after allocations? */
200static int malloc_guard = 0;
201
202#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
203/* pass the kernel a hint on free pages ? */
204static int malloc_hint;
205#endif
206
207/* xmalloc behaviour ? */
208static int malloc_xmalloc;
209
210/* zero fill ? */
211static int malloc_zero;
212
213/* junk fill ? */
214static int malloc_junk;
215
216#ifdef __FreeBSD__
217/* utrace ? */
218static int malloc_utrace;
219
220struct ut { void *p; size_t s; void *r; };
221
222void utrace(struct ut *, int);
223
224#define UTRACE(a, b, c) \
225 if (malloc_utrace) \
226 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
227#else /* !__FreeBSD__ */
228#define UTRACE(a,b,c)
229#endif
230
231/* my last break. */
232static void *malloc_brk;
233
234/* one location cache for free-list holders */
235static struct pgfree *px;
236
237/* compile-time options */
238char *malloc_options;
239
240/* Name of the current public function */
241static char *malloc_func;
242
243/* Macro for mmap */
244#define MMAP(size) \
245 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
246 MMAP_FD, (off_t)0)
247
95/* 248/*
96 * nextf[i] is the pointer to the next free block of size 2^(i+3). The 249 * Necessary function declarations
97 * smallest allocatable block is 8 bytes. The overhead information
98 * precedes the data area returned to the user.
99 */ 250 */
100#define NBUCKETS 30 251static int extend_pgdir(u_long index);
101static union overhead *nextf[NBUCKETS]; 252static void *imalloc(size_t size);
102extern char *sbrk(); 253static void ifree(void *ptr);
254static void *irealloc(void *ptr, size_t size);
255static void *malloc_bytes(size_t size);
256
257#ifdef MALLOC_STATS
258void
259malloc_dump(FILE *fd)
260{
261 struct pginfo **pd;
262 struct pgfree *pf;
263 int j;
264
265 pd = page_dir;
266
267 /* print out all the pages */
268 for(j=0;j<=last_index;j++) {
269 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
270 if (pd[j] == MALLOC_NOT_MINE) {
271 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
272 ;
273 j--;
274 fprintf(fd, ".. %5d not mine\n", j);
275 } else if (pd[j] == MALLOC_FREE) {
276 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
277 ;
278 j--;
279 fprintf(fd, ".. %5d free\n", j);
280 } else if (pd[j] == MALLOC_FIRST) {
281 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
282 ;
283 j--;
284 fprintf(fd, ".. %5d in use\n", j);
285 } else if (pd[j] < MALLOC_MAGIC) {
286 fprintf(fd, "(%p)\n", pd[j]);
287 } else {
288 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
289 pd[j], pd[j]->free, pd[j]->total,
290 pd[j]->size, pd[j]->page, pd[j]->next);
291 }
292 }
293
294 for(pf=free_list.next; pf; pf=pf->next) {
295 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
296 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
297 if (pf == pf->next) {
298 fprintf(fd, "Free_list loops\n");
299 break;
300 }
301 }
302
303 /* print out various info */
304 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
305 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
306 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
307 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
308 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
309 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
310 (last_index + malloc_pageshift) << malloc_pageshift);
311 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
312}
313#endif /* MALLOC_STATS */
314
315extern char *__progname;
316
317static void
318wrterror(char *p)
319{
320 char *q = " error: ";
321 struct iovec iov[4];
322
323 iov[0].iov_base = __progname;
324 iov[0].iov_len = strlen(__progname);
325 iov[1].iov_base = malloc_func;
326 iov[1].iov_len = strlen(malloc_func);
327 iov[2].iov_base = q;
328 iov[2].iov_len = strlen(q);
329 iov[3].iov_base = p;
330 iov[3].iov_len = strlen(p);
331 writev(STDERR_FILENO, iov, 4);
332
333 suicide = 1;
334#ifdef MALLOC_STATS
335 if (malloc_stats)
336 malloc_dump(stderr);
337#endif /* MALLOC_STATS */
338 abort();
339}
340
341static void
342wrtwarning(char *p)
343{
344 char *q = " warning: ";
345 struct iovec iov[4];
346
347 if (malloc_abort)
348 wrterror(p);
349 else if (malloc_silent)
350 return;
351
352 iov[0].iov_base = __progname;
353 iov[0].iov_len = strlen(__progname);
354 iov[1].iov_base = malloc_func;
355 iov[1].iov_len = strlen(malloc_func);
356 iov[2].iov_base = q;
357 iov[2].iov_len = strlen(q);
358 iov[3].iov_base = p;
359 iov[3].iov_len = strlen(p);
360 writev(STDERR_FILENO, iov, 4);
361}
362
363#ifdef MALLOC_STATS
364static void
365malloc_exit(void)
366{
367 FILE *fd = fopen("malloc.out", "a");
368 char *q = "malloc() warning: Couldn't dump stats\n";
369 if (fd != NULL) {
370 malloc_dump(fd);
371 fclose(fd);
372 } else
373 write(STDERR_FILENO, q, strlen(q));
374}
375#endif /* MALLOC_STATS */
103 376
104static int pagesz; /* page size */
105static int pagebucket; /* page size bucket */
106 377
107#ifdef MSTATS
108/* 378/*
109 * nmalloc[i] is the difference between the number of mallocs and frees 379 * Allocate a number of pages from the OS
110 * for a given block size.
111 */ 380 */
112static u_int nmalloc[NBUCKETS]; 381static void *
113#include <stdio.h> 382map_pages(size_t pages)
114#endif 383{
384 caddr_t result, tail;
115 385
116#if defined(DEBUG) || defined(RCHECK) 386 result = (caddr_t)pageround((u_long)sbrk(0));
117#define ASSERT(p) if (!(p)) botch("p") 387 pages <<= malloc_pageshift;
118#include <stdio.h> 388 if (pages > SIZE_T_MAX - (size_t)result) {
119static 389#ifdef MALLOC_EXTRA_SANITY
120botch(s) 390 wrtwarning("(ES): overflow in map_pages fails\n");
121 char *s; 391#endif /* MALLOC_EXTRA_SANITY */
392 errno = ENOMEM;
393 return (NULL);
394 }
395 tail = result + pages + malloc_guard;
396
397 if (brk(tail) == (char *)-1) {
398#ifdef MALLOC_EXTRA_SANITY
399 wrtwarning("(ES): map_pages fails\n");
400#endif /* MALLOC_EXTRA_SANITY */
401 return (NULL);
402 }
403 if (malloc_guard)
404 mprotect(result + pages, malloc_pagesize, PROT_NONE);
405
406 last_index = ptr2index(tail) - 1;
407 malloc_brk = tail;
408
409 if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
410 return (NULL);
411
412 return (result);
413}
414
415/*
416 * Extend page directory
417 */
418static int
419extend_pgdir(u_long index)
420{
421 struct pginfo **new, **old;
422 size_t i, oldlen;
423
424 /* Make it this many pages */
425 i = index * sizeof *page_dir;
426 i /= malloc_pagesize;
427 i += 2;
428
429 /* remember the old mapping size */
430 oldlen = malloc_ninfo * sizeof *page_dir;
431
432 /*
433 * NOTE: we allocate new pages and copy the directory rather than tempt
434 * fate by trying to "grow" the region.. There is nothing to prevent
435 * us from accidently re-mapping space that's been allocated by our caller
436 * via dlopen() or other mmap().
437 *
438 * The copy problem is not too bad, as there is 4K of page index per
439 * 4MB of malloc arena.
440 *
441 * We can totally avoid the copy if we open a file descriptor to associate
442 * the anon mappings with. Then, when we remap the pages at the new
443 * address, the old pages will be "magically" remapped.. But this means
444 * keeping open a "secret" file descriptor.....
445 */
446
447 /* Get new pages */
448 new = (struct pginfo**) MMAP(i * malloc_pagesize);
449 if (new == MAP_FAILED)
450 return (0);
451
452 /* Copy the old stuff */
453 memcpy(new, page_dir,
454 malloc_ninfo * sizeof *page_dir);
455
456 /* register the new size */
457 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
458
459 /* swap the pointers */
460 old = page_dir;
461 page_dir = new;
462
463 /* Now free the old stuff */
464 munmap(old, oldlen);
465 return (1);
466}
467
468/*
469 * Initialize the world
470 */
471static void
472malloc_init(void)
122{ 473{
123 fprintf(stderr, "\r\nassertion botched: %s\r\n", s); 474 char *p, b[64];
124 (void) fflush(stderr); /* just in case user buffered it */ 475 int i, j;
476 int save_errno = errno;
477
478 _MALLOC_LOCK_INIT();
479
480 INIT_MMAP();
481
482#ifdef MALLOC_EXTRA_SANITY
483 malloc_junk = 1;
484#endif /* MALLOC_EXTRA_SANITY */
485
486 for (i = 0; i < 3; i++) {
487 if (i == 0) {
488 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
489 if (j <= 0)
490 continue;
491 b[j] = '\0';
492 p = b;
493 } else if (i == 1) {
494 if (issetugid() == 0)
495 p = getenv("MALLOC_OPTIONS");
496 else
497 continue;
498 } else if (i == 2) {
499 p = malloc_options;
500 }
501 for (; p != NULL && *p != '\0'; p++) {
502 switch (*p) {
503 case '>': malloc_cache <<= 1; break;
504 case '<': malloc_cache >>= 1; break;
505 case 'a': malloc_abort = 0; break;
506 case 'A': malloc_abort = 1; break;
507#ifdef MALLOC_STATS
508 case 'd': malloc_stats = 0; break;
509 case 'D': malloc_stats = 1; break;
510#endif /* MALLOC_STATS */
511 case 'f': malloc_freeprot = 0; break;
512 case 'F': malloc_freeprot = 1; break;
513 case 'g': malloc_guard = 0; break;
514 case 'G': malloc_guard = malloc_pagesize; break;
515#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
516 case 'h': malloc_hint = 0; break;
517 case 'H': malloc_hint = 1; break;
518#endif /* __FreeBSD__ */
519 case 'r': malloc_realloc = 0; break;
520 case 'R': malloc_realloc = 1; break;
521 case 'j': malloc_junk = 0; break;
522 case 'J': malloc_junk = 1; break;
523 case 'n': malloc_silent = 0; break;
524 case 'N': malloc_silent = 1; break;
525#ifdef __FreeBSD__
526 case 'u': malloc_utrace = 0; break;
527 case 'U': malloc_utrace = 1; break;
528#endif /* __FreeBSD__ */
529 case 'x': malloc_xmalloc = 0; break;
530 case 'X': malloc_xmalloc = 1; break;
531 case 'z': malloc_zero = 0; break;
532 case 'Z': malloc_zero = 1; break;
533 default:
534 j = malloc_abort;
535 malloc_abort = 0;
536 wrtwarning("unknown char in MALLOC_OPTIONS\n");
537 malloc_abort = j;
538 break;
539 }
540 }
541 }
542
543 UTRACE(0, 0, 0);
544
545 /*
546 * We want junk in the entire allocation, and zero only in the part
547 * the user asked for.
548 */
549 if (malloc_zero)
550 malloc_junk=1;
551
552#ifdef MALLOC_STATS
553 if (malloc_stats && (atexit(malloc_exit) == -1))
554 wrtwarning("atexit(2) failed. Will not be able to dump malloc stats on exit\n");
555#endif /* MALLOC_STATS */
556
557 /* Allocate one page for the page directory */
558 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
559
560 if (page_dir == MAP_FAILED)
561 wrterror("mmap(2) failed, check limits\n");
562
563 /*
564 * We need a maximum of malloc_pageshift buckets, steal these from the
565 * front of the page_directory;
566 */
567 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
568 malloc_origo -= malloc_pageshift;
569
570 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
571
572 /* Been here, done that */
573 malloc_started++;
574
575 /* Recalculate the cache size in bytes, and make sure it's nonzero */
576
577 if (!malloc_cache)
578 malloc_cache++;
579
580 malloc_cache <<= malloc_pageshift;
581
582 /*
583 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
584 * We can sbrk(2) further back when we keep this on a low address.
585 */
586 px = (struct pgfree *) imalloc (sizeof *px);
587 errno = save_errno;
588}
589
590/*
591 * Allocate a number of complete pages
592 */
593static void *
594malloc_pages(size_t size)
595{
596 void *p, *delay_free = NULL;
597 int i;
598 struct pgfree *pf;
599 u_long index;
600
601 size = pageround(size) + malloc_guard;
602
603 p = NULL;
604 /* Look for free pages before asking for more */
605 for(pf = free_list.next; pf; pf = pf->next) {
606
607#ifdef MALLOC_EXTRA_SANITY
608 if (pf->size & malloc_pagemask)
609 wrterror("(ES): junk length entry on free_list\n");
610 if (!pf->size)
611 wrterror("(ES): zero length entry on free_list\n");
612 if (pf->page == pf->end)
613 wrterror("(ES): zero entry on free_list\n");
614 if (pf->page > pf->end)
615 wrterror("(ES): sick entry on free_list\n");
616 if ((void*)pf->page >= (void*)sbrk(0))
617 wrterror("(ES): entry on free_list past brk\n");
618 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
619 wrterror("(ES): non-free first page on free-list\n");
620 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
621 wrterror("(ES): non-free last page on free-list\n");
622#endif /* MALLOC_EXTRA_SANITY */
623
624 if (pf->size < size)
625 continue;
626
627 if (pf->size == size) {
628 p = pf->page;
629 if (pf->next != NULL)
630 pf->next->prev = pf->prev;
631 pf->prev->next = pf->next;
632 delay_free = pf;
633 break;
634 }
635
636 p = pf->page;
637 pf->page = (char *)pf->page + size;
638 pf->size -= size;
639 break;
640 }
641
642 size -= malloc_guard;
643
644#ifdef MALLOC_EXTRA_SANITY
645 if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE)
646 wrterror("(ES): allocated non-free page on free-list\n");
647#endif /* MALLOC_EXTRA_SANITY */
648
649 if ((malloc_guard || malloc_freeprot) && p != NULL)
650 mprotect(p, size, PROT_READ|PROT_WRITE);
651
652 size >>= malloc_pageshift;
653
654 /* Map new pages */
655 if (p == NULL)
656 p = map_pages(size);
657
658 if (p != NULL) {
659
660 index = ptr2index(p);
661 page_dir[index] = MALLOC_FIRST;
662 for (i=1;i<size;i++)
663 page_dir[index+i] = MALLOC_FOLLOW;
664
665 if (malloc_junk)
666 memset(p, SOME_JUNK, size << malloc_pageshift);
667 }
668
669 if (delay_free) {
670 if (px == NULL)
671 px = delay_free;
672 else
673 ifree(delay_free);
674 }
675
676 return (p);
677}
678
679/*
680 * Allocate a page of fragments
681 */
682
683static __inline__ int
684malloc_make_chunks(int bits)
685{
686 struct pginfo *bp;
687 void *pp;
688 int i, k, l;
689
690 /* Allocate a new bucket */
691 pp = malloc_pages((size_t)malloc_pagesize);
692 if (pp == NULL)
693 return (0);
694
695 /* Find length of admin structure */
696 l = sizeof *bp - sizeof(u_long);
697 l += sizeof(u_long) *
698 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
699
700 /* Don't waste more than two chunks on this */
701 /*
702 * If we are to allocate a memory protected page for the malloc(0)
703 * case (when bits=0), it must be from a different page than the
704 * pginfo page.
705 * --> Treat it like the big chunk alloc, get a second data page.
706 */
707 if (bits != 0 && (1UL<<(bits)) <= l+l) {
708 bp = (struct pginfo *)pp;
709 } else {
710 bp = (struct pginfo *)imalloc(l);
711 if (bp == NULL) {
712 ifree(pp);
713 return (0);
714 }
715 }
716
717 /* memory protect the page allocated in the malloc(0) case */
718 if (bits == 0) {
719
720 bp->size = 0;
721 bp->shift = 1;
722 i = malloc_minsize-1;
723 while (i >>= 1)
724 bp->shift++;
725 bp->total = bp->free = malloc_pagesize >> bp->shift;
726 bp->page = pp;
727
728 k = mprotect(pp, malloc_pagesize, PROT_NONE);
729 if (k < 0) {
730 ifree(pp);
731 ifree(bp);
732 return (0);
733 }
734 } else {
735 bp->size = (1UL<<bits);
736 bp->shift = bits;
737 bp->total = bp->free = malloc_pagesize >> bits;
738 bp->page = pp;
739 }
740
741 /* set all valid bits in the bitmap */
742 k = bp->total;
743 i = 0;
744
745 /* Do a bunch at a time */
746 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
747 bp->bits[i / MALLOC_BITS] = ~0UL;
748
749 for(; i < k; i++)
750 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
751
752 if (bp == bp->page) {
753 /* Mark the ones we stole for ourselves */
754 for(i=0;l > 0;i++) {
755 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
756 bp->free--;
757 bp->total--;
758 l -= (1 << bits);
759 }
760 }
761
762 /* MALLOC_LOCK */
763
764 page_dir[ptr2index(pp)] = bp;
765
766 bp->next = page_dir[bits];
767 page_dir[bits] = bp;
768
769 /* MALLOC_UNLOCK */
770
771 return (1);
772}
773
774/*
775 * Allocate a fragment
776 */
777static void *
778malloc_bytes(size_t size)
779{
780 int i,j;
781 u_long u;
782 struct pginfo *bp;
783 int k;
784 u_long *lp;
785
786 /* Don't bother with anything less than this */
787 /* unless we have a malloc(0) requests */
788 if (size != 0 && size < malloc_minsize)
789 size = malloc_minsize;
790
791 /* Find the right bucket */
792 if (size == 0)
793 j=0;
794 else {
795 j = 1;
796 i = size-1;
797 while (i >>= 1)
798 j++;
799 }
800
801 /* If it's empty, make a page more of that size chunks */
802 if (page_dir[j] == NULL && !malloc_make_chunks(j))
803 return (NULL);
804
805 bp = page_dir[j];
806
807 /* Find first word of bitmap which isn't empty */
808 for (lp = bp->bits; !*lp; lp++)
809 ;
810
811 /* Find that bit, and tweak it */
812 u = 1;
813 k = 0;
814 while (!(*lp & u)) {
815 u += u;
816 k++;
817 }
818
819 if (malloc_guard) {
820 /* Walk to a random position. */
821 i = arc4random() % bp->free;
822 while (i > 0) {
823 u += u;
824 k++;
825 if (k >= MALLOC_BITS) {
826 lp++;
827 u = 1;
828 k = 0;
829 }
830#ifdef MALLOC_EXTRA_SANITY
831 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS)
832 wrterror("chunk overflow\n");
833#endif /* MALLOC_EXTRA_SANITY */
834 if (*lp & u)
835 i--;
836 }
837 }
838 *lp ^= u;
839
840 /* If there are no more free, remove from free-list */
841 if (!--bp->free) {
842 page_dir[j] = bp->next;
843 bp->next = NULL;
844 }
845
846 /* Adjust to the real offset of that chunk */
847 k += (lp-bp->bits)*MALLOC_BITS;
848 k <<= bp->shift;
849
850 if (malloc_junk && bp->size != 0)
851 memset((char *)bp->page + k, SOME_JUNK, bp->size);
852
853 return ((u_char *)bp->page + k);
854}
855
856/*
857 * Allocate a piece of memory
858 */
859static void *
860imalloc(size_t size)
861{
862 void *result;
863
864 if (!malloc_started)
865 malloc_init();
866
867 if (suicide)
125 abort(); 868 abort();
869
870 if ((size + malloc_pagesize) < size) { /* Check for overflow */
871 result = NULL;
872 errno = ENOMEM;
873 }
874 else if (size <= malloc_maxsize)
875 result = malloc_bytes(size);
876 else
877 result = malloc_pages(size);
878
879 if (malloc_abort == 1 && result == NULL)
880 wrterror("allocation failed\n");
881
882 if (malloc_zero && result != NULL)
883 memset(result, 0, size);
884
885 return (result);
126} 886}
127#else
128#define ASSERT(p)
129#endif
130 887
131void * 888/*
132malloc(nbytes) 889 * Change the size of an allocation.
133 size_t nbytes; 890 */
891static void *
892irealloc(void *ptr, size_t size)
134{ 893{
135 register union overhead *op; 894 void *p;
136 register long bucket, n; 895 u_long osize, index;
137 register unsigned amt; 896 struct pginfo **mp;
897 int i;
138 898
139 /* 899 if (suicide)
140 * First time malloc is called, setup page size and 900 abort();
141 * align break pointer so all data will be page aligned. 901
142 */ 902 if (!malloc_started) {
143 if (pagesz == 0) { 903 wrtwarning("malloc() has never been called\n");
144 pagesz = n = getpagesize(); 904 return (NULL);
145 op = (union overhead *)sbrk(0); 905 }
146 n = n - sizeof (*op) - ((long)op & (n - 1)); 906
147 if (n < 0) 907 index = ptr2index(ptr);
148 n += pagesz; 908
149 if (n) { 909 if (index < malloc_pageshift) {
150 if (sbrk(n) == (char *)-1) 910 wrtwarning("junk pointer, too low to make sense\n");
151 return (NULL); 911 return (NULL);
152 } 912 }
153 bucket = 0; 913
154 amt = 8; 914 if (index > last_index) {
155 while (pagesz > amt) { 915 wrtwarning("junk pointer, too high to make sense\n");
156 amt <<= 1; 916 return (NULL);
157 bucket++; 917 }
158 } 918
159 pagebucket = bucket; 919 mp = &page_dir[index];
920
921 if (*mp == MALLOC_FIRST) { /* Page allocation */
922
923 /* Check the pointer */
924 if ((u_long)ptr & malloc_pagemask) {
925 wrtwarning("modified (page-) pointer\n");
926 return (NULL);
160 } 927 }
161 /* 928
162 * Convert amount of memory requested into closest block size 929 /* Find the size in bytes */
163 * stored in hash buckets which satisfies request. 930 for (osize = malloc_pagesize; *(++mp) == MALLOC_FOLLOW;)
164 * Account for space used per block for accounting. 931 osize += malloc_pagesize;
165 */ 932
166 if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { 933 if (!malloc_realloc && /* Unless we have to, */
167#ifndef RCHECK 934 size <= osize && /* .. or are too small, */
168 amt = 8; /* size of first bucket */ 935 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
169 bucket = 0; 936 if (malloc_junk)
170#else 937 memset((char *)ptr + size, SOME_JUNK, osize-size);
171 amt = 16; /* size of first bucket */ 938 return (ptr); /* ..don't do anything else. */
172 bucket = 1;
173#endif
174 n = -((long)sizeof (*op) + RSLOP);
175 } else {
176 amt = pagesz;
177 bucket = pagebucket;
178 } 939 }
179 while (nbytes > amt + n) { 940
180 amt <<= 1; 941 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
181 if (amt == 0) 942
182 return (NULL); 943 /* Check the pointer for sane values */
183 bucket++; 944 if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) {
945 wrtwarning("modified (chunk-) pointer\n");
946 return (NULL);
184 } 947 }
185 /* 948
186 * If nothing in hash bucket right now, 949 /* Find the chunk index in the page */
187 * request more memory from the system. 950 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
188 */ 951
189 if ((op = nextf[bucket]) == NULL) { 952 /* Verify that it isn't a free chunk already */
190 morecore(bucket); 953 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
191 if ((op = nextf[bucket]) == NULL) 954 wrtwarning("chunk is already free\n");
192 return (NULL); 955 return (NULL);
193 } 956 }
194 /* remove from linked list */ 957
195 nextf[bucket] = op->ov_next; 958 osize = (*mp)->size;
196 op->ov_magic = MAGIC; 959
197 op->ov_index = bucket; 960 if (!malloc_realloc && /* Unless we have to, */
198#ifdef MSTATS 961 size <= osize && /* ..or are too small, */
199 nmalloc[bucket]++; 962 (size > osize/2 || /* ..or could use a smaller size, */
200#endif 963 osize == malloc_minsize)) { /* ..(if there is one) */
201#ifdef RCHECK 964 if (malloc_junk)
202 /* 965 memset((char *)ptr + size, SOME_JUNK, osize-size);
203 * Record allocated size of block and 966 return (ptr); /* ..don't do anything else. */
204 * bound space with magic numbers. 967 }
205 */ 968
206 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 969 } else {
207 op->ov_rmagic = RMAGIC; 970 wrtwarning("pointer to wrong page\n");
208 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 971 return (NULL);
209#endif 972 }
210 return ((char *)(op + 1)); 973
974 p = imalloc(size);
975
976 if (p != NULL) {
977 /* copy the lesser of the two sizes, and free the old one */
978 /* Don't move from/to 0 sized region !!! */
979 if (osize != 0 && size != 0) {
980 if (osize < size)
981 memcpy(p, ptr, osize);
982 else
983 memcpy(p, ptr, size);
984 }
985 ifree(ptr);
986 }
987 return (p);
211} 988}
212 989
213/* 990/*
214 * Allocate more memory to the indicated bucket. 991 * Free a sequence of pages
215 */ 992 */
216static void 993
217morecore(bucket) 994static __inline__ void
218 int bucket; 995free_pages(void *ptr, u_long index, struct pginfo *info)
219{ 996{
220 register union overhead *op; 997 u_long i, l;
221 register long sz; /* size of desired block */ 998 struct pgfree *pf, *pt=NULL;
222 long amt; /* amount to allocate */ 999 void *tail;
223 int nblks; /* how many blocks we get */
224 1000
225 /* 1001 if (info == MALLOC_FREE) {
226 * sbrk_size <= 0 only for big, FLUFFY, requests (about 1002 wrtwarning("page is already free\n");
227 * 2^30 bytes on a VAX, I think) or for a negative arg. 1003 return;
228 */ 1004 }
229 sz = 1 << (bucket + 3); 1005
230#ifdef DEBUG 1006 if (info != MALLOC_FIRST) {
231 ASSERT(sz > 0); 1007 wrtwarning("pointer to wrong page\n");
232#else 1008 return;
233 if (sz <= 0) 1009 }
234 return; 1010
1011 if ((u_long)ptr & malloc_pagemask) {
1012 wrtwarning("modified (page-) pointer\n");
1013 return;
1014 }
1015
1016 /* Count how many pages and mark them free at the same time */
1017 page_dir[index] = MALLOC_FREE;
1018 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
1019 page_dir[index + i] = MALLOC_FREE;
1020
1021 l = i << malloc_pageshift;
1022
1023 if (malloc_junk)
1024 memset(ptr, SOME_JUNK, l);
1025
1026#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
1027 if (malloc_hint)
1028 madvise(ptr, l, MADV_FREE);
235#endif 1029#endif
236 if (sz < pagesz) { 1030
237 amt = pagesz; 1031 if (malloc_guard) {
238 nblks = amt / sz; 1032 page_dir[index + i] = MALLOC_FREE;
1033 l += malloc_guard;
1034 }
1035 tail = (char *)ptr+l;
1036
1037 if (malloc_freeprot)
1038 mprotect(ptr, tail - ptr, PROT_NONE);
1039
1040 /* add to free-list */
1041 if (px == NULL)
1042 px = imalloc(sizeof *px); /* This cannot fail... */
1043 px->page = ptr;
1044 px->end = tail;
1045 px->size = l;
1046
1047 if (free_list.next == NULL) {
1048
1049 /* Nothing on free list, put this at head */
1050 px->next = free_list.next;
1051 px->prev = &free_list;
1052 free_list.next = px;
1053 pf = px;
1054 px = NULL;
1055
1056 } else {
1057
1058 /* Find the right spot, leave pf pointing to the modified entry. */
1059
1060 for(pf = free_list.next; pf->end < ptr && pf->next != NULL;
1061 pf = pf->next)
1062 ; /* Race ahead here */
1063
1064 if (pf->page > tail) {
1065 /* Insert before entry */
1066 px->next = pf;
1067 px->prev = pf->prev;
1068 pf->prev = px;
1069 px->prev->next = px;
1070 pf = px;
1071 px = NULL;
1072 } else if (pf->end == ptr ) {
1073 /* Append to the previous entry */
1074 pf->end = (char *)pf->end + l;
1075 pf->size += l;
1076 if (pf->next != NULL && pf->end == pf->next->page ) {
1077 /* And collapse the next too. */
1078 pt = pf->next;
1079 pf->end = pt->end;
1080 pf->size += pt->size;
1081 pf->next = pt->next;
1082 if (pf->next != NULL)
1083 pf->next->prev = pf;
1084 }
1085 } else if (pf->page == tail) {
1086 /* Prepend to entry */
1087 pf->size += l;
1088 pf->page = ptr;
1089 } else if (pf->next == NULL) {
1090 /* Append at tail of chain */
1091 px->next = NULL;
1092 px->prev = pf;
1093 pf->next = px;
1094 pf = px;
1095 px = NULL;
239 } else { 1096 } else {
240 amt = sz + pagesz; 1097 wrterror("freelist is destroyed\n");
241 nblks = 1;
242 } 1098 }
243 op = (union overhead *)sbrk(amt); 1099 }
244 /* no more room! */ 1100
245 if ((long)op == -1) 1101 /* Return something to OS ? */
246 return; 1102 if (pf->next == NULL && /* If we're the last one, */
1103 pf->size > malloc_cache && /* ..and the cache is full, */
1104 pf->end == malloc_brk && /* ..and none behind us, */
1105 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1106
247 /* 1107 /*
248 * Add new memory allocated to that on 1108 * Keep the cache intact. Notice that the '>' above guarantees that
249 * free list for this hash bucket. 1109 * the pf will always have at least one page afterwards.
250 */ 1110 */
251 nextf[bucket] = op; 1111 pf->end = (char *)pf->page + malloc_cache;
252 while (--nblks > 0) { 1112 pf->size = malloc_cache;
253 op->ov_next = (union overhead *)((caddr_t)op + sz);
254 op = (union overhead *)((caddr_t)op + sz);
255 }
256}
257 1113
258void 1114 brk(pf->end);
259free(cp) 1115 malloc_brk = pf->end;
260 void *cp; 1116
261{ 1117 index = ptr2index(pf->end);
262 register long size; 1118
263 register union overhead *op; 1119 for(i=index;i <= last_index;)
264 1120 page_dir[i++] = MALLOC_NOT_MINE;
265 if (cp == NULL) 1121
266 return; 1122 last_index = index - 1;
267 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 1123
268#ifdef DEBUG 1124 /* XXX: We could realloc/shrink the pagedir here I guess. */
269 ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ 1125 }
270#else 1126 if (pt != NULL)
271 if (op->ov_magic != MAGIC) 1127 ifree(pt);
272 return; /* sanity */
273#endif
274#ifdef RCHECK
275 ASSERT(op->ov_rmagic == RMAGIC);
276 ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
277#endif
278 size = op->ov_index;
279 ASSERT(size < NBUCKETS);
280 op->ov_next = nextf[size]; /* also clobbers ov_magic */
281 nextf[size] = op;
282#ifdef MSTATS
283 nmalloc[size]--;
284#endif
285} 1128}
286 1129
287/* 1130/*
288 * When a program attempts "storage compaction" as mentioned in the 1131 * Free a chunk, and possibly the page it's on, if the page becomes empty.
289 * old malloc man page, it realloc's an already freed block. Usually
290 * this is the last block it freed; occasionally it might be farther
291 * back. We have to search all the free lists for the block in order
292 * to determine its bucket: 1st we make one pass thru the lists
293 * checking only the first block in each; if that fails we search
294 * ``realloc_srchlen'' blocks in each list for a match (the variable
295 * is extern so the caller can modify it). If that fails we just copy
296 * however many bytes was given to realloc() and hope it's not huge.
297 */ 1132 */
298int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
299 1133
300void * 1134/* ARGSUSED */
301realloc(cp, nbytes) 1135static __inline__ void
302 void *cp; 1136free_bytes(void *ptr, int index, struct pginfo *info)
303 size_t nbytes; 1137{
304{ 1138 int i;
305 register u_long onb; 1139 struct pginfo **mp;
306 register long i; 1140 void *vp;
307 union overhead *op; 1141
308 char *res; 1142 /* Find the chunk number on the page */
309 int was_alloced = 0; 1143 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
310 1144
311 if (cp == NULL) 1145 if ((u_long)ptr & ((1UL<<(info->shift))-1)) {
312 return (malloc(nbytes)); 1146 wrtwarning("modified (chunk-) pointer\n");
313 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 1147 return;
314 if (op->ov_magic == MAGIC) { 1148 }
315 was_alloced++; 1149
316 i = op->ov_index; 1150 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
317 } else { 1151 wrtwarning("chunk is already free\n");
318 /* 1152 return;
319 * Already free, doing "compaction". 1153 }
320 * 1154
321 * Search for the old block of memory on the 1155 if (malloc_junk && info->size != 0)
322 * free list. First, check the most common 1156 memset(ptr, SOME_JUNK, info->size);
323 * case (last element free'd), then (this failing) 1157
324 * the last ``realloc_srchlen'' items free'd. 1158 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
325 * If all lookups fail, then assume the size of 1159 info->free++;
326 * the memory block being realloc'd is the 1160
327 * largest possible (so that all "nbytes" of new 1161 if (info->size != 0)
328 * memory are copied into). Note that this could cause 1162 mp = page_dir + info->shift;
329 * a memory fault if the old area was tiny, and the moon 1163 else
330 * is gibbous. However, that is very unlikely. 1164 mp = page_dir;
331 */ 1165
332 if ((i = findbucket(op, 1)) < 0 && 1166 if (info->free == 1) {
333 (i = findbucket(op, realloc_srchlen)) < 0) 1167
334 i = NBUCKETS; 1168 /* Page became non-full */
335 } 1169
336 onb = 1 << (i + 3); 1170 /* Insert in address order */
337 if (onb < pagesz) 1171 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
338 onb -= sizeof (*op) + RSLOP; 1172 mp = &(*mp)->next;
339 else 1173 info->next = *mp;
340 onb += pagesz - sizeof (*op) - RSLOP; 1174 *mp = info;
341 /* avoid the copy if same size block */ 1175 return;
342 if (was_alloced) { 1176 }
343 if (i) { 1177
344 i = 1 << (i + 2); 1178 if (info->free != info->total)
345 if (i < pagesz) 1179 return;
346 i -= sizeof (*op) + RSLOP; 1180
347 else 1181 /* Find & remove this page in the queue */
348 i += pagesz - sizeof (*op) - RSLOP; 1182 while (*mp != info) {
349 } 1183 mp = &((*mp)->next);
350 if (nbytes <= onb && nbytes > i) { 1184#ifdef MALLOC_EXTRA_SANITY
351#ifdef RCHECK 1185 if (!*mp)
352 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 1186 wrterror("(ES): Not on queue\n");
353 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 1187#endif /* MALLOC_EXTRA_SANITY */
354#endif 1188 }
355 return(cp); 1189 *mp = info->next;
356 } else 1190
357 free(cp); 1191 /* Free the page & the info structure if need be */
358 } 1192 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
359 if ((res = malloc(nbytes)) == NULL) 1193
360 return (NULL); 1194 /* If the page was mprotected, unprotect it before releasing it */
361 if (cp != res) /* common optimization if "compacting" */ 1195 if (info->size == 0) {
362 bcopy(cp, res, (nbytes < onb) ? nbytes : onb); 1196 mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
363 return (res); 1197 /* Do we have to care if mprotect succeeds here ? */
1198 }
1199
1200 vp = info->page; /* Order is important ! */
1201 if(vp != (void*)info)
1202 ifree(info);
1203 ifree(vp);
1204}
1205
1206static void
1207ifree(void *ptr)
1208{
1209 struct pginfo *info;
1210 u_long index;
1211
1212 /* This is legal */
1213 if (ptr == NULL)
1214 return;
1215
1216 if (!malloc_started) {
1217 wrtwarning("malloc() has never been called\n");
1218 return;
1219 }
1220
1221 /* If we're already sinking, don't make matters any worse. */
1222 if (suicide)
1223 return;
1224
1225 index = ptr2index(ptr);
1226
1227 if (index < malloc_pageshift) {
1228 wrtwarning("junk pointer, too low to make sense\n");
1229 return;
1230 }
1231
1232 if (index > last_index) {
1233 wrtwarning("junk pointer, too high to make sense\n");
1234 return;
1235 }
1236
1237 info = page_dir[index];
1238
1239 if (info < MALLOC_MAGIC)
1240 free_pages(ptr, index, info);
1241 else
1242 free_bytes(ptr, index, info);
1243 return;
364} 1244}
365 1245
1246static int malloc_active;
1247
366/* 1248/*
367 * Search ``srchlen'' elements of each free list for a block whose 1249 * Common function for handling recursion. Only
368 * header starts at ``freep''. If srchlen is -1 search the whole list. 1250 * print the error message once, to avoid making the problem
369 * Return bucket number, or -1 if not found. 1251 * potentially worse.
370 */ 1252 */
371static 1253static void
372findbucket(freep, srchlen) 1254malloc_recurse(void)
373 union overhead *freep;
374 int srchlen;
375{ 1255{
376 register union overhead *p; 1256 static int noprint;
377 register int i, j; 1257
378 1258 if (noprint == 0)
379 for (i = 0; i < NBUCKETS; i++) { 1259 wrtwarning("recursive call\n");
380 j = 0; 1260 noprint = 1;
381 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { 1261 malloc_active--;
382 if (p == freep) 1262 _MALLOC_UNLOCK();
383 return (i); 1263 errno = EDEADLK;
384 j++;
385 }
386 }
387 return (-1);
388} 1264}
389 1265
390#ifdef MSTATS
391/* 1266/*
392 * mstats - print out statistics about malloc 1267 * These are the public exported interface routines.
393 *
394 * Prints two lines of numbers, one showing the length of the free list
395 * for each size category, the second showing the number of mallocs -
396 * frees for each size category.
397 */ 1268 */
398mstats(s) 1269void *
399 char *s; 1270malloc(size_t size)
400{ 1271{
401 register int i, j; 1272 void *r;
402 register union overhead *p; 1273
403 int totfree = 0, 1274 _MALLOC_LOCK();
404 totused = 0; 1275 malloc_func = " in malloc():";
405 1276 if (malloc_active++) {
406 fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); 1277 malloc_recurse();
407 for (i = 0; i < NBUCKETS; i++) { 1278 return (NULL);
408 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) 1279 }
409 ; 1280 r = imalloc(size);
410 fprintf(stderr, " %d", j); 1281 UTRACE(0, size, r);
411 totfree += j * (1 << (i + 3)); 1282 malloc_active--;
412 } 1283 _MALLOC_UNLOCK();
413 fprintf(stderr, "\nused:\t"); 1284 if (malloc_xmalloc && r == NULL)
414 for (i = 0; i < NBUCKETS; i++) { 1285 wrterror("out of memory\n");
415 fprintf(stderr, " %d", nmalloc[i]); 1286 return (r);
416 totused += nmalloc[i] * (1 << (i + 3)); 1287}
417 } 1288
418 fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", 1289void
419 totused, totfree); 1290free(void *ptr)
1291{
1292 _MALLOC_LOCK();
1293 malloc_func = " in free():";
1294 if (malloc_active++) {
1295 malloc_recurse();
1296 return;
1297 }
1298 ifree(ptr);
1299 UTRACE(ptr, 0, 0);
1300 malloc_active--;
1301 _MALLOC_UNLOCK();
1302 return;
1303}
1304
1305void *
1306realloc(void *ptr, size_t size)
1307{
1308 void *r;
1309
1310 _MALLOC_LOCK();
1311 malloc_func = " in realloc():";
1312 if (malloc_active++) {
1313 malloc_recurse();
1314 return (NULL);
1315 }
1316 if (ptr == NULL) {
1317 r = imalloc(size);
1318 } else {
1319 r = irealloc(ptr, size);
1320 }
1321 UTRACE(ptr, size, r);
1322 malloc_active--;
1323 _MALLOC_UNLOCK();
1324 if (malloc_xmalloc && r == NULL)
1325 wrterror("out of memory\n");
1326 return (r);
420} 1327}
421#endif
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
deleted file mode 100644
index 735252c837..0000000000
--- a/src/lib/libc/stdlib/memory.3
+++ /dev/null
@@ -1,71 +0,0 @@
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.\" from: @(#)memory.3 5.1 (Berkeley) 5/2/91
33.\" $Id: memory.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt MEMORY 3
37.Os BSD 4
38.Sh NAME
39.Nm malloc ,
40.Nm free ,
41.Nm realloc ,
42.Nm calloc ,
43.Nm alloca
44.Nd general memory allocation operations
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void *
48.Fn malloc "size_t size"
49.Ft void
50.Fn free "void *ptr"
51.Ft void *
52.Fn realloc "void *ptr" "size_t size"
53.Ft void *
54.Fn calloc "size_t nelem" "size_t elsize"
55.Ft void *
56.Fn alloca "size_t size"
57.Sh DESCRIPTION
58These functions allocate and free memory for the calling process.
59They are described in the
60individual manual pages.
61.Sh SEE ALSO
62.Xr calloc 3 ,
63.Xr free 3 ,
64.Xr malloc 3 ,
65.Xr realloc 3 ,
66.Xr alloca 3 ,
67.Sh STANDARDS
68These functions, with the exception of
69.Fn alloca
70conform to
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
index 381fdc0830..1826acc369 100644
--- a/src/lib/libc/stdlib/merge.c
+++ b/src/lib/libc/stdlib/merge.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)merge.c 8.2 (Berkeley) 2/14/94";*/ 34static char *rcsid = "$OpenBSD: merge.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42/* 37/*
@@ -59,8 +54,8 @@ static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
59#include <stdlib.h> 54#include <stdlib.h>
60#include <string.h> 55#include <string.h>
61 56
62static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); 57static void setup(u_char *, u_char *, size_t, size_t, int (*)());
63static void insertionsort __P((u_char *, size_t, size_t, int (*)())); 58static void insertionsort(u_char *, size_t, size_t, int (*)());
64 59
65#define ISIZE sizeof(int) 60#define ISIZE sizeof(int)
66#define PSIZE sizeof(u_char *) 61#define PSIZE sizeof(u_char *)
@@ -100,7 +95,7 @@ mergesort(base, nmemb, size, cmp)
100 void *base; 95 void *base;
101 size_t nmemb; 96 size_t nmemb;
102 register size_t size; 97 register size_t size;
103 int (*cmp) __P((const void *, const void *)); 98 int (*cmp)(const void *, const void *);
104{ 99{
105 register int i, sense; 100 register int i, sense;
106 int big, iflag; 101 int big, iflag;
@@ -148,7 +143,7 @@ mergesort(base, nmemb, size, cmp)
148 sense = 0; 143 sense = 0;
149 } 144 }
150 if (!big) { /* here i = 0 */ 145 if (!big) { /* here i = 0 */
151LINEAR: while ((b += size) < t && cmp(q, b) >sense) 146 while ((b += size) < t && cmp(q, b) >sense)
152 if (++i == 6) { 147 if (++i == 6) {
153 big = 1; 148 big = 1;
154 goto EXPONENTIAL; 149 goto EXPONENTIAL;
@@ -169,7 +164,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1)
169 goto FASTCASE; 164 goto FASTCASE;
170 } else 165 } else
171 b = p; 166 b = p;
172SLOWCASE: while (t > b+size) { 167 while (t > b+size) {
173 i = (((t - b) / size) >> 1) * size; 168 i = (((t - b) / size) >> 1) * size;
174 if ((*cmp)(q, p = b + i) <= sense) 169 if ((*cmp)(q, p = b + i) <= sense)
175 t = p; 170 t = p;
@@ -258,7 +253,7 @@ COPY: b = t;
258void 253void
259setup(list1, list2, n, size, cmp) 254setup(list1, list2, n, size, cmp)
260 size_t n, size; 255 size_t n, size;
261 int (*cmp) __P((const void *, const void *)); 256 int (*cmp)(const void *, const void *);
262 u_char *list1, *list2; 257 u_char *list1, *list2;
263{ 258{
264 int i, length, size2, tmp, sense; 259 int i, length, size2, tmp, sense;
@@ -333,7 +328,7 @@ static void
333insertionsort(a, n, size, cmp) 328insertionsort(a, n, size, cmp)
334 u_char *a; 329 u_char *a;
335 size_t n, size; 330 size_t n, size;
336 int (*cmp) __P((const void *, const void *)); 331 int (*cmp)(const void *, const void *);
337{ 332{
338 u_char *ai, *s, *t, *u, tmp; 333 u_char *ai, *s, *t, *u, tmp;
339 int i; 334 int i;
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
index 43356e66b3..cd34260b5c 100644
--- a/src/lib/libc/stdlib/mrand48.c
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: mrand48.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
index fe1cd5781b..ba878b8fdc 100644
--- a/src/lib/libc/stdlib/multibyte.c
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/ 31static char *rcsid = "$OpenBSD: multibyte.c,v 1.4 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: multibyte.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -74,13 +69,7 @@ mbtowc(pwc, s, n)
74 69
75/*ARGSUSED*/ 70/*ARGSUSED*/
76int 71int
77#ifdef __STDC__
78wctomb(char *s, wchar_t wchar) 72wctomb(char *s, wchar_t wchar)
79#else
80wctomb(s, wchar)
81 char *s;
82 wchar_t wchar;
83#endif
84{ 73{
85 if (s == NULL) 74 if (s == NULL)
86 return 0; 75 return 0;
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
index 63f839cb05..b1ec2cebb1 100644
--- a/src/lib/libc/stdlib/nrand48.c
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: nrand48.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16long 20long
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
index 2194c2c608..1789e686ef 100644
--- a/src/lib/libc/stdlib/putenv.c
+++ b/src/lib/libc/stdlib/putenv.c
@@ -1,6 +1,6 @@
1/*- 1/*-
2 * Copyright (c) 1988 The Regents of the University of California. 2 * Copyright (c) 1988, 1993
3 * All rights reserved. 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)putenv.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: putenv.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: putenv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
@@ -43,17 +38,17 @@ int
43putenv(str) 38putenv(str)
44 const char *str; 39 const char *str;
45{ 40{
46 register char *p, *equal; 41 char *p, *equal;
47 int rval; 42 int rval;
48 43
49 if (!(p = strdup(str))) 44 if ((p = strdup(str)) == NULL)
50 return(1); 45 return (-1);
51 if (!(equal = strchr(p, '='))) { 46 if ((equal = strchr(p, '=')) == NULL) {
52 (void)free(p); 47 (void)free(p);
53 return(1); 48 return (-1);
54 } 49 }
55 *equal = '\0'; 50 *equal = '\0';
56 rval = setenv(p, equal + 1, 1); 51 rval = setenv(p, equal + 1, 1);
57 (void)free(p); 52 (void)free(p);
58 return(rval); 53 return (rval);
59} 54}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
index cb1e052191..093212edf5 100644
--- a/src/lib/libc/stdlib/qabs.3
+++ b/src/lib/libc/stdlib/qabs.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qabs.3,v 1.6 2003/06/02 20:18:38 millert Exp $
37.\" $Id: qabs.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt QABS 3 35.Dt QABS 3
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qabs 46.Fn qabs
52function 47function returns the absolute value of the quad integer
53returns the absolute value of the quad integer 48.Fa j .
54.Ar j .
55.Sh SEE ALSO 49.Sh SEE ALSO
56.Xr abs 3 , 50.Xr abs 3 ,
57.Xr labs 3 ,
58.Xr floor 3 ,
59.Xr cabs 3 , 51.Xr cabs 3 ,
52.Xr floor 3 ,
53.Xr labs 3 ,
60.Xr math 3 54.Xr math 3
61.Sh BUGS 55.Sh BUGS
62The absolute value of the most negative integer remains negative. 56The 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
index 9c51a8baa9..296d2d4742 100644
--- a/src/lib/libc/stdlib/qabs.c
+++ b/src/lib/libc/stdlib/qabs.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/ 31static char *rcsid = "$OpenBSD: qabs.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: qabs.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
index 0efcfc96ef..5f17ec17d4 100644
--- a/src/lib/libc/stdlib/qdiv.3
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qdiv.3,v 1.6 2004/01/23 23:08:46 jmc Exp $
37.\" $Id: qdiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt QDIV 3 35.Dt QDIV 3
@@ -49,17 +44,16 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qdiv 46.Fn qdiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar qdiv_t 50.Li qdiv_t
57that contains two 51that contains two
58.Em quad integer 52.Li quad integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
65.Xr ldiv 3 , 59.Xr ldiv 3 ,
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
index 8f8e3f89c4..6688ccb712 100644
--- a/src/lib/libc/stdlib/qdiv.c
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/ 34static char *rcsid = "$OpenBSD: qdiv.c,v 1.3 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: qdiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <stdlib.h> /* qdiv_t */ 37#include <stdlib.h> /* qdiv_t */
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
index eb122cde12..668ea90243 100644
--- a/src/lib/libc/stdlib/qsort.3
+++ b/src/lib/libc/stdlib/qsort.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,15 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)qsort.3 8.1 (Berkeley) 6/4/93 32.\" $OpenBSD: qsort.3,v 1.14 2003/10/01 08:11:58 jmc Exp $
37.\" $Id: qsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 4, 1993 34.Dd June 4, 1993
40.Dt QSORT 3 35.Dt QSORT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm qsort, heapsort, mergesort 38.Nm qsort ,
39.Nm heapsort ,
40.Nm mergesort
44.Nd sort functions 41.Nd sort functions
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
@@ -72,7 +69,7 @@ objects, the initial member of which is pointed to by
72.Fa base . 69.Fa base .
73The size of each object is specified by 70The size of each object is specified by
74.Fa size . 71.Fa size .
75.Fn Mergesort 72.Fn mergesort
76behaves similarly, but 73behaves similarly, but
77.Em requires 74.Em requires
78that 75that
@@ -106,51 +103,49 @@ is stable.
106.Pp 103.Pp
107The 104The
108.Fn qsort 105.Fn qsort
109function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm, 106function is an implementation of C.A.R. Hoare's
107.Dq quicksort
108algorithm,
110a variant of partition-exchange sorting; in particular, see D.E. Knuth's 109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
111Algorithm Q. 110Algorithm Q.
112.Fn Qsort 111.Fn qsort
113takes O N lg N average time. 112takes O N lg N average time.
114This implementation uses median selection to avoid its 113This implementation uses median selection to avoid its
115O N**2 worst-case behavior. 114O N**2 worst-case behavior.
116.Pp 115.Pp
117The 116The
118.Fn heapsort 117.Fn heapsort
119function is an implementation of J.W.J. William's ``heapsort'' algorithm, 118function is an implementation of J.W.J. William's
119.Dq heapsort
120algorithm,
120a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. 121a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
121.Fn Heapsort 122.Fn heapsort
122takes O N lg N worst-case time. 123takes O N lg N worst-case time.
123Its 124This implementation of
124.Em only 125.Fn heapsort
125advantage over 126is implemented without recursive function calls.
126.Fn qsort
127is that it uses almost no additional memory; while
128.Fn qsort
129does not allocate memory, it is implemented using recursion.
130.Pp 127.Pp
131The function 128The function
132.Fn mergesort 129.Fn mergesort
133requires additional memory of size 130requires additional memory of size
134.Fa nmemb * 131.Fa nmemb *
135.Fa size 132.Fa size
136bytes; it should be used only when space is not at a premium. 133bytes; it should be used only when space is not at a premium.
137.Fn Mergesort 134.Fn mergesort
138is optimized for data with pre-existing order; its worst case 135is optimized for data with pre-existing order; its worst case
139time is O N lg N; its best case is O N. 136time is O N lg N; its best case is O N.
140.Pp 137.Pp
141Normally, 138Normally,
142.Fn qsort 139.Fn qsort
143is faster than 140is faster than
144.Fn mergesort 141.Fn mergesort ,
145is faster than 142which is faster than
146.Fn heapsort . 143.Fn heapsort .
147Memory availability and pre-existing order in the data can make this 144Memory availability and pre-existing order in the data can make this untrue.
148untrue.
149.Sh RETURN VALUES 145.Sh RETURN VALUES
150The 146The
151.Fn qsort 147.Fn qsort
152function 148function returns no value.
153returns no value.
154.Pp 149.Pp
155Upon successful completion, 150Upon successful completion,
156.Fn heapsort 151.Fn heapsort
@@ -163,30 +158,25 @@ is set to indicate the error.
163.Sh ERRORS 158.Sh ERRORS
164The 159The
165.Fn heapsort 160.Fn heapsort
166function succeeds unless: 161and
162.Fn mergesort
163functions succeed unless:
167.Bl -tag -width Er 164.Bl -tag -width Er
168.It Bq Er EINVAL 165.It Bq Er EINVAL
169The 166The
170.Fa size 167.Fa size
171argument is zero, or, 168argument is zero, or the
172the
173.Fa size 169.Fa size
174argument to 170argument to
175.Fn mergesort 171.Fn mergesort
176is less than 172is less than
177.Dq "sizeof(void *) / 2" . 173.Dq "sizeof(void *) / 2" .
178.It Bq Er ENOMEM 174.It Bq Er ENOMEM
179.Fn Heapsort 175.Fn heapsort
180or 176or
181.Fn mergesort 177.Fn mergesort
182were unable to allocate memory. 178were unable to allocate memory.
183.El 179.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 180.Sh SEE ALSO
191.Xr sort 1 , 181.Xr sort 1 ,
192.Xr radixsort 3 182.Xr radixsort 3
@@ -204,7 +194,7 @@ This is no longer true.
204.%T "Heapsort" 194.%T "Heapsort"
205.%J "Communications of the ACM" 195.%J "Communications of the ACM"
206.%V 7:1 196.%V 7:1
207.%P pp. 347-348 197.%P pp. 347\-348
208.Re 198.Re
209.Rs 199.Rs
210.%A Knuth, D.E. 200.%A Knuth, D.E.
@@ -212,23 +202,32 @@ This is no longer true.
212.%B "The Art of Computer Programming" 202.%B "The Art of Computer Programming"
213.%V Vol. 3 203.%V Vol. 3
214.%T "Sorting and Searching" 204.%T "Sorting and Searching"
215.%P pp. 114-123, 145-149 205.%P pp. 114\-123, 145\-149
216.Re 206.Re
217.Rs 207.Rs
218.%A Mcilroy, P.M. 208.%A McIlroy, P.M.
219.%T "Optimistic Sorting and Information Theoretic Complexity" 209.%T "Optimistic Sorting and Information Theoretic Complexity"
220.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" 210.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
221.%V January 1992 211.%P pp. 467\-464
212.%D January 1993
222.Re 213.Re
223.Rs 214.Rs
224.%A Bentley, J.L. 215.%A Bentley, J.L.
216.%A McIlroy, M.D.
225.%T "Engineering a Sort Function" 217.%T "Engineering a Sort Function"
226.%J "bentley@research.att.com" 218.%J "Software \- Practice and Experience"
227.%V January 1992 219.%V Vol. 23(11)
220.%P pp. 1249\-1265
221.%D November 1993
228.Re 222.Re
229.Sh STANDARDS 223.Sh STANDARDS
224Previous versions of
225.Fn qsort
226did not permit the comparison routine itself to call
227.Fn qsort .
228This is no longer true.
229.Pp
230The 230The
231.Fn qsort 231.Fn qsort
232function 232function conforms to
233conforms to
234.St -ansiC . 233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
index c06bd54054..2a972c0eb0 100644
--- a/src/lib/libc/stdlib/qsort.c
+++ b/src/lib/libc/stdlib/qsort.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,15 +28,14 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char sccsid[] = "from: @(#)qsort.c 8.1 (Berkeley) 6/4/93";*/ 31static char *rcsid = "$OpenBSD: qsort.c,v 1.8 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: qsort.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
40#include <stdlib.h> 35#include <stdlib.h>
41 36
42static inline char *med3 __P((char *, char *, char *, int (*)())); 37static __inline char *med3(char *, char *, char *, int (*)());
43static inline void swapfunc __P((char *, char *, int, int)); 38static __inline void swapfunc(char *, char *, int, int);
44 39
45#define min(a, b) (a) < (b) ? a : b 40#define min(a, b) (a) < (b) ? a : b
46 41
@@ -61,12 +56,12 @@ static inline void swapfunc __P((char *, char *, int, int));
61#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 56#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
62 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 57 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
63 58
64static inline void 59static __inline void
65swapfunc(a, b, n, swaptype) 60swapfunc(a, b, n, swaptype)
66 char *a, *b; 61 char *a, *b;
67 int n, swaptype; 62 int n, swaptype;
68{ 63{
69 if(swaptype <= 1) 64 if (swaptype <= 1)
70 swapcode(long, a, b, n) 65 swapcode(long, a, b, n)
71 else 66 else
72 swapcode(char, a, b, n) 67 swapcode(char, a, b, n)
@@ -82,7 +77,7 @@ swapfunc(a, b, n, swaptype)
82 77
83#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) 78#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
84 79
85static inline char * 80static __inline char *
86med3(a, b, c, cmp) 81med3(a, b, c, cmp)
87 char *a, *b, *c; 82 char *a, *b, *c;
88 int (*cmp)(); 83 int (*cmp)();
@@ -93,27 +88,28 @@ med3(a, b, c, cmp)
93} 88}
94 89
95void 90void
96qsort(a, n, es, cmp) 91qsort(aa, n, es, cmp)
97 void *a; 92 void *aa;
98 size_t n, es; 93 size_t n, es;
99 int (*cmp)(); 94 int (*cmp)();
100{ 95{
101 char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 96 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
102 int d, r, swaptype, swap_cnt; 97 int d, r, swaptype, swap_cnt;
98 register char *a = aa;
103 99
104loop: SWAPINIT(a, es); 100loop: SWAPINIT(a, es);
105 swap_cnt = 0; 101 swap_cnt = 0;
106 if (n < 7) { 102 if (n < 7) {
107 for (pm = a + es; pm < (char *) a + n * es; pm += es) 103 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 104 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es) 105 pl -= es)
110 swap(pl, pl - es); 106 swap(pl, pl - es);
111 return; 107 return;
112 } 108 }
113 pm = a + (n / 2) * es; 109 pm = (char *)a + (n / 2) * es;
114 if (n > 7) { 110 if (n > 7) {
115 pl = a; 111 pl = (char *)a;
116 pn = a + (n - 1) * es; 112 pn = (char *)a + (n - 1) * es;
117 if (n > 40) { 113 if (n > 40) {
118 d = (n / 8) * es; 114 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp); 115 pl = med3(pl, pl + d, pl + 2 * d, cmp);
@@ -123,9 +119,9 @@ loop: SWAPINIT(a, es);
123 pm = med3(pl, pm, pn, cmp); 119 pm = med3(pl, pm, pn, cmp);
124 } 120 }
125 swap(a, pm); 121 swap(a, pm);
126 pa = pb = a + es; 122 pa = pb = (char *)a + es;
127 123
128 pc = pd = a + (n - 1) * es; 124 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) { 125 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) { 126 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) { 127 if (r == 0) {
@@ -151,14 +147,14 @@ loop: SWAPINIT(a, es);
151 pc -= es; 147 pc -= es;
152 } 148 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */ 149 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = a + es; pm < (char *) a + n * es; pm += es) 150 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 151 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es) 152 pl -= es)
157 swap(pl, pl - es); 153 swap(pl, pl - es);
158 return; 154 return;
159 } 155 }
160 156
161 pn = a + n * es; 157 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa); 158 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r); 159 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es); 160 r = min(pd - pc, pn - pd - es);
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
index a2af9f17a4..028837d4d1 100644
--- a/src/lib/libc/stdlib/radixsort.3
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,32 +25,33 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94 28.\" $OpenBSD: radixsort.3,v 1.9 2003/06/02 20:18:38 millert Exp $
33.\" $Id: radixsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\" 29.\"
35.Dd January 27, 1994 30.Dd January 27, 1994
36.Dt RADIXSORT 3 31.Dt RADIXSORT 3
37.Os 32.Os
38.Sh NAME 33.Sh NAME
39.Nm radixsort 34.Nm radixsort ,
35.Nm sradixsort
40.Nd radix sort 36.Nd radix sort
41.Sh SYNOPSIS 37.Sh SYNOPSIS
42.Fd #include <limits.h> 38.Fd #include <limits.h>
43.Fd #include <stdlib.h> 39.Fd #include <stdlib.h>
44.Ft int 40.Ft int
45.Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 41.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
46.Ft int 42.Ft int
47.Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 43.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
48.Sh DESCRIPTION 44.Sh DESCRIPTION
49The 45The
50.Fn radixsort 46.Fn radixsort
51and 47and
52.Fn sradixsort 48.Fn sradixsort
53functions 49functions are implementations of radix sort.
54are implementations of radix sort.
55.Pp 50.Pp
56These functions sort an array of pointers to byte strings, the initial 51These functions sort an array of
57member of which is referenced by 52.Fa nmemb
53pointers to byte strings.
54The initial member is referenced by
58.Fa base . 55.Fa base .
59The byte strings may contain any values; the end of each string 56The byte strings may contain any values; the end of each string
60is denoted by the user-specified value 57is denoted by the user-specified value
@@ -63,26 +60,24 @@ is denoted by the user-specified value
63Applications may specify a sort order by providing the 60Applications may specify a sort order by providing the
64.Fa table 61.Fa table
65argument. 62argument.
66If 63If non-null,
67.Pf non- Dv NULL ,
68.Fa table 64.Fa table
69must reference an array of 65must reference an array of
70.Dv UCHAR_MAX 66.Dv UCHAR_MAX
71+ 1 bytes which contains the sort 67+ 1 bytes which contains the sort weight of each possible byte value.
72weight of each possible byte value.
73The end-of-string byte must have a sort weight of 0 or 255 68The end-of-string byte must have a sort weight of 0 or 255
74(for sorting in reverse order). 69(for sorting in reverse order).
75More than one byte may have the same sort weight. 70More than one byte may have the same sort weight.
76The 71The
77.Fa table 72.Fa table
78argument 73argument is useful for applications which wish to sort different characters
79is useful for applications which wish to sort different characters
80equally, for example, providing a table with the same weights 74equally, for example, providing a table with the same weights
81for A-Z as for a-z will result in a case-insensitive sort. 75for A-Z as for a-z will result in a case-insensitive sort.
82If 76If
83.Fa table 77.Fa table
84is NULL, the contents of the array are sorted in ascending order 78is
85according to the 79.Dv NULL ,
80the contents of the array are sorted in ascending order according to the
86.Tn ASCII 81.Tn ASCII
87order of the byte strings they reference and 82order of the byte strings they reference and
88.Fa endbyte 83.Fa endbyte
@@ -90,7 +85,7 @@ has a sorting weight of 0.
90.Pp 85.Pp
91The 86The
92.Fn sradixsort 87.Fn sradixsort
93function is stable, that is, if two elements compare as equal, their 88function is stable; that is, if two elements compare as equal, their
94order in the sorted array is unchanged. 89order in the sorted array is unchanged.
95The 90The
96.Fn sradixsort 91.Fn sradixsort
@@ -107,7 +102,7 @@ particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
107They take linear time relative to the number of bytes in the strings. 102They take linear time relative to the number of bytes in the strings.
108.Sh RETURN VALUES 103.Sh RETURN VALUES
109Upon successful completion 0 is returned. 104Upon successful completion 0 is returned.
110Otherwise, \-1 is returned and the global variable 105Otherwise, \-1 is returned and the global variable
111.Va errno 106.Va errno
112is set to indicate the error. 107is set to indicate the error.
113.Sh ERRORS 108.Sh ERRORS
@@ -122,15 +117,13 @@ is not 0 or 255.
122.Pp 117.Pp
123Additionally, the 118Additionally, the
124.Fn sradixsort 119.Fn sradixsort
125function 120function may fail and set
126may fail and set
127.Va errno 121.Va errno
128for any of the errors specified for the library routine 122for any of the errors specified for the library routine
129.Xr malloc 3 . 123.Xr malloc 3 .
130.Sh SEE ALSO 124.Sh SEE ALSO
131.Xr sort 1 , 125.Xr sort 1 ,
132.Xr qsort 3 126.Xr qsort 3
133.Pp
134.Rs 127.Rs
135.%A Knuth, D.E. 128.%A Knuth, D.E.
136.%D 1968 129.%D 1968
@@ -158,4 +151,5 @@ for any of the errors specified for the library routine
158.Sh HISTORY 151.Sh HISTORY
159The 152The
160.Fn radixsort 153.Fn radixsort
161function first appeared in 4.4BSD. 154function first appeared in
155.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
index dd51013c94..1ff30416d9 100644
--- a/src/lib/libc/stdlib/radixsort.c
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)radixsort.c 8.1 (Berkeley) 6/4/93";*/ 34static char *rcsid = "$OpenBSD: radixsort.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
39static char *rcsid = "$Id: radixsort.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42/* 37/*
@@ -61,11 +56,11 @@ typedef struct {
61 int sn, si; 56 int sn, si;
62} stack; 57} stack;
63 58
64static inline void simplesort 59static __inline void simplesort
65 __P((const u_char **, int, int, const u_char *, u_int)); 60(const u_char **, int, int, const u_char *, u_int);
66static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); 61static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
67static void r_sort_b __P((const u_char **, 62static void r_sort_b(const u_char **,
68 const u_char **, int, int, const u_char *, u_int)); 63 const u_char **, int, int, const u_char *, u_int);
69 64
70#define THRESHOLD 20 /* Divert to simplesort(). */ 65#define THRESHOLD 20 /* Divert to simplesort(). */
71#define SIZE 512 /* Default stack size. */ 66#define SIZE 512 /* Default stack size. */
@@ -295,7 +290,7 @@ r_sort_b(a, ta, n, i, tr, endch)
295 } 290 }
296} 291}
297 292
298static inline void 293static __inline void
299simplesort(a, n, b, tr, endch) /* insertion sort */ 294simplesort(a, n, b, tr, endch) /* insertion sort */
300 register const u_char **a; 295 register const u_char **a;
301 int n, b; 296 int n, b;
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
index a0e7740e66..0d9c52a3b9 100644
--- a/src/lib/libc/stdlib/rand.3
+++ b/src/lib/libc/stdlib/rand.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)rand.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: rand.3,v 1.9 2003/06/02 20:18:38 millert Exp $
37.\" $Id: rand.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt RAND 3 35.Dt RAND 3
@@ -46,12 +41,15 @@
46.Sh SYNOPSIS 41.Sh SYNOPSIS
47.Fd #include <stdlib.h> 42.Fd #include <stdlib.h>
48.Ft void 43.Ft void
49.Fn srand "unsigned seed" 44.Fn srand "unsigned int seed"
50.Ft int 45.Ft int
51.Fn rand void 46.Fn rand void
47.Ft int
48.Fn rand_r "unsigned int *seed"
52.Sh DESCRIPTION 49.Sh DESCRIPTION
53.Bf -symbolic 50.Bf -symbolic
54These interfaces are obsoleted by random(3). 51These interfaces are obsoleted by
52.Xr random 3 .
55.Ef 53.Ef
56.Pp 54.Pp
57The 55The
@@ -73,13 +71,28 @@ with the same seed value.
73.Pp 71.Pp
74If no seed value is provided, the functions are automatically 72If no seed value is provided, the functions are automatically
75seeded with a value of 1. 73seeded with a value of 1.
74.Pp
75The
76.Fn rand_r
77is a thread-safe version of
78.Fn rand .
79Storage for the seed must be provided through the
80.Fa seed
81argument, and needs to have been initialized by the caller.
76.Sh SEE ALSO 82.Sh SEE ALSO
83.Xr arc4random 3 ,
84.Xr rand48 3 ,
77.Xr random 3 85.Xr random 3
78.Sh STANDARDS 86.Sh STANDARDS
79The 87The
80.Fn rand 88.Fn rand
81and 89and
82.Fn srand 90.Fn srand
83functions 91functions conform to
84conform to
85.St -ansiC . 92.St -ansiC .
93.Pp
94The
95.Fn rand_r
96function conforms to ISO/IEC 9945-1 ANSI/IEEE
97.Pq Dq Tn POSIX
98Std 1003.1c Draft 10.
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
index 361d473448..d58d040ad5 100644
--- a/src/lib/libc/stdlib/rand.c
+++ b/src/lib/libc/stdlib/rand.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,24 +28,34 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)rand.c 5.6 (Berkeley) 6/24/91";*/ 31static char *rcsid = "$OpenBSD: rand.c,v 1.7 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: rand.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
40#include <stdlib.h> 35#include <stdlib.h>
41 36
42static u_long next = 1; 37static u_int next = 1;
38
39int
40rand_r(seed)
41u_int *seed;
42{
43
44 *seed = *seed * 1103515245 + 12345;
45 return (*seed % ((u_int)RAND_MAX + 1));
46}
43 47
44int 48int
45rand() 49rand()
46{ 50{
47 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1)); 51
52 return (rand_r(&next));
48} 53}
49 54
50void 55void
51srand(seed) 56srand(seed)
52u_int seed; 57u_int seed;
53{ 58{
59
54 next = seed; 60 next = seed;
55} 61}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
index 5a772c9a8c..78cd0a7cd5 100644
--- a/src/lib/libc/stdlib/rand48.3
+++ b/src/lib/libc/stdlib/rand48.3
@@ -1,4 +1,4 @@
1\" Copyright (c) 1993 Martin Birgmeier 1.\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved. 2.\" All rights reserved.
3.\" 3.\"
4.\" You may redistribute unmodified or modified versions of this source 4.\" You may redistribute unmodified or modified versions of this source
@@ -9,7 +9,7 @@
9.\" of any kind. I shall in no event be liable for anything that happens 9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software. 10.\" to anyone/anything when using this software.
11.\" 11.\"
12.\" $Id: rand48.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $ 12.\" $OpenBSD: rand48.3,v 1.10 2003/06/01 19:27:27 jmc Exp $
13.\" 13.\"
14.Dd October 8, 1993 14.Dd October 8, 1993
15.Dt RAND48 3 15.Dt RAND48 3
@@ -24,10 +24,10 @@
24.Nm srand48 , 24.Nm srand48 ,
25.Nm seed48 , 25.Nm seed48 ,
26.Nm lcong48 26.Nm lcong48
27.Nd pseudo random number generators and initialization routines 27.Nd pseudo-random number generators and initialization routines
28.Sh SYNOPSIS 28.Sh SYNOPSIS
29.Fd #include <stdlib.h> 29.Fd #include <stdlib.h>
30.Ft double 30.Ft double
31.Fn drand48 void 31.Fn drand48 void
32.Ft double 32.Ft double
33.Fn erand48 "unsigned short xseed[3]" 33.Fn erand48 "unsigned short xseed[3]"
@@ -49,12 +49,13 @@
49The 49The
50.Fn rand48 50.Fn rand48
51family of functions generates pseudo-random numbers using a linear 51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size. The 52congruential algorithm working on integers 48 bits in size.
53particular formula employed is 53The particular formula employed is
54r(n+1) = (a * r(n) + c) mod m 54r(n+1) = (a * r(n) + c) mod m
55where the default values are 55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and 56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48. 57the addend c = 0xb = 11.
58The modulus is always fixed at m = 2 ** 48.
58r(n) is called the seed of the random number generator. 59r(n) is called the seed of the random number generator.
59.Pp 60.Pp
60For all the six generator routines described next, the first 61For all the six generator routines described next, the first
@@ -63,15 +64,17 @@ computational step is to perform a single iteration of the algorithm.
63.Fn drand48 64.Fn drand48
64and 65and
65.Fn erand48 66.Fn erand48
66return values of type double. The full 48 bits of r(n+1) are 67return values of type double.
68The full 48 bits of r(n+1) are
67loaded into the mantissa of the returned value, with the exponent set 69loaded into the mantissa of the returned value, with the exponent set
68such that the values produced lie in the interval [0.0, 1.0). 70such that the values produced lie in the interval [0.0, 1.0].
69.Pp 71.Pp
70.Fn lrand48 72.Fn lrand48
71and 73and
72.Fn nrand48 74.Fn nrand48
73return values of type long in the range 75return values of type long in the range
74[0, 2**31-1]. The high-order (31) bits of 76[0, 2**31-1].
77The high-order (31) bits of
75r(n+1) are loaded into the lower bits of the returned value, with 78r(n+1) are loaded into the lower bits of the returned value, with
76the topmost (sign) bit set to zero. 79the topmost (sign) bit set to zero.
77.Pp 80.Pp
@@ -79,14 +82,15 @@ the topmost (sign) bit set to zero.
79and 82and
80.Fn jrand48 83.Fn jrand48
81return values of type long in the range 84return values of type long in the range
82[-2**31, 2**31-1]. The high-order (32) bits of 85[-2**31, 2**31-1].
83r(n+1) are loaded into the returned value. 86The high-order (32) bits of r(n+1) are loaded into the returned value.
84.Pp 87.Pp
85.Fn drand48 , 88.Fn drand48 ,
86.Fn lrand48 , 89.Fn lrand48 ,
87and 90and
88.Fn mrand48 91.Fn mrand48
89use an internal buffer to store r(n). For these functions 92use an internal buffer to store r(n).
93For these functions
90the initial value of r(0) = 0x1234abcd330e = 20017429951246. 94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
91.Pp 95.Pp
92On the other hand, 96On the other hand,
@@ -118,12 +122,12 @@ also initializes the internal buffer r(n) of
118and 122and
119.Fn mrand48 , 123.Fn mrand48 ,
120but here all 48 bits of the seed can be specified in an array of 3 shorts, 124but here all 48 bits of the seed can be specified in an array of 3 shorts,
121where the zeroth member specifies the lowest bits. Again, 125where the zeroth member specifies the lowest bits.
122the constant multiplicand and addend of the algorithm are 126Again, the constant multiplicand and addend of the algorithm are
123reset to the default values given above. 127reset to the default values given above.
124.Fn seed48 128.Fn seed48
125returns a pointer to an array of 3 shorts which contains the old seed. 129returns a pointer to an array of 3 shorts which contains the old seed.
126This array is statically allocated, thus its contents are lost after 130This array is statically allocated, so its contents are lost after
127each new call to 131each new call to
128.Fn seed48 . 132.Fn seed48 .
129.Pp 133.Pp
@@ -152,9 +156,10 @@ always also set the multiplicand and addend for any of the six
152generator calls. 156generator calls.
153.Pp 157.Pp
154For a more powerful random number generator, see 158For a more powerful random number generator, see
155.Xr random 3 159.Xr random 3 .
156.Sh AUTHOR
157Martin Birgmeier
158.Sh SEE ALSO 160.Sh SEE ALSO
161.Xr arc4random 3 ,
159.Xr rand 3 , 162.Xr rand 3 ,
160.Xr random 3 . 163.Xr random 3
164.Sh AUTHORS
165Martin Birgmeier
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
index 12496d1c8c..afa49f65f3 100644
--- a/src/lib/libc/stdlib/rand48.h
+++ b/src/lib/libc/stdlib/rand48.h
@@ -9,6 +9,8 @@
9 * This software is provided ``as is'', and comes with no warranties 9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens 10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
12 */ 14 */
13 15
14#ifndef _RAND48_H_ 16#ifndef _RAND48_H_
@@ -17,7 +19,7 @@
17#include <math.h> 19#include <math.h>
18#include <stdlib.h> 20#include <stdlib.h>
19 21
20void __dorand48 __P((unsigned short[3])); 22void __dorand48(unsigned short[3]);
21 23
22#define RAND48_SEED_0 (0x330e) 24#define RAND48_SEED_0 (0x330e)
23#define RAND48_SEED_1 (0xabcd) 25#define RAND48_SEED_1 (0xabcd)
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
index 38c15a9803..f43f06420d 100644
--- a/src/lib/libc/stdlib/random.3
+++ b/src/lib/libc/stdlib/random.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
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 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,97 +25,106 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)random.3 6.5 (Berkeley) 4/19/91 28.\" $OpenBSD: random.3,v 1.17 2003/06/02 20:18:38 millert Exp $
33.\" $Id: random.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\" 29.\"
35.Dd April 19, 1991 30.Dd April 19, 1991
36.Dt RANDOM 3 31.Dt RANDOM 3
37.Os BSD 4.2 32.Os
38.Sh NAME 33.Sh NAME
39.Nm random , 34.Nm random ,
40.Nm srandom , 35.Nm srandom ,
36.Nm srandomdev ,
41.Nm initstate , 37.Nm initstate ,
42.Nm setstate 38.Nm setstate
43.Nd better random number generator; routines for changing generators 39.Nd better random number generator; routines for changing generators
44.Sh SYNOPSIS 40.Sh SYNOPSIS
45.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
46.Ft long 42.Ft long
47.Fn random void 43.Fn random void
48.Ft void 44.Ft void
49.Fn srandom "unsigned seed" 45.Fn srandom "unsigned int seed"
46.Ft void
47.Fn srandomdev void
50.Ft char * 48.Ft char *
51.Fn initstate "unsigned seed" "char *state" "int n" 49.Fn initstate "unsigned int seed" "char *state" "size_t n"
52.Ft char * 50.Ft char *
53.Fn setstate "char *state" 51.Fn setstate "const char *state"
54.Sh DESCRIPTION 52.Sh DESCRIPTION
55The 53The
56.Fn random 54.Fn random
57function 55function uses a non-linear additive feedback random number generator employing
58uses a non-linear additive feedback random number generator employing a 56a default table of size 31 long integers to return successive pseudo-random
59default table of size 31 long integers to return successive pseudo-random 57numbers in the range from 0 to (2**31)\-1.
60numbers in the range from 0 to
61.if t 2\u\s731\s10\d\(mi1.
62.if n (2**31)\(mi1.
63The period of this random number generator is very large, approximately 58The period of this random number generator is very large, approximately
64.if t 16\(mu(2\u\s731\s10\d\(mi1). 5916*((2**31)\-1).
65.if n 16*((2**31)\(mi1).
66.Pp 60.Pp
67The 61The
68.Fn random Ns / Fn srandom 62.Fn random
69have (almost) the same calling sequence and initialization properties as 63and
70.Xr rand 3 Ns / Xr srand 3 . 64.Fn srandom
65functions have (almost) the same calling sequence and initialization
66properties as
67.Xr rand 3 Ns / Ns Xr srand 3 .
71The difference is that 68The difference is that
72.Xr rand 69.Xr rand
73produces a much less random sequence \(em in fact, the low dozen bits 70produces a much less random sequence \(em in fact, the low dozen bits
74generated by rand go through a cyclic pattern. All the bits generated by 71generated by rand go through a cyclic pattern.
72All the bits generated by
75.Fn random 73.Fn random
76are usable. For example, 74are usable.
75For example,
77.Sq Li random()&01 76.Sq Li random()&01
78will produce a random binary 77will produce a random binary
79value. 78value.
80.Pp 79.Pp
81Unlike 80Like
82.Xr srand ,
83.Fn srandom
84does not return the old seed; the reason for this is that the amount of
85state information used is much more than a single word. (Two other
86routines are provided to deal with restarting/changing random
87number generators). Like
88.Xr rand 3 , 81.Xr rand 3 ,
89however,
90.Fn random 82.Fn random
91will by default produce a sequence of numbers that can be duplicated 83will by default produce a sequence of numbers that can be duplicated
92by calling 84by calling
93.Fn srandom 85.Fn srandom
94with 86with
95.Ql 1 87.Ql 1
96as the seed. 88as the seed.
97.Pp 89.Pp
98The 90The
91.Fn srandomdev
92routine initializes a state array using the
93.Xr arandom 4
94random number device which returns good random numbers,
95suitable for cryptographic use.
96Note that this particular seeding procedure can generate
97states which are impossible to reproduce by calling
98.Fn srandom
99with any value, since the succeeding terms in the
100state buffer are no longer derived from the LC algorithm applied to
101a fixed seed.
102.Pp
103The
99.Fn initstate 104.Fn initstate
100routine allows a state array, passed in as an argument, to be initialized 105routine allows a state array, passed in as an argument, to be initialized
101for future use. The size of the state array (in bytes) is used by 106for future use.
107The size of the state array (in bytes) is used by
102.Fn initstate 108.Fn initstate
103to decide how sophisticated a random number generator it should use \(em the 109to decide how sophisticated a random number generator it should use \(em the
104more state, the better the random numbers will be. 110more state, the better the random numbers will be.
105(Current "optimal" values for the amount of state information are 111(Current "optimal" values for the amount of state information are
1068, 32, 64, 128, and 256 bytes; other amounts will be rounded down to 1128, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
107the nearest known amount. Using less than 8 bytes will cause an error.) 113the nearest known amount.
114Using less than 8 bytes will cause an error.)
108The seed for the initialization (which specifies a starting point for 115The seed for the initialization (which specifies a starting point for
109the random number sequence, and provides for restarting at the same 116the random number sequence, and provides for restarting at the same
110point) is also an argument. 117point) is also an argument.
111The 118The
112.Fn initstate 119.Fn initstate
113function 120function returns a pointer to the previous state information array.
114returns a pointer to the previous state information array.
115.Pp 121.Pp
116Once a state has been initialized, the 122Once a state has been initialized, the
117.Fn setstate 123.Fn setstate
118routine provides for rapid switching between states. 124routine provides for rapid switching between states.
119The 125The
120.Fn setstate 126.Fn setstate
121function 127function returns a pointer to the previous state array; its
122returns a pointer to the previous state array; its
123argument state array is used for further random number generation 128argument state array is used for further random number generation
124until the next call to 129until the next call to
125.Fn initstate 130.Fn initstate
@@ -143,12 +148,8 @@ is that the size of the state array does not have to be remembered after
143it is initialized. 148it is initialized.
144.Pp 149.Pp
145With 256 bytes of state information, the period of the random number 150With 256 bytes of state information, the period of the random number
146generator is greater than 151generator is greater than 2**69
147.if t 2\u\s769\s10\d,
148.if n 2**69
149which should be sufficient for most purposes. 152which should be sufficient for most purposes.
150.Sh AUTHOR
151Earl T. Cohen
152.Sh DIAGNOSTICS 153.Sh DIAGNOSTICS
153If 154If
154.Fn initstate 155.Fn initstate
@@ -157,11 +158,29 @@ is called with less than 8 bytes of state information, or if
157detects that the state information has been garbled, error 158detects that the state information has been garbled, error
158messages are printed on the standard error output. 159messages are printed on the standard error output.
159.Sh SEE ALSO 160.Sh SEE ALSO
160.Xr rand 3 161.Xr arc4random 3 ,
162.Xr drand48 3 ,
163.Xr rand 3 ,
164.Xr random 4
165.Sh STANDARDS
166The
167.Fn random ,
168.Fn srandom ,
169.Fn initstate ,
170and
171.Fn setstate
172functions conform to
173.St -xpg4.2 .
174.Pp
175The
176.Fn srandomdev
177function is an extension.
161.Sh HISTORY 178.Sh HISTORY
162These 179These
163functions appeared in 180functions appeared in
164.Bx 4.2 . 181.Bx 4.2 .
182.Sh AUTHORS
183.An Earl T. Cohen
165.Sh BUGS 184.Sh BUGS
166About 2/3 the speed of 185About 2/3 the speed of
167.Xr rand 3 . 186.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..4807d2f27d 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,12 +28,16 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: random.c,v 1.12 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
34#include <sys/param.h>
35#include <sys/sysctl.h>
36#include <sys/time.h>
37#include <fcntl.h>
39#include <stdio.h> 38#include <stdio.h>
40#include <stdlib.h> 39#include <stdlib.h>
40#include <unistd.h>
41 41
42/* 42/*
43 * random.c: 43 * random.c:
@@ -55,10 +55,10 @@ static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
55 * congruential generator. If the amount of state information is less than 55 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 56 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 57 *
58 * Internally, the state information is treated as an array of longs; the 58 * Internally, the state information is treated as an array of int32_t; the
59 * zeroeth element of the array is the type of R.N.G. being used (small 59 * zeroeth element of the array is the type of R.N.G. being used (small
60 * integer); the remainder of the array is the state information for the 60 * integer); the remainder of the array is the state information for the
61 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of 61 * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of
62 * state information, which will allow a degree seven polynomial. (Note: 62 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 63 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 64 * stored in it -- see setstate() for details).
@@ -134,14 +134,14 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. 134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 135 */
136 136
137static long randtbl[DEG_3 + 1] = { 137static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 138 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 139 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 140 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 141 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 142 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 143 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 144 0xf3bec5da,
145}; 145};
146 146
147/* 147/*
@@ -158,8 +158,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 158 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 159 * to point to randtbl[1] (as explained below).
160 */ 160 */
161static long *fptr = &randtbl[SEP_3 + 1]; 161static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 162static int32_t *rptr = &randtbl[1];
163 163
164/* 164/*
165 * The following things are the pointer to the state information table, the 165 * The following things are the pointer to the state information table, the
@@ -171,11 +171,11 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 171 * this is more efficient than indexing every time to find the address of
172 * the last element to see if the front and rear pointers have wrapped. 172 * the last element to see if the front and rear pointers have wrapped.
173 */ 173 */
174static long *state = &randtbl[1]; 174static int32_t *state = &randtbl[1];
175static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 176static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 177static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 178static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1];
179 179
180/* 180/*
181 * srandom: 181 * srandom:
@@ -191,17 +191,28 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
191 */ 191 */
192void 192void
193srandom(x) 193srandom(x)
194 u_int x; 194 unsigned int x;
195{ 195{
196 register int i, j; 196 int i;
197 int32_t test;
198 div_t val;
197 199
198 if (rand_type == TYPE_0) 200 if (rand_type == TYPE_0)
199 state[0] = x; 201 state[0] = x;
200 else { 202 else {
201 j = 1;
202 state[0] = x; 203 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 204 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 205 /*
206 * Implement the following, without overflowing 31 bits:
207 *
208 * state[i] = (16807 * state[i - 1]) % 2147483647;
209 *
210 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
211 */
212 val = div(state[i-1], 127773);
213 test = 16807 * val.rem - 2836 * val.quot;
214 state[i] = test + (test < 0 ? 2147483647 : 0);
215 }
205 fptr = &state[rand_sep]; 216 fptr = &state[rand_sep];
206 rptr = &state[0]; 217 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 218 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +221,65 @@ srandom(x)
210} 221}
211 222
212/* 223/*
224 * srandomdev:
225 *
226 * Many programs choose the seed value in a totally predictable manner.
227 * This often causes problems. We seed the generator using the much more
228 * secure arandom(4) interface. Note that this particular seeding
229 * procedure can generate states which are impossible to reproduce by
230 * calling srandom() with any value, since the succeeding terms in the
231 * state buffer are no longer derived from the LC algorithm applied to
232 * a fixed seed.
233 */
234void
235srandomdev()
236{
237 int fd, i, mib[2], n;
238 size_t len;
239
240 if (rand_type == TYPE_0)
241 len = sizeof(state[0]);
242 else
243 len = rand_deg * sizeof(state[0]);
244
245 /*
246 * To get seed data, first try reading from /dev/arandom.
247 * If that fails, try the KERN_ARND sysctl() (one int at a time).
248 * As a last resort, call srandom().
249 */
250 if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
251 read(fd, (void *) state, len) == (ssize_t) len) {
252 close(fd);
253 } else {
254 if (fd != -1)
255 close(fd);
256 mib[0] = CTL_KERN;
257 mib[1] = KERN_ARND;
258 n = len / sizeof(int);
259 len = sizeof(int);
260 for (i = 0; i < n; i++) {
261 if (sysctl(mib, 2, (char *)((int *)state + i), &len,
262 NULL, 0) == -1)
263 break;
264 }
265 if (i != n) {
266 struct timeval tv;
267 u_int junk;
268
269 /* XXX - this could be better */
270 gettimeofday(&tv, NULL);
271 srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
272 return;
273 }
274 }
275
276 if (rand_type != TYPE_0) {
277 fptr = &state[rand_sep];
278 rptr = &state[0];
279 }
280}
281
282/*
213 * initstate: 283 * initstate:
214 * 284 *
215 * Initialize the state information in the given array of n bytes for future 285 * Initialize the state information in the given array of n bytes for future
@@ -232,19 +302,16 @@ char *
232initstate(seed, arg_state, n) 302initstate(seed, arg_state, n)
233 u_int seed; /* seed for R.N.G. */ 303 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */ 304 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */ 305 size_t n; /* # bytes of state info */
236{ 306{
237 register char *ostate = (char *)(&state[-1]); 307 char *ostate = (char *)(&state[-1]);
238 308
239 if (rand_type == TYPE_0) 309 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 310 state[-1] = rand_type;
241 else 311 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 312 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 313 if (n < BREAK_0)
244 (void)fprintf(stderr, 314 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 315 if (n < BREAK_1) {
249 rand_type = TYPE_0; 316 rand_type = TYPE_0;
250 rand_deg = DEG_0; 317 rand_deg = DEG_0;
@@ -266,7 +333,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 333 rand_deg = DEG_4;
267 rand_sep = SEP_4; 334 rand_sep = SEP_4;
268 } 335 }
269 state = &(((long *)arg_state)[1]); /* first location */ 336 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 337 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 338 srandom(seed);
272 if (rand_type == TYPE_0) 339 if (rand_type == TYPE_0)
@@ -293,11 +360,11 @@ initstate(seed, arg_state, n)
293 */ 360 */
294char * 361char *
295setstate(arg_state) 362setstate(arg_state)
296 char *arg_state; 363 const char *arg_state;
297{ 364{
298 register long *new_state = (long *)arg_state; 365 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 366 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 367 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 368 char *ostate = (char *)(&state[-1]);
302 369
303 if (rand_type == TYPE_0) 370 if (rand_type == TYPE_0)
@@ -315,8 +382,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 382 rand_sep = seps[type];
316 break; 383 break;
317 default: 384 default:
318 (void)fprintf(stderr, 385 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 386 }
321 state = &new_state[1]; 387 state = &new_state[1];
322 if (rand_type != TYPE_0) { 388 if (rand_type != TYPE_0) {
@@ -347,7 +413,7 @@ setstate(arg_state)
347long 413long
348random() 414random()
349{ 415{
350 long i; 416 int32_t i;
351 417
352 if (rand_type == TYPE_0) 418 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 419 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +426,5 @@ random()
360 } else if (++rptr >= end_ptr) 426 } else if (++rptr >= end_ptr)
361 rptr = state; 427 rptr = state;
362 } 428 }
363 return(i); 429 return((long)i);
364} 430}
diff --git a/src/lib/libc/stdlib/realloc.3 b/src/lib/libc/stdlib/realloc.3
deleted file mode 100644
index 66f09b2081..0000000000
--- a/src/lib/libc/stdlib/realloc.3
+++ /dev/null
@@ -1,100 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" from: @(#)realloc.3 5.1 (Berkeley) 5/2/91
33.\" $Id: realloc.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt REALLOC 3
37.Os
38.Sh NAME
39.Nm realloc
40.Nd reallocation of memory function
41.Sh SYNOPSIS
42.Fd #include <stdlib.h>
43.Ft void *
44.Fn realloc "void *ptr" "size_t size"
45.Sh DESCRIPTION
46The
47.Fn realloc
48function changes the size of the object pointed to by
49.Fa ptr
50to the size specified by
51.Fa size .
52The contents of the object are unchanged up to the lesser
53of the new and old sizes.
54If the new size is larger, the value of the newly allocated portion
55of the object is indeterminate.
56If
57.Fa ptr
58is a null pointer, the
59.Fn realloc
60function behaves like the
61.Xr malloc 3
62function for the specified size.
63Otherwise, if
64.Fa ptr
65does not match a pointer earlier returned by the
66.Xr calloc 3 ,
67.Xr malloc 3 ,
68or
69.Fn realloc
70function, or if the space has been deallocated
71by a call to the
72.Xr free
73or
74.Fn realloc
75function, unpredictable and usually detrimental
76behavior will occur.
77If the space cannot be allocated, the object
78pointed to by
79.Fa ptr
80is unchanged.
81If
82.Fa size
83is zero and
84.Fa ptr
85is not a null pointer, the object it points to is freed.
86.Pp
87The
88.Fn realloc
89function returns either a null pointer or a pointer
90to the possibly moved allocated space.
91.Sh SEE ALSO
92.Xr alloca 3 ,
93.Xr calloc 3 ,
94.Xr free 3 ,
95.Xr malloc 3 ,
96.Sh STANDARDS
97The
98.Fn realloc
99function conforms to
100.St -ansiC .
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
index 9d8b1ff2ce..b8093b51e1 100644
--- a/src/lib/libc/stdlib/realpath.3
+++ b/src/lib/libc/stdlib/realpath.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
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 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,10 +28,9 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)realpath.3 8.2 (Berkeley) 2/16/94 31.\" $OpenBSD: realpath.3,v 1.10 2003/06/02 20:18:38 millert Exp $
36.\" $Id: realpath.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
37.\" 32.\"
38.Dd "February 16, 1994" 33.Dd February 16, 1994
39.Dt REALPATH 3 34.Dt REALPATH 3
40.Os 35.Os
41.Sh NAME 36.Sh NAME
@@ -57,8 +52,7 @@ and
57.Pa /../ 52.Pa /../
58in 53in
59.Fa pathname , 54.Fa pathname ,
60and copies the resulting absolute pathname into 55and copies the resulting absolute pathname into the memory referenced by
61the memory referenced by
62.Fa resolvedname . 56.Fa resolvedname .
63The 57The
64.Fa resolvedname 58.Fa resolvedname
@@ -68,7 +62,7 @@ refer to a buffer capable of storing at least
68.Dv MAXPATHLEN 62.Dv MAXPATHLEN
69characters. 63characters.
70.Pp 64.Pp
71The 65The
72.Fn realpath 66.Fn realpath
73function will resolve both absolute and relative paths 67function will resolve both absolute and relative paths
74and return the absolute pathname corresponding to 68and return the absolute pathname corresponding to
@@ -78,18 +72,18 @@ All but the last component of
78must exist when 72must exist when
79.Fn realpath 73.Fn realpath
80is called. 74is called.
81.Sh "RETURN VALUES" 75.Sh RETURN VALUES
82The 76The
83.Fn realpath 77.Fn realpath
84function returns 78function returns
85.Fa resolved_name 79.Fa resolvedname
86on success. 80on success.
87If an error occurs, 81If an error occurs,
88.Fn realpath 82.Fn realpath
89returns 83returns
90.Dv NULL , 84.Dv NULL ,
91and 85and
92.Fa resolved_name 86.Fa resolvedname
93contains the pathname which caused the problem. 87contains the pathname which caused the problem.
94.Sh ERRORS 88.Sh ERRORS
95The function 89The function
@@ -102,9 +96,16 @@ for any of the errors specified for the library functions
102.Xr fchdir 2 , 96.Xr fchdir 2 ,
103.Xr lstat 2 , 97.Xr lstat 2 ,
104.Xr open 2 , 98.Xr open 2 ,
105.Xr readlink 2 99.Xr readlink 2 ,
106and 100and
107.Xr getcwd 3 . 101.Xr getcwd 3 .
102.Sh SEE ALSO
103.Xr getcwd 3
104.Sh HISTORY
105The
106.Fn realpath
107function call first appeared in
108.Bx 4.4 .
108.Sh CAVEATS 109.Sh CAVEATS
109This implementation of 110This implementation of
110.Fn realpath 111.Fn realpath
@@ -114,13 +115,6 @@ The
114version always returns absolute pathnames, 115version always returns absolute pathnames,
115whereas the Solaris implementation will, 116whereas the Solaris implementation will,
116under certain circumstances, return a relative 117under certain circumstances, return a relative
117.Fa resolved_path 118.Fa resolvedname
118when given a relative 119when given a relative
119.Fa pathname . 120.Fa pathname .
120.Sh "SEE ALSO"
121.Xr getcwd 3
122.Sh HISTORY
123The
124.Fn realpath
125function call first appeared in
126.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index e349b7e068..1525d0372f 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -13,11 +13,7 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. Neither the name of the University nor the names of its contributors
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 17 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 18 * without specific prior written permission.
23 * 19 *
@@ -35,8 +31,7 @@
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ 34static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $";
39static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 35#endif /* LIBC_SCCS and not lint */
41 36
42#include <sys/param.h> 37#include <sys/param.h>
@@ -61,15 +56,20 @@ realpath(path, resolved)
61 char *resolved; 56 char *resolved;
62{ 57{
63 struct stat sb; 58 struct stat sb;
64 int fd, n, rootd, serrno; 59 int fd, n, needslash, serrno;
65 char *p, *q, wbuf[MAXPATHLEN]; 60 char *p, *q, wbuf[MAXPATHLEN];
61 int symlinks = 0;
66 62
67 /* Save the starting point. */ 63 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) { 64 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strcpy(resolved, "."); 65 (void)strlcpy(resolved, ".", MAXPATHLEN);
70 return (NULL); 66 return (NULL);
71 } 67 }
72 68
69 /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
70 if (path[0] == '.' && path[1] == '\0')
71 path = "";
72
73 /* 73 /*
74 * Find the dirname and basename from the path to be resolved. 74 * Find the dirname and basename from the path to be resolved.
75 * Change directory to the dirname component. 75 * Change directory to the dirname component.
@@ -78,8 +78,7 @@ realpath(path, resolved)
78 * if it is a directory, then change to that directory. 78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename. 79 * get the current directory name and append the basename.
80 */ 80 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1); 81 strlcpy(resolved, path, MAXPATHLEN);
82 resolved[MAXPATHLEN - 1] = '\0';
83loop: 82loop:
84 q = strrchr(resolved, '/'); 83 q = strrchr(resolved, '/');
85 if (q != NULL) { 84 if (q != NULL) {
@@ -99,9 +98,13 @@ loop:
99 p = resolved; 98 p = resolved;
100 99
101 /* Deal with the last component. */ 100 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) { 101 if (*p != '\0' && lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) { 102 if (S_ISLNK(sb.st_mode)) {
104 n = readlink(p, resolved, MAXPATHLEN); 103 if (++symlinks > MAXSYMLINKS) {
104 errno = ELOOP;
105 goto err1;
106 }
107 n = readlink(p, resolved, MAXPATHLEN-1);
105 if (n < 0) 108 if (n < 0)
106 goto err1; 109 goto err1;
107 resolved[n] = '\0'; 110 resolved[n] = '\0';
@@ -118,7 +121,7 @@ loop:
118 * Save the last component name and get the full pathname of 121 * Save the last component name and get the full pathname of
119 * the current directory. 122 * the current directory.
120 */ 123 */
121 (void)strcpy(wbuf, p); 124 (void)strlcpy(wbuf, p, sizeof wbuf);
122 if (getcwd(resolved, MAXPATHLEN) == 0) 125 if (getcwd(resolved, MAXPATHLEN) == 0)
123 goto err1; 126 goto err1;
124 127
@@ -127,18 +130,18 @@ loop:
127 * happens if the last component is empty, or the dirname is root. 130 * happens if the last component is empty, or the dirname is root.
128 */ 131 */
129 if (resolved[0] == '/' && resolved[1] == '\0') 132 if (resolved[0] == '/' && resolved[1] == '\0')
130 rootd = 1; 133 needslash = 0;
131 else 134 else
132 rootd = 0; 135 needslash = 1;
133 136
134 if (*wbuf) { 137 if (*wbuf) {
135 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { 138 if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) {
136 errno = ENAMETOOLONG; 139 errno = ENAMETOOLONG;
137 goto err1; 140 goto err1;
138 } 141 }
139 if (rootd == 0) 142 if (needslash)
140 (void)strcat(resolved, "/"); 143 strlcat(resolved, "/", MAXPATHLEN);
141 (void)strcat(resolved, wbuf); 144 strlcat(resolved, wbuf, MAXPATHLEN);
142 } 145 }
143 146
144 /* Go back to where we came from. */ 147 /* Go back to where we came from. */
diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c
new file mode 100644
index 0000000000..f4c5769a8c
--- /dev/null
+++ b/src/lib/libc/stdlib/remque.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: remque.c,v 1.1 2003/05/08 23:26:30 millert Exp $ */
2
3/*
4 * Copyright (c) 1993 John Brezak
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. The name of the author may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: remque.c,v 1.1 2003/05/08 23:26:30 millert Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <search.h>
36
37struct qelem {
38 struct qelem *q_forw;
39 struct qelem *q_back;
40};
41
42void
43remque(void *element)
44{
45 struct qelem *e = (struct qelem *) element;
46 e->q_forw->q_back = e->q_back;
47 e->q_back->q_forw = e->q_forw;
48}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
index e3d31901dd..c4dcd0ead8 100644
--- a/src/lib/libc/stdlib/seed48.c
+++ b/src/lib/libc/stdlib/seed48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: seed48.c,v 1.2 1996/08/19 08:33:48 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..2ba072b65c 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,14 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ 31static char *rcsid = "$OpenBSD: setenv.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <stdlib.h> 34#include <stdlib.h>
40#include <string.h> 35#include <string.h>
41 36
37char *__findenv(const char *name, int *offset);
38
42/* 39/*
43 * setenv -- 40 * setenv --
44 * Set the value of the environmental variable "name" to be 41 * Set the value of the environmental variable "name" to be
@@ -54,7 +51,6 @@ setenv(name, value, rewrite)
54 static int alloced; /* if allocated space before */ 51 static int alloced; /* if allocated space before */
55 register char *C; 52 register char *C;
56 int l_value, offset; 53 int l_value, offset;
57 char *__findenv();
58 54
59 if (*value == '=') /* no `=' in value */ 55 if (*value == '=') /* no `=' in value */
60 ++value; 56 ++value;
@@ -63,7 +59,8 @@ setenv(name, value, rewrite)
63 if (!rewrite) 59 if (!rewrite)
64 return (0); 60 return (0);
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 61 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 62 while ((*C++ = *value++))
63 ;
67 return (0); 64 return (0);
68 } 65 }
69 } else { /* create new slot */ 66 } else { /* create new slot */
@@ -72,10 +69,11 @@ setenv(name, value, rewrite)
72 69
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 70 for (P = environ, cnt = 0; *P; ++P, ++cnt);
74 if (alloced) { /* just increase size */ 71 if (alloced) { /* just increase size */
75 environ = (char **)realloc((char *)environ, 72 P = (char **)realloc((void *)environ,
76 (size_t)(sizeof(char *) * (cnt + 2))); 73 (size_t)(sizeof(char *) * (cnt + 2)));
77 if (!environ) 74 if (!P)
78 return (-1); 75 return (-1);
76 environ = P;
79 } 77 }
80 else { /* get new space */ 78 else { /* get new space */
81 alloced = 1; /* copy old entries into it */ 79 alloced = 1; /* copy old entries into it */
@@ -95,7 +93,7 @@ setenv(name, value, rewrite)
95 return (-1); 93 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 94 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 95 ;
98 for (*C++ = '='; *C++ = *value++; ) 96 for (*C++ = '='; (*C++ = *value++); )
99 ; 97 ;
100 return (0); 98 return (0);
101} 99}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
index daf733f93e..fcff8a172e 100644
--- a/src/lib/libc/stdlib/srand48.c
+++ b/src/lib/libc/stdlib/srand48.c
@@ -11,6 +11,10 @@
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 */ 12 */
13 13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: srand48.c,v 1.2 1996/08/19 08:33:49 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
14#include "rand48.h" 18#include "rand48.h"
15 19
16extern unsigned short __rand48_seed[3]; 20extern unsigned short __rand48_seed[3];
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
index 0b7f973857..e25b0a5511 100644
--- a/src/lib/libc/stdlib/strtod.3
+++ b/src/lib/libc/stdlib/strtod.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtod.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strtod.3,v 1.8 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtod.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt STRTOD 3 35.Dt STRTOD 3
@@ -51,20 +46,25 @@ string to double
51.Sh DESCRIPTION 46.Sh DESCRIPTION
52The 47The
53.Fn strtod 48.Fn strtod
54function converts the initial portion of the string 49function converts the initial portion of the string pointed to by
55pointed to by
56.Fa nptr 50.Fa nptr
57to 51to
58.Em double 52.Li double
59representation. 53representation.
60.Pp 54.Pp
61The expected form of the string is an optional plus (``+'') or minus 55The expected form of the string is an optional plus
62sign (``-'') followed by a sequence of digits optionally containing 56.Pq Ql +
57or minus sign
58.Pq Ql -
59followed by a sequence of digits optionally containing
63a decimal-point character, optionally followed by an exponent. 60a decimal-point character, optionally followed by an exponent.
64An exponent consists of an ``E'' or ``e'', followed by an optional plus 61An exponent consists of an
65or minus sign, followed by a sequence of digits. 62.Sq E
63or
64.Sq e ,
65followed by an optional plus or minus sign, followed by a sequence of digits.
66.Pp 66.Pp
67Leading white-space characters in the string (as defined by the 67Leading whitespace characters in the string (as defined by the
68.Xr isspace 3 68.Xr isspace 3
69function) are skipped. 69function) are skipped.
70.Sh RETURN VALUES 70.Sh RETURN VALUES
@@ -88,18 +88,18 @@ is stored in the location referenced by
88If the correct value would cause overflow, plus or minus 88If the correct value would cause overflow, plus or minus
89.Dv HUGE_VAL 89.Dv HUGE_VAL
90is returned (according to the sign of the value), and 90is returned (according to the sign of the value), and
91.Dv ERANGE 91.Er ERANGE
92is stored in 92is stored in
93.Va errno . 93.Va errno .
94If the correct value would cause underflow, zero is 94If the correct value would cause underflow, zero is returned and
95returned and 95.Er ERANGE
96.Dv ERANGE 96is stored in
97is stored in
98.Va errno . 97.Va errno .
99.Sh ERRORS 98.Sh ERRORS
100.Bl -tag -width Er 99.Bl -tag -width Er
101.It Bq Er ERANGE 100.It Bq Er ERANGE
102Overflow or underflow occurred. 101Overflow or underflow occurred.
102.El
103.Sh SEE ALSO 103.Sh SEE ALSO
104.Xr atof 3 , 104.Xr atof 3 ,
105.Xr atoi 3 , 105.Xr atoi 3 ,
@@ -109,6 +109,5 @@ Overflow or underflow occurred.
109.Sh STANDARDS 109.Sh STANDARDS
110The 110The
111.Fn strtod 111.Fn strtod
112function 112function conforms to
113conforms to
114.St -ansiC . 113.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index b13fa128f5..8e839d6155 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -90,12 +90,14 @@
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 93static char *rcsid = "$OpenBSD: strtod.c,v 1.19 2004/02/03 16:52:11 drahn Exp $";
94#endif /* LIBC_SCCS and not lint */ 94#endif /* LIBC_SCCS and not lint */
95 95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) 97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98#include <machine/endian.h> 98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__) || \
99 defined(__x86_64__) || (defined(__arm__) && defined(__VFP_FP__))
100#include <sys/types.h>
99#if BYTE_ORDER == BIG_ENDIAN 101#if BYTE_ORDER == BIG_ENDIAN
100#define IEEE_BIG_ENDIAN 102#define IEEE_BIG_ENDIAN
101#else 103#else
@@ -103,7 +105,16 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
103#endif 105#endif
104#endif 106#endif
105 107
106#ifdef vax 108#if defined(__arm__) && !defined(__VFP_FP__)
109/*
110 * Although the CPU is little endian the FP has different
111 * byte and word endianness. The byte order is still little endian
112 * but the word order is big endian.
113 */
114#define IEEE_BIG_ENDIAN
115#endif
116
117#ifdef __vax__
107#define VAX 118#define VAX
108#endif 119#endif
109 120
@@ -143,7 +154,6 @@ extern void *MALLOC(size_t);
143#include "errno.h" 154#include "errno.h"
144 155
145#ifdef Bad_float_h 156#ifdef Bad_float_h
146#undef __STDC__
147#ifdef IEEE_BIG_ENDIAN 157#ifdef IEEE_BIG_ENDIAN
148#define IEEE_ARITHMETIC 158#define IEEE_ARITHMETIC
149#endif 159#endif
@@ -212,19 +222,24 @@ Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
212IBM should be defined. 222IBM should be defined.
213#endif 223#endif
214 224
225typedef union {
226 double d;
227 ULong ul[2];
228} _double;
229#define value(x) ((x).d)
215#ifdef IEEE_LITTLE_ENDIAN 230#ifdef IEEE_LITTLE_ENDIAN
216#define word0(x) ((ULong *)&x)[1] 231#define word0(x) ((x).ul[1])
217#define word1(x) ((ULong *)&x)[0] 232#define word1(x) ((x).ul[0])
218#else 233#else
219#define word0(x) ((ULong *)&x)[0] 234#define word0(x) ((x).ul[0])
220#define word1(x) ((ULong *)&x)[1] 235#define word1(x) ((x).ul[1])
221#endif 236#endif
222 237
223/* The following definition of Storeinc is appropriate for MIPS processors. 238/* The following definition of Storeinc is appropriate for MIPS processors.
224 * An alternative that might be better on some machines is 239 * An alternative that might be better on some machines is
225 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 240 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
226 */ 241 */
227#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) 242#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
228#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 243#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
229((unsigned short *)a)[0] = (unsigned short)c, a++) 244((unsigned short *)a)[0] = (unsigned short)c, a++)
230#else 245#else
@@ -380,7 +395,7 @@ Balloc
380 int x; 395 int x;
381 Bigint *rv; 396 Bigint *rv;
382 397
383 if (rv = freelist[k]) { 398 if ((rv = freelist[k])) {
384 freelist[k] = rv->next; 399 freelist[k] = rv->next;
385 } 400 }
386 else { 401 else {
@@ -628,7 +643,7 @@ mult
628 xc0 = c->x; 643 xc0 = c->x;
629#ifdef Pack_32 644#ifdef Pack_32
630 for(; xb < xbe; xb++, xc0++) { 645 for(; xb < xbe; xb++, xc0++) {
631 if (y = *xb & 0xffff) { 646 if ((y = *xb & 0xffff)) {
632 x = xa; 647 x = xa;
633 xc = xc0; 648 xc = xc0;
634 carry = 0; 649 carry = 0;
@@ -642,7 +657,7 @@ mult
642 while(x < xae); 657 while(x < xae);
643 *xc = carry; 658 *xc = carry;
644 } 659 }
645 if (y = *xb >> 16) { 660 if ((y = *xb >> 16)) {
646 x = xa; 661 x = xa;
647 xc = xc0; 662 xc = xc0;
648 carry = 0; 663 carry = 0;
@@ -693,7 +708,7 @@ pow5mult
693 int i; 708 int i;
694 static int p05[3] = { 5, 25, 125 }; 709 static int p05[3] = { 5, 25, 125 };
695 710
696 if (i = k & 3) 711 if ((i = k & 3))
697 b = multadd(b, p05[i-1], 0); 712 b = multadd(b, p05[i-1], 0);
698 713
699 if (!(k >>= 2)) 714 if (!(k >>= 2))
@@ -756,7 +771,7 @@ lshift
756 z = *x++ >> k1; 771 z = *x++ >> k1;
757 } 772 }
758 while(x < xe); 773 while(x < xe);
759 if (*x1 = z) 774 if ((*x1 = z))
760 ++n1; 775 ++n1;
761 } 776 }
762#else 777#else
@@ -899,14 +914,16 @@ diff
899 static double 914 static double
900ulp 915ulp
901#ifdef KR_headers 916#ifdef KR_headers
902 (x) double x; 917 (_x) double _x;
903#else 918#else
904 (double x) 919 (double _x)
905#endif 920#endif
906{ 921{
922 _double x;
907 register Long L; 923 register Long L;
908 double a; 924 _double a;
909 925
926 value(x) = _x;
910 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 927 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
911#ifndef Sudden_Underflow 928#ifndef Sudden_Underflow
912 if (L > 0) { 929 if (L > 0) {
@@ -931,7 +948,7 @@ ulp
931 } 948 }
932 } 949 }
933#endif 950#endif
934 return a; 951 return value(a);
935 } 952 }
936 953
937 static double 954 static double
@@ -944,7 +961,7 @@ b2d
944{ 961{
945 ULong *xa, *xa0, w, y, z; 962 ULong *xa, *xa0, w, y, z;
946 int k; 963 int k;
947 double d; 964 _double d;
948#ifdef VAX 965#ifdef VAX
949 ULong d0, d1; 966 ULong d0, d1;
950#else 967#else
@@ -1001,22 +1018,27 @@ b2d
1001#undef d0 1018#undef d0
1002#undef d1 1019#undef d1
1003#endif 1020#endif
1004 return d; 1021 return value(d);
1005 } 1022 }
1006 1023
1007 static Bigint * 1024 static Bigint *
1008d2b 1025d2b
1009#ifdef KR_headers 1026#ifdef KR_headers
1010 (d, e, bits) double d; int *e, *bits; 1027 (_d, e, bits) double d; int *e, *bits;
1011#else 1028#else
1012 (double d, int *e, int *bits) 1029 (double _d, int *e, int *bits)
1013#endif 1030#endif
1014{ 1031{
1015 Bigint *b; 1032 Bigint *b;
1016 int de, i, k; 1033 int de, i, k;
1017 ULong *x, y, z; 1034 ULong *x, y, z;
1035 _double d;
1018#ifdef VAX 1036#ifdef VAX
1019 ULong d0, d1; 1037 ULong d0, d1;
1038#endif
1039
1040 value(d) = _d;
1041#ifdef VAX
1020 d0 = word0(d) >> 16 | word0(d) << 16; 1042 d0 = word0(d) >> 16 | word0(d) << 16;
1021 d1 = word1(d) >> 16 | word1(d) << 16; 1043 d1 = word1(d) >> 16 | word1(d) << 16;
1022#else 1044#else
@@ -1141,11 +1163,11 @@ ratio
1141 (Bigint *a, Bigint *b) 1163 (Bigint *a, Bigint *b)
1142#endif 1164#endif
1143{ 1165{
1144 double da, db; 1166 _double da, db;
1145 int k, ka, kb; 1167 int k, ka, kb;
1146 1168
1147 da = b2d(a, &ka); 1169 value(da) = b2d(a, &ka);
1148 db = b2d(b, &kb); 1170 value(db) = b2d(b, &kb);
1149#ifdef Pack_32 1171#ifdef Pack_32
1150 k = ka - kb + 32*(a->wds - b->wds); 1172 k = ka - kb + 32*(a->wds - b->wds);
1151#else 1173#else
@@ -1171,7 +1193,7 @@ ratio
1171 word0(db) += k*Exp_msk1; 1193 word0(db) += k*Exp_msk1;
1172 } 1194 }
1173#endif 1195#endif
1174 return da / db; 1196 return value(da) / value(db);
1175 } 1197 }
1176 1198
1177static CONST double 1199static CONST double
@@ -1211,7 +1233,8 @@ strtod
1211 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1233 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1212 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1234 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1213 CONST char *s, *s0, *s1; 1235 CONST char *s, *s0, *s1;
1214 double aadj, aadj1, adj, rv, rv0; 1236 double aadj, aadj1, adj;
1237 _double rv, rv0;
1215 Long L; 1238 Long L;
1216 ULong y, z; 1239 ULong y, z;
1217 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1240 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@@ -1223,10 +1246,10 @@ strtod
1223#endif 1246#endif
1224 1247
1225 sign = nz0 = nz = 0; 1248 sign = nz0 = nz = 0;
1226 rv = 0.; 1249 value(rv) = 0.;
1227 1250
1228 1251
1229 for(s = s00; isspace(*s); s++) 1252 for(s = s00; isspace((unsigned char) *s); s++)
1230 ; 1253 ;
1231 1254
1232 if (*s == '-') { 1255 if (*s == '-') {
@@ -1340,9 +1363,9 @@ strtod
1340 if (!nd0) 1363 if (!nd0)
1341 nd0 = nd; 1364 nd0 = nd;
1342 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1365 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1343 rv = y; 1366 value(rv) = y;
1344 if (k > 9) 1367 if (k > 9)
1345 rv = tens[k - 9] * rv + z; 1368 value(rv) = tens[k - 9] * value(rv) + z;
1346 bd0 = 0; 1369 bd0 = 0;
1347 if (nd <= DBL_DIG 1370 if (nd <= DBL_DIG
1348#ifndef RND_PRODQUOT 1371#ifndef RND_PRODQUOT
@@ -1356,7 +1379,8 @@ strtod
1356#ifdef VAX 1379#ifdef VAX
1357 goto vax_ovfl_check; 1380 goto vax_ovfl_check;
1358#else 1381#else
1359 /* rv = */ rounded_product(rv, tens[e]); 1382 /* value(rv) = */ rounded_product(value(rv),
1383 tens[e]);
1360 goto ret; 1384 goto ret;
1361#endif 1385#endif
1362 } 1386 }
@@ -1366,27 +1390,30 @@ strtod
1366 * this for larger i values. 1390 * this for larger i values.
1367 */ 1391 */
1368 e -= i; 1392 e -= i;
1369 rv *= tens[i]; 1393 value(rv) *= tens[i];
1370#ifdef VAX 1394#ifdef VAX
1371 /* VAX exponent range is so narrow we must 1395 /* VAX exponent range is so narrow we must
1372 * worry about overflow here... 1396 * worry about overflow here...
1373 */ 1397 */
1374 vax_ovfl_check: 1398 vax_ovfl_check:
1375 word0(rv) -= P*Exp_msk1; 1399 word0(rv) -= P*Exp_msk1;
1376 /* rv = */ rounded_product(rv, tens[e]); 1400 /* value(rv) = */ rounded_product(value(rv),
1401 tens[e]);
1377 if ((word0(rv) & Exp_mask) 1402 if ((word0(rv) & Exp_mask)
1378 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1403 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1379 goto ovfl; 1404 goto ovfl;
1380 word0(rv) += P*Exp_msk1; 1405 word0(rv) += P*Exp_msk1;
1381#else 1406#else
1382 /* rv = */ rounded_product(rv, tens[e]); 1407 /* value(rv) = */ rounded_product(value(rv),
1408 tens[e]);
1383#endif 1409#endif
1384 goto ret; 1410 goto ret;
1385 } 1411 }
1386 } 1412 }
1387#ifndef Inaccurate_Divide 1413#ifndef Inaccurate_Divide
1388 else if (e >= -Ten_pmax) { 1414 else if (e >= -Ten_pmax) {
1389 /* rv = */ rounded_quotient(rv, tens[-e]); 1415 /* value(rv) = */ rounded_quotient(value(rv),
1416 tens[-e]);
1390 goto ret; 1417 goto ret;
1391 } 1418 }
1392#endif 1419#endif
@@ -1397,13 +1424,13 @@ strtod
1397 1424
1398 if (e1 > 0) { 1425 if (e1 > 0) {
1399 if (i = e1 & 15) 1426 if (i = e1 & 15)
1400 rv *= tens[i]; 1427 value(rv) *= tens[i];
1401 if (e1 &= ~15) { 1428 if (e1 &= ~15) {
1402 if (e1 > DBL_MAX_10_EXP) { 1429 if (e1 > DBL_MAX_10_EXP) {
1403 ovfl: 1430 ovfl:
1404 errno = ERANGE; 1431 errno = ERANGE;
1405#ifdef __STDC__ 1432#ifndef Bad_float_h
1406 rv = HUGE_VAL; 1433 value(rv) = HUGE_VAL;
1407#else 1434#else
1408 /* Can't trust HUGE_VAL */ 1435 /* Can't trust HUGE_VAL */
1409#ifdef IEEE_Arith 1436#ifdef IEEE_Arith
@@ -1421,10 +1448,10 @@ strtod
1421 if (e1 >>= 4) { 1448 if (e1 >>= 4) {
1422 for(j = 0; e1 > 1; j++, e1 >>= 1) 1449 for(j = 0; e1 > 1; j++, e1 >>= 1)
1423 if (e1 & 1) 1450 if (e1 & 1)
1424 rv *= bigtens[j]; 1451 value(rv) *= bigtens[j];
1425 /* The last multiplication could overflow. */ 1452 /* The last multiplication could overflow. */
1426 word0(rv) -= P*Exp_msk1; 1453 word0(rv) -= P*Exp_msk1;
1427 rv *= bigtens[j]; 1454 value(rv) *= bigtens[j];
1428 if ((z = word0(rv) & Exp_mask) 1455 if ((z = word0(rv) & Exp_mask)
1429 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1456 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1430 goto ovfl; 1457 goto ovfl;
@@ -1443,23 +1470,23 @@ strtod
1443 else if (e1 < 0) { 1470 else if (e1 < 0) {
1444 e1 = -e1; 1471 e1 = -e1;
1445 if (i = e1 & 15) 1472 if (i = e1 & 15)
1446 rv /= tens[i]; 1473 value(rv) /= tens[i];
1447 if (e1 &= ~15) { 1474 if (e1 &= ~15) {
1448 e1 >>= 4; 1475 e1 >>= 4;
1449 if (e1 >= 1 << n_bigtens) 1476 if (e1 >= 1 << n_bigtens)
1450 goto undfl; 1477 goto undfl;
1451 for(j = 0; e1 > 1; j++, e1 >>= 1) 1478 for(j = 0; e1 > 1; j++, e1 >>= 1)
1452 if (e1 & 1) 1479 if (e1 & 1)
1453 rv *= tinytens[j]; 1480 value(rv) *= tinytens[j];
1454 /* The last multiplication could underflow. */ 1481 /* The last multiplication could underflow. */
1455 rv0 = rv; 1482 value(rv0) = value(rv);
1456 rv *= tinytens[j]; 1483 value(rv) *= tinytens[j];
1457 if (!rv) { 1484 if (!value(rv)) {
1458 rv = 2.*rv0; 1485 value(rv) = 2.*value(rv0);
1459 rv *= tinytens[j]; 1486 value(rv) *= tinytens[j];
1460 if (!rv) { 1487 if (!value(rv)) {
1461 undfl: 1488 undfl:
1462 rv = 0.; 1489 value(rv) = 0.;
1463 errno = ERANGE; 1490 errno = ERANGE;
1464 if (bd0) 1491 if (bd0)
1465 goto retfree; 1492 goto retfree;
@@ -1483,7 +1510,7 @@ strtod
1483 for(;;) { 1510 for(;;) {
1484 bd = Balloc(bd0->k); 1511 bd = Balloc(bd0->k);
1485 Bcopy(bd, bd0); 1512 Bcopy(bd, bd0);
1486 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ 1513 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1487 bs = i2b(1); 1514 bs = i2b(1);
1488 1515
1489 if (e >= 0) { 1516 if (e >= 0) {
@@ -1595,12 +1622,12 @@ strtod
1595 break; 1622 break;
1596#endif 1623#endif
1597 if (dsign) 1624 if (dsign)
1598 rv += ulp(rv); 1625 value(rv) += ulp(value(rv));
1599#ifndef ROUND_BIASED 1626#ifndef ROUND_BIASED
1600 else { 1627 else {
1601 rv -= ulp(rv); 1628 value(rv) -= ulp(value(rv));
1602#ifndef Sudden_Underflow 1629#ifndef Sudden_Underflow
1603 if (!rv) 1630 if (!value(rv))
1604 goto undfl; 1631 goto undfl;
1605#endif 1632#endif
1606 } 1633 }
@@ -1651,10 +1678,10 @@ strtod
1651 /* Check for overflow */ 1678 /* Check for overflow */
1652 1679
1653 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 1680 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1654 rv0 = rv; 1681 value(rv0) = value(rv);
1655 word0(rv) -= P*Exp_msk1; 1682 word0(rv) -= P*Exp_msk1;
1656 adj = aadj1 * ulp(rv); 1683 adj = aadj1 * ulp(value(rv));
1657 rv += adj; 1684 value(rv) += adj;
1658 if ((word0(rv) & Exp_mask) >= 1685 if ((word0(rv) & Exp_mask) >=
1659 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 1686 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1660 if (word0(rv0) == Big0 && word1(rv0) == Big1) 1687 if (word0(rv0) == Big0 && word1(rv0) == Big1)
@@ -1669,10 +1696,10 @@ strtod
1669 else { 1696 else {
1670#ifdef Sudden_Underflow 1697#ifdef Sudden_Underflow
1671 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 1698 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1672 rv0 = rv; 1699 value(rv0) = value(rv);
1673 word0(rv) += P*Exp_msk1; 1700 word0(rv) += P*Exp_msk1;
1674 adj = aadj1 * ulp(rv); 1701 adj = aadj1 * ulp(value(rv));
1675 rv += adj; 1702 value(rv) += adj;
1676#ifdef IBM 1703#ifdef IBM
1677 if ((word0(rv) & Exp_mask) < P*Exp_msk1) 1704 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1678#else 1705#else
@@ -1690,8 +1717,8 @@ strtod
1690 word0(rv) -= P*Exp_msk1; 1717 word0(rv) -= P*Exp_msk1;
1691 } 1718 }
1692 else { 1719 else {
1693 adj = aadj1 * ulp(rv); 1720 adj = aadj1 * ulp(value(rv));
1694 rv += adj; 1721 value(rv) += adj;
1695 } 1722 }
1696#else 1723#else
1697 /* Compute adj so that the IEEE rounding rules will 1724 /* Compute adj so that the IEEE rounding rules will
@@ -1706,8 +1733,8 @@ strtod
1706 if (!dsign) 1733 if (!dsign)
1707 aadj1 = -aadj1; 1734 aadj1 = -aadj1;
1708 } 1735 }
1709 adj = aadj1 * ulp(rv); 1736 adj = aadj1 * ulp(value(rv));
1710 rv += adj; 1737 value(rv) += adj;
1711#endif 1738#endif
1712 } 1739 }
1713 z = word0(rv) & Exp_mask; 1740 z = word0(rv) & Exp_mask;
@@ -1738,7 +1765,7 @@ strtod
1738 ret: 1765 ret:
1739 if (se) 1766 if (se)
1740 *se = (char *)s; 1767 *se = (char *)s;
1741 return sign ? -rv : rv; 1768 return sign ? -value(rv) : value(rv);
1742 } 1769 }
1743 1770
1744 static int 1771 static int
@@ -1884,10 +1911,10 @@ quorem
1884 char * 1911 char *
1885__dtoa 1912__dtoa
1886#ifdef KR_headers 1913#ifdef KR_headers
1887 (d, mode, ndigits, decpt, sign, rve) 1914 (_d, mode, ndigits, decpt, sign, rve)
1888 double d; int mode, ndigits, *decpt, *sign; char **rve; 1915 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1889#else 1916#else
1890 (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) 1917 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1891#endif 1918#endif
1892{ 1919{
1893 /* Arguments ndigits, decpt, sign are similar to those 1920 /* Arguments ndigits, decpt, sign are similar to those
@@ -1933,11 +1960,13 @@ __dtoa
1933 ULong x; 1960 ULong x;
1934#endif 1961#endif
1935 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1962 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1936 double d2, ds, eps; 1963 double ds;
1937 char *s, *s0; 1964 char *s, *s0;
1938 static Bigint *result; 1965 static Bigint *result;
1939 static int result_k; 1966 static int result_k;
1967 _double d, d2, eps;
1940 1968
1969 value(d) = _d;
1941 if (result) { 1970 if (result) {
1942 result->k = result_k; 1971 result->k = result_k;
1943 result->maxwds = 1 << result_k; 1972 result->maxwds = 1 << result_k;
@@ -1964,7 +1993,7 @@ __dtoa
1964 *decpt = 9999; 1993 *decpt = 9999;
1965 s = 1994 s =
1966#ifdef IEEE_Arith 1995#ifdef IEEE_Arith
1967 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : 1996 !word1(d) && !(word0(d) & 0xfffff) ? ndigits < 8 ? "Inf" : "Infinity" :
1968#endif 1997#endif
1969 "NaN"; 1998 "NaN";
1970 if (rve) 1999 if (rve)
@@ -1977,9 +2006,9 @@ __dtoa
1977 } 2006 }
1978#endif 2007#endif
1979#ifdef IBM 2008#ifdef IBM
1980 d += 0; /* normalize */ 2009 value(d) += 0; /* normalize */
1981#endif 2010#endif
1982 if (!d) { 2011 if (!value(d)) {
1983 *decpt = 1; 2012 *decpt = 1;
1984 s = "0"; 2013 s = "0";
1985 if (rve) 2014 if (rve)
@@ -1987,18 +2016,18 @@ __dtoa
1987 return s; 2016 return s;
1988 } 2017 }
1989 2018
1990 b = d2b(d, &be, &bbits); 2019 b = d2b(value(d), &be, &bbits);
1991#ifdef Sudden_Underflow 2020#ifdef Sudden_Underflow
1992 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 2021 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1993#else 2022#else
1994 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 2023 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
1995#endif 2024#endif
1996 d2 = d; 2025 value(d2) = value(d);
1997 word0(d2) &= Frac_mask1; 2026 word0(d2) &= Frac_mask1;
1998 word0(d2) |= Exp_11; 2027 word0(d2) |= Exp_11;
1999#ifdef IBM 2028#ifdef IBM
2000 if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 2029 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2001 d2 /= 1 << j; 2030 value(d2) /= 1 << j;
2002#endif 2031#endif
2003 2032
2004 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 2033 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2037,19 +2066,20 @@ __dtoa
2037 i = bbits + be + (Bias + (P-1) - 1); 2066 i = bbits + be + (Bias + (P-1) - 1);
2038 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2067 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2039 : word1(d) << 32 - i; 2068 : word1(d) << 32 - i;
2040 d2 = x; 2069 value(d2) = x;
2041 word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2070 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2042 i -= (Bias + (P-1) - 1) + 1; 2071 i -= (Bias + (P-1) - 1) + 1;
2043 denorm = 1; 2072 denorm = 1;
2044 } 2073 }
2045#endif 2074#endif
2046 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2075 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2076 i*0.301029995663981;
2047 k = (int)ds; 2077 k = (int)ds;
2048 if (ds < 0. && ds != k) 2078 if (ds < 0. && ds != k)
2049 k--; /* want k = floor(ds) */ 2079 k--; /* want k = floor(ds) */
2050 k_check = 1; 2080 k_check = 1;
2051 if (k >= 0 && k <= Ten_pmax) { 2081 if (k >= 0 && k <= Ten_pmax) {
2052 if (d < tens[k]) 2082 if (value(d) < tens[k])
2053 k--; 2083 k--;
2054 k_check = 0; 2084 k_check = 0;
2055 } 2085 }
@@ -2116,7 +2146,7 @@ __dtoa
2116 /* Try to get by with floating-point arithmetic. */ 2146 /* Try to get by with floating-point arithmetic. */
2117 2147
2118 i = 0; 2148 i = 0;
2119 d2 = d; 2149 value(d2) = value(d);
2120 k0 = k; 2150 k0 = k;
2121 ilim0 = ilim; 2151 ilim0 = ilim;
2122 ieps = 2; /* conservative */ 2152 ieps = 2; /* conservative */
@@ -2126,7 +2156,7 @@ __dtoa
2126 if (j & Bletch) { 2156 if (j & Bletch) {
2127 /* prevent overflows */ 2157 /* prevent overflows */
2128 j &= Bletch - 1; 2158 j &= Bletch - 1;
2129 d /= bigtens[n_bigtens-1]; 2159 value(d) /= bigtens[n_bigtens-1];
2130 ieps++; 2160 ieps++;
2131 } 2161 }
2132 for(; j; j >>= 1, i++) 2162 for(; j; j >>= 1, i++)
@@ -2134,32 +2164,32 @@ __dtoa
2134 ieps++; 2164 ieps++;
2135 ds *= bigtens[i]; 2165 ds *= bigtens[i];
2136 } 2166 }
2137 d /= ds; 2167 value(d) /= ds;
2138 } 2168 }
2139 else if (j1 = -k) { 2169 else if (j1 = -k) {
2140 d *= tens[j1 & 0xf]; 2170 value(d) *= tens[j1 & 0xf];
2141 for(j = j1 >> 4; j; j >>= 1, i++) 2171 for(j = j1 >> 4; j; j >>= 1, i++)
2142 if (j & 1) { 2172 if (j & 1) {
2143 ieps++; 2173 ieps++;
2144 d *= bigtens[i]; 2174 value(d) *= bigtens[i];
2145 } 2175 }
2146 } 2176 }
2147 if (k_check && d < 1. && ilim > 0) { 2177 if (k_check && value(d) < 1. && ilim > 0) {
2148 if (ilim1 <= 0) 2178 if (ilim1 <= 0)
2149 goto fast_failed; 2179 goto fast_failed;
2150 ilim = ilim1; 2180 ilim = ilim1;
2151 k--; 2181 k--;
2152 d *= 10.; 2182 value(d) *= 10.;
2153 ieps++; 2183 ieps++;
2154 } 2184 }
2155 eps = ieps*d + 7.; 2185 value(eps) = ieps*value(d) + 7.;
2156 word0(eps) -= (P-1)*Exp_msk1; 2186 word0(eps) -= (P-1)*Exp_msk1;
2157 if (ilim == 0) { 2187 if (ilim == 0) {
2158 S = mhi = 0; 2188 S = mhi = 0;
2159 d -= 5.; 2189 value(d) -= 5.;
2160 if (d > eps) 2190 if (value(d) > value(eps))
2161 goto one_digit; 2191 goto one_digit;
2162 if (d < -eps) 2192 if (value(d) < -value(eps))
2163 goto no_digits; 2193 goto no_digits;
2164 goto fast_failed; 2194 goto fast_failed;
2165 } 2195 }
@@ -2168,33 +2198,33 @@ __dtoa
2168 /* Use Steele & White method of only 2198 /* Use Steele & White method of only
2169 * generating digits needed. 2199 * generating digits needed.
2170 */ 2200 */
2171 eps = 0.5/tens[ilim-1] - eps; 2201 value(eps) = 0.5/tens[ilim-1] - value(eps);
2172 for(i = 0;;) { 2202 for(i = 0;;) {
2173 L = d; 2203 L = value(d);
2174 d -= L; 2204 value(d) -= L;
2175 *s++ = '0' + (int)L; 2205 *s++ = '0' + (int)L;
2176 if (d < eps) 2206 if (value(d) < value(eps))
2177 goto ret1; 2207 goto ret1;
2178 if (1. - d < eps) 2208 if (1. - value(d) < value(eps))
2179 goto bump_up; 2209 goto bump_up;
2180 if (++i >= ilim) 2210 if (++i >= ilim)
2181 break; 2211 break;
2182 eps *= 10.; 2212 value(eps) *= 10.;
2183 d *= 10.; 2213 value(d) *= 10.;
2184 } 2214 }
2185 } 2215 }
2186 else { 2216 else {
2187#endif 2217#endif
2188 /* Generate ilim digits, then fix them up. */ 2218 /* Generate ilim digits, then fix them up. */
2189 eps *= tens[ilim-1]; 2219 value(eps) *= tens[ilim-1];
2190 for(i = 1;; i++, d *= 10.) { 2220 for(i = 1;; i++, value(d) *= 10.) {
2191 L = d; 2221 L = value(d);
2192 d -= L; 2222 value(d) -= L;
2193 *s++ = '0' + (int)L; 2223 *s++ = '0' + (int)L;
2194 if (i == ilim) { 2224 if (i == ilim) {
2195 if (d > 0.5 + eps) 2225 if (value(d) > 0.5 + value(eps))
2196 goto bump_up; 2226 goto bump_up;
2197 else if (d < 0.5 - eps) { 2227 else if (value(d) < 0.5 - value(eps)) {
2198 while(*--s == '0'); 2228 while(*--s == '0');
2199 s++; 2229 s++;
2200 goto ret1; 2230 goto ret1;
@@ -2207,7 +2237,7 @@ __dtoa
2207#endif 2237#endif
2208 fast_failed: 2238 fast_failed:
2209 s = s0; 2239 s = s0;
2210 d = d2; 2240 value(d) = value(d2);
2211 k = k0; 2241 k = k0;
2212 ilim = ilim0; 2242 ilim = ilim0;
2213 } 2243 }
@@ -2219,24 +2249,24 @@ __dtoa
2219 ds = tens[k]; 2249 ds = tens[k];
2220 if (ndigits < 0 && ilim <= 0) { 2250 if (ndigits < 0 && ilim <= 0) {
2221 S = mhi = 0; 2251 S = mhi = 0;
2222 if (ilim < 0 || d <= 5*ds) 2252 if (ilim < 0 || value(d) <= 5*ds)
2223 goto no_digits; 2253 goto no_digits;
2224 goto one_digit; 2254 goto one_digit;
2225 } 2255 }
2226 for(i = 1;; i++) { 2256 for(i = 1;; i++) {
2227 L = d / ds; 2257 L = value(d) / ds;
2228 d -= L*ds; 2258 value(d) -= L*ds;
2229#ifdef Check_FLT_ROUNDS 2259#ifdef Check_FLT_ROUNDS
2230 /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2260 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2231 if (d < 0) { 2261 if (value(d) < 0) {
2232 L--; 2262 L--;
2233 d += ds; 2263 value(d) += ds;
2234 } 2264 }
2235#endif 2265#endif
2236 *s++ = '0' + (int)L; 2266 *s++ = '0' + (int)L;
2237 if (i == ilim) { 2267 if (i == ilim) {
2238 d += d; 2268 value(d) += value(d);
2239 if (d > ds || d == ds && L & 1) { 2269 if (value(d) > ds || value(d) == ds && L & 1) {
2240 bump_up: 2270 bump_up:
2241 while(*--s == '9') 2271 while(*--s == '9')
2242 if (s == s0) { 2272 if (s == s0) {
@@ -2248,7 +2278,7 @@ __dtoa
2248 } 2278 }
2249 break; 2279 break;
2250 } 2280 }
2251 if (!(d *= 10.)) 2281 if (!(value(d) *= 10.))
2252 break; 2282 break;
2253 } 2283 }
2254 goto ret1; 2284 goto ret1;
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
index 808ba90165..3f5375c5e3 100644
--- a/src/lib/libc/stdlib/strtol.3
+++ b/src/lib/libc/stdlib/strtol.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,49 +29,57 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtol.3 5.4 (Berkeley) 6/25/92 32.\" $OpenBSD: strtol.3,v 1.13 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtol.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
38.\" 33.\"
39.Dd June 25, 1992 34.Dd June 25, 1992
40.Dt STRTOL 3 35.Dt STRTOL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtol, strtoq 38.Nm strtol ,
44.Nd convert string value to a long or quad_t integer 39.Nm strtoll ,
40.Nm strtoq
41.Nd "convert string value to a long or long long integer"
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
48.Ft long 45.Ft long
49.Fn strtol "char *nptr" "char **endptr" "int base" 46.Fn strtol "const char *nptr" "char **endptr" "int base"
50 47.Pp
48.Fd #include <stdlib.h>
49.Fd #include <limits.h>
50.Ft long long
51.Fn strtoll "const char *nptr" "char **endptr" "int base"
52.Pp
51.Fd #include <sys/types.h> 53.Fd #include <sys/types.h>
52.Fd #include <stdlib.h> 54.Fd #include <stdlib.h>
53.Fd #include <limits.h> 55.Fd #include <limits.h>
54.Ft quad_t 56.Ft quad_t
55.Fn strtoq "char *nptr" "char **endptr" "int base" 57.Fn strtoq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 58.Sh DESCRIPTION
57The 59The
58.Fn strtol 60.Fn strtol
59function 61function converts the string in
60converts the string in
61.Fa nptr 62.Fa nptr
62to a 63to a
63.Em long 64.Li long
64value. 65value.
65The 66The
66.Fn strtoq 67.Fn strtoll
67function 68function converts the string in
68converts the string in
69.Fa nptr 69.Fa nptr
70to a 70to a
71.Em quad_t 71.Li long long
72value. 72value.
73The
74.Fn strtoq
75function is a deprecated equivalent of
76.Fn strtoll
77and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 78The conversion is done according to the given
74.Fa base , 79.Fa base ,
75which must be between 2 and 36 inclusive, 80which must be a number between 2 and 36 inclusive or the special value 0.
76or be the special value 0.
77.Pp 81.Pp
78The string may begin with an arbitrary amount of white space 82The string may begin with an arbitrary amount of whitespace
79(as determined by 83(as determined by
80.Xr isspace 3 ) 84.Xr isspace 3 )
81followed by a single optional 85followed by a single optional
@@ -85,25 +89,22 @@ or
85sign. 89sign.
86If 90If
87.Fa base 91.Fa base
88is zero or 16, 92is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 93.Ql 0x
91prefix, 94prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 95.Fa base
94is taken as 10 (decimal) unless the next character is 96is taken as 10 (decimal) unless the next character is
95.Ql 0 , 97.Ql 0 ,
96in which case it is taken as 8 (octal). 98in which case it is taken as 8 (octal).
97.Pp 99.Pp
98The remainder of the string is converted to a 100The remainder of the string is converted to a
99.Em long 101.Li long
100value in the obvious manner, 102value in the obvious manner,
101stopping at the first character which is not a valid digit 103stopping at the first character which is not a valid digit
102in the given base. 104in the given base.
103(In bases above 10, the letter 105(In bases above 10, the letter
104.Ql A 106.Ql A
105in either upper or lower case 107in either upper or lower case represents 10,
106represents 10,
107.Ql B 108.Ql B
108represents 11, and so forth, with 109represents 11, and so forth, with
109.Ql Z 110.Ql Z
@@ -111,7 +112,7 @@ representing 35.)
111.Pp 112.Pp
112If 113If
113.Fa endptr 114.Fa endptr
114is non nil, 115is non-null,
115.Fn strtol 116.Fn strtol
116stores the address of the first invalid character in 117stores the address of the first invalid character in
117.Fa *endptr . 118.Fa *endptr .
@@ -133,8 +134,7 @@ on return, the entire string was valid.)
133.Sh RETURN VALUES 134.Sh RETURN VALUES
134The 135The
135.Fn strtol 136.Fn strtol
136function 137function returns the result of the conversion,
137returns the result of the conversion,
138unless the value would underflow or overflow. 138unless the value would underflow or overflow.
139If an underflow occurs, 139If an underflow occurs,
140.Fn strtol 140.Fn strtol
@@ -148,6 +148,76 @@ In both cases,
148.Va errno 148.Va errno
149is set to 149is set to
150.Er ERANGE . 150.Er ERANGE .
151.Pp
152The
153.Fn strtoll
154function has identical return values except that
155.Dv LLONG_MIN
156and
157.Dv LLONG_MAX
158are used to indicate underflow and overflow respectively.
159.Sh EXAMPLES
160Ensuring that a string is a valid number (i.e., in range and containing no
161trailing characters) requires clearing
162.Va errno
163beforehand explicitly since
164.Va errno
165is not changed on a successful call to
166.Fn strtol ,
167and the return value of
168.Fn strtol
169cannot be used unambiguously to signal an error:
170.Bd -literal -offset indent
171char *ep;
172long lval;
173
174\&...
175
176errno = 0;
177lval = strtol(buf, &ep, 10);
178if (buf[0] == '\e0' || *ep != '\e0')
179 goto not_a_number;
180if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
181 goto out_of_range;
182.Ed
183.Pp
184This example will accept
185.Dq 12
186but not
187.Dq 12foo
188or
189.Dq 12\en .
190If trailing whitespace is acceptable, further checks must be done on
191.Va *ep ;
192alternately, use
193.Xr sscanf 3 .
194.Pp
195If
196.Fn strtol
197is being used instead of
198.Xr atoi 3 ,
199error checking is further complicated because the desired return value is an
200.Li int
201rather than a
202.Li long ;
203however, on some architectures integers and long integers are the same size.
204Thus the following is necessary:
205.Bd -literal -offset indent
206char *ep;
207int ival;
208long lval;
209
210\&...
211
212errno = 0;
213lval = strtol(buf, &ep, 10);
214if (buf[0] == '\e0' || *ep != '\e0')
215 goto not_a_number;
216if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
217 (lval > INT_MAX || lval < INT_MIN))
218 goto out_of_range;
219ival = lval;
220.Ed
151.Sh ERRORS 221.Sh ERRORS
152.Bl -tag -width Er 222.Bl -tag -width Er
153.It Bq Er ERANGE 223.It Bq Er ERANGE
@@ -157,13 +227,21 @@ The given string was out of range; the value converted has been clamped.
157.Xr atof 3 , 227.Xr atof 3 ,
158.Xr atoi 3 , 228.Xr atoi 3 ,
159.Xr atol 3 , 229.Xr atol 3 ,
230.Xr atoll 3 ,
231.Xr sscanf 3 ,
160.Xr strtod 3 , 232.Xr strtod 3 ,
161.Xr strtoul 3 233.Xr strtoul 3
162.Sh STANDARDS 234.Sh STANDARDS
163The 235The
164.Fn strtol 236.Fn strtol
165function 237and
166conforms to 238.Fn strtoll
167.St -ansiC . 239functions conform to
240.St -ansiC-99 .
241The
242.Fn strtoq
243function is a
244.Bx
245extension and is provided for backwards compatibility with legacy programs.
168.Sh BUGS 246.Sh BUGS
169Ignores the current locale. 247Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..1c39720794 100644
--- a/src/lib/libc/stdlib/strtol.c
+++ b/src/lib/libc/stdlib/strtol.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,12 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: strtol.c,v 1.5 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <limits.h>
40#include <ctype.h> 34#include <ctype.h>
41#include <errno.h> 35#include <errno.h>
36#include <limits.h>
42#include <stdlib.h> 37#include <stdlib.h>
43 38
44 39
@@ -54,25 +49,28 @@ strtol(nptr, endptr, base)
54 char **endptr; 49 char **endptr;
55 register int base; 50 register int base;
56{ 51{
57 register const char *s = nptr; 52 register const char *s;
58 register unsigned long acc; 53 register long acc, cutoff;
59 register int c; 54 register int c;
60 register unsigned long cutoff; 55 register int neg, any, cutlim;
61 register int neg = 0, any, cutlim;
62 56
63 /* 57 /*
64 * Skip white space and pick up leading +/- sign if any. 58 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 59 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 60 * assume decimal; if base is already 16, allow 0x.
67 */ 61 */
62 s = nptr;
68 do { 63 do {
69 c = *s++; 64 c = (unsigned char) *s++;
70 } while (isspace(c)); 65 } while (isspace(c));
71 if (c == '-') { 66 if (c == '-') {
72 neg = 1; 67 neg = 1;
73 c = *s++; 68 c = *s++;
74 } else if (c == '+') 69 } else {
75 c = *s++; 70 neg = 0;
71 if (c == '+')
72 c = *s++;
73 }
76 if ((base == 0 || base == 16) && 74 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 75 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 76 c = s[1];
@@ -99,10 +97,17 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 97 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 98 * overflow.
101 */ 99 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 100 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 101 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 102 cutoff /= base;
105 for (acc = 0, any = 0;; c = *s++) { 103 if (neg) {
104 if (cutlim > 0) {
105 cutlim -= base;
106 cutoff += 1;
107 }
108 cutlim = -cutlim;
109 }
110 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
106 if (isdigit(c)) 111 if (isdigit(c))
107 c -= '0'; 112 c -= '0';
108 else if (isalpha(c)) 113 else if (isalpha(c))
@@ -111,19 +116,30 @@ strtol(nptr, endptr, base)
111 break; 116 break;
112 if (c >= base) 117 if (c >= base)
113 break; 118 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 119 if (any < 0)
115 any = -1; 120 continue;
116 else { 121 if (neg) {
117 any = 1; 122 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 123 any = -1;
119 acc += c; 124 acc = LONG_MIN;
125 errno = ERANGE;
126 } else {
127 any = 1;
128 acc *= base;
129 acc -= c;
130 }
131 } else {
132 if (acc > cutoff || acc == cutoff && c > cutlim) {
133 any = -1;
134 acc = LONG_MAX;
135 errno = ERANGE;
136 } else {
137 any = 1;
138 acc *= base;
139 acc += c;
140 }
120 } 141 }
121 } 142 }
122 if (any < 0) {
123 acc = neg ? LONG_MIN : LONG_MAX;
124 errno = ERANGE;
125 } else if (neg)
126 acc = -acc;
127 if (endptr != 0) 143 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 144 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 145 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoll.c
index fc559e9d7f..ac9353890f 100644
--- a/src/lib/libc/stdlib/strtoq.c
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,33 +28,32 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; 31static const char rcsid[] = "$OpenBSD: strtoll.c,v 1.2 2003/06/02 20:18:38 millert Exp $";
36#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
37 33
38#include <sys/types.h> 34#include <sys/types.h>
39 35
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 36#include <ctype.h>
37#include <errno.h>
38#include <limits.h>
43#include <stdlib.h> 39#include <stdlib.h>
44 40
45/* 41/*
46 * Convert a string to a quad integer. 42 * Convert a string to a long long.
47 * 43 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 44 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 45 * alphabets and digits are each contiguous.
50 */ 46 */
51quad_t 47long long
52strtoq(nptr, endptr, base) 48strtoll(nptr, endptr, base)
53 const char *nptr; 49 const char *nptr;
54 char **endptr; 50 char **endptr;
55 register int base; 51 int base;
56{ 52{
57 register const char *s; 53 const char *s;
58 register u_quad_t acc; 54 long long acc, cutoff;
59 register int c; 55 int c;
60 register u_quad_t qbase, cutoff; 56 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 57
63 /* 58 /*
64 * Skip white space and pick up leading +/- sign if any. 59 * Skip white space and pick up leading +/- sign if any.
@@ -67,7 +62,7 @@ strtoq(nptr, endptr, base)
67 */ 62 */
68 s = nptr; 63 s = nptr;
69 do { 64 do {
70 c = *s++; 65 c = (unsigned char) *s++;
71 } while (isspace(c)); 66 } while (isspace(c));
72 if (c == '-') { 67 if (c == '-') {
73 neg = 1; 68 neg = 1;
@@ -93,7 +88,7 @@ strtoq(nptr, endptr, base)
93 * followed by a legal input character, is too big. One that 88 * followed by a legal input character, is too big. One that
94 * is equal to this value may be valid or not; the limit 89 * is equal to this value may be valid or not; the limit
95 * between valid and invalid numbers is then based on the last 90 * between valid and invalid numbers is then based on the last
96 * digit. For instance, if the range for quads is 91 * digit. For instance, if the range for long longs is
97 * [-9223372036854775808..9223372036854775807] and the input base 92 * [-9223372036854775808..9223372036854775807] and the input base
98 * is 10, cutoff will be set to 922337203685477580 and cutlim to 93 * is 10, cutoff will be set to 922337203685477580 and cutlim to
99 * either 7 (neg==0) or 8 (neg==1), meaning that if we have 94 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
@@ -104,11 +99,17 @@ strtoq(nptr, endptr, base)
104 * Set any if any `digits' consumed; make it negative to indicate 99 * Set any if any `digits' consumed; make it negative to indicate
105 * overflow. 100 * overflow.
106 */ 101 */
107 qbase = (unsigned)base; 102 cutoff = neg ? LLONG_MIN : LLONG_MAX;
108 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 103 cutlim = cutoff % base;
109 cutlim = cutoff % qbase; 104 cutoff /= base;
110 cutoff /= qbase; 105 if (neg) {
111 for (acc = 0, any = 0;; c = *s++) { 106 if (cutlim > 0) {
107 cutlim -= base;
108 cutoff += 1;
109 }
110 cutlim = -cutlim;
111 }
112 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
112 if (isdigit(c)) 113 if (isdigit(c))
113 c -= '0'; 114 c -= '0';
114 else if (isalpha(c)) 115 else if (isalpha(c))
@@ -117,20 +118,45 @@ strtoq(nptr, endptr, base)
117 break; 118 break;
118 if (c >= base) 119 if (c >= base)
119 break; 120 break;
120 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 121 if (any < 0)
121 any = -1; 122 continue;
122 else { 123 if (neg) {
123 any = 1; 124 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
124 acc *= qbase; 125 any = -1;
125 acc += c; 126 acc = LLONG_MIN;
127 errno = ERANGE;
128 } else {
129 any = 1;
130 acc *= base;
131 acc -= c;
132 }
133 } else {
134 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
135 any = -1;
136 acc = LLONG_MAX;
137 errno = ERANGE;
138 } else {
139 any = 1;
140 acc *= base;
141 acc += c;
142 }
126 } 143 }
127 } 144 }
128 if (any < 0) {
129 acc = neg ? QUAD_MIN : QUAD_MAX;
130 errno = ERANGE;
131 } else if (neg)
132 acc = -acc;
133 if (endptr != 0) 145 if (endptr != 0)
134 *endptr = (char *) (any ? s - 1 : nptr); 146 *endptr = (char *) (any ? s - 1 : nptr);
135 return (acc); 147 return (acc);
136} 148}
149
150#ifdef __weak_alias
151__weak_alias(strtoq, strtoll);
152#else
153quad_t
154strtoq(nptr, endptr, base)
155 const char *nptr;
156 char **endptr;
157 int base;
158{
159
160 return ((quad_t)strtoll(nptr, endptr, base);
161}
162#endif
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
index db551b0141..4f6d6a51f9 100644
--- a/src/lib/libc/stdlib/strtoul.3
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,21 +29,27 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtoul.3 5.4 (Berkeley) 6/25/92 32.\" $OpenBSD: strtoul.3,v 1.15 2003/06/02 20:18:38 millert Exp $
37.\" $Id: strtoul.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 33.\"
39.Dd June 25, 1992 34.Dd June 25, 1992
40.Dt STRTOUL 3 35.Dt STRTOUL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtoul, strtouq 38.Nm strtoul ,
44.Nd convert a string to an unsigned long or uquad_t integer 39.Nm strtoull ,
40.Nm strtouq
41.Nd "convert a string to an unsigned long or unsigned long long integer"
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
48.Ft unsigned long 45.Ft unsigned long
49.Fn strtoul "const char *nptr" "char **endptr" "int base" 46.Fn strtoul "const char *nptr" "char **endptr" "int base"
50 47.Pp
48.Fd #include <stdlib.h>
49.Fd #include <limits.h>
50.Ft unsigned long long
51.Fn strtoull "const char *nptr" "char **endptr" "int base"
52.Pp
51.Fd #include <sys/types.h> 53.Fd #include <sys/types.h>
52.Fd #include <stdlib.h> 54.Fd #include <stdlib.h>
53.Fd #include <limits.h> 55.Fd #include <limits.h>
@@ -56,26 +58,34 @@
56.Sh DESCRIPTION 58.Sh DESCRIPTION
57The 59The
58.Fn strtoul 60.Fn strtoul
59function 61function converts the string in
60converts the string in
61.Fa nptr 62.Fa nptr
62to an 63to an
63.Em unsigned long 64.Li unsigned long
64value. 65value.
65The 66The
66.Fn strtouq 67.Fn strtoull
67function 68function converts the string in
68converts the string in
69.Fa nptr 69.Fa nptr
70to a 70to an
71.Em u_quad_t 71.Li unsigned long long
72value. 72value.
73The
74.Fn strtouq
75function is a deprecated equivalent of
76.Fn strtoull
77and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 78The conversion is done according to the given
74.Fa base , 79.Fa base ,
75which must be between 2 and 36 inclusive, 80which must be a number between 2 and 36 inclusive
76or be the special value 0. 81or the special value 0.
82If the string in
83.Fa nptr
84represents a negative number, it will be converted to its unsigned equivalent.
85This behavior is consistent with what happens when a signed integer type is
86cast to its unsigned counterpart.
77.Pp 87.Pp
78The string may begin with an arbitrary amount of white space 88The string may begin with an arbitrary amount of whitespace
79(as determined by 89(as determined by
80.Xr isspace 3 ) 90.Xr isspace 3 )
81followed by a single optional 91followed by a single optional
@@ -85,26 +95,22 @@ or
85sign. 95sign.
86If 96If
87.Fa base 97.Fa base
88is zero or 16, 98is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 99.Ql 0x
91prefix, 100prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 101.Fa base
94is taken as 10 (decimal) unless the next character is 102is taken as 10 (decimal) unless the next character is
95.Ql 0 , 103.Ql 0 ,
96in which case it is taken as 8 (octal). 104in which case it is taken as 8 (octal).
97.Pp 105.Pp
98The remainder of the string is converted to an 106The remainder of the string is converted to an
99.Em unsigned long 107.Li unsigned long
100value in the obvious manner, 108value in the obvious manner, stopping at the end of the string
101stopping at the end of the string
102or at the first character that does not produce a valid digit 109or at the first character that does not produce a valid digit
103in the given base. 110in the given base.
104(In bases above 10, the letter 111(In bases above 10, the letter
105.Ql A 112.Ql A
106in either upper or lower case 113in either upper or lower case represents 10,
107represents 10,
108.Ql B 114.Ql B
109represents 11, and so forth, with 115represents 11, and so forth, with
110.Ql Z 116.Ql Z
@@ -112,7 +118,7 @@ representing 35.)
112.Pp 118.Pp
113If 119If
114.Fa endptr 120.Fa endptr
115is non nil, 121is non-null,
116.Fn strtoul 122.Fn strtoul
117stores the address of the first invalid character in 123stores the address of the first invalid character in
118.Fa *endptr . 124.Fa *endptr .
@@ -134,12 +140,18 @@ on return, the entire string was valid.)
134.Sh RETURN VALUES 140.Sh RETURN VALUES
135The 141The
136.Fn strtoul 142.Fn strtoul
137function 143function returns the result of the conversion,
138returns either the result of the conversion 144unless the value would overflow, in which case
139or, if there was a leading minus sign, 145.Dv ULONG_MAX
140the negation of the result of the conversion, 146is returned and
141unless the original (non-negated) value would overflow; 147.Va errno
142in the latter case, 148is set to
149.Er ERANGE .
150If there was a leading minus sign,
151.Fn strtoul
152returns the (unsigned) negation of the absolute value of the number, unless
153the absolute value would overflow.
154In this case,
143.Fn strtoul 155.Fn strtoul
144returns 156returns
145.Dv ULONG_MAX 157.Dv ULONG_MAX
@@ -147,18 +159,73 @@ and sets the global variable
147.Va errno 159.Va errno
148to 160to
149.Er ERANGE . 161.Er ERANGE .
162.Pp
163The
164.Fn strtoull
165function has identical return values except that
166.Dv ULLONG_MAX
167is used to indicate overflow.
168.Pp
169There is no way to determine if
170.Fn strtoul
171has processed a negative number (and returned an unsigned value) short of
172examining the string in
173.Fa nptr
174directly.
175.Sh EXAMPLES
176Ensuring that a string is a valid number (i.e., in range and containing no
177trailing characters) requires clearing
178.Va errno
179beforehand explicitly since
180.Va errno
181is not changed on a successful call to
182.Fn strtoul ,
183and the return value of
184.Fn strtoul
185cannot be used unambiguously to signal an error:
186.Bd -literal -offset indent
187char *ep;
188unsigned long ulval;
189
190\&...
191
192errno = 0;
193ulval = strtoul(buf, &ep, 10);
194if (buf[0] == '\e0' || *ep != '\e0')
195 goto not_a_number;
196if (errno == ERANGE && ulval == ULONG_MAX)
197 goto out_of_range;
198.Ed
199.Pp
200This example will accept
201.Dq 12
202but not
203.Dq 12foo
204or
205.Dq 12\en .
206If trailing whitespace is acceptable, further checks must be done on
207.Va *ep ;
208alternately, use
209.Xr sscanf 3 .
150.Sh ERRORS 210.Sh ERRORS
151.Bl -tag -width Er 211.Bl -tag -width Er
152.It Bq Er ERANGE 212.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped. 213The given string was out of range; the value converted has been clamped.
154.El 214.El
155.Sh SEE ALSO 215.Sh SEE ALSO
216.Xr sscanf 3 ,
156.Xr strtol 3 217.Xr strtol 3
157.Sh STANDARDS 218.Sh STANDARDS
158The 219The
159.Fn strtoul 220.Fn strtoul
160function 221and
161conforms to 222.Fn strtoull
162.St -ansiC . 223functions conform to
224.St -ansiC-99 .
225The
226.Fn strtouq
227function is a
228.Bx
229extension and is provided for backwards compatibility with legacy programs.
163.Sh BUGS 230.Sh BUGS
164Ignores the current locale. 231Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..7d31ce79fb 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,13 +28,12 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: strtoul.c,v 1.5 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <limits.h>
40#include <ctype.h> 34#include <ctype.h>
41#include <errno.h> 35#include <errno.h>
36#include <limits.h>
42#include <stdlib.h> 37#include <stdlib.h>
43 38
44/* 39/*
@@ -53,23 +48,26 @@ strtoul(nptr, endptr, base)
53 char **endptr; 48 char **endptr;
54 register int base; 49 register int base;
55{ 50{
56 register const char *s = nptr; 51 register const char *s;
57 register unsigned long acc; 52 register unsigned long acc, cutoff;
58 register int c; 53 register int c;
59 register unsigned long cutoff; 54 register int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 55
62 /* 56 /*
63 * See strtol for comments as to the logic used. 57 * See strtol for comments as to the logic used.
64 */ 58 */
59 s = nptr;
65 do { 60 do {
66 c = *s++; 61 c = (unsigned char) *s++;
67 } while (isspace(c)); 62 } while (isspace(c));
68 if (c == '-') { 63 if (c == '-') {
69 neg = 1; 64 neg = 1;
70 c = *s++; 65 c = *s++;
71 } else if (c == '+') 66 } else {
72 c = *s++; 67 neg = 0;
68 if (c == '+')
69 c = *s++;
70 }
73 if ((base == 0 || base == 16) && 71 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 72 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 73 c = s[1];
@@ -78,9 +76,10 @@ strtoul(nptr, endptr, base)
78 } 76 }
79 if (base == 0) 77 if (base == 0)
80 base = c == '0' ? 8 : 10; 78 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 79
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 80 cutoff = ULONG_MAX / (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 81 cutlim = ULONG_MAX % (unsigned long)base;
82 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
84 if (isdigit(c)) 83 if (isdigit(c))
85 c -= '0'; 84 c -= '0';
86 else if (isalpha(c)) 85 else if (isalpha(c))
@@ -89,18 +88,19 @@ strtoul(nptr, endptr, base)
89 break; 88 break;
90 if (c >= base) 89 if (c >= base)
91 break; 90 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 91 if (any < 0)
92 continue;
93 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 94 any = -1;
94 else { 95 acc = ULONG_MAX;
96 errno = ERANGE;
97 } else {
95 any = 1; 98 any = 1;
96 acc *= base; 99 acc *= (unsigned long)base;
97 acc += c; 100 acc += c;
98 } 101 }
99 } 102 }
100 if (any < 0) { 103 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 104 acc = -acc;
105 if (endptr != 0) 105 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 106 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtoull.c
index cc647d8d28..a0ac9b381f 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,40 +28,39 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; 31static const char rcsid[] = "$OpenBSD: strtoull.c,v 1.2 2003/06/02 20:18:38 millert Exp $";
36#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
37 33
38#include <sys/types.h> 34#include <sys/types.h>
39 35
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 36#include <ctype.h>
37#include <errno.h>
38#include <limits.h>
43#include <stdlib.h> 39#include <stdlib.h>
44 40
45/* 41/*
46 * Convert a string to an unsigned quad integer. 42 * Convert a string to an unsigned long long.
47 * 43 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 44 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 45 * alphabets and digits are each contiguous.
50 */ 46 */
51u_quad_t 47unsigned long long
52strtouq(nptr, endptr, base) 48strtoull(nptr, endptr, base)
53 const char *nptr; 49 const char *nptr;
54 char **endptr; 50 char **endptr;
55 register int base; 51 int base;
56{ 52{
57 register const char *s = nptr; 53 const char *s;
58 register u_quad_t acc; 54 unsigned long long acc, cutoff;
59 register int c; 55 int c;
60 register u_quad_t qbase, cutoff; 56 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 57
63 /* 58 /*
64 * See strtoq for comments as to the logic used. 59 * See strtoq for comments as to the logic used.
65 */ 60 */
66 s = nptr; 61 s = nptr;
67 do { 62 do {
68 c = *s++; 63 c = (unsigned char) *s++;
69 } while (isspace(c)); 64 } while (isspace(c));
70 if (c == '-') { 65 if (c == '-') {
71 neg = 1; 66 neg = 1;
@@ -83,10 +78,10 @@ strtouq(nptr, endptr, base)
83 } 78 }
84 if (base == 0) 79 if (base == 0)
85 base = c == '0' ? 8 : 10; 80 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 81
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 82 cutoff = ULLONG_MAX / (unsigned long long)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 83 cutlim = ULLONG_MAX % (unsigned long long)base;
89 for (acc = 0, any = 0;; c = *s++) { 84 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
90 if (isdigit(c)) 85 if (isdigit(c))
91 c -= '0'; 86 c -= '0';
92 else if (isalpha(c)) 87 else if (isalpha(c))
@@ -95,20 +90,35 @@ strtouq(nptr, endptr, base)
95 break; 90 break;
96 if (c >= base) 91 if (c >= base)
97 break; 92 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 93 if (any < 0)
94 continue;
95 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
99 any = -1; 96 any = -1;
100 else { 97 acc = ULLONG_MAX;
98 errno = ERANGE;
99 } else {
101 any = 1; 100 any = 1;
102 acc *= qbase; 101 acc *= (unsigned long long)base;
103 acc += c; 102 acc += c;
104 } 103 }
105 } 104 }
106 if (any < 0) { 105 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 106 acc = -acc;
111 if (endptr != 0) 107 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 108 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc); 109 return (acc);
114} 110}
111
112#ifdef __weak_alias
113__weak_alias(strtouq, strtoull);
114#else
115u_quad_t
116strtouq(nptr, endptr, base)
117 const char *nptr;
118 char **endptr;
119 int base;
120{
121
122 return ((u_quad_t)strtoull(nptr, endptr, base);
123}
124#endif
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
index 520f51db0a..1034b01066 100644
--- a/src/lib/libc/stdlib/system.3
+++ b/src/lib/libc/stdlib/system.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
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 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,8 +29,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)system.3 6.5 (Berkeley) 6/29/91 32.\" $OpenBSD: system.3,v 1.9 2003/06/02 20:18:38 millert Exp $
37.\" $Id: system.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd June 29, 1991
40.Dt SYSTEM 3 35.Dt SYSTEM 3
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn system 46.Fn system
52function 47function hands the argument
53hands the argument
54.Fa string 48.Fa string
55to the command interpreter 49to the command interpreter
56.Xr sh 1 . 50.Xr sh 1 .
@@ -64,36 +58,42 @@ and blocking
64.Pp 58.Pp
65If 59If
66.Fa string 60.Fa string
67is a 61is
68.Dv NULL 62.Dv NULL ,
69pointer,
70.Fn system 63.Fn system
71will return non-zero. 64will return non-zero.
72Otherwise, 65Otherwise,
73.Fn system 66.Fn system
74returns the termination status of the shell in the format specified by 67returns the termination status of the shell in the format specified by
75.Xr waitpid 3 . 68.Xr waitpid 2 .
76.Sh RETURN VALUES 69.Sh RETURN VALUES
77If a child process cannot be created, or the termination status of 70If a child process cannot be created, or the termination status of
78the shell cannot be obtained, 71the shell cannot be obtained,
79.Fn system 72.Fn system
80returns -1 and sets 73returns \-1 and sets
81.Va errno 74.Va errno
82to indicate the error. 75to indicate the error.
83If execution of the shell fails, 76If execution of the shell fails,
84.Fn system 77.Fn system
85returns the termination status for a program that terminates with a call of 78returns the termination status for a program that terminates with a call of
86.Fn exit 127 . 79.Fn exit 127 .
87.Sh SEE ALSO 80.Sh SEE ALSO
88.Xr sh 1 , 81.Xr sh 1 ,
89.Xr execve 2 , 82.Xr execve 2 ,
90.Xr popen 3 , 83.Xr waitpid 2 ,
91.Xr waitpid 3 , 84.Xr popen 3
92.Sh STANDARDS 85.Sh STANDARDS
93The 86The
94.Fn system 87.Fn system
95function 88function conforms to
96conforms to 89.St -ansiC
97.St -ansiC
98and 90and
99.St -1003.2-92 . 91.St -p1003.2-92 .
92.Sh CAVEATS
93Never supply the
94.Fn system
95function with a command containing any part of an unsanitized user-supplied
96string.
97Shell meta-characters present will be honored by the
98.Xr sh 1
99command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index c2f39325f6..06b439230b 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
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 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,8 +28,7 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/ 31static char *rcsid = "$OpenBSD: system.c,v 1.6 2003/06/02 20:18:38 millert Exp $";
36static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
38 33
39#include <sys/types.h> 34#include <sys/types.h>
@@ -51,20 +46,24 @@ system(command)
51{ 46{
52 pid_t pid; 47 pid_t pid;
53 sig_t intsave, quitsave; 48 sig_t intsave, quitsave;
54 int omask; 49 sigset_t mask, omask;
55 int pstat; 50 int pstat;
56 char *argp[] = {"sh", "-c", (char *) command, NULL}; 51 char *argp[] = {"sh", "-c", NULL, NULL};
57 52
58 if (!command) /* just checking... */ 53 if (!command) /* just checking... */
59 return(1); 54 return(1);
60 55
61 omask = sigblock(sigmask(SIGCHLD)); 56 argp[2] = (char *)command;
62 switch(pid = vfork()) { 57
58 sigemptyset(&mask);
59 sigaddset(&mask, SIGCHLD);
60 sigprocmask(SIG_BLOCK, &mask, &omask);
61 switch (pid = vfork()) {
63 case -1: /* error */ 62 case -1: /* error */
64 (void)sigsetmask(omask); 63 sigprocmask(SIG_SETMASK, &omask, NULL);
65 return(-1); 64 return(-1);
66 case 0: /* child */ 65 case 0: /* child */
67 (void)sigsetmask(omask); 66 sigprocmask(SIG_SETMASK, &omask, NULL);
68 execve(_PATH_BSHELL, argp, environ); 67 execve(_PATH_BSHELL, argp, environ);
69 _exit(127); 68 _exit(127);
70 } 69 }
@@ -72,8 +71,8 @@ system(command)
72 intsave = signal(SIGINT, SIG_IGN); 71 intsave = signal(SIGINT, SIG_IGN);
73 quitsave = signal(SIGQUIT, SIG_IGN); 72 quitsave = signal(SIGQUIT, SIG_IGN);
74 pid = waitpid(pid, (int *)&pstat, 0); 73 pid = waitpid(pid, (int *)&pstat, 0);
75 (void)sigsetmask(omask); 74 sigprocmask(SIG_SETMASK, &omask, NULL);
76 (void)signal(SIGINT, intsave); 75 (void)signal(SIGINT, intsave);
77 (void)signal(SIGQUIT, quitsave); 76 (void)signal(SIGQUIT, quitsave);
78 return(pid == -1 ? -1 : pstat); 77 return (pid == -1 ? -1 : pstat);
79} 78}
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..15d7b84a3a
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,116 @@
1.\" $OpenBSD: tsearch.3,v 1.12 2003/06/17 21:56:24 millert Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd June 15, 1997
18.Dt TSEARCH 3
19.Os
20.Sh NAME
21.Nm tsearch ,
22.Nm tfind ,
23.Nm tdelete ,
24.Nm twalk
25.Nd manipulate binary search trees
26.Sh SYNOPSIS
27.Fd #include <search.h>
28.Ft void *
29.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
30.Ft void *
31.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
32.Ft void *
33.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
34.Ft void
35.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
36.Sh DESCRIPTION
37The
38.Fn tdelete ,
39.Fn tfind ,
40.Fn tsearch ,
41and
42.Fn twalk
43functions manage binary search trees based on algorithms T and D
44from Knuth (6.2.2).
45The comparison function passed in by
46the user has the same style of return values as
47.Xr strcmp 3 .
48.Pp
49.Fn tfind
50searches for the datum matched by the argument
51.Fa key
52in the binary tree rooted at
53.Fa rootp ,
54returning a pointer to the datum if it is found and
55.Dv NULL
56if it is not.
57.Pp
58.Fn tsearch
59is identical to
60.Fn tfind
61except that if no match is found,
62.Fa key
63is inserted into the tree and a pointer to it is returned.
64If
65.Fa rootp
66points to a null value a new binary search tree is created.
67.Pp
68.Fn tdelete
69deletes a node from the specified binary search tree and returns
70a pointer to the parent of the node to be deleted.
71It takes the same arguments as
72.Fn tfind
73and
74.Fn tsearch .
75If the node to be deleted is the root of the binary search tree,
76.Fa rootp
77will be adjusted.
78.Pp
79.Fn twalk
80walks the binary search tree rooted in
81.Fa root
82and calls the function
83.Fa action
84on each node.
85.Fa action
86is called with three arguments: a pointer to the current node,
87a value from the enum
88.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
89specifying the traversal type, and a node level (where level
90zero is the root of the tree).
91.Sh RETURN VALUES
92The
93.Fn tsearch
94function returns
95.Dv NULL
96if allocation of a new node fails (usually
97due to a lack of free memory).
98.Pp
99.Fn tfind ,
100.Fn tsearch ,
101and
102.Fn tdelete
103return
104.Dv NULL
105if
106.Fa rootp
107is
108.Dv NULL
109or the datum cannot be found.
110.Pp
111The
112.Fn twalk
113function returns no value.
114.Sh SEE ALSO
115.Xr bsearch 3 ,
116.Xr lsearch 3
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}