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.inc64
-rw-r--r--src/lib/libc/stdlib/_Exit.c22
-rw-r--r--src/lib/libc/stdlib/_rand48.c1
-rw-r--r--src/lib/libc/stdlib/a64l.3133
-rw-r--r--src/lib/libc/stdlib/a64l.c30
-rw-r--r--src/lib/libc/stdlib/abort.328
-rw-r--r--src/lib/libc/stdlib/abort.c41
-rw-r--r--src/lib/libc/stdlib/abs.326
-rw-r--r--src/lib/libc/stdlib/abs.c15
-rw-r--r--src/lib/libc/stdlib/alloca.343
-rw-r--r--src/lib/libc/stdlib/atexit.327
-rw-r--r--src/lib/libc/stdlib/atexit.c233
-rw-r--r--src/lib/libc/stdlib/atexit.h67
-rw-r--r--src/lib/libc/stdlib/atof.315
-rw-r--r--src/lib/libc/stdlib/atof.c15
-rw-r--r--src/lib/libc/stdlib/atoi.337
-rw-r--r--src/lib/libc/stdlib/atoi.c15
-rw-r--r--src/lib/libc/stdlib/atol.321
-rw-r--r--src/lib/libc/stdlib/atol.c15
-rw-r--r--src/lib/libc/stdlib/atoll.3 (renamed from src/lib/libc/stdlib/calloc.3)61
-rw-r--r--src/lib/libc/stdlib/atoll.c38
-rw-r--r--src/lib/libc/stdlib/bsearch.325
-rw-r--r--src/lib/libc/stdlib/bsearch.c25
-rw-r--r--src/lib/libc/stdlib/cfree.c40
-rw-r--r--src/lib/libc/stdlib/div.327
-rw-r--r--src/lib/libc/stdlib/div.c15
-rw-r--r--src/lib/libc/stdlib/drand48.c1
-rw-r--r--src/lib/libc/stdlib/ecvt.3165
-rw-r--r--src/lib/libc/stdlib/ecvt.c105
-rw-r--r--src/lib/libc/stdlib/erand48.c1
-rw-r--r--src/lib/libc/stdlib/exit.366
-rw-r--r--src/lib/libc/stdlib/exit.c40
-rw-r--r--src/lib/libc/stdlib/gcvt.c111
-rw-r--r--src/lib/libc/stdlib/getenv.380
-rw-r--r--src/lib/libc/stdlib/getenv.c74
-rw-r--r--src/lib/libc/stdlib/getopt.3315
-rw-r--r--src/lib/libc/stdlib/getopt.c118
-rw-r--r--src/lib/libc/stdlib/getopt_long.3464
-rw-r--r--src/lib/libc/stdlib/getopt_long.c517
-rw-r--r--src/lib/libc/stdlib/getsubopt.3145
-rw-r--r--src/lib/libc/stdlib/getsubopt.c92
-rw-r--r--src/lib/libc/stdlib/hcreate.3184
-rw-r--r--src/lib/libc/stdlib/hcreate.c191
-rw-r--r--src/lib/libc/stdlib/heapsort.c27
-rw-r--r--src/lib/libc/stdlib/imaxabs.3 (renamed from src/lib/libc/stdlib/free.3)66
-rw-r--r--src/lib/libc/stdlib/imaxabs.c38
-rw-r--r--src/lib/libc/stdlib/imaxdiv.367
-rw-r--r--src/lib/libc/stdlib/imaxdiv.c50
-rw-r--r--src/lib/libc/stdlib/insque.3106
-rw-r--r--src/lib/libc/stdlib/insque.c48
-rw-r--r--src/lib/libc/stdlib/jrand48.c1
-rw-r--r--src/lib/libc/stdlib/l64a.c17
-rw-r--r--src/lib/libc/stdlib/labs.336
-rw-r--r--src/lib/libc/stdlib/labs.c15
-rw-r--r--src/lib/libc/stdlib/lcong48.c1
-rw-r--r--src/lib/libc/stdlib/ldiv.333
-rw-r--r--src/lib/libc/stdlib/ldiv.c15
-rw-r--r--src/lib/libc/stdlib/llabs.c (renamed from src/lib/libc/stdlib/calloc.c)27
-rw-r--r--src/lib/libc/stdlib/lldiv.3 (renamed from src/lib/libc/stdlib/memory.3)74
-rw-r--r--src/lib/libc/stdlib/lldiv.c50
-rw-r--r--src/lib/libc/stdlib/lrand48.c1
-rw-r--r--src/lib/libc/stdlib/lsearch.3108
-rw-r--r--src/lib/libc/stdlib/lsearch.c88
-rw-r--r--src/lib/libc/stdlib/malloc.3425
-rw-r--r--src/lib/libc/stdlib/malloc.c1673
-rw-r--r--src/lib/libc/stdlib/merge.c43
-rw-r--r--src/lib/libc/stdlib/mrand48.c1
-rw-r--r--src/lib/libc/stdlib/multibyte.c131
-rw-r--r--src/lib/libc/stdlib/nrand48.c1
-rw-r--r--src/lib/libc/stdlib/putenv.c31
-rw-r--r--src/lib/libc/stdlib/qabs.321
-rw-r--r--src/lib/libc/stdlib/qabs.c15
-rw-r--r--src/lib/libc/stdlib/qdiv.326
-rw-r--r--src/lib/libc/stdlib/qdiv.c15
-rw-r--r--src/lib/libc/stdlib/qsort.393
-rw-r--r--src/lib/libc/stdlib/qsort.c58
-rw-r--r--src/lib/libc/stdlib/radixsort.356
-rw-r--r--src/lib/libc/stdlib/radixsort.c66
-rw-r--r--src/lib/libc/stdlib/rand.337
-rw-r--r--src/lib/libc/stdlib/rand.c27
-rw-r--r--src/lib/libc/stdlib/rand48.347
-rw-r--r--src/lib/libc/stdlib/rand48.h4
-rw-r--r--src/lib/libc/stdlib/random.3114
-rw-r--r--src/lib/libc/stdlib/random.c131
-rw-r--r--src/lib/libc/stdlib/realloc.3100
-rw-r--r--src/lib/libc/stdlib/realpath.361
-rw-r--r--src/lib/libc/stdlib/realpath.c237
-rw-r--r--src/lib/libc/stdlib/remque.c44
-rw-r--r--src/lib/libc/stdlib/seed48.c1
-rw-r--r--src/lib/libc/stdlib/setenv.c75
-rw-r--r--src/lib/libc/stdlib/srand48.c1
-rw-r--r--src/lib/libc/stdlib/strtod.367
-rw-r--r--src/lib/libc/stdlib/strtod.c522
-rw-r--r--src/lib/libc/stdlib/strtof.c39
-rw-r--r--src/lib/libc/stdlib/strtoimax.c140
-rw-r--r--src/lib/libc/stdlib/strtol.3195
-rw-r--r--src/lib/libc/stdlib/strtol.c86
-rw-r--r--src/lib/libc/stdlib/strtoll.c (renamed from src/lib/libc/stdlib/strtoq.c)97
-rw-r--r--src/lib/libc/stdlib/strtonum.3152
-rw-r--r--src/lib/libc/stdlib/strtonum.c65
-rw-r--r--src/lib/libc/stdlib/strtoul.3176
-rw-r--r--src/lib/libc/stdlib/strtoul.c60
-rw-r--r--src/lib/libc/stdlib/strtoull.c (renamed from src/lib/libc/stdlib/strtouq.c)69
-rw-r--r--src/lib/libc/stdlib/strtoumax.c102
-rw-r--r--src/lib/libc/stdlib/system.357
-rw-r--r--src/lib/libc/stdlib/system.c35
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3127
-rw-r--r--src/lib/libc/stdlib/tsearch.c121
109 files changed, 7611 insertions, 2690 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index 782a4ab022..09db4ce793 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,24 +1,29 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 1# $OpenBSD: Makefile.inc,v 1.39 2008/08/22 17:14:56 otto 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 cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
9 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ 8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \
10 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ 9 lldiv.c lsearch.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 10 random.c realpath.c setenv.c strtoimax.c strtod.c strtof.c strtol.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 11 strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c system.c \
12 tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \
13 lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c _Exit.c
13 14
14.if (${MACHINE_ARCH} == "m68k") 15.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c 16SRCS+= abs.S div.c labs.c ldiv.c
17LSRCS+= abs.c
16.elif (${MACHINE_ARCH} == "i386") 18.elif (${MACHINE_ARCH} == "i386")
17SRCS+= abs.S div.S labs.S ldiv.S 19SRCS+= abs.S div.S labs.S ldiv.S
20LSRCS+= abs.c div.c labs.c ldiv.c
18.elif (${MACHINE_ARCH} == "ns32k") 21.elif (${MACHINE_ARCH} == "ns32k")
19SRCS+= abs.S div.c labs.c ldiv.c 22SRCS+= abs.S div.c labs.c ldiv.c
23LSRCS+= abs.c
20.elif (${MACHINE_ARCH} == "tahoe") 24.elif (${MACHINE_ARCH} == "tahoe")
21SRCS+= abs.S div.c labs.c ldiv.c 25SRCS+= abs.S div.c labs.c ldiv.c
26LSRCS+= abs.c
22.elif (${MACHINE_ARCH} == "vax") 27.elif (${MACHINE_ARCH} == "vax")
23SRCS+= abs.c div.c labs.c ldiv.c 28SRCS+= abs.c div.c labs.c ldiv.c
24.elif (${MACHINE_ARCH} == "alpha") 29.elif (${MACHINE_ARCH} == "alpha")
@@ -28,18 +33,41 @@ SRCS+= abs.c div.c labs.c ldiv.c
28SRCS+= abs.c div.c labs.c ldiv.c 33SRCS+= abs.c div.c labs.c ldiv.c
29.endif 34.endif
30 35
31MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 36.if (${MACHINE_ARCH} == "vax") || (${MACHINE_ARCH} == "m68k")
32 calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ 37SRCS+= insque.S remque.S
33 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ 38.else
34 rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ 39SRCS+= insque.c remque.c
35 system.3 40.endif
41
42MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
43 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
44 getsubopt.3 hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 \
45 lldiv.3 lsearch.3 malloc.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \
46 rand.3 random.3 realpath.3 strtod.3 strtonum.3 strtol.3 strtoul.3 \
47 system.3 tsearch.3
36 48
49MLINKS+=exit.3 _Exit.3
50MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
37MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 51MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
52MLINKS+=getopt_long.3 getopt_long_only.3
53MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
54MLINKS+=insque.3 remque.3
55MLINKS+=labs.3 llabs.3
56MLINKS+=lsearch.3 lfind.3
57MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
58MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
38MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 59MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
39MLINKS+=rand.3 srand.3 60MLINKS+=radixsort.3 sradixsort.3
40MLINKS+=strtol.3 strtoq.3 61MLINKS+=rand.3 srand.3 rand.3 rand_r.3
41MLINKS+=strtoul.3 strtouq.3 62MLINKS+=random.3 initstate.3 random.3 setstate.3
42MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 63MLINKS+=random.3 srandom.3 random.3 srandomdev.3
43MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 64MLINKS+=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 65MLINKS+=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 66MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
67MLINKS+=strtod.3 strtof.3
68MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3
69MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 strtoul.3 strtoumax.3
70MLINKS+=tsearch.3 tfind.3
71MLINKS+=tsearch.3 tdelete.3
72MLINKS+=tsearch.3 twalk.3
73MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_Exit.c b/src/lib/libc/stdlib/_Exit.c
new file mode 100644
index 0000000000..5a2291a931
--- /dev/null
+++ b/src/lib/libc/stdlib/_Exit.c
@@ -0,0 +1,22 @@
1/* $OpenBSD: _Exit.c,v 1.2 2005/08/08 08:05:36 espie Exp $ */
2
3/*
4 * Placed in the public domain by Todd C. Miller on January 21, 2004.
5 */
6
7#include <stdlib.h>
8#include <unistd.h>
9
10/*
11 * _Exit() is the ISO/ANSI C99 equivalent of the POSIX _exit() function.
12 * No atexit() handlers are called and no signal handlers are run.
13 * Whether or not stdio buffers are flushed or temporary files are removed
14 * is implementation-dependent. As such it is safest to *not* flush
15 * stdio buffers or remove temporary files. This is also consistent
16 * with most other implementations.
17 */
18void
19_Exit(int status)
20{
21 _exit(status);
22}
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
index 83ade4645a..7c950f7cee 100644
--- a/src/lib/libc/stdlib/_rand48.c
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: _rand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..6eec5ce3b3
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,133 @@
1.\" $OpenBSD: a64l.3,v 1.10 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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 NUL-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..5312929c6f 100644
--- a/src/lib/libc/stdlib/a64l.c
+++ b/src/lib/libc/stdlib/a64l.c
@@ -1,34 +1,42 @@
1/* $OpenBSD: a64l.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Written by J.T. Conklin <jtc@netbsd.org>. 3 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain. 4 * Public domain.
4 */ 5 */
5 6
6#if defined(LIBC_SCCS) && !defined(lint) 7#include <errno.h>
7static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; 8#include <stdlib.h>
8#endif
9 9
10long 10long
11a64l(s) 11a64l(const char *s)
12 const char *s;
13{ 12{
14 long value, digit, shift; 13 long value, digit, shift;
15 int i; 14 int i;
16 15
16 if (s == NULL) {
17 errno = EINVAL;
18 return(-1L);
19 }
20
17 value = 0; 21 value = 0;
18 shift = 0; 22 shift = 0;
19 for (i = 0; *s && i < 6; i++, s++) { 23 for (i = 0; *s && i < 6; i++, s++) {
20 if (*s <= '/') 24 if (*s >= '.' && *s <= '/')
21 digit = *s - '.'; 25 digit = *s - '.';
22 else if (*s <= '9') 26 else if (*s >= '0' && *s <= '9')
23 digit = *s - '0' + 2; 27 digit = *s - '0' + 2;
24 else if (*s <= 'Z') 28 else if (*s >= 'A' && *s <= 'Z')
25 digit = *s - 'A' + 12; 29 digit = *s - 'A' + 12;
26 else 30 else if (*s >= 'a' && *s <= 'z')
27 digit = *s - 'a' + 38; 31 digit = *s - 'a' + 38;
32 else {
33 errno = EINVAL;
34 return(-1L);
35 }
28 36
29 value |= digit << shift; 37 value |= digit << shift;
30 shift += 6; 38 shift += 6;
31 } 39 }
32 40
33 return (long) value; 41 return(value);
34} 42}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
index ab57327585..4ec85882b2 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,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: @(#)abort.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: abort.3,v 1.8 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt ABORT 3 35.Dt ABORT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -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..244e3b28aa 100644
--- a/src/lib/libc/stdlib/abort.c
+++ b/src/lib/libc/stdlib/abort.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: abort.c,v 1.15 2007/09/03 14:40:16 millert Exp $ */
1/* 2/*
2 * Copyright (c) 1985 Regents of the University of California. 3 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,27 +28,43 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/
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 */
38
39#include <signal.h> 31#include <signal.h>
40#include <stdlib.h> 32#include <stdlib.h>
41#include <unistd.h> 33#include <unistd.h>
34#include "thread_private.h"
35#include "atexit.h"
42 36
43void 37void
44abort() 38abort(void)
45{ 39{
40 struct atexit *p = __atexit;
41 static int cleanup_called = 0;
46 sigset_t mask; 42 sigset_t mask;
47 43
44
48 sigfillset(&mask); 45 sigfillset(&mask);
49 /* 46 /*
50 * don't block SIGABRT to give any handler a chance; we ignore 47 * don't block SIGABRT to give any handler a chance; we ignore
51 * any errors -- X311J doesn't allow abort to return anyway. 48 * any errors -- X311J doesn't allow abort to return anyway.
52 */ 49 */
53 sigdelset(&mask, SIGABRT); 50 sigdelset(&mask, SIGABRT);
54 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 51 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
52
53 /*
54 * POSIX requires we flush stdio buffers on abort
55 */
56 if (cleanup_called == 0) {
57 /* the cleanup routine lives in fns[0] on the last page */
58 while (p != NULL && p->next != NULL)
59 p = p->next;
60 /* the check for fn_dso == NULL is mostly paranoia */
61 if (p != NULL && p->fns[0].fn_dso == NULL &&
62 p->fns[0].fn_ptr.std_func != NULL) {
63 cleanup_called = 1;
64 (*p->fns[0].fn_ptr.std_func)();
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..c4135f9c84 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,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: @(#)abs.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: abs.3,v 1.8 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt ABS 3 35.Dt ABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,21 +44,18 @@
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 imaxabs 3 ,
58.Xr labs 3 ,
67.Xr math 3 59.Xr math 3
68.Sh STANDARDS 60.Sh STANDARDS
69The 61The
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
index 64468e0224..5d2fbae69f 100644
--- a/src/lib/libc/stdlib/abs.c
+++ b/src/lib/libc/stdlib/abs.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: abs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)abs.c 5.2 (Berkeley) 5/17/90";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41int 33int
42abs(j) 34abs(int j)
43 int j;
44{ 35{
45 return(j < 0 ? -j : j); 36 return(j < 0 ? -j : j);
46} 37}
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
index dcb97ab11c..d7fddb04c2 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.11 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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..0615feabb1 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,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: @(#)atexit.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atexit.3,v 1.8 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt ATEXIT 3 35.Dt ATEXIT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,17 +44,22 @@
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,
62and more are allowed as long as sufficient memory can be allocated. 56and more are allowed as long as sufficient memory can be allocated.
57.Pp
58.Fn atexit
59is very difficult to use correctly without creating
60.Xr exit 3 Ns -time
61races.
62Unless absolutely necessary, please avoid using it.
63.Sh RETURN VALUES 63.Sh RETURN VALUES
64.Rv -std atexit 64.Rv -std atexit
65.Sh ERRORS 65.Sh ERRORS
@@ -73,6 +73,5 @@ The existing list of functions is unmodified.
73.Sh STANDARDS 73.Sh STANDARDS
74The 74The
75.Fn atexit 75.Fn atexit
76function 76function conforms to
77conforms to
78.St -ansiC . 77.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 4da1eb0d9c..4d28fb5ef6 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -1,68 +1,209 @@
1/*- 1/* $OpenBSD: atexit.c,v 1.14 2007/09/05 20:47:47 chl Exp $ */
2 * Copyright (c) 1990 The Regents of the University of California. 2/*
3 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 4 * All rights reserved.
4 * 5 *
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 6 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
10 * are met: 8 * 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 * 9 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 10 * - Redistributions of source code must retain the above copyright
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 11 * notice, this list of conditions and the following disclaimer.
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 12 * - Redistributions in binary form must reproduce the above
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 13 * copyright notice, this list of conditions and the following
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 14 * disclaimer in the documentation and/or other materials provided
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 15 * with the distribution.
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 16 *
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 18 * "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 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * SUCH DAMAGE. 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * 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 *
35 */ 30 */
36 31
37#if defined(LIBC_SCCS) && !defined(lint) 32#include <sys/types.h>
38/*static char *sccsid = "from: @(#)atexit.c 5.2 (Berkeley) 11/14/90";*/ 33#include <sys/mman.h>
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 */
41
42#include <stdlib.h> 34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
43#include "atexit.h" 37#include "atexit.h"
38#include "thread_private.h"
44 39
40int __atexit_invalid = 1;
45struct atexit *__atexit; 41struct atexit *__atexit;
46 42
47/* 43/*
48 * Register a function to be performed at exit. 44 * Function pointers are stored in a linked list of pages. The list
45 * is initially empty, and pages are allocated on demand. The first
46 * function pointer in the first allocated page (the last one in
47 * the linked list) is reserved for the cleanup function.
48 *
49 * Outside the following functions, all pages are mprotect()'ed
50 * to prevent unintentional/malicious corruption.
51 */
52
53/*
54 * Register a function to be performed at exit or when a shared object
55 * with the given dso handle is unloaded dynamically. Also used as
56 * the backend for atexit(). For more info on this API, see:
57 *
58 * http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor
49 */ 59 */
50int 60int
51atexit(fn) 61__cxa_atexit(void (*func)(void *), void *arg, void *dso)
52 void (*fn)();
53{ 62{
54 static struct atexit __atexit0; /* one guaranteed table */ 63 struct atexit *p = __atexit;
55 register struct atexit *p; 64 struct atexit_fn *fnp;
65 int pgsize = getpagesize();
66 int ret = -1;
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 _ATEXIT_LOCK();
60 if ((p = malloc(sizeof(*p))) == NULL) 71 p = __atexit;
61 return (-1); 72 if (p != NULL) {
62 p->ind = 0; 73 if (p->ind + 1 >= p->max)
74 p = NULL;
75 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
76 goto unlock;
77 }
78 if (p == NULL) {
79 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
80 MAP_ANON | MAP_PRIVATE, -1, 0);
81 if (p == MAP_FAILED)
82 goto unlock;
83 if (__atexit == NULL) {
84 memset(&p->fns[0], 0, sizeof(p->fns[0]));
85 p->ind = 1;
86 } else
87 p->ind = 0;
88 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
89 sizeof(p->fns[0]);
63 p->next = __atexit; 90 p->next = __atexit;
64 __atexit = p; 91 __atexit = p;
92 if (__atexit_invalid)
93 __atexit_invalid = 0;
94 }
95 fnp = &p->fns[p->ind++];
96 fnp->fn_ptr.cxa_func = func;
97 fnp->fn_arg = arg;
98 fnp->fn_dso = dso;
99 if (mprotect(p, pgsize, PROT_READ))
100 goto unlock;
101 ret = 0;
102unlock:
103 _ATEXIT_UNLOCK();
104 return (ret);
105}
106
107/*
108 * Register a function to be performed at exit.
109 */
110int
111atexit(void (*func)(void))
112{
113 return (__cxa_atexit((void (*)(void *))func, NULL, NULL));
114}
115
116/*
117 * Call all handlers registered with __cxa_atexit() for the shared
118 * object owning 'dso'.
119 * Note: if 'dso' is NULL, then all remaining handlers are called.
120 */
121void
122__cxa_finalize(void *dso)
123{
124 struct atexit *p, *q;
125 struct atexit_fn fn;
126 int n, pgsize = getpagesize();
127 static int call_depth;
128
129 if (__atexit_invalid)
130 return;
131
132 call_depth++;
133
134 for (p = __atexit; p != NULL; p = p->next) {
135 for (n = p->ind; --n >= 0;) {
136 if (p->fns[n].fn_ptr.cxa_func == NULL)
137 continue; /* already called */
138 if (dso != NULL && dso != p->fns[n].fn_dso)
139 continue; /* wrong DSO */
140
141 /*
142 * Mark handler as having been already called to avoid
143 * dupes and loops, then call the appropriate function.
144 */
145 fn = p->fns[n];
146 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) {
147 p->fns[n].fn_ptr.cxa_func = NULL;
148 mprotect(p, pgsize, PROT_READ);
149 }
150 if (dso != NULL)
151 (*fn.fn_ptr.cxa_func)(fn.fn_arg);
152 else
153 (*fn.fn_ptr.std_func)();
154 }
155 }
156
157 /*
158 * If called via exit(), unmap the pages since we have now run
159 * all the handlers. We defer this until calldepth == 0 so that
160 * we don't unmap things prematurely if called recursively.
161 */
162 if (dso == NULL && --call_depth == 0) {
163 for (p = __atexit; p != NULL; ) {
164 q = p;
165 p = p->next;
166 munmap(q, pgsize);
167 }
168 __atexit = NULL;
169 }
170}
171
172/*
173 * Register the cleanup function
174 */
175void
176__atexit_register_cleanup(void (*func)(void))
177{
178 struct atexit *p;
179 int pgsize = getpagesize();
180
181 if (pgsize < sizeof(*p))
182 return;
183 _ATEXIT_LOCK();
184 p = __atexit;
185 while (p != NULL && p->next != NULL)
186 p = p->next;
187 if (p == NULL) {
188 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
189 MAP_ANON | MAP_PRIVATE, -1, 0);
190 if (p == MAP_FAILED)
191 goto unlock;
192 p->ind = 1;
193 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
194 sizeof(p->fns[0]);
195 p->next = NULL;
196 __atexit = p;
197 if (__atexit_invalid)
198 __atexit_invalid = 0;
199 } else {
200 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
201 goto unlock;
65 } 202 }
66 p->fns[p->ind++] = fn; 203 p->fns[0].fn_ptr.std_func = func;
67 return (0); 204 p->fns[0].fn_arg = NULL;
205 p->fns[0].fn_dso = NULL;
206 mprotect(p, pgsize, PROT_READ);
207unlock:
208 _ATEXIT_UNLOCK();
68} 209}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
index 8b756e8fe2..1b23565dd0 100644
--- a/src/lib/libc/stdlib/atexit.h
+++ b/src/lib/libc/stdlib/atexit.h
@@ -1,46 +1,51 @@
1/*- 1/* $OpenBSD: atexit.h,v 1.7 2007/09/03 14:40:16 millert 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 struct atexit_fn {
38 union {
39 void (*std_func)(void);
40 void (*cxa_func)(void *);
41 } fn_ptr;
42 void *fn_arg; /* argument for CXA callback */
43 void *fn_dso; /* shared module handle */
44 } fns[1]; /* the table itself */
44}; 45};
45 46
47extern int __atexit_invalid;
46extern struct atexit *__atexit; /* points to head of LIFO stack */ 48extern struct atexit *__atexit; /* points to head of LIFO stack */
49
50int __cxa_atexit(void (*)(void *), void *, void *);
51void __cxa_finalize(void *);
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
index 53e04f71c5..2538d0c879 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,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: @(#)atof.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: atof.3,v 1.5 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt ATOF 3 35.Dt ATOF 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -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..d14b58b070 100644
--- a/src/lib/libc/stdlib/atof.c
+++ b/src/lib/libc/stdlib/atof.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: atof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1988 The Regents of the University of California. 3 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41double 33double
42atof(ascii) 34atof(const char *ascii)
43 const char *ascii;
44{ 35{
45 return(strtod(ascii, (char **)NULL)); 36 return(strtod(ascii, (char **)NULL));
46} 37}
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
index 219ba73c00..0c6b62b25f 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.9 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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
@@ -67,9 +61,26 @@ It is equivalent to:
67.Xr atol 3 , 61.Xr atol 3 ,
68.Xr strtod 3 , 62.Xr strtod 3 ,
69.Xr strtol 3 , 63.Xr strtol 3 ,
64.Xr strtonum 3 ,
70.Xr strtoul 3 65.Xr strtoul 3
71.Sh STANDARDS 66.Sh STANDARDS
72The 67The
73.Fn atoi 68.Fn atoi
74function conforms to 69function conforms to
75.St -ansiC . 70.St -ansiC .
71.Sh CAVEATS
72.Nm
73does no overflow checking, handles unsigned numbers poorly,
74and handles strings containing trailing extra characters
75(like
76.Dq "123abc" )
77poorly.
78Careful use of
79.Xr strtol 3
80and
81.Xr strtoul 3
82can alleviate these problems,
83but
84.Xr strtonum 3
85can be used to convert numbers from strings much more safely
86and easily.
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
index df7845f90c..b0842678e2 100644
--- a/src/lib/libc/stdlib/atoi.c
+++ b/src/lib/libc/stdlib/atoi.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: atoi.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1988 Regents of the University of California. 3 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atoi.c 5.7 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41int 33int
42atoi(str) 34atoi(const char *str)
43 const char *str;
44{ 35{
45 return((int)strtol(str, (char **)NULL, 10)); 36 return((int)strtol(str, (char **)NULL, 10));
46} 37}
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
index 86e3d324a3..3c5551182d 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,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: @(#)atol.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atol.3,v 1.7 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt ATOL 3 35.Dt ATOL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -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..1970804401 100644
--- a/src/lib/libc/stdlib/atol.c
+++ b/src/lib/libc/stdlib/atol.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: atol.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1988 Regents of the University of California. 3 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)atol.c 5.7 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41long 33long
42atol(str) 34atol(const char *str)
43 const char *str;
44{ 35{
45 return(strtol(str, (char **)NULL, 10)); 36 return(strtol(str, (char **)NULL, 10));
46} 37}
diff --git a/src/lib/libc/stdlib/calloc.3 b/src/lib/libc/stdlib/atoll.3
index d0754b46a0..608a61f4ce 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.5 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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 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..a65e682cfb
--- /dev/null
+++ b/src/lib/libc/stdlib/atoll.c
@@ -0,0 +1,38 @@
1/* $OpenBSD: atoll.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
4 * 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
31#include <stdlib.h>
32
33long long
34atoll(str)
35 const char *str;
36{
37 return(strtoll(str, (char **)NULL, 10));
38}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 1622c96c6b..4877a1023e 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.7 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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..8193d27c60 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 *
@@ -31,11 +27,6 @@
31 * SUCH DAMAGE. 27 * SUCH DAMAGE.
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)bsearch.c 5.4 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 30#include <stdlib.h>
40 31
41/* 32/*
@@ -55,16 +46,12 @@ static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
55 * look at item 3. 46 * look at item 3.
56 */ 47 */
57void * 48void *
58bsearch(key, base0, nmemb, size, compar) 49bsearch(const void *key, const void *base0, size_t nmemb, size_t size,
59 register const void *key; 50 int (*compar)(const void *, const void *))
60 const void *base0;
61 size_t nmemb;
62 register size_t size;
63 register int (*compar) __P((const void *, const void *));
64{ 51{
65 register const char *base = base0; 52 const char *base = base0;
66 register int lim, cmp; 53 int lim, cmp;
67 register const void *p; 54 const void *p;
68 55
69 for (lim = nmemb; lim != 0; lim >>= 1) { 56 for (lim = nmemb; lim != 0; lim >>= 1) {
70 p = base + (lim >> 1) * size; 57 p = base + (lim >> 1) * size;
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..373c7ff75d
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: cfree.c,v 1.5 2005/08/08 08:05:36 espie 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#include <sys/cdefs.h>
29#include <stdlib.h>
30
31#ifdef __indr_reference
32__indr_reference(free, cfree);
33#else
34
35void
36cfree(void *p)
37{
38 free(p);
39}
40#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
index a4730694a5..4a48ab1ea4 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,10 +27,9 @@
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.9 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
38.Dt DIV 3 33.Dt DIV 3
39.Os 34.Os
40.Sh NAME 35.Sh NAME
@@ -47,24 +42,24 @@
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
56.Xr imaxdiv 3 ,
62.Xr ldiv 3 , 57.Xr ldiv 3 ,
63.Xr qdiv 3 , 58.Xr lldiv 3 ,
64.Xr math 3 59.Xr math 3 ,
60.Xr qdiv 3
65.Sh STANDARDS 61.Sh STANDARDS
66The 62The
67.Fn div 63.Fn div
68function 64function conforms to
69conforms to
70.St -ansiC . 65.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
index 122ac0deec..f7ac2db4b0 100644
--- a/src/lib/libc/stdlib/div.c
+++ b/src/lib/libc/stdlib/div.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: div.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1990 Regents of the University of California. 3 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -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 *
@@ -34,16 +31,10 @@
34 * SUCH DAMAGE. 31 * SUCH DAMAGE.
35 */ 32 */
36 33
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)div.c 5.2 (Berkeley) 4/16/91";*/
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 */
41
42#include <stdlib.h> /* div_t */ 34#include <stdlib.h> /* div_t */
43 35
44div_t 36div_t
45div(num, denom) 37div(int num, int denom)
46 int num, denom;
47{ 38{
48 div_t r; 39 div_t r;
49 40
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
index ae1a8634dc..b6c046c831 100644
--- a/src/lib/libc/stdlib/drand48.c
+++ b/src/lib/libc/stdlib/drand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: drand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3
new file mode 100644
index 0000000000..0717a2c02a
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: ecvt.3,v 1.8 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
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..719370a8f3
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,105 @@
1/* $OpenBSD: ecvt.c,v 1.6 2006/10/29 18:45:56 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2002, 2006 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#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27extern char *__dtoa(double, int, int, int *, int *, char **);
28extern void __freedtoa(char *);
29static char *__cvt(double, int, int *, int *, int, int);
30
31static char *
32__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
33{
34 static char *s;
35 char *p, *rve, c;
36 size_t siz;
37
38 if (ndigit == 0) {
39 *sign = value < 0.0;
40 *decpt = 0;
41 return ("");
42 }
43
44 if (s) {
45 free(s);
46 s = NULL;
47 }
48
49 if (ndigit < 0)
50 siz = -ndigit + 1;
51 else
52 siz = ndigit + 1;
53
54
55 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
56 if (value == 0.0) {
57 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
58 *sign = 0;
59 if ((rve = s = (char *)malloc(siz)) == NULL)
60 return(NULL);
61 *rve++ = '0';
62 *rve = '\0';
63 } else {
64 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
65 if (*decpt == 9999) {
66 /* Infinity or Nan, convert to inf or nan like printf */
67 *decpt = 0;
68 c = *p;
69 __freedtoa(p);
70 return(c == 'I' ? "inf" : "nan");
71 }
72 /* Make a local copy and adjust rve to be in terms of s */
73 if (pad && fmode)
74 siz += *decpt;
75 if ((s = (char *)malloc(siz)) == NULL) {
76 __freedtoa(p);
77 return(NULL);
78 }
79 (void) strlcpy(s, p, siz);
80 rve = s + (rve - p);
81 __freedtoa(p);
82 }
83
84 /* Add trailing zeros */
85 if (pad) {
86 siz -= rve - s;
87 while (--siz)
88 *rve++ = '0';
89 *rve = '\0';
90 }
91
92 return(s);
93}
94
95char *
96ecvt(double value, int ndigit, int *decpt, int *sign)
97{
98 return(__cvt(value, ndigit, decpt, sign, 0, 1));
99}
100
101char *
102fcvt(double value, int ndigit, int *decpt, int *sign)
103{
104 return(__cvt(value, ndigit, decpt, sign, 1, 1));
105}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
index cc9fbf770c..2ffeaa6e71 100644
--- a/src/lib/libc/stdlib/erand48.c
+++ b/src/lib/libc/stdlib/erand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: erand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
index adb81ffcb4..45eae80a08 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,25 +29,30 @@
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.11 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt EXIT 3 35.Dt EXIT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm exit 38.Nm exit, _Exit
44.Nd perform normal program termination 39.Nd perform normal program termination
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft void 42.Ft void
48.Fn exit "int status" 43.Fn exit "int status"
44.Ft void
45.Fn _Exit "int status"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50.Fn Exit 47The
51terminates a process. 48.Fn exit
49and
50.Fn _Exit
51functions terminate a process.
52.Pp 52.Pp
53Before termination it performs the following functions in the 53Before termination,
54order listed: 54.Fn exit
55performs the following operations in the order listed:
55.Bl -enum -offset indent 56.Bl -enum -offset indent
56.It 57.It
57Call the functions registered with the 58Call the functions registered with the
@@ -66,19 +67,48 @@ Unlink all files created with the
66.Xr tmpfile 3 67.Xr tmpfile 3
67function. 68function.
68.El 69.El
70.Pp
71The
72.Fn _Exit
73function terminates without calling the functions registered with the
74.Xr atexit 3
75function.
76The
77.Ox
78implementation of
79.Fn _Exit
80does not flush open output streams or unlink files created with the
81.Xr tmpfile 3
82function.
83However, this behavior is implementation-specific.
84.Pp
85Lastly,
86.Fn exit
87and
88.Fn _Exit
89call
90.Xr _exit 2 .
91Note that typically
92.Xr _exit 2
93only passes the lower 8 bits of
94.Fa status
95on to the parent, thus negative values have less meaning.
69.Sh RETURN VALUES 96.Sh RETURN VALUES
70The 97The
71.Fn exit 98.Fn exit
72function 99and
73never returns. 100.Fn _Exit
101functions never return.
74.Sh SEE ALSO 102.Sh SEE ALSO
75.Xr _exit 2 , 103.Xr _exit 2 ,
76.Xr atexit 3 , 104.Xr atexit 3 ,
77.Xr intro 3 , 105.Xr intro 3 ,
106.Xr sysexits 3 ,
78.Xr tmpfile 3 107.Xr tmpfile 3
79.Sh STANDARDS 108.Sh STANDARDS
80The 109The
81.Fn exit 110.Fn exit
82function 111and
83conforms to 112.Fn _Exit
84.St -ansiC . 113functions conform to
114.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
index b1412f42bb..83fe3d2de5 100644
--- a/src/lib/libc/stdlib/exit.c
+++ b/src/lib/libc/stdlib/exit.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: exit.c,v 1.12 2007/09/03 14:40:16 millert Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,31 +28,32 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <sys/types.h>
35/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/ 32#include <sys/mman.h>
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 */
38
39#include <stdlib.h> 33#include <stdlib.h>
40#include <unistd.h> 34#include <unistd.h>
41#include "atexit.h" 35#include "atexit.h"
36#include "thread_private.h"
42 37
43void (*__cleanup)(); 38/*
39 * This variable is zero until a process has created a thread.
40 * It is used to avoid calling locking functions in libc when they
41 * are not required. By default, libc is intended to be(come)
42 * thread-safe, but without a (significant) penalty to non-threaded
43 * processes.
44 */
45int __isthreaded = 0;
44 46
45/* 47/*
46 * Exit, flushing stdio buffers if necessary. 48 * Exit, flushing stdio buffers if necessary.
47 */ 49 */
48void 50void
49exit(status) 51exit(int status)
50 int status;
51{ 52{
52 register struct atexit *p; 53 /*
53 register int n; 54 * Call functions registered by atexit() or _cxa_atexit()
54 55 * (including the stdio cleanup routine) and then _exit().
55 for (p = __atexit; p; p = p->next) 56 */
56 for (n = p->ind; --n >= 0;) 57 __cxa_finalize(NULL);
57 (*p->fns[n])();
58 if (__cleanup)
59 (*__cleanup)();
60 _exit(status); 58 _exit(status);
61} 59}
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..c24157e465
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,111 @@
1/* $OpenBSD: gcvt.c,v 1.10 2006/10/29 18:45:56 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003, 2006 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#include <locale.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28extern char *__dtoa(double, int, int, int *, int *, char **);
29extern void __freedtoa(char *);
30
31char *
32gcvt(double value, int ndigit, char *buf)
33{
34 char *digits, *dst, *src;
35 int i, decpt, sign;
36 struct lconv *lconv;
37
38 lconv = localeconv();
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 /*
47 * Infinity or NaN, convert to inf or nan with sign.
48 * We assume the buffer is at least ndigit long.
49 */
50 snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "",
51 *digits == 'I' ? "inf" : "nan");
52 __freedtoa(digits);
53 return (buf);
54 }
55
56 dst = buf;
57 if (sign)
58 *dst++ = '-';
59
60 if (decpt < 0 || decpt > ndigit) {
61 /* exponential format (e.g. 1.2345e+13) */
62 if (--decpt < 0) {
63 sign = 1;
64 decpt = -decpt;
65 } else
66 sign = 0;
67 src = digits;
68 *dst++ = *src++;
69 *dst++ = *lconv->decimal_point;
70 while (*src != '\0')
71 *dst++ = *src++;
72 *dst++ = 'e';
73 if (sign)
74 *dst++ = '-';
75 else
76 *dst++ = '+';
77 if (decpt < 10) {
78 *dst++ = '0';
79 *dst++ = '0' + decpt;
80 *dst = '\0';
81 } else {
82 /* XXX - optimize */
83 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
84 continue;
85 dst[i + 1] = '\0';
86 while (decpt != 0) {
87 dst[i--] = '0' + decpt % 10;
88 decpt /= 10;
89 }
90 }
91 } else {
92 /* standard format */
93 for (i = 0, src = digits; i < decpt; i++) {
94 if (*src != '\0')
95 *dst++ = *src++;
96 else
97 *dst++ = '0';
98 }
99 if (*src != '\0') {
100 if (src == digits)
101 *dst++ = '0'; /* zero before decimal point */
102 *dst++ = *lconv->decimal_point;
103 for (i = decpt; digits[i] != '\0'; i++) {
104 *dst++ = digits[i];
105 }
106 }
107 *dst = '\0';
108 }
109 __freedtoa(digits);
110 return (buf);
111}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
index 411eb35da4..1d8546997f 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.12 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
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,8 +105,11 @@ 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 Er
125.It Bq Er ENOMEM 115.It Bq Er ENOMEM
@@ -140,12 +130,18 @@ The
140function conforms to 130function conforms to
141.St -ansiC . 131.St -ansiC .
142.Sh HISTORY 132.Sh HISTORY
133The function
134.Fn getenv
135appeared in
136.At v7
137and
138.Bx 3 .
143The functions 139The functions
144.Fn setenv 140.Fn setenv
145and 141and
146.Fn unsetenv 142.Fn unsetenv
147appeared in 143appeared in
148.At v7 . 144.Bx 4.3 Tahoe .
149The 145The
150.Fn putenv 146.Fn putenv
151function appeared in 147function appeared in
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 09d47f2149..72367b34e2 100644
--- a/src/lib/libc/stdlib/getenv.c
+++ b/src/lib/libc/stdlib/getenv.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: getenv.c,v 1.8 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1987 Regents of the University of California. 3 * Copyright (c) 1987, 1993
3 * All rights reserved. 4 * The Regents of the University of California. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,27 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)getenv.c 5.8 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
42/* 34char *__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 35
56/* 36/*
57 * __findenv -- 37 * __findenv --
@@ -63,20 +43,38 @@ getenv(name)
63 * This routine *should* be a static; don't use it. 43 * This routine *should* be a static; don't use it.
64 */ 44 */
65char * 45char *
66__findenv(name, offset) 46__findenv(const char *name, int *offset)
67 register char *name;
68 int *offset;
69{ 47{
70 extern char **environ; 48 extern char **environ;
71 register int len; 49 int len, i;
72 register char **P, *C; 50 const char *np;
51 char **p, *cp;
52
53 if (name == NULL || environ == NULL)
54 return (NULL);
55 for (np = name; *np && *np != '='; ++np)
56 ;
57 len = np - name;
58 for (p = environ; (cp = *p) != NULL; ++p) {
59 for (np = name, i = len; i && *cp; i--)
60 if (*cp++ != *np++)
61 break;
62 if (i == 0 && *cp++ == '=') {
63 *offset = p - environ;
64 return (cp);
65 }
66 }
67 return (NULL);
68}
69
70/*
71 * getenv --
72 * Returns ptr to value associated with name, if any, else NULL.
73 */
74char *
75getenv(const char *name)
76{
77 int offset;
73 78
74 for (C = name, len = 0; *C && *C != '='; ++C, ++len); 79 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} 80}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
index f843881afd..06167cb7d6 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,20 +25,20 @@
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.40 2007/05/31 19:19:31 jmc Exp $
33.\" 29.\"
34.Dd April 19, 1994 30.Dd $Mdocdate: May 31 2007 $
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
40.Sh SYNOPSIS 36.Sh SYNOPSIS
41.Fd #include <unistd.h> 37.Fd #include <unistd.h>
42.Vt extern char *optarg; 38.Vt extern char *optarg;
39.Vt extern int opterr;
43.Vt extern int optind; 40.Vt extern int optind;
44.Vt extern int optopt; 41.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset; 42.Vt extern int optreset;
47.Ft int 43.Ft int
48.Fn getopt "int argc" "char * const *argv" "const char *optstring" 44.Fn getopt "int argc" "char * const *argv" "const char *optstring"
@@ -61,20 +57,23 @@ 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 POSIX.
67For example, an option string 66For example, an option string
68.Li "\&""x"" 67.Qq x
69recognizes an option 68recognizes an option
70.Dq Fl x , 69.Fl x ,
71and an option string 70and an option string
72.Li "\&""x:"" 71.Qq Li x:
73recognizes an option and argument 72recognizes an option and argument
74.Dq Fl x Ar argument . 73.Fl x Ar argument .
75It does not matter to 74It does not matter to
76.Fn getopt 75.Fn getopt
77if a following argument has leading white space. 76if a following argument has leading whitespace.
78.Pp 77.Pp
79On return from 78On return from
80.Fn getopt , 79.Fn getopt ,
@@ -87,23 +86,23 @@ contains the index to the next
87argument for a subsequent call 86argument for a subsequent call
88to 87to
89.Fn getopt . 88.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp 89.Pp
97The variable 90The variables
98.Va opterr 91.Va opterr
99and 92and
100.Va optind 93.Va optind
101are both initialized to 1. 94are both initialized to 1.
102The 95The
103.Va optind 96.Va optind
104variable may be set to another value before a set of calls to 97variable may be set to another value larger than 0 before a set of calls to
105.Fn getopt 98.Fn getopt
106in order to skip over more or less argv entries. 99in order to skip over more or less
100.Fa argv
101entries.
102An
103.Va optind
104value of 0 is reserved for compatibility with GNU
105.Fn getopt .
107.Pp 106.Pp
108In order to use 107In order to use
109.Fn getopt 108.Fn getopt
@@ -119,101 +118,163 @@ must be reinitialized.
119.Pp 118.Pp
120The 119The
121.Fn getopt 120.Fn getopt
122function 121function 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 122The interpretation of options in the argument list may be cancelled
127by the option 123by the option
128.Ql -- 124.Ql --
129(double dash) which causes 125(double dash) which causes
130.Fn getopt 126.Fn getopt
131to signal the end of argument processing and returns \-1. 127to signal the end of argument processing and return \-1.
132When all options have been processed (i.e., up to the first non-option 128When all options have been processed (i.e., up to the first non-option
133argument), 129argument),
134.Fn getopt 130.Fn getopt
135returns \-1. 131returns \-1.
136.Sh DIAGNOSTICS 132.Sh RETURN VALUES
137If the 133The
138.Fn getopt 134.Fn getopt
139function encounters a character not found in the string 135function returns the next known option character in
140.Va optarg 136.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 137If
150.Va optstring 138.Fn getopt
151has a leading 139encounters a character not found in
152.Ql \&: 140.Fa optstring
153then a missing option argument causes a 141or if it detects a missing option argument,
154.Ql \&: 142it returns
155to be returned in addition to suppressing any error messages. 143.Sq \&?
156.Pp 144(question mark).
157Option arguments are allowed to begin with 145If
158.Dq Li \- ; 146.Fa optstring
159this is reasonable but 147has a leading
160reduces the amount of error checking possible. 148.Sq \&:
161.Sh EXTENSIONS 149then a missing option argument causes
150.Sq \&:
151to be returned instead of
152.Sq \&? .
153In either case, the variable
154.Va optopt
155is set to the character that caused the error.
162The 156The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt 157.Fn getopt
166function multiple times. 158function returns \-1 when the argument list is exhausted.
167This is an extension to the 159.Sh ENVIRONMENT
168.St -p1003.2 160.Bl -tag -width POSIXLY_CORRECTXX
169specification. 161.It Ev POSIXLY_CORRECT
170.Sh EXAMPLE 162If set, a leading
171.Bd -literal -compact 163.Sq -
172extern char *optarg; 164in
173extern int optind; 165.Ar optstring
166is ignored.
167.El
168.Sh EXAMPLES
169The following code accepts the options
170.Fl b
171and
172.Fl f Ar argument
173and adjusts
174.Va argc
175and
176.Va argv
177after option argument processing has completed.
178.Bd -literal -offset indent
174int bflag, ch, fd; 179int bflag, ch, fd;
175 180
176bflag = 0; 181bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) 182while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch(ch) { 183 switch (ch) {
179 case 'b': 184 case 'b':
180 bflag = 1; 185 bflag = 1;
181 break; 186 break;
182 case 'f': 187 case 'f':
183 if ((fd = open(optarg, O_RDONLY, 0)) < 0) { 188 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
184 (void)fprintf(stderr, 189 err(1, "%s", optarg);
185 "myname: %s: %s\en", optarg, strerror(errno));
186 exit(1);
187 }
188 break; 190 break;
189 case '?':
190 default: 191 default:
191 usage(); 192 usage();
193 /* NOTREACHED */
194 }
192} 195}
193argc -= optind; 196argc -= optind;
194argv += optind; 197argv += optind;
195.Ed 198.Ed
196.Sh HISTORY 199.Sh DIAGNOSTICS
200If the
201.Fn getopt
202function encounters a character not found in the string
203.Fa optstring
204or detects
205a missing option argument, it writes an error message to
206.Em stderr
207and returns
208.Ql \&? .
209Setting
210.Va opterr
211to a zero will disable these error messages.
212If
213.Fa optstring
214has a leading
215.Ql \&:
216then a missing option argument causes a
217.Ql \&:
218to be returned in addition to suppressing any error messages.
219.Pp
220Option arguments are allowed to begin with
221.Ql - ;
222this is reasonable but reduces the amount of error checking possible.
223.Sh SEE ALSO
224.Xr getopt 1 ,
225.Xr getopt_long 3 ,
226.Xr getsubopt 3
227.Sh STANDARDS
197The 228The
198.Fn getopt 229.Fn getopt
199function appeared 230function implements a superset of the functionality specified by
200.Bx 4.3 . 231.St -p1003.1 .
201.Sh BUGS 232.Pp
233The following extensions are supported:
234.Bl -tag -width "xxx"
235.It Li o
202The 236The
237.Va optreset
238variable was added to make it possible to call the
203.Fn getopt 239.Fn getopt
204function was once specified to return 240function multiple times.
205.Dv EOF 241.It Li o
206instead of \-1. 242If the
207This was changed by 243.Va optind
208.St -p1003.2-92 244variable is set to 0,
209to decouple
210.Fn getopt 245.Fn getopt
211from 246will behave as if the
212.Pa <stdio.h> . 247.Va optreset
213.Pp 248variable has been set.
249This is for compatibility with
250.Tn GNU
251.Fn getopt .
252New code should use
253.Va optreset
254instead.
255.It Li o
256If the first character of
257.Fa optstring
258is a plus sign
259.Pq Ql + ,
260it will be ignored.
261This is for compatibility with
262.Tn GNU
263.Fn getopt .
264.It Li o
265If the first character of
266.Fa optstring
267is a dash
268.Pq Ql - ,
269non-options will be returned as arguments to the option character
270.Ql \e1 .
271This is for compatibility with
272.Tn GNU
273.Fn getopt .
274.It Li o
214A single dash 275A single dash
215.Dq Li - 276.Pq Ql -
216may be specified as an character in 277may be specified as a character in
217.Fa optstring , 278.Fa optstring ,
218however it should 279however it should
219.Em never 280.Em never
@@ -221,40 +282,90 @@ have an argument associated with it.
221This allows 282This allows
222.Fn getopt 283.Fn getopt
223to be used with programs that expect 284to be used with programs that expect
224.Dq Li - 285.Ql -
225as an option flag. 286as an option flag.
226This practice is wrong, and should not be used in any current development. 287This practice is wrong, and should not be used in any current development.
227It is provided for backward compatibility 288It is provided for backward compatibility
228.Em only . 289.Em only .
290Care should be taken not to use
291.Ql -
292as the first character in
293.Fa optstring
294to avoid a semantic conflict with
295.Tn GNU
296.Fn getopt
297semantics (see above).
229By default, a single dash causes 298By default, a single dash causes
230.Fn getopt 299.Fn getopt
231to return \-1. 300to return \-1.
232This is, we believe, compatible with System V. 301.El
302.Pp
303Historic
304.Bx
305versions of
306.Fn getopt
307set
308.Fa optopt
309to the last option character processed.
310However, this conflicts with
311.St -p1003.1
312which stipulates that
313.Fa optopt
314be set to the last character that caused an error.
315.Sh HISTORY
316The
317.Fn getopt
318function appeared in
319.Bx 4.3 .
320.Sh BUGS
321The
322.Fn getopt
323function was once specified to return
324.Dv EOF
325instead of \-1.
326This was changed by
327.St -p1003.2-92
328to decouple
329.Fn getopt
330from
331.Aq Pa stdio.h .
233.Pp 332.Pp
234It is also possible to handle digits as option letters. 333It is possible to handle digits as option letters.
235This allows 334This allows
236.Fn getopt 335.Fn getopt
237to be used with programs that expect a number 336to be used with programs that expect a number
238.Pq Dq Li \&-\&3 337.Pq Dq Li \-3
239as an option. 338as an option.
240This practice is wrong, and should not be used in any current development. 339This practice is wrong, and should not be used in any current development.
241It is provided for backward compatibility 340It is provided for backward compatibility
242.Em only . 341.Em only .
243The following code fragment works in most cases. 342The following code fragment works in most cases and can handle mixed
343number and letter arguments.
244.Bd -literal -offset indent 344.Bd -literal -offset indent
245int length; 345int aflag = 0, bflag = 0, ch, lastch = '\e0';
246char *p; 346int length = -1, newarg = 1, prevoptind = 1;
247 347
248while ((c = getopt(argc, argv, "0123456789")) != -1) 348while ((ch = getopt(argc, argv, "0123456789ab")) != -1) {
249 switch (c) { 349 switch (ch) {
250 case '0': case '1': case '2': case '3': case '4': 350 case '0': case '1': case '2': case '3': case '4':
251 case '5': case '6': case '7': case '8': case '9': 351 case '5': case '6': case '7': case '8': case '9':
252 p = argv[optind - 1]; 352 if (newarg || !isdigit(lastch))
253 if (p[0] == '-' && p[1] == ch && !p[2]) 353 length = 0;
254 length = atoi(++p); 354 else if (length > INT_MAX / 10)
255 else 355 usage();
256 length = atoi(argv[optind] + 1); 356 length = (length * 10) + (ch - '0');
257 break; 357 break;
358 case 'a':
359 aflag = 1;
360 break;
361 case 'b':
362 bflag = 1;
363 break;
364 default:
365 usage();
258 } 366 }
367 lastch = ch;
368 newarg = optind != prevoptind;
369 prevoptind = optind;
259} 370}
260.Ed 371.Ed
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..2bab963734
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.3
@@ -0,0 +1,464 @@
1.\" $OpenBSD: getopt_long.3,v 1.15 2007/07/03 12:06:07 jmc 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 $Mdocdate: July 3 2007 $
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 -offset indent
82$ myprogram --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
96Abbreviated long option names are accepted when
97.Fn getopt_long
98processes long options if the abbreviation is unique.
99An exact match is always preferred for a defined long option.
100.Pp
101The
102.Fn getopt_long
103call requires a structure to be initialized describing the long
104options.
105The structure is:
106.Bd -literal -offset indent
107struct option {
108 char *name;
109 int has_arg;
110 int *flag;
111 int val;
112};
113.Ed
114.Pp
115The
116.Fa name
117field should contain the option name without the leading double dash.
118.Pp
119The
120.Fa has_arg
121field should be one of:
122.Pp
123.Bl -tag -width "optional_argument" -compact -offset indent
124.It Dv no_argument
125no argument to the option is expected.
126.It Dv required_argument
127an argument to the option is required.
128.It Dv optional_argument
129an argument to the option may be presented.
130.El
131.Pp
132If
133.Fa flag
134is not
135.Dv NULL ,
136then the integer pointed to by it will be set to the value in the
137.Fa val
138field.
139If the
140.Fa flag
141field is
142.Dv NULL ,
143then the
144.Fa val
145field will be returned.
146Setting
147.Fa flag
148to
149.Dv NULL
150and setting
151.Fa val
152to the corresponding short option will make this function act just
153like
154.Xr getopt 3 .
155.Pp
156If the
157.Fa longindex
158field is not
159.Dv NULL ,
160then the integer pointed to by it will be set to the index of the long
161option relative to
162.Fa longopts .
163.Pp
164The last element of the
165.Fa longopts
166array has to be filled with zeroes.
167.Pp
168The
169.Fn getopt_long_only
170function behaves identically to
171.Fn getopt_long
172with the exception that long options may start with
173.Sq -
174in addition to
175.Sq -- .
176If an option starting with
177.Sq -
178does not match a long option but does match a single-character option,
179the single-character option is returned.
180.Sh RETURN VALUES
181If the
182.Fa flag
183field in
184.Li struct option
185is
186.Dv NULL ,
187.Fn getopt_long
188and
189.Fn getopt_long_only
190return the value specified in the
191.Fa val
192field, which is usually just the corresponding short option.
193If
194.Fa flag
195is not
196.Dv NULL ,
197these functions return 0 and store
198.Fa val
199in the location pointed to by
200.Fa flag .
201These functions return
202.Sq \:
203if there was a missing option argument,
204.Sq \&?
205if the user specified an unknown or ambiguous option, and
206\-1 when the argument list has been exhausted.
207.Sh EXAMPLES
208.Bd -literal
209int bflag, ch, fd;
210int daggerset;
211
212/* options descriptor */
213static struct option longopts[] = {
214 { "buffy", no_argument, NULL, 'b' },
215 { "fluoride", required_argument, NULL, 'f' },
216 { "daggerset", no_argument, &daggerset, 1 },
217 { NULL, 0, NULL, 0 }
218};
219
220bflag = 0;
221while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
222 switch (ch) {
223 case 'b':
224 bflag = 1;
225 break;
226 case 'f':
227 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
228 err(1, "unable to open %s", optarg);
229 break;
230 case 0:
231 if (daggerset)
232 fprintf(stderr, "Buffy will use her dagger to "
233 "apply fluoride to dracula's teeth\en");
234 break;
235 default:
236 usage();
237 /* NOTREACHED */
238 }
239argc -= optind;
240argv += optind;
241.Ed
242.Sh IMPLEMENTATION DIFFERENCES
243This section describes differences to the GNU implementation
244found in glibc-2.1.3:
245.Bl -bullet
246.It
247handling of
248.Ql -
249as the first character of the option string in the presence of the
250environment variable
251.Ev POSIXLY_CORRECT :
252.Bl -tag -width "OpenBSD"
253.It GNU
254ignores
255.Ev POSIXLY_CORRECT
256and returns non-options as arguments to option
257.Ql \e1 .
258.It OpenBSD
259honors
260.Ev POSIXLY_CORRECT
261and stops at the first non-option.
262.El
263.It
264handling of
265.Ql -
266within the option string (not the first character):
267.Bl -tag -width "OpenBSD"
268.It GNU
269treats a
270.Ql -
271on the command line as a non-argument.
272.It OpenBSD
273a
274.Ql -
275within the option string matches a
276.Ql -
277(single dash) on the command line.
278This functionality is provided for backward compatibility with
279programs, such as
280.Xr su 1 ,
281that use
282.Ql -
283as an option flag.
284This practice is wrong, and should not be used in any current development.
285.El
286.It
287handling of
288.Ql ::
289in the option string in the presence of
290.Ev POSIXLY_CORRECT :
291.Bl -tag -width "OpenBSD"
292.It Both
293GNU and
294.Ox
295ignore
296.Ev POSIXLY_CORRECT
297here and take
298.Ql ::
299to mean the preceding option takes an optional argument.
300.El
301.It
302return value in case of missing argument if first character
303(after
304.Ql +
305or
306.Ql - )
307in the option string is not
308.Ql \&: :
309.Bl -tag -width "OpenBSD"
310.It GNU
311returns
312.Ql \&?
313.It OpenBSD
314returns
315.Ql \&:
316(since
317.Ox Ns 's
318.Xr getopt 3
319does).
320.El
321.It
322handling of
323.Ql --a
324in
325.Xr getopt 3 :
326.Bl -tag -width "OpenBSD"
327.It GNU
328parses this as option
329.Ql - ,
330option
331.Ql a .
332.It OpenBSD
333parses this as
334.Ql -- ,
335and returns \-1 (ignoring the
336.Ql a )
337(because the original
338.Fn getopt
339did.)
340.El
341.It
342setting of
343.Va optopt
344for long options with
345.Va flag
346.No non- Ns Dv NULL :
347.Bl -tag -width "OpenBSD"
348.It GNU
349sets
350.Va optopt
351to
352.Va val .
353.It OpenBSD
354sets
355.Va optopt
356to 0 (since
357.Va val
358would never be returned).
359.El
360.It
361handling of
362.Ql -W
363with
364.Ql W;
365in the option string in
366.Xr getopt 3
367(not
368.Fn getopt_long ) :
369.Bl -tag -width "OpenBSD"
370.It GNU
371causes a segmentation fault.
372.It OpenBSD
373no special handling is done;
374.Ql W;
375is interpreted as two separate options, neither of which take an argument.
376.El
377.It
378setting of
379.Va optarg
380for long options without an argument that are invoked via
381.Ql -W
382(with
383.Ql W;
384in the option string):
385.Bl -tag -width "OpenBSD"
386.It GNU
387sets
388.Va optarg
389to the option name (the argument of
390.Ql -W ) .
391.It OpenBSD
392sets
393.Va optarg
394to
395.Dv NULL
396(the argument of the long option).
397.El
398.It
399handling of
400.Ql -W
401with an argument that is not (a prefix to) a known long option
402(with
403.Ql W;
404in the option string):
405.Bl -tag -width "OpenBSD"
406.It GNU
407returns
408.Ql -W
409with
410.Va optarg
411set to the unknown option.
412.It OpenBSD
413treats this as an error (unknown option) and returns
414.Ql \&?
415with
416.Va optopt
417set to 0 and
418.Va optarg
419set to
420.Dv NULL
421(as GNU's man page documents).
422.El
423.It
424The error messages are different.
425.It
426.Ox
427does not permute the argument vector at the same points in
428the calling sequence as GNU does.
429The aspects normally used by the caller
430(ordering after \-1 is returned, value of
431.Va optind
432relative to current positions) are the same, though.
433(We do fewer variable swaps.)
434.El
435.Sh ENVIRONMENT
436.Bl -tag -width Ev
437.It Ev POSIXLY_CORRECT
438If set, option processing stops when the first non-option is found and
439a leading
440.Sq -
441or
442.Sq +
443in the
444.Ar optstring
445is ignored.
446.El
447.Sh SEE ALSO
448.Xr getopt 3
449.Sh HISTORY
450The
451.Fn getopt_long
452and
453.Fn getopt_long_only
454functions first appeared in GNU libiberty.
455This implementation first appeared in
456.Ox 3.3 .
457.Sh BUGS
458The
459.Ar argv
460argument is not really
461.Dv const
462as its elements may be permuted (unless
463.Ev POSIXLY_CORRECT
464is 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..73d97c0ed3
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -0,0 +1,517 @@
1/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl 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 *
39 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
40 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
43 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 * POSSIBILITY OF SUCH DAMAGE.
50 */
51
52#include <err.h>
53#include <errno.h>
54#include <getopt.h>
55#include <stdlib.h>
56#include <string.h>
57
58#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
59
60#ifdef REPLACE_GETOPT
61int opterr = 1; /* if error message should be printed */
62int optind = 1; /* index into parent argv vector */
63int optopt = '?'; /* character checked for validity */
64int optreset; /* reset getopt */
65char *optarg; /* argument associated with option */
66#endif
67
68#define PRINT_ERROR ((opterr) && (*options != ':'))
69
70#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
71#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
72#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
73
74/* return values */
75#define BADCH (int)'?'
76#define BADARG ((*options == ':') ? (int)':' : (int)'?')
77#define INORDER (int)1
78
79#define EMSG ""
80
81static int getopt_internal(int, char * const *, const char *,
82 const struct option *, int *, int);
83static int parse_long_options(char * const *, const char *,
84 const struct option *, int *, int);
85static int gcd(int, int);
86static void permute_args(int, int, int, char * const *);
87
88static char *place = EMSG; /* option letter processing */
89
90/* XXX: set optreset to 1 rather than these two */
91static int nonopt_start = -1; /* first non option argument (for permute) */
92static int nonopt_end = -1; /* first option after non options (for permute) */
93
94/* Error messages */
95static const char recargchar[] = "option requires an argument -- %c";
96static const char recargstring[] = "option requires an argument -- %s";
97static const char ambig[] = "ambiguous option -- %.*s";
98static const char noarg[] = "option doesn't take an argument -- %.*s";
99static const char illoptchar[] = "unknown option -- %c";
100static const char illoptstring[] = "unknown option -- %s";
101
102/*
103 * Compute the greatest common divisor of a and b.
104 */
105static int
106gcd(int a, int b)
107{
108 int c;
109
110 c = a % b;
111 while (c != 0) {
112 a = b;
113 b = c;
114 c = a % b;
115 }
116
117 return (b);
118}
119
120/*
121 * Exchange the block from nonopt_start to nonopt_end with the block
122 * from nonopt_end to opt_end (keeping the same order of arguments
123 * in each block).
124 */
125static void
126permute_args(int panonopt_start, int panonopt_end, int opt_end,
127 char * const *nargv)
128{
129 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
130 char *swap;
131
132 /*
133 * compute lengths of blocks and number and size of cycles
134 */
135 nnonopts = panonopt_end - panonopt_start;
136 nopts = opt_end - panonopt_end;
137 ncycle = gcd(nnonopts, nopts);
138 cyclelen = (opt_end - panonopt_start) / ncycle;
139
140 for (i = 0; i < ncycle; i++) {
141 cstart = panonopt_end+i;
142 pos = cstart;
143 for (j = 0; j < cyclelen; j++) {
144 if (pos >= panonopt_end)
145 pos -= nnonopts;
146 else
147 pos += nopts;
148 swap = nargv[pos];
149 /* LINTED const cast */
150 ((char **) nargv)[pos] = nargv[cstart];
151 /* LINTED const cast */
152 ((char **)nargv)[cstart] = swap;
153 }
154 }
155}
156
157/*
158 * parse_long_options --
159 * Parse long options in argc/argv argument vector.
160 * Returns -1 if short_too is set and the option does not match long_options.
161 */
162static int
163parse_long_options(char * const *nargv, const char *options,
164 const struct option *long_options, int *idx, int short_too)
165{
166 char *current_argv, *has_equal;
167 size_t current_argv_len;
168 int i, match;
169
170 current_argv = place;
171 match = -1;
172
173 optind++;
174
175 if ((has_equal = strchr(current_argv, '=')) != NULL) {
176 /* argument found (--option=arg) */
177 current_argv_len = has_equal - current_argv;
178 has_equal++;
179 } else
180 current_argv_len = strlen(current_argv);
181
182 for (i = 0; long_options[i].name; i++) {
183 /* find matching long option */
184 if (strncmp(current_argv, long_options[i].name,
185 current_argv_len))
186 continue;
187
188 if (strlen(long_options[i].name) == current_argv_len) {
189 /* exact match */
190 match = i;
191 break;
192 }
193 /*
194 * If this is a known short option, don't allow
195 * a partial match of a single character.
196 */
197 if (short_too && current_argv_len == 1)
198 continue;
199
200 if (match == -1) /* partial match */
201 match = i;
202 else {
203 /* ambiguous abbreviation */
204 if (PRINT_ERROR)
205 warnx(ambig, (int)current_argv_len,
206 current_argv);
207 optopt = 0;
208 return (BADCH);
209 }
210 }
211 if (match != -1) { /* option found */
212 if (long_options[match].has_arg == no_argument
213 && has_equal) {
214 if (PRINT_ERROR)
215 warnx(noarg, (int)current_argv_len,
216 current_argv);
217 /*
218 * XXX: GNU sets optopt to val regardless of flag
219 */
220 if (long_options[match].flag == NULL)
221 optopt = long_options[match].val;
222 else
223 optopt = 0;
224 return (BADARG);
225 }
226 if (long_options[match].has_arg == required_argument ||
227 long_options[match].has_arg == optional_argument) {
228 if (has_equal)
229 optarg = has_equal;
230 else if (long_options[match].has_arg ==
231 required_argument) {
232 /*
233 * optional argument doesn't use next nargv
234 */
235 optarg = nargv[optind++];
236 }
237 }
238 if ((long_options[match].has_arg == required_argument)
239 && (optarg == NULL)) {
240 /*
241 * Missing argument; leading ':' indicates no error
242 * should be generated.
243 */
244 if (PRINT_ERROR)
245 warnx(recargstring,
246 current_argv);
247 /*
248 * XXX: GNU sets optopt to val regardless of flag
249 */
250 if (long_options[match].flag == NULL)
251 optopt = long_options[match].val;
252 else
253 optopt = 0;
254 --optind;
255 return (BADARG);
256 }
257 } else { /* unknown option */
258 if (short_too) {
259 --optind;
260 return (-1);
261 }
262 if (PRINT_ERROR)
263 warnx(illoptstring, current_argv);
264 optopt = 0;
265 return (BADCH);
266 }
267 if (idx)
268 *idx = match;
269 if (long_options[match].flag) {
270 *long_options[match].flag = long_options[match].val;
271 return (0);
272 } else
273 return (long_options[match].val);
274}
275
276/*
277 * getopt_internal --
278 * Parse argc/argv argument vector. Called by user level routines.
279 */
280static int
281getopt_internal(int nargc, char * const *nargv, const char *options,
282 const struct option *long_options, int *idx, int flags)
283{
284 char *oli; /* option letter list index */
285 int optchar, short_too;
286 static int posixly_correct = -1;
287
288 if (options == NULL)
289 return (-1);
290
291 /*
292 * Disable GNU extensions if POSIXLY_CORRECT is set or options
293 * string begins with a '+'.
294 */
295 if (posixly_correct == -1)
296 posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
297 if (posixly_correct || *options == '+')
298 flags &= ~FLAG_PERMUTE;
299 else if (*options == '-')
300 flags |= FLAG_ALLARGS;
301 if (*options == '+' || *options == '-')
302 options++;
303
304 /*
305 * XXX Some GNU programs (like cvs) set optind to 0 instead of
306 * XXX using optreset. Work around this braindamage.
307 */
308 if (optind == 0)
309 optind = optreset = 1;
310
311 optarg = NULL;
312 if (optreset)
313 nonopt_start = nonopt_end = -1;
314start:
315 if (optreset || !*place) { /* update scanning pointer */
316 optreset = 0;
317 if (optind >= nargc) { /* end of argument vector */
318 place = EMSG;
319 if (nonopt_end != -1) {
320 /* do permutation, if we have to */
321 permute_args(nonopt_start, nonopt_end,
322 optind, nargv);
323 optind -= nonopt_end - nonopt_start;
324 }
325 else if (nonopt_start != -1) {
326 /*
327 * If we skipped non-options, set optind
328 * to the first of them.
329 */
330 optind = nonopt_start;
331 }
332 nonopt_start = nonopt_end = -1;
333 return (-1);
334 }
335 if (*(place = nargv[optind]) != '-' ||
336 (place[1] == '\0' && strchr(options, '-') == NULL)) {
337 place = EMSG; /* found non-option */
338 if (flags & FLAG_ALLARGS) {
339 /*
340 * GNU extension:
341 * return non-option as argument to option 1
342 */
343 optarg = nargv[optind++];
344 return (INORDER);
345 }
346 if (!(flags & FLAG_PERMUTE)) {
347 /*
348 * If no permutation wanted, stop parsing
349 * at first non-option.
350 */
351 return (-1);
352 }
353 /* do permutation */
354 if (nonopt_start == -1)
355 nonopt_start = optind;
356 else if (nonopt_end != -1) {
357 permute_args(nonopt_start, nonopt_end,
358 optind, nargv);
359 nonopt_start = optind -
360 (nonopt_end - nonopt_start);
361 nonopt_end = -1;
362 }
363 optind++;
364 /* process next argument */
365 goto start;
366 }
367 if (nonopt_start != -1 && nonopt_end == -1)
368 nonopt_end = optind;
369
370 /*
371 * If we have "-" do nothing, if "--" we are done.
372 */
373 if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
374 optind++;
375 place = EMSG;
376 /*
377 * We found an option (--), so if we skipped
378 * non-options, we have to permute.
379 */
380 if (nonopt_end != -1) {
381 permute_args(nonopt_start, nonopt_end,
382 optind, nargv);
383 optind -= nonopt_end - nonopt_start;
384 }
385 nonopt_start = nonopt_end = -1;
386 return (-1);
387 }
388 }
389
390 /*
391 * Check long options if:
392 * 1) we were passed some
393 * 2) the arg is not just "-"
394 * 3) either the arg starts with -- we are getopt_long_only()
395 */
396 if (long_options != NULL && place != nargv[optind] &&
397 (*place == '-' || (flags & FLAG_LONGONLY))) {
398 short_too = 0;
399 if (*place == '-')
400 place++; /* --foo long option */
401 else if (*place != ':' && strchr(options, *place) != NULL)
402 short_too = 1; /* could be short option too */
403
404 optchar = parse_long_options(nargv, options, long_options,
405 idx, short_too);
406 if (optchar != -1) {
407 place = EMSG;
408 return (optchar);
409 }
410 }
411
412 if ((optchar = (int)*place++) == (int)':' ||
413 (optchar == (int)'-' && *place != '\0') ||
414 (oli = strchr(options, optchar)) == NULL) {
415 /*
416 * If the user specified "-" and '-' isn't listed in
417 * options, return -1 (non-option) as per POSIX.
418 * Otherwise, it is an unknown option character (or ':').
419 */
420 if (optchar == (int)'-' && *place == '\0')
421 return (-1);
422 if (!*place)
423 ++optind;
424 if (PRINT_ERROR)
425 warnx(illoptchar, optchar);
426 optopt = optchar;
427 return (BADCH);
428 }
429 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
430 /* -W long-option */
431 if (*place) /* no space */
432 /* NOTHING */;
433 else if (++optind >= nargc) { /* no arg */
434 place = EMSG;
435 if (PRINT_ERROR)
436 warnx(recargchar, optchar);
437 optopt = optchar;
438 return (BADARG);
439 } else /* white space */
440 place = nargv[optind];
441 optchar = parse_long_options(nargv, options, long_options,
442 idx, 0);
443 place = EMSG;
444 return (optchar);
445 }
446 if (*++oli != ':') { /* doesn't take argument */
447 if (!*place)
448 ++optind;
449 } else { /* takes (optional) argument */
450 optarg = NULL;
451 if (*place) /* no white space */
452 optarg = place;
453 else if (oli[1] != ':') { /* arg not optional */
454 if (++optind >= nargc) { /* no arg */
455 place = EMSG;
456 if (PRINT_ERROR)
457 warnx(recargchar, optchar);
458 optopt = optchar;
459 return (BADARG);
460 } else
461 optarg = nargv[optind];
462 }
463 place = EMSG;
464 ++optind;
465 }
466 /* dump back option letter */
467 return (optchar);
468}
469
470#ifdef REPLACE_GETOPT
471/*
472 * getopt --
473 * Parse argc/argv argument vector.
474 *
475 * [eventually this will replace the BSD getopt]
476 */
477int
478getopt(int nargc, char * const *nargv, const char *options)
479{
480
481 /*
482 * We don't pass FLAG_PERMUTE to getopt_internal() since
483 * the BSD getopt(3) (unlike GNU) has never done this.
484 *
485 * Furthermore, since many privileged programs call getopt()
486 * before dropping privileges it makes sense to keep things
487 * as simple (and bug-free) as possible.
488 */
489 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
490}
491#endif /* REPLACE_GETOPT */
492
493/*
494 * getopt_long --
495 * Parse argc/argv argument vector.
496 */
497int
498getopt_long(int nargc, char * const *nargv, const char *options,
499 const struct option *long_options, int *idx)
500{
501
502 return (getopt_internal(nargc, nargv, options, long_options, idx,
503 FLAG_PERMUTE));
504}
505
506/*
507 * getopt_long_only --
508 * Parse argc/argv argument vector.
509 */
510int
511getopt_long_only(int nargc, char * const *nargv, const char *options,
512 const struct option *long_options, int *idx)
513{
514
515 return (getopt_internal(nargc, nargv, options, long_options, idx,
516 FLAG_PERMUTE|FLAG_LONGONLY));
517}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..9f35df703f
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,145 @@
1.\" $OpenBSD: getsubopt.3,v 1.12 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
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 NUL 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
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 }
134 break;
135 }
136}
137.Ed
138.Sh SEE ALSO
139.Xr getopt 3 ,
140.Xr strsep 3
141.Sh HISTORY
142The
143.Fn getsubopt
144function first appeared in
145.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..735c85ba8a
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,92 @@
1/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie 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#include <unistd.h>
33#include <stdlib.h>
34#include <string.h>
35
36/*
37 * The SVID interface to getsubopt provides no way of figuring out which
38 * part of the suboptions list wasn't matched. This makes error messages
39 * tricky... The extern variable suboptarg is a pointer to the token
40 * which didn't match.
41 */
42char *suboptarg;
43
44int
45getsubopt(char **optionp, char * const *tokens, char **valuep)
46{
47 int cnt;
48 char *p;
49
50 suboptarg = *valuep = NULL;
51
52 if (!optionp || !*optionp)
53 return(-1);
54
55 /* skip leading white-space, commas */
56 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
57
58 if (!*p) {
59 *optionp = p;
60 return(-1);
61 }
62
63 /* save the start of the token, and skip the rest of the token. */
64 for (suboptarg = p;
65 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
66
67 if (*p) {
68 /*
69 * If there's an equals sign, set the value pointer, and
70 * skip over the value part of the token. Terminate the
71 * token.
72 */
73 if (*p == '=') {
74 *p = '\0';
75 for (*valuep = ++p;
76 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
77 if (*p)
78 *p++ = '\0';
79 } else
80 *p++ = '\0';
81 /* Skip any whitespace or commas after this token. */
82 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
83 }
84
85 /* set optionp for next round. */
86 *optionp = p;
87
88 for (cnt = 0; *tokens; ++tokens, ++cnt)
89 if (!strcmp(suboptarg, *tokens))
90 return(cnt);
91 return(-1);
92}
diff --git a/src/lib/libc/stdlib/hcreate.3 b/src/lib/libc/stdlib/hcreate.3
new file mode 100644
index 0000000000..4ff17a087d
--- /dev/null
+++ b/src/lib/libc/stdlib/hcreate.3
@@ -0,0 +1,184 @@
1.\" $OpenBSD: hcreate.3,v 1.5 2008/06/26 05:42:05 ray Exp $
2.\" $NetBSD: hcreate.3,v 1.6 2003/04/16 13:34:46 wiz Exp $
3.\"
4.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" This code is derived from software contributed to The NetBSD Foundation
8.\" by Klaus Klein.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29.\" POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: June 26 2008 $
32.Dt HCREATE 3
33.Os
34.Sh NAME
35.Nm hcreate ,
36.Nm hdestroy ,
37.Nm hsearch
38.Nd manage hash search table
39.Sh SYNOPSIS
40.In search.h
41.Ft int
42.Fn hcreate "size_t nel"
43.Ft void
44.Fn hdestroy "void"
45.Ft ENTRY *
46.Fn hsearch "ENTRY item" "ACTION action"
47.Sh DESCRIPTION
48The
49.Fn hcreate ,
50.Fn hdestroy ,
51and
52.Fn hsearch
53functions manage hash search tables.
54.Pp
55The
56.Fn hcreate
57function allocates and initializes the table.
58The
59.Fa nel
60argument specifies an estimate of the maximum number of entries to be held
61by the table.
62Unless further memory allocation fails, supplying an insufficient
63.Fa nel
64value will not result in functional harm, although a performance degradation
65may occur.
66Initialization using the
67.Fn hcreate
68function is mandatory prior to any access operations using
69.Fn hsearch .
70.Pp
71The
72.Fn hdestroy
73function destroys a table previously created using
74.Fn hcreate .
75After a call to
76.Fn hdestroy ,
77the data can no longer be accessed.
78.Pp
79The
80.Fn hsearch
81function is used to search to the hash table.
82It returns a pointer into the
83hash table indicating the address of an item.
84The
85.Fa item
86argument is of type
87.Dv ENTRY ,
88a structural type which contains the following members:
89.Pp
90.Bl -tag -compact -offset indent -width voidX*dataXX
91.It Fa char *key
92comparison key.
93.It Fa void *data
94pointer to data associated with
95.Fa key .
96.El
97.Pp
98The key comparison function used by
99.Fn hsearch
100is
101.Xr strcmp 3 .
102.Pp
103The
104.Fa action
105argument is of type
106.Dv ACTION ,
107an enumeration type which defines the following values:
108.Bl -tag -offset indent -width ENTERXX
109.It Dv ENTER
110Insert
111.Fa item
112into the hash table.
113If an existing item with the same key is found, it is not replaced.
114Note that the
115.Fa key
116and
117.Fa data
118elements of
119.Fa item
120are used directly by the new table entry.
121The storage for the
122key must not be modified during the lifetime of the hash table.
123.It Dv FIND
124Search the hash table without inserting
125.Fa item .
126.El
127.Sh RETURN VALUES
128If successful, the
129.Fn hcreate
130function returns a non-zero value.
131Otherwise, a value of 0 is returned and
132.Va errno
133is set to indicate the error.
134.Pp
135The
136.Fn hdestroy
137functions
138returns no value.
139.Pp
140If successful, the
141.Fn hsearch
142function returns a pointer to a hash table entry matching
143the provided key.
144If the action is
145.Dv FIND
146and the item was not found, or if the action is
147.Dv ENTER
148and the insertion failed,
149.Dv NULL
150is returned and
151.Va errno
152is set to indicate the error.
153If the action is
154.Dv ENTER
155and an entry already existed in the table matching the given
156key, the existing entry is returned and is not replaced.
157.Sh ERRORS
158The
159.Fn hcreate
160and
161.Fn hsearch
162functions will fail if:
163.Bl -tag -width Er
164.It Bq Er ENOMEM
165Insufficient memory is available.
166.El
167.Sh SEE ALSO
168.Xr bsearch 3 ,
169.Xr lsearch 3 ,
170.Xr malloc 3 ,
171.Xr strcmp 3
172.Sh STANDARDS
173These functions conform to
174.St -p1003.1-2004 .
175.Sh HISTORY
176The
177.Fn hcreate ,
178.Fn hdestroy
179and
180.Fn hsearch
181functions first appeared in
182.At V .
183.Sh BUGS
184The interface permits the use of only one hash table at a time.
diff --git a/src/lib/libc/stdlib/hcreate.c b/src/lib/libc/stdlib/hcreate.c
new file mode 100644
index 0000000000..094f32c173
--- /dev/null
+++ b/src/lib/libc/stdlib/hcreate.c
@@ -0,0 +1,191 @@
1/* $OpenBSD: hcreate.c,v 1.4 2007/09/02 15:19:17 deraadt Exp $ */
2/* $NetBSD: hcreate.c,v 1.5 2004/04/23 02:48:12 simonb Exp $ */
3
4/*
5 * Copyright (c) 2001 Christopher G. Demetriou
6 * All rights reserved.
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 for the
19 * NetBSD Project. See http://www.NetBSD.org/ for
20 * information about NetBSD.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
36 */
37
38/*
39 * hcreate() / hsearch() / hdestroy()
40 *
41 * SysV/XPG4 hash table functions.
42 *
43 * Implementation done based on NetBSD manual page and Solaris manual page,
44 * plus my own personal experience about how they're supposed to work.
45 *
46 * I tried to look at Knuth (as cited by the Solaris manual page), but
47 * nobody had a copy in the office, so...
48 */
49
50#include "namespace.h"
51#include <assert.h>
52#include <errno.h>
53#include <inttypes.h>
54#include <search.h>
55#include <stdlib.h>
56#include <string.h>
57#include <sys/queue.h>
58
59#ifndef _DIAGASSERT
60#define _DIAGASSERT(x)
61#endif
62
63/*
64 * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit
65 * ptr machine) without adjusting MAX_BUCKETS_LG2 below.
66 */
67struct internal_entry {
68 SLIST_ENTRY(internal_entry) link;
69 ENTRY ent;
70};
71SLIST_HEAD(internal_head, internal_entry);
72
73#define MIN_BUCKETS_LG2 4
74#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2)
75
76/*
77 * max * sizeof internal_entry must fit into size_t.
78 * assumes internal_entry is <= 32 (2^5) bytes.
79 */
80#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5)
81#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2)
82
83/* Default hash function, from db/hash/hash_func.c */
84extern u_int32_t (*__default_hash)(const void *, size_t);
85
86static struct internal_head *htable;
87static size_t htablesize;
88
89int
90hcreate(size_t nel)
91{
92 size_t idx;
93 unsigned int p2;
94
95 /* Make sure this isn't called when a table already exists. */
96 _DIAGASSERT(htable == NULL);
97 if (htable != NULL) {
98 errno = EINVAL;
99 return 0;
100 }
101
102 /* If nel is too small, make it min sized. */
103 if (nel < MIN_BUCKETS)
104 nel = MIN_BUCKETS;
105
106 /* If it's too large, cap it. */
107 if (nel > MAX_BUCKETS)
108 nel = MAX_BUCKETS;
109
110 /* If it's is not a power of two in size, round up. */
111 if ((nel & (nel - 1)) != 0) {
112 for (p2 = 0; nel != 0; p2++)
113 nel >>= 1;
114 _DIAGASSERT(p2 <= MAX_BUCKETS_LG2);
115 nel = 1 << p2;
116 }
117
118 /* Allocate the table. */
119 htablesize = nel;
120 htable = calloc(htablesize, sizeof htable[0]);
121 if (htable == NULL) {
122 errno = ENOMEM;
123 return 0;
124 }
125
126 /* Initialize it. */
127 for (idx = 0; idx < htablesize; idx++)
128 SLIST_INIT(&htable[idx]);
129
130 return 1;
131}
132
133void
134hdestroy(void)
135{
136 struct internal_entry *ie;
137 size_t idx;
138
139 _DIAGASSERT(htable != NULL);
140 if (htable == NULL)
141 return;
142
143 for (idx = 0; idx < htablesize; idx++) {
144 while (!SLIST_EMPTY(&htable[idx])) {
145 ie = SLIST_FIRST(&htable[idx]);
146 SLIST_REMOVE_HEAD(&htable[idx], link);
147 free(ie->ent.key);
148 free(ie);
149 }
150 }
151 free(htable);
152 htable = NULL;
153}
154
155ENTRY *
156hsearch(ENTRY item, ACTION action)
157{
158 struct internal_head *head;
159 struct internal_entry *ie;
160 uint32_t hashval;
161 size_t len;
162
163 _DIAGASSERT(htable != NULL);
164 _DIAGASSERT(item.key != NULL);
165 _DIAGASSERT(action == ENTER || action == FIND);
166
167 len = strlen(item.key);
168 hashval = (*__default_hash)(item.key, len);
169
170 head = &htable[hashval & (htablesize - 1)];
171 ie = SLIST_FIRST(head);
172 while (ie != NULL) {
173 if (strcmp(ie->ent.key, item.key) == 0)
174 break;
175 ie = SLIST_NEXT(ie, link);
176 }
177
178 if (ie != NULL)
179 return &ie->ent;
180 else if (action == FIND)
181 return NULL;
182
183 ie = malloc(sizeof *ie);
184 if (ie == NULL)
185 return NULL;
186 ie->ent.key = item.key;
187 ie->ent.data = item.data;
188
189 SLIST_INSERT_HEAD(head, ie, link);
190 return &ie->ent;
191}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
index bd998fa357..e6fb61ba2f 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 *
@@ -34,11 +30,6 @@
34 * SUCH DAMAGE. 30 * SUCH DAMAGE.
35 */ 31 */
36 32
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";*/
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 */
41
42#include <sys/types.h> 33#include <sys/types.h>
43#include <errno.h> 34#include <errno.h>
44#include <stdlib.h> 35#include <stdlib.h>
@@ -73,7 +64,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 64 * 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. 65 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
75 * 66 *
76 * There two cases. If j == nmemb, select largest of Ki and Kj. If 67 * 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. 68 * j < nmemb, select largest of Ki, Kj and Kj+1.
78 */ 69 */
79#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ 70#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
@@ -95,12 +86,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 86 * 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 87 * 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 88 * 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 89 * element, is usually quite small, so it would be preferable to first
99 * heapify, always maintaining the invariant that the larger child is copied 90 * heapify, always maintaining the invariant that the larger child is copied
100 * over its parent's record. 91 * over its parent's record.
101 * 92 *
102 * Then, starting from the *bottom* of the heap, finding k's correct place, 93 * 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 94 * 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. 95 * is 'lost' when k is assigned its correct place in the heap.
105 * 96 *
106 * The time savings from this optimization are on the order of 15-20% for the 97 * The time savings from this optimization are on the order of 15-20% for the
@@ -139,13 +130,11 @@ static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp
139 * only advantage over quicksort is that it requires little additional memory. 130 * only advantage over quicksort is that it requires little additional memory.
140 */ 131 */
141int 132int
142heapsort(vbase, nmemb, size, compar) 133heapsort(void *vbase, size_t nmemb, size_t size,
143 void *vbase; 134 int (*compar)(const void *, const void *))
144 size_t nmemb, size;
145 int (*compar) __P((const void *, const void *));
146{ 135{
147 register int cnt, i, j, l; 136 int cnt, i, j, l;
148 register char tmp, *tmp1, *tmp2; 137 char tmp, *tmp1, *tmp2;
149 char *base, *k, *p, *t; 138 char *base, *k, *p, *t;
150 139
151 if (nmemb <= 1) 140 if (nmemb <= 1)
diff --git a/src/lib/libc/stdlib/free.3 b/src/lib/libc/stdlib/imaxabs.3
index 3d0131d7de..10933e0a66 100644
--- a/src/lib/libc/stdlib/free.3
+++ b/src/lib/libc/stdlib/imaxabs.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,50 +29,38 @@
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: @(#)free.3 5.2 (Berkeley) 6/29/91 32.\" $OpenBSD: imaxabs.3,v 1.3 2007/05/31 19:19:31 jmc Exp $
37.\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt FREE 3 35.Dt IMAXABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm free 38.Nm imaxabs
44.Nd free up memory allocated with malloc, calloc or realloc 39.Nd integer absolute value function
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <inttypes.h>
47.Ft void 42.Ft intmax_t
48.Fn free "void *ptr" 43.Fn imaxabs "intmax_t j"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn free 46.Fn imaxabs
52function causes the space pointed to by 47function computes the absolute value of the intmax_t variable
53.Fa ptr 48.Fa j .
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 49.Sh RETURN VALUES
71The 50The
72.Fn free 51.Fn imaxabs
73function returns no value. 52function returns the absolute value.
74.Sh SEE ALSO 53.Sh SEE ALSO
75.Xr calloc 3 , 54.Xr abs 3 ,
76.Xr malloc 3 , 55.Xr cabs 3 ,
77.Xr realloc 3 56.Xr floor 3 ,
57.Xr hypot 3 ,
58.Xr labs 3 ,
59.Xr math 3
78.Sh STANDARDS 60.Sh STANDARDS
79The 61The
80.Fn free 62.Fn abs
81function conforms to 63function conforms to
82.St -ansiC . 64.St -ansiC-99 .
65.Sh BUGS
66The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/imaxabs.c b/src/lib/libc/stdlib/imaxabs.c
new file mode 100644
index 0000000000..b7e910eefd
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxabs.c
@@ -0,0 +1,38 @@
1/* $OpenBSD: imaxabs.c,v 1.1 2006/01/13 17:58:09 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. 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#include <inttypes.h>
33
34intmax_t
35imaxabs(intmax_t j)
36{
37 return (j < 0 ? -j : j);
38}
diff --git a/src/lib/libc/stdlib/imaxdiv.3 b/src/lib/libc/stdlib/imaxdiv.3
new file mode 100644
index 0000000000..c4dee627aa
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxdiv.3
@@ -0,0 +1,67 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: imaxdiv.3,v 1.3 2007/05/31 19:19:31 jmc Exp $
33.\"
34.Dd $Mdocdate: May 31 2007 $
35.Dt IMAXDIV 3
36.Os
37.Sh NAME
38.Nm imaxdiv
39.Nd return quotient and remainder from division
40.Sh SYNOPSIS
41.Fd #include <inttypes.h>
42.Ft imaxdiv_t
43.Fn imaxdiv "intmax_t num" "intmax_t denom"
44.Sh DESCRIPTION
45The
46.Fn imaxdiv
47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li imaxdiv_t
51that contains two
52.Li intmax_t
53members named
54.Fa quot
55and
56.Fa rem .
57.Sh SEE ALSO
58.Xr div 3 ,
59.Xr ldiv 3 ,
60.Xr lldiv 3 ,
61.Xr math 3 ,
62.Xr qdiv 3
63.Sh STANDARDS
64The
65.Fn imaxdiv
66function conforms to
67.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/imaxdiv.c b/src/lib/libc/stdlib/imaxdiv.c
new file mode 100644
index 0000000000..0515a94b96
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxdiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: imaxdiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2/*
3 * Copyright (c) 1990 Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. 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#include <inttypes.h> /* imaxdiv_t */
35
36imaxdiv_t
37imaxdiv(intmax_t num, intmax_t denom)
38{
39 imaxdiv_t r;
40
41 /* see div.c for comments */
42
43 r.quot = num / denom;
44 r.rem = num % denom;
45 if (num >= 0 && r.rem < 0) {
46 r.quot++;
47 r.rem -= denom;
48 }
49 return (r);
50}
diff --git a/src/lib/libc/stdlib/insque.3 b/src/lib/libc/stdlib/insque.3
new file mode 100644
index 0000000000..dcb2b0d158
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: insque.3,v 1.7 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
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 -offset indent
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.Pp
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 insque
87and
88.Fn remque
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
100.Li insque
101and
102.Li remque
103instructions on the
104.Tn VAX .
105They first appeared in
106.Bx 4.2 .
diff --git a/src/lib/libc/stdlib/insque.c b/src/lib/libc/stdlib/insque.c
new file mode 100644
index 0000000000..8724efec74
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: insque.c,v 1.2 2005/08/08 08:05:36 espie 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#include <search.h>
32
33struct qelem {
34 struct qelem *q_forw;
35 struct qelem *q_back;
36};
37
38void
39insque(void *entry, void *pred)
40{
41 struct qelem *e = (struct qelem *) entry;
42 struct qelem *p = (struct qelem *) pred;
43
44 e->q_forw = p->q_forw;
45 e->q_back = p;
46 p->q_forw->q_back = e;
47 p->q_forw = e;
48}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
index 205781e0ee..cb8c592750 100644
--- a/src/lib/libc/stdlib/jrand48.c
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: jrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
index 3069b31bf6..4f33df37b2 100644
--- a/src/lib/libc/stdlib/l64a.c
+++ b/src/lib/libc/stdlib/l64a.c
@@ -1,25 +1,24 @@
1/* $OpenBSD: l64a.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Written by J.T. Conklin <jtc@netbsd.org>. 3 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain. 4 * Public domain.
4 */ 5 */
5 6
6#if defined(LIBC_SCCS) && !defined(lint) 7#include <errno.h>
7static char *rcsid = "$NetBSD: l64a.c,v 1.4 1995/05/11 23:04:52 jtc Exp $";
8#endif
9
10#include <stdlib.h> 8#include <stdlib.h>
11 9
12char * 10char *
13l64a (value) 11l64a(long value)
14 long value;
15{ 12{
16 static char buf[8]; 13 static char buf[8];
17 char *s = buf; 14 char *s = buf;
18 int digit; 15 int digit;
19 int i; 16 int i;
20 17
21 if (!value) 18 if (value < 0) {
22 return NULL; 19 errno = EINVAL;
20 return(NULL);
21 }
23 22
24 for (i = 0; value != 0 && i < 6; i++) { 23 for (i = 0; value != 0 && i < 6; i++) {
25 digit = value & 0x3f; 24 digit = value & 0x3f;
@@ -39,5 +38,5 @@ l64a (value)
39 38
40 *s = '\0'; 39 *s = '\0';
41 40
42 return buf; 41 return(buf);
43} 42}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
index 28e4d2053c..21c134fe5d 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,41 @@
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.9 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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 imaxabs 3 ,
59.Xr math 3 60.Xr math 3
60.Sh STANDARDS 61.Sh STANDARDS
61The 62The
62.Fn labs 63.Fn labs
63function 64and
64conforms to 65.Fn llabs
65.St -ansiC . 66functions conform to
67.St -ansiC-99 .
66.Sh BUGS 68.Sh BUGS
67The absolute value of the most negative integer remains negative. 69The 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..ca60b9aba2 100644
--- a/src/lib/libc/stdlib/labs.c
+++ b/src/lib/libc/stdlib/labs.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: labs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41long 33long
42labs(j) 34labs(long j)
43 long j;
44{ 35{
45 return(j < 0 ? -j : j); 36 return(j < 0 ? -j : j);
46} 37}
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
index 965d46b17a..2cf5c271ba 100644
--- a/src/lib/libc/stdlib/lcong48.c
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: lcong48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
index a7b5ccf878..9627776899 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,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: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: ldiv.3,v 1.9 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
40.Dt LDIV 3 35.Dt LDIV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,24 +44,24 @@
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 imaxdiv 3 ,
66.Xr math 3 60.Xr lldiv 3 ,
61.Xr math 3 ,
62.Xr qdiv 3
67.Sh STANDARDS 63.Sh STANDARDS
68The 64The
69.Fn ldiv 65.Fn ldiv
70function 66function conforms to
71conforms to
72.St -ansiC . 67.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
index f7074507e5..775065f525 100644
--- a/src/lib/libc/stdlib/ldiv.c
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: ldiv.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1990 Regents of the University of California. 3 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -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 *
@@ -34,16 +31,10 @@
34 * SUCH DAMAGE. 31 * SUCH DAMAGE.
35 */ 32 */
36 33
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/
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 */
41
42#include <stdlib.h> /* ldiv_t */ 34#include <stdlib.h> /* ldiv_t */
43 35
44ldiv_t 36ldiv_t
45ldiv(num, denom) 37ldiv(long num, long denom)
46 long num, denom;
47{ 38{
48 ldiv_t r; 39 ldiv_t r;
49 40
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/llabs.c
index 3353fab052..fc2cd8261c 100644
--- a/src/lib/libc/stdlib/calloc.c
+++ b/src/lib/libc/stdlib/llabs.c
@@ -1,3 +1,5 @@
1/* $OpenBSD: llabs.c,v 1.3 2007/01/08 19:39:25 deraadt Exp $ */
2
1/*- 3/*-
2 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 5 * All rights reserved.
@@ -10,11 +12,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
13 * 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
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 16 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 17 * without specific prior written permission.
20 * 18 *
@@ -31,23 +29,10 @@
31 * SUCH DAMAGE. 29 * SUCH DAMAGE.
32 */ 30 */
33 31
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)calloc.c 5.6 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 32#include <stdlib.h>
40#include <string.h>
41 33
42void * 34long long
43calloc(num, size) 35llabs(long long j)
44 size_t num;
45 register size_t size;
46{ 36{
47 register void *p; 37 return (j < 0 ? -j : j);
48
49 size *= num;
50 if (p = malloc(size))
51 memset(p, '\0', size);
52 return(p);
53} 38}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/lldiv.3
index 735252c837..a5be188ba2 100644
--- a/src/lib/libc/stdlib/memory.3
+++ b/src/lib/libc/stdlib/lldiv.3
@@ -1,6 +1,10 @@
1.\" Copyright (c) 1991 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
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
4.\" Redistribution and use in source and binary forms, with or without 8.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 9.\" modification, are permitted provided that the following conditions
6.\" are met: 10.\" are met:
@@ -9,11 +13,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
12.\" 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
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 17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 18.\" without specific prior written permission.
19.\" 19.\"
@@ -29,43 +29,39 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" from: @(#)memory.3 5.1 (Berkeley) 5/2/91 32.\" $OpenBSD: lldiv.3,v 1.2 2007/05/31 19:19:31 jmc Exp $
33.\" $Id: memory.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
34.\" 33.\"
35.Dd May 2, 1991 34.Dd $Mdocdate: May 31 2007 $
36.Dt MEMORY 3 35.Dt LLDIV 3
37.Os BSD 4 36.Os
38.Sh NAME 37.Sh NAME
39.Nm malloc , 38.Nm lldiv
40.Nm free , 39.Nd return quotient and remainder from division
41.Nm realloc ,
42.Nm calloc ,
43.Nm alloca
44.Nd general memory allocation operations
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft void * 42.Ft lldiv_t
48.Fn malloc "size_t size" 43.Fn lldiv "long long num" "long long denom"
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 44.Sh DESCRIPTION
58These functions allocate and free memory for the calling process. 45The
59They are described in the 46.Fn lldiv
60individual manual pages. 47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li lldiv_t
51that contains two
52.Li long long integer
53members named
54.Fa quot
55and
56.Fa rem .
61.Sh SEE ALSO 57.Sh SEE ALSO
62.Xr calloc 3 , 58.Xr div 3 ,
63.Xr free 3 , 59.Xr imaxdiv 3 ,
64.Xr malloc 3 , 60.Xr ldiv 3 ,
65.Xr realloc 3 , 61.Xr math 3 ,
66.Xr alloca 3 , 62.Xr qdiv 3
67.Sh STANDARDS 63.Sh STANDARDS
68These functions, with the exception of 64The
69.Fn alloca 65.Fn lldiv
70conform to 66function conforms to
71.St -ansiC . 67.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/lldiv.c b/src/lib/libc/stdlib/lldiv.c
new file mode 100644
index 0000000000..e8d6c978b3
--- /dev/null
+++ b/src/lib/libc/stdlib/lldiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: lldiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2/*
3 * Copyright (c) 1990 Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. 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#include <stdlib.h> /* lldiv_t */
35
36lldiv_t
37lldiv(long long num, long long denom)
38{
39 lldiv_t r;
40
41 /* see div.c for comments */
42
43 r.quot = num / denom;
44 r.rem = num % denom;
45 if (num >= 0 && r.rem < 0) {
46 r.quot++;
47 r.rem -= denom;
48 }
49 return (r);
50}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
index 8e7f26237f..21beb858ca 100644
--- a/src/lib/libc/stdlib/lrand48.c
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: lrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3
new file mode 100644
index 0000000000..e13ef4ec74
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.3
@@ -0,0 +1,108 @@
1.\" $OpenBSD: lsearch.3,v 1.8 2007/05/31 19:19:31 jmc Exp $
2.\"
3.\" Copyright (c) 1989, 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.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93
31.\"
32.Dd $Mdocdate: May 31 2007 $
33.Dt LSEARCH 3
34.Os
35.Sh NAME
36.Nm lsearch ,
37.Nm lfind
38.Nd linear searching routines
39.Sh SYNOPSIS
40.Fd #include <search.h>
41.Ft char *
42.Fn lsearch "const void *key" "const void *base" "size_t *nelp" \
43 "size_t width" "int (*compar)(void *, void *)"
44.Ft char *
45.Fn lfind "const void *key" "const void *base" "size_t *nelp" \
46 "size_t width" "int (*compar)(void *, void *)"
47.Sh DESCRIPTION
48The functions
49.Fn lsearch
50and
51.Fn lfind
52provide basic linear searching functionality.
53.Pp
54.Fa base
55is the pointer to the beginning of an array.
56The argument
57.Fa nelp
58is the current number of elements in the array, where each element
59is
60.Fa width
61bytes long.
62The
63.Fa compar
64function
65is a comparison routine which is used to compare two elements.
66It takes two arguments which point to the
67.Fa key
68object and to an array member, in that order, and must return an integer
69less than, equivalent to, or greater than zero if the
70.Fa key
71object is considered, respectively, to be less than, equal to, or greater
72than the array member.
73.Pp
74The
75.Fn lsearch
76and
77.Fn lfind
78functions
79return a pointer into the array referenced by
80.Fa base
81where
82.Fa key
83is located.
84If
85.Fa key
86does not exist,
87.Fn lfind
88will return a null pointer and
89.Fn lsearch
90will add it to the array.
91When an element is added to the array by
92.Fn lsearch ,
93the location referenced by the argument
94.Fa nelp
95is incremented by one.
96.Sh SEE ALSO
97.Xr bsearch 3 ,
98.Xr db 3
99.Sh STANDARDS
100The
101.Fn lsearch
102and
103.Fn lfind
104functions conform to the
105.St -p1003.1-2001
106and
107.St -xpg4.3
108specifications.
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c
new file mode 100644
index 0000000000..0815430199
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -0,0 +1,88 @@
1/* $OpenBSD: lsearch.c,v 1.3 2004/10/01 04:08:45 jsg Exp $ */
2
3/*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Roger L. Snyder.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if defined(LIBC_SCCS) && !defined(lint)
36static char sccsid[] = "@(#)lsearch.c 8.1 (Berkeley) 6/4/93";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/types.h>
40#include <string.h>
41#include <search.h>
42
43typedef int (*cmp_fn_t)(const void *, const void *);
44static void *linear_base(const void *, const void *, size_t *, size_t,
45 cmp_fn_t, int);
46
47void *
48lsearch(const void *key, const void *base, size_t *nelp, size_t width,
49 cmp_fn_t compar)
50{
51
52 return(linear_base(key, base, nelp, width, compar, 1));
53}
54
55void *
56lfind(const void *key, const void *base, size_t *nelp, size_t width,
57 cmp_fn_t compar)
58{
59 return(linear_base(key, base, nelp, width, compar, 0));
60}
61
62static void *
63linear_base(const void *key, const void *base, size_t *nelp, size_t width,
64 cmp_fn_t compar, int add_flag)
65{
66 const char *element, *end;
67
68 end = (const char *)base + *nelp * width;
69 for (element = base; element < end; element += width)
70 if (!compar(key, element)) /* key found */
71 return((void *)element);
72
73 if (!add_flag) /* key not found */
74 return(NULL);
75
76 /*
77 * The UNIX System User's Manual, 1986 edition claims that
78 * a NULL pointer is returned by lsearch with errno set
79 * appropriately, if there is not enough room in the table
80 * to add a new item. This can't be done as none of these
81 * routines have any method of determining the size of the
82 * table. This comment isn't in the 1986-87 System V
83 * manual.
84 */
85 ++*nelp;
86 memcpy((void *)end, key, width);
87 return((void *)end);
88}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index 3bbf2bf65e..b9d62d04d0 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.54 2008/08/07 18:41:47 otto 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 $Mdocdate: August 7 2008 $
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,388 @@ 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
86When using
87.Fn malloc
88be careful to avoid the following idiom:
89.Bd -literal -offset indent
90if ((p = malloc(num * size)) == NULL)
91 err(1, "malloc");
92.Ed
93.Pp
94The multiplication may lead to an integer overflow.
95To avoid this,
96.Fn calloc
97is recommended.
98.Pp
99If
100.Fn malloc
101must be used, be sure to test for overflow:
102.Bd -literal -offset indent
103if (size && num > SIZE_MAX / size) {
104 errno = ENOMEM;
105 err(1, "overflow");
106}
107.Ed
108.Pp
109The
110.Fn calloc
111function allocates space for an array of
112.Fa nmemb
113objects, each of whose size is
114.Fa size .
115The space is initialized to zero.
116The use of
117.Fn calloc
118is strongly encouraged when allocating multiple sized objects
119in order to avoid possible integer overflows.
120.Pp
121The
122.Fn free
123function causes the space pointed to by
124.Fa ptr
125to be either placed on a list of free pages to make it available for future
126allocation or, if required, to be returned to the kernel using
127.Xr munmap 2 .
128If
129.Fa ptr
130is a null pointer, no action occurs.
131.Pp
132A
133.Fn cfree
134function is also provided for compatibility with old systems and other
135.Nm malloc
136libraries; it is simply an alias for
137.Fn free .
138.Pp
139The
140.Fn realloc
141function changes the size of the object pointed to by
142.Fa ptr
143to
144.Fa size
145bytes and returns a pointer to the (possibly moved) object.
146The contents of the object are unchanged up to the lesser
147of the new and old sizes.
148If the new size is larger, the value of the newly allocated portion
149of the object is indeterminate and uninitialized.
150If
151.Fa ptr
152is a null pointer, the
153.Fn realloc
154function behaves like the
155.Fn malloc
156function for the specified size.
157If the space cannot be allocated, the object
158pointed to by
159.Fa ptr
160is unchanged.
161If
162.Fa size
163is zero and
164.Fa ptr
165is not a null pointer, the object it points to is freed and a new zero size
166object is returned.
167.Pp
168When using
169.Fn realloc
170be careful to avoid the following idiom:
171.Bd -literal -offset indent
172size += 50;
173if ((p = realloc(p, size)) == NULL)
174 return (NULL);
175.Ed
176.Pp
177Do not adjust the variable describing how much memory has been allocated
178until the allocation has been successful.
179This can cause aberrant program behavior if the incorrect size value is used.
180In most cases, the above sample will also result in a leak of memory.
181As stated earlier, a return value of
182.Dv NULL
183indicates that the old object still remains allocated.
184Better code looks like this:
185.Bd -literal -offset indent
186newsize = size + 50;
187if ((newp = realloc(p, newsize)) == NULL) {
188 free(p);
189 p = NULL;
190 size = 0;
191 return (NULL);
192}
193p = newp;
194size = newsize;
195.Ed
196.Pp
197As with
198.Fn malloc
199it is important to ensure the new size value will not overflow;
200i.e. avoid allocations like the following:
201.Bd -literal -offset indent
202if ((newp = realloc(p, num * size)) == NULL) {
203 ...
204.Ed
205.Pp
206Malloc will first look for a symbolic link called
207.Pa /etc/malloc.conf
208and next check the environment for a variable called
209.Ev MALLOC_OPTIONS
210and finally for the global variable
211.Va malloc_options
212and scan them for flags in that order.
213Flags are single letters, uppercase means on, lowercase means off.
214.Bl -tag -width indent
215.It Cm A
216.Dq Abort .
217.Fn malloc
218will coredump the process, rather than tolerate failure.
219This is a very handy debugging aid, since the core file will represent the
220time of failure, rather than when the null pointer was accessed.
221.It Cm D
222.Dq Dump .
223.Fn malloc
224will dump statistics in a file called
225.Pa malloc.out
226at exit.
227This option requires the library to have been compiled with -DMALLOC_STATS in
228order to have any effect.
229.It Cm F
230.Dq Freeguard .
231Enable use after free protection.
232Unused pages on the freelist are read and write protected to
233cause a segmentation fault upon access.
234.It Cm G
235.Dq Guard .
236Enable guard pages and chunk randomization.
237Each page size or larger allocation is followed by a guard page that will
238cause a segmentation fault upon any access.
239Smaller than page size chunks are returned in a random order.
240.It Cm H
241.Dq Hint .
242Pass a hint to the kernel about pages we don't use.
243If the machine is paging a lot this may help a bit.
244.It Cm J
245.Dq Junk .
246Fill some junk into the area allocated.
247Currently junk is bytes of 0xd0 when allocating; this is pronounced
248.Dq Duh .
249\&:-)
250Freed chunks are filled with 0xdf.
251.It Cm N
252Do not output warning messages when encountering possible corruption
253or bad pointers.
254.It Cm P
255.Dq Move allocations within a page.
256Allocations larger than half a page but smaller that a page
257are aligned to the end of a page to catch buffer overruns in more
258cases.
259.It Cm R
260.Dq realloc .
261Always reallocate when
262.Fn realloc
263is called, even if the initial allocation was big enough.
264This can substantially aid in compacting memory.
265.\".Pp
266.\".It Cm U
267.\".Dq utrace .
268.\"Generate entries for
269.\".Xr ktrace 1
270.\"for all operations.
271.\"Consult the source for this one.
272.It Cm X
273.Dq xmalloc .
274Rather than return failure,
275.Xr abort 3
276the program with a diagnostic message on stderr.
277It is the intention that this option be set at compile time by
278including in the source:
279.Bd -literal -offset indent
280extern char *malloc_options;
281malloc_options = "X";
282.Ed
283.Pp
284Note that this will cause code that is supposed to handle
285out-of-memory conditions gracefully to abort instead.
286.It Cm Z
287.Dq Zero .
288Fill some junk into the area allocated (see
289.Cm J ) ,
290except for the exact length the user asked for, which is zeroed.
291.It Cm <
292.Dq Half the cache size .
293Decrease the size of the free page cache by a factor of two.
294.It Cm >
295.Dq Double the cache size .
296Increase the size of the free page cache by a factor of two.
297.El
298.Pp
299So to set a systemwide reduction of cache size and coredumps on problems:
300.Li ln -s 'A<' /etc/malloc.conf
301.Pp
302The
303.Cm J
304and
305.Cm Z
306flags are mostly for testing and debugging.
307If a program changes behavior if either of these options are used,
308it is buggy.
309.Pp
310The default number of free pages cached is 64.
65.Sh RETURN VALUES 311.Sh RETURN VALUES
66The 312The
67.Fn malloc 313.Fn malloc
68function returns 314and
69a pointer to the allocated space if successful; otherwise 315.Fn calloc
70a null pointer is returned. 316functions return a pointer to the allocated space if successful; otherwise,
317a null pointer is returned and
318.Va errno
319is set to
320.Er ENOMEM .
321.Pp
322The
323.Fn free
324and
325.Fn cfree
326functions return no value.
327.Pp
328The
329.Fn realloc
330function returns a pointer to the (possibly moved) allocated space
331if successful; otherwise, a null pointer is returned and
332.Va errno
333is set to
334.Er ENOMEM .
335.Sh ENVIRONMENT
336.Bl -tag -width Ev
337.It Ev MALLOC_OPTIONS
338See above.
339.El
340.Sh FILES
341.Bl -tag -width "/etc/malloc.conf"
342.It Pa /etc/malloc.conf
343symbolic link to filename containing option flags
344.El
345.Sh DIAGNOSTICS
346If
347.Fn malloc ,
348.Fn calloc ,
349.Fn realloc ,
350or
351.Fn free
352detect an error or warning condition,
353a message will be printed to file descriptor
3542 (not using stdio).
355Errors will always result in the process being
356.Xr abort 3 'ed.
357If the
358.Cm A
359option has been specified, warnings will also
360.Xr abort 3
361the process.
362.Pp
363Here is a brief description of the error messages and what they mean:
364.Bl -tag -width Ds
365.It Dq out of memory
366If the
367.Cm A
368option is specified it is an error for
369.Fn malloc ,
370.Fn calloc ,
371or
372.Fn realloc
373to return
374.Dv NULL .
375.It Dq malloc init mmap failed
376This is a rather weird condition that is most likely to indicate a
377seriously overloaded system or a ulimit restriction.
378.It any other error
379.Fn malloc
380detected an internal error;
381consult sources and/or wizards.
382.El
383.Pp
384Here is a brief description of the warning messages and what they mean:
385.Bl -tag -width Ds
386.It Dq bogus pointer (double free?)
387An attempt to
388.Fn free
389or
390.Fn realloc
391an unallocated pointer was made.
392.It Dq chunk is already free
393There was an attempt to free a chunk that had already been freed.
394.It Dq modified chunk-pointer
395The pointer passed to
396.Fn free
397or
398.Fn realloc
399has been modified.
400.It Dq recursive call
401An attempt was made to call recursively into these functions, i.e., from a
402signal handler.
403This behavior is not supported.
404In particular, signal handlers should
405.Em not
406use any of the
407.Fn malloc
408functions nor utilize any other functions which may call
409.Fn malloc
410(e.g.,
411.Xr stdio 3
412routines).
413.It Dq unknown char in MALLOC_OPTIONS
414We found something we didn't understand.
415.It Dq malloc cache overflow/underflow
416The internal malloc page cache has been corrupted.
417.It Dq malloc free slot lost
418The internal malloc page cache has been corrupted.
419.It Dq guard size
420An inconsistent guard size was detected.
421.El
71.Sh SEE ALSO 422.Sh SEE ALSO
72.Xr brk 2 , 423.Xr brk 2 ,
73.Xr getpagesize 2 , 424.Xr mmap 2 ,
74.Xr free 3 , 425.Xr munmap 2 ,
75.Xr calloc 3 ,
76.Xr alloca 3 , 426.Xr alloca 3 ,
77.Xr realloc 3 , 427.Xr getpagesize 3
78.Xr memory 3
79.Sh STANDARDS 428.Sh STANDARDS
80The 429The
81.Fn malloc 430.Fn malloc
82function conforms to 431function conforms to
83.St -ansiC . 432.St -ansiC .
84.Sh BUGS 433.Sh HISTORY
85The current implementation of 434The present implementation of
86.Xr malloc 435.Fn malloc
87does not always fail gracefully when system 436started out as a filesystem on a drum
88memory limits are approached. 437attached to a 20-bit binary challenged computer built with discrete germanium
89It may fail to allocate memory when larger free blocks could be broken 438transistors, and it has since graduated to handle primary storage rather than
90up, or when limits are exceeded because the size is rounded up. 439secondary.
91It is optimized for sizes that are powers of two. 440.Pp
441The main difference from other
442.Fn malloc
443implementations are believed to be that
444the free pages are not accessed until allocated.
445Most
446.Fn malloc
447implementations will store a data structure containing a,
448possibly double-, linked list in the free chunks of memory, used to tie
449all the free memory together.
450That is a quite suboptimal thing to do.
451Every time the free-list is traversed, all the otherwise unused, and very
452likely paged out, pages get faulted into primary memory, just to see what
453lies after them in the list.
454.Pp
455On systems which are paging, this can increase the page-faults
456of 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..be80640e81 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,421 +1,1398 @@
1/* $OpenBSD: malloc.c,v 1.98 2008/08/25 17:56:17 otto Exp $ */
1/* 2/*
2 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Permission to use, copy, modify, and distribute this software for any
6 * modification, are permitted provided that the following conditions 6 * purpose with or without fee is hereby granted, provided that the above
7 * are met: 7 * copyright notice and this permission notice appear in all copies.
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 * 8 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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 */ 16 */
33 17
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/
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 */
38
39/* 18/*
40 * malloc.c (Caltech) 2/21/82 19 * Parts of this code, mainly the sub page sized chunk management code is
41 * Chris Kingsley, kingsley@cit-20. 20 * derived from the malloc implementation with the following license:
42 * 21 */
43 * This is a very fast storage allocator. It allocates blocks of a small 22/*
44 * number of different sizes, and keeps free lists of each size. Blocks that 23 * ----------------------------------------------------------------------------
45 * don't exactly fit are passed up to the next larger size. In this 24 * "THE BEER-WARE LICENSE" (Revision 42):
46 * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. 25 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
47 * This is designed for use in a virtual memory environment. 26 * can do whatever you want with this stuff. If we meet some day, and you think
27 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
28 * ----------------------------------------------------------------------------
48 */ 29 */
49 30
31/* #define MALLOC_STATS */
32
50#include <sys/types.h> 33#include <sys/types.h>
34#include <sys/param.h>
35#include <sys/mman.h>
36#include <sys/uio.h>
37#include <errno.h>
38#include <stdint.h>
51#include <stdlib.h> 39#include <stdlib.h>
52#include <string.h> 40#include <string.h>
41#include <stdio.h>
53#include <unistd.h> 42#include <unistd.h>
54 43
55#define NULL 0 44#ifdef MALLOC_STATS
56 45#include <fcntl.h>
57static void morecore();
58static int findbucket();
59
60/*
61 * The overhead on a block is at least 4 bytes. When free, this space
62 * contains a pointer to the next free block, and the bottom two bits must
63 * be zero. When in use, the first byte is set to MAGIC, and the second
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 */
70union overhead {
71 union overhead *ov_next; /* when free */
72 struct {
73 u_char ovu_magic; /* magic number */
74 u_char ovu_index; /* bucket # */
75#ifdef RCHECK
76 u_short ovu_rmagic; /* range magic number */
77 u_long ovu_size; /* actual block size */
78#endif 46#endif
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};
85 47
86#define MAGIC 0xef /* magic # on accounting info */ 48#include "thread_private.h"
87#define RMAGIC 0x5555 /* magic # on range info */
88 49
89#ifdef RCHECK 50#define MALLOC_MINSHIFT 4
90#define RSLOP sizeof (u_short) 51#define MALLOC_MAXSHIFT 16
52
53#if defined(__sparc__) && !defined(__sparcv9__)
54#define MALLOC_PAGESHIFT (13U)
91#else 55#else
92#define RSLOP 0 56#define MALLOC_PAGESHIFT (PGSHIFT)
93#endif 57#endif
94 58
59#define MALLOC_PAGESIZE (1UL << MALLOC_PAGESHIFT)
60#define MALLOC_MINSIZE (1UL << MALLOC_MINSHIFT)
61#define MALLOC_PAGEMASK (MALLOC_PAGESIZE - 1)
62#define MASK_POINTER(p) ((void *)(((uintptr_t)(p)) & ~MALLOC_PAGEMASK))
63
64#define MALLOC_MAXCHUNK (1 << (MALLOC_PAGESHIFT-1))
65#define MALLOC_MAXCACHE 256
66#define MALLOC_DELAYED_CHUNKS 16 /* should be power of 2 */
67
68#define PAGEROUND(x) (((x) + (MALLOC_PAGEMASK)) & ~MALLOC_PAGEMASK)
69
95/* 70/*
96 * nextf[i] is the pointer to the next free block of size 2^(i+3). The 71 * What to use for Junk. This is the byte value we use to fill with
97 * smallest allocatable block is 8 bytes. The overhead information 72 * when the 'J' option is enabled. Use SOME_JUNK right after alloc,
98 * precedes the data area returned to the user. 73 * and SOME_FREEJUNK right before free.
99 */ 74 */
100#define NBUCKETS 30 75#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
101static union overhead *nextf[NBUCKETS]; 76#define SOME_FREEJUNK 0xdf
102extern char *sbrk(); 77
78#define MMAP(sz) mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
79 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
80
81struct region_info {
82 void *p; /* page; low bits used to mark chunks */
83 uintptr_t size; /* size for pages, or chunk_info pointer */
84};
85
86struct dir_info {
87 u_int32_t canary1;
88 struct region_info *r; /* region slots */
89 size_t regions_total; /* number of region slots */
90 size_t regions_bits; /* log2 of total */
91 size_t regions_free; /* number of free slots */
92 /* list of free chunk info structs */
93 struct chunk_info *chunk_info_list;
94 /* lists of chunks with free slots */
95 struct chunk_info *chunk_dir[MALLOC_MAXSHIFT];
96 size_t free_regions_size; /* free pages cached */
97 /* free pages cache */
98 struct region_info free_regions[MALLOC_MAXCACHE];
99 /* delayed free chunk slots */
100 void *delayed_chunks[MALLOC_DELAYED_CHUNKS];
101#ifdef MALLOC_STATS
102 size_t inserts;
103 size_t insert_collisions;
104 size_t finds;
105 size_t find_collisions;
106 size_t deletes;
107 size_t delete_moves;
108#define STATS_INC(x) ((x)++)
109#define STATS_ZERO(x) ((x) = 0)
110#else
111#define STATS_INC(x) /* nothing */
112#define STATS_ZERO(x) /* nothing */
113#endif /* MALLOC_STATS */
114 u_int32_t canary2;
115};
103 116
104static int pagesz; /* page size */
105static int pagebucket; /* page size bucket */
106 117
107#ifdef MSTATS
108/* 118/*
109 * nmalloc[i] is the difference between the number of mallocs and frees 119 * This structure describes a page worth of chunks.
110 * for a given block size. 120 *
121 * How many bits per u_long in the bitmap
111 */ 122 */
112static u_int nmalloc[NBUCKETS]; 123#define MALLOC_BITS (NBBY * sizeof(u_long))
113#include <stdio.h> 124struct chunk_info {
125 struct chunk_info *next; /* next on the free list */
126 void *page; /* pointer to the page */
127 u_int32_t canary;
128 u_short size; /* size of this page's chunks */
129 u_short shift; /* how far to shift for this size */
130 u_short free; /* how many free chunks */
131 u_short total; /* how many chunk */
132 /* which chunks are free */
133 u_long bits[(MALLOC_PAGESIZE / MALLOC_MINSIZE) / MALLOC_BITS];
134};
135
136static struct dir_info g_pool;
137static char *malloc_func; /* current function */
138char *malloc_options; /* compile-time options */
139
140static int malloc_abort = 1; /* abort() on error */
141static int malloc_active; /* status of malloc */
142static int malloc_freeprot; /* mprotect free pages PROT_NONE? */
143static int malloc_hint; /* call madvice on free pages? */
144static int malloc_junk; /* junk fill? */
145static int malloc_move; /* move allocations to end of page? */
146static int malloc_realloc; /* always realloc? */
147static int malloc_silent; /* avoid outputting warnings? */
148static int malloc_xmalloc; /* xmalloc behaviour? */
149static int malloc_zero; /* zero fill? */
150static size_t malloc_guard; /* use guard pages after allocations? */
151
152static u_int malloc_cache = 64; /* free pages we cache */
153static size_t malloc_guarded; /* bytes used for guards */
154static size_t malloc_used; /* bytes allocated */
155
156#ifdef MALLOC_STATS
157static int malloc_stats; /* dump statistics at end */
114#endif 158#endif
115 159
116#if defined(DEBUG) || defined(RCHECK) 160static size_t rbytesused; /* random bytes used */
117#define ASSERT(p) if (!(p)) botch("p") 161static u_char rbytes[4096]; /* random bytes */
118#include <stdio.h> 162static u_char getrbyte(void);
119static 163
120botch(s) 164extern char *__progname;
121 char *s; 165
166/* low bits of r->p determine size: 0 means >= page size and p->size holding
167 * real size, otherwise r->size is a shift count, or 1 for malloc(0)
168 */
169#define REALSIZE(sz, r) \
170 (sz) = (uintptr_t)(r)->p & MALLOC_PAGEMASK, \
171 (sz) = ((sz) == 0 ? (r)->size : ((sz) == 1 ? 0 : (1 << ((sz)-1))))
172
173static inline size_t
174hash(void *p)
122{ 175{
123 fprintf(stderr, "\r\nassertion botched: %s\r\n", s); 176 size_t sum;
124 (void) fflush(stderr); /* just in case user buffered it */ 177 union {
125 abort(); 178 uintptr_t p;
126} 179 unsigned short a[sizeof(void *) / sizeof(short)];
127#else 180 } u;
128#define ASSERT(p) 181 u.p = (uintptr_t)p >> MALLOC_PAGESHIFT;
182 sum = u.a[0];
183 sum = (sum << 7) - sum + u.a[1];
184#ifdef __LP64__
185 sum = (sum << 7) - sum + u.a[2];
186 sum = (sum << 7) - sum + u.a[3];
129#endif 187#endif
188 return sum;
189}
130 190
131void * 191#ifdef MALLOC_STATS
132malloc(nbytes) 192static void
133 size_t nbytes; 193dump_chunk(int fd, struct chunk_info *p, int fromfreelist)
134{ 194{
135 register union overhead *op; 195 char buf[64];
136 register long bucket, n;
137 register unsigned amt;
138 196
139 /* 197 while (p) {
140 * First time malloc is called, setup page size and 198 snprintf(buf, sizeof(buf), "chunk %d %d/%d %p\n", p->size,
141 * align break pointer so all data will be page aligned. 199 p->free, p->total, p->page);
142 */ 200 write(fd, buf, strlen(buf));
143 if (pagesz == 0) { 201 if (!fromfreelist)
144 pagesz = n = getpagesize(); 202 break;
145 op = (union overhead *)sbrk(0); 203 p = p->next;
146 n = n - sizeof (*op) - ((long)op & (n - 1)); 204 if (p != NULL) {
147 if (n < 0) 205 snprintf(buf, sizeof(buf), " ");
148 n += pagesz; 206 write(fd, buf, strlen(buf));
149 if (n) {
150 if (sbrk(n) == (char *)-1)
151 return (NULL);
152 } 207 }
153 bucket = 0; 208 }
154 amt = 8; 209}
155 while (pagesz > amt) { 210
156 amt <<= 1; 211static void
157 bucket++; 212dump_free_chunk_info(int fd, struct dir_info *d)
213{
214 char buf[64];
215 int i;
216
217 snprintf(buf, sizeof(buf), "Free chunk structs:\n");
218 write(fd, buf, strlen(buf));
219 for (i = 0; i < MALLOC_MAXSHIFT; i++) {
220 struct chunk_info *p = d->chunk_dir[i];
221 if (p != NULL) {
222 snprintf(buf, sizeof(buf), "%2d) ", i);
223 write(fd, buf, strlen(buf));
224 dump_chunk(fd, p, 1);
158 } 225 }
159 pagebucket = bucket;
160 } 226 }
161 /* 227
162 * Convert amount of memory requested into closest block size 228}
163 * stored in hash buckets which satisfies request. 229
164 * Account for space used per block for accounting. 230static void
165 */ 231dump_free_page_info(int fd, struct dir_info *d)
166 if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { 232{
167#ifndef RCHECK 233 char buf[64];
168 amt = 8; /* size of first bucket */ 234 int i;
169 bucket = 0; 235
170#else 236 snprintf(buf, sizeof(buf), "Free pages cached: %zu\n",
171 amt = 16; /* size of first bucket */ 237 d->free_regions_size);
172 bucket = 1; 238 write(fd, buf, strlen(buf));
173#endif 239 for (i = 0; i < malloc_cache; i++) {
174 n = -((long)sizeof (*op) + RSLOP); 240 if (d->free_regions[i].p != NULL) {
175 } else { 241 snprintf(buf, sizeof(buf), "%2d) ", i);
176 amt = pagesz; 242 write(fd, buf, strlen(buf));
177 bucket = pagebucket; 243 snprintf(buf, sizeof(buf), "free at %p: %zu\n",
244 d->free_regions[i].p, d->free_regions[i].size);
245 write(fd, buf, strlen(buf));
246 }
178 } 247 }
179 while (nbytes > amt + n) { 248}
180 amt <<= 1; 249
181 if (amt == 0) 250static void
182 return (NULL); 251malloc_dump1(int fd, struct dir_info *d)
183 bucket++; 252{
253 char buf[64];
254 size_t i, realsize;
255
256 snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d);
257 write(fd, buf, strlen(buf));
258 snprintf(buf, sizeof(buf), "Regions slots %zu\n", d->regions_total);
259 write(fd, buf, strlen(buf));
260 snprintf(buf, sizeof(buf), "Finds %zu/%zu %f\n", d->finds,
261 d->find_collisions,
262 1.0 + (double)d->find_collisions / d->finds);
263 write(fd, buf, strlen(buf));
264 snprintf(buf, sizeof(buf), "Inserts %zu/%zu %f\n", d->inserts,
265 d->insert_collisions,
266 1.0 + (double)d->insert_collisions / d->inserts);
267 write(fd, buf, strlen(buf));
268 snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes,
269 d->delete_moves);
270 write(fd, buf, strlen(buf));
271 snprintf(buf, sizeof(buf), "Regions slots free %zu\n", d->regions_free);
272 write(fd, buf, strlen(buf));
273 for (i = 0; i < d->regions_total; i++) {
274 if (d->r[i].p != NULL) {
275 size_t h = hash(d->r[i].p) &
276 (d->regions_total - 1);
277 snprintf(buf, sizeof(buf), "%4zx) #%zx %zd ",
278 i, h, h - i);
279 write(fd, buf, strlen(buf));
280 REALSIZE(realsize, &d->r[i]);
281 if (realsize > MALLOC_MAXCHUNK) {
282 snprintf(buf, sizeof(buf),
283 "%p: %zu\n", d->r[i].p, realsize);
284 write(fd, buf, strlen(buf));
285 } else
286 dump_chunk(fd,
287 (struct chunk_info *)d->r[i].size, 0);
288 }
184 } 289 }
185 /* 290 dump_free_chunk_info(fd, d);
186 * If nothing in hash bucket right now, 291 dump_free_page_info(fd, d);
187 * request more memory from the system. 292 snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used);
188 */ 293 write(fd, buf, strlen(buf));
189 if ((op = nextf[bucket]) == NULL) { 294 snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded);
190 morecore(bucket); 295 write(fd, buf, strlen(buf));
191 if ((op = nextf[bucket]) == NULL) 296}
192 return (NULL); 297
193 } 298
194 /* remove from linked list */ 299void
195 nextf[bucket] = op->ov_next; 300malloc_dump(int fd)
196 op->ov_magic = MAGIC; 301{
197 op->ov_index = bucket; 302 malloc_dump1(fd, &g_pool);
198#ifdef MSTATS 303}
199 nmalloc[bucket]++; 304
200#endif 305static void
201#ifdef RCHECK 306malloc_exit(void)
202 /* 307{
203 * Record allocated size of block and 308 char *q = "malloc() warning: Couldn't dump stats\n";
204 * bound space with magic numbers. 309 int save_errno = errno, fd;
205 */ 310
206 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 311 fd = open("malloc.out", O_RDWR|O_APPEND);
207 op->ov_rmagic = RMAGIC; 312 if (fd != -1) {
208 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 313 malloc_dump(fd);
209#endif 314 close(fd);
210 return ((char *)(op + 1)); 315 } else
316 write(STDERR_FILENO, q, strlen(q));
317 errno = save_errno;
318}
319#endif /* MALLOC_STATS */
320
321
322
323static void
324wrterror(char *p)
325{
326 char *q = " error: ";
327 struct iovec iov[5];
328
329 iov[0].iov_base = __progname;
330 iov[0].iov_len = strlen(__progname);
331 iov[1].iov_base = malloc_func;
332 iov[1].iov_len = strlen(malloc_func);
333 iov[2].iov_base = q;
334 iov[2].iov_len = strlen(q);
335 iov[3].iov_base = p;
336 iov[3].iov_len = strlen(p);
337 iov[4].iov_base = "\n";
338 iov[4].iov_len = 1;
339 writev(STDERR_FILENO, iov, 5);
340
341#ifdef MALLOC_STATS
342 if (malloc_stats)
343 malloc_dump(STDERR_FILENO);
344#endif /* MALLOC_STATS */
345 //malloc_active--;
346 if (malloc_abort)
347 abort();
348}
349
350static void
351wrtwarning(char *p)
352{
353 char *q = " warning: ";
354 struct iovec iov[5];
355
356 if (malloc_abort)
357 wrterror(p);
358 else if (malloc_silent)
359 return;
360
361 iov[0].iov_base = __progname;
362 iov[0].iov_len = strlen(__progname);
363 iov[1].iov_base = malloc_func;
364 iov[1].iov_len = strlen(malloc_func);
365 iov[2].iov_base = q;
366 iov[2].iov_len = strlen(q);
367 iov[3].iov_base = p;
368 iov[3].iov_len = strlen(p);
369 iov[4].iov_base = "\n";
370 iov[4].iov_len = 1;
371
372 writev(STDERR_FILENO, iov, 5);
211} 373}
212 374
213/* 375/*
214 * Allocate more memory to the indicated bucket. 376 * Cache maintenance. We keep at most malloc_cache pages cached.
377 * If the cache is becoming full, unmap pages in the cache for real,
378 * and then add the region to the cache
379 * Opposed to the regular region data structure, the sizes in the
380 * cache are in MALLOC_PAGESIZE units.
215 */ 381 */
216static void 382static void
217morecore(bucket) 383unmap(struct dir_info *d, void *p, size_t sz)
218 int bucket;
219{ 384{
220 register union overhead *op; 385 size_t psz = sz >> MALLOC_PAGESHIFT;
221 register long sz; /* size of desired block */ 386 size_t rsz, tounmap;
222 long amt; /* amount to allocate */ 387 struct region_info *r;
223 int nblks; /* how many blocks we get */ 388 u_int i, offset;
224 389
225 /* 390 if (sz != PAGEROUND(sz)) {
226 * sbrk_size <= 0 only for big, FLUFFY, requests (about 391 wrterror("munmap round");
227 * 2^30 bytes on a VAX, I think) or for a negative arg.
228 */
229 sz = 1 << (bucket + 3);
230#ifdef DEBUG
231 ASSERT(sz > 0);
232#else
233 if (sz <= 0)
234 return; 392 return;
235#endif
236 if (sz < pagesz) {
237 amt = pagesz;
238 nblks = amt / sz;
239 } else {
240 amt = sz + pagesz;
241 nblks = 1;
242 } 393 }
243 op = (union overhead *)sbrk(amt); 394
244 /* no more room! */ 395 if (psz > malloc_cache) {
245 if ((long)op == -1) 396 if (munmap(p, sz))
246 return; 397 wrterror("munmap");
398 malloc_used -= sz;
399 return;
400 }
401 tounmap = 0;
402 rsz = malloc_cache - d->free_regions_size;
403 if (psz > rsz)
404 tounmap = psz - rsz;
405 d->free_regions_size -= tounmap;
406 offset = getrbyte();
407 for (i = 0; tounmap > 0 && i < malloc_cache; i++) {
408 r = &d->free_regions[(i + offset) & (malloc_cache - 1)];
409 if (r->p != NULL) {
410 if (r->size <= tounmap) {
411 rsz = r->size << MALLOC_PAGESHIFT;
412 if (munmap(r->p, rsz))
413 wrterror("munmap");
414 tounmap -= r->size;
415 r->p = NULL;
416 r->size = 0;
417 malloc_used -= rsz;
418 } else {
419 rsz = tounmap << MALLOC_PAGESHIFT;
420 if (munmap((char *)r->p + ((r->size - tounmap)
421 << MALLOC_PAGESHIFT), rsz))
422 wrterror("munmap");
423 r->size -= tounmap ;
424 tounmap = 0;
425 malloc_used -= rsz;
426 }
427 }
428 }
429 if (tounmap > 0)
430 wrtwarning("malloc cache underflow");
431 for (i = 0; i < malloc_cache; i++) {
432 r = &d->free_regions[i];
433 if (r->p == NULL) {
434 if (malloc_hint)
435 madvise(p, sz, MADV_FREE);
436 if (malloc_freeprot)
437 mprotect(p, sz, PROT_NONE);
438 r->p = p;
439 r->size = psz;
440 d->free_regions_size += psz;
441 break;
442 }
443 }
444 if (i == malloc_cache)
445 wrtwarning("malloc free slot lost");
446 if (d->free_regions_size > malloc_cache)
447 wrtwarning("malloc cache overflow");
448}
449
450static void *
451map(struct dir_info *d, size_t sz, int zero_fill)
452{
453 size_t psz = sz >> MALLOC_PAGESHIFT;
454 struct region_info *r, *big = NULL;
455 u_int i, offset;
456 void *p;
457
458 if (sz != PAGEROUND(sz)) {
459 wrterror("map round");
460 return NULL;
461 }
462 if (psz > d->free_regions_size) {
463 p = MMAP(sz);
464 if (p != MAP_FAILED)
465 malloc_used += sz;
466 /* zero fill not needed */
467 return p;
468 }
469 offset = getrbyte();
470 for (i = 0; i < malloc_cache; i++) {
471 r = &d->free_regions[(i + offset) & (malloc_cache - 1)];
472 if (r->p != NULL) {
473 if (r->size == psz) {
474 p = r->p;
475 if (malloc_freeprot)
476 mprotect(p, sz, PROT_READ | PROT_WRITE);
477 if (malloc_hint)
478 madvise(p, sz, MADV_NORMAL);
479 r->p = NULL;
480 r->size = 0;
481 d->free_regions_size -= psz;
482 if (zero_fill)
483 memset(p, 0, sz);
484 return p;
485 } else if (r->size > psz)
486 big = r;
487 }
488 }
489 if (big != NULL) {
490 r = big;
491 p = (char *)r->p + ((r->size - psz) << MALLOC_PAGESHIFT);
492 if (malloc_freeprot)
493 mprotect(p, sz, PROT_READ | PROT_WRITE);
494 if (malloc_hint)
495 madvise(p, sz, MADV_NORMAL);
496 r->size -= psz;
497 d->free_regions_size -= psz;
498 if (zero_fill)
499 memset(p, 0, sz);
500 return p;
501 }
502 p = MMAP(sz);
503 if (p != MAP_FAILED)
504 malloc_used += sz;
505 if (d->free_regions_size > malloc_cache)
506 wrtwarning("malloc cache");
507 /* zero fill not needed */
508 return p;
509}
510
511static void
512rbytes_init(void)
513{
514 arc4random_buf(rbytes, sizeof(rbytes));
515 rbytesused = 0;
516}
517
518static u_char
519getrbyte(void)
520{
521 if (rbytesused >= sizeof(rbytes))
522 rbytes_init();
523 return rbytes[rbytesused++];
524}
525
526/*
527 * Initialize a dir_info, which should have been cleared by caller
528 */
529static int
530omalloc_init(struct dir_info *d)
531{
532 char *p, b[64];
533 int i, j, save_errno = errno;
534 size_t regioninfo_size;
535
536 rbytes_init();
537
538 for (i = 0; i < 3; i++) {
539 switch (i) {
540 case 0:
541 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
542 if (j <= 0)
543 continue;
544 b[j] = '\0';
545 p = b;
546 break;
547 case 1:
548 if (issetugid() == 0)
549 p = getenv("MALLOC_OPTIONS");
550 else
551 continue;
552 break;
553 case 2:
554 p = malloc_options;
555 break;
556 default:
557 p = NULL;
558 }
559
560 for (; p != NULL && *p != '\0'; p++) {
561 switch (*p) {
562 case '>':
563 malloc_cache <<= 1;
564 if (malloc_cache > MALLOC_MAXCACHE)
565 malloc_cache = MALLOC_MAXCACHE;
566 break;
567 case '<':
568 malloc_cache >>= 1;
569 break;
570 case 'a':
571 malloc_abort = 0;
572 break;
573 case 'A':
574 malloc_abort = 1;
575 break;
576#ifdef MALLOC_STATS
577 case 'd':
578 malloc_stats = 0;
579 break;
580 case 'D':
581 malloc_stats = 1;
582 break;
583#endif /* MALLOC_STATS */
584 case 'f':
585 malloc_freeprot = 0;
586 break;
587 case 'F':
588 malloc_freeprot = 1;
589 break;
590 case 'g':
591 malloc_guard = 0;
592 break;
593 case 'G':
594 malloc_guard = MALLOC_PAGESIZE;
595 break;
596 case 'h':
597 malloc_hint = 0;
598 break;
599 case 'H':
600 malloc_hint = 1;
601 break;
602 case 'j':
603 malloc_junk = 0;
604 break;
605 case 'J':
606 malloc_junk = 1;
607 break;
608 case 'n':
609 malloc_silent = 0;
610 break;
611 case 'N':
612 malloc_silent = 1;
613 break;
614 case 'p':
615 malloc_move = 0;
616 break;
617 case 'P':
618 malloc_move = 1;
619 break;
620 case 'r':
621 malloc_realloc = 0;
622 break;
623 case 'R':
624 malloc_realloc = 1;
625 break;
626 case 'x':
627 malloc_xmalloc = 0;
628 break;
629 case 'X':
630 malloc_xmalloc = 1;
631 break;
632 case 'z':
633 malloc_zero = 0;
634 break;
635 case 'Z':
636 malloc_zero = 1;
637 break;
638 default:
639 j = malloc_abort;
640 malloc_abort = 0;
641 wrtwarning("unknown char in MALLOC_OPTIONS");
642 malloc_abort = j;
643 break;
644 }
645 }
646 }
647
247 /* 648 /*
248 * Add new memory allocated to that on 649 * We want junk in the entire allocation, and zero only in the part
249 * free list for this hash bucket. 650 * the user asked for.
250 */ 651 */
251 nextf[bucket] = op; 652 if (malloc_zero)
252 while (--nblks > 0) { 653 malloc_junk = 1;
253 op->ov_next = (union overhead *)((caddr_t)op + sz); 654
254 op = (union overhead *)((caddr_t)op + sz); 655#ifdef MALLOC_STATS
255 } 656 if (malloc_stats && (atexit(malloc_exit) == -1))
657 wrtwarning("atexit(2) failed."
658 " Will not be able to dump malloc stats on exit");
659#endif /* MALLOC_STATS */
660
661 errno = save_errno;
662
663 d->regions_bits = 9;
664 d->regions_free = d->regions_total = 1 << d->regions_bits;
665 regioninfo_size = d->regions_total * sizeof(struct region_info);
666 d->r = MMAP(regioninfo_size);
667 if (d->r == MAP_FAILED) {
668 wrterror("malloc init mmap failed");
669 d->regions_total = 0;
670 return 1;
671 }
672 malloc_used += regioninfo_size;
673 memset(d->r, 0, regioninfo_size);
674 d->canary1 = arc4random();
675 d->canary2 = ~d->canary1;
676 return 0;
256} 677}
257 678
258void 679static int
259free(cp) 680omalloc_grow(struct dir_info *d)
260 void *cp; 681{
261{ 682 size_t newbits;
262 register long size; 683 size_t newtotal;
263 register union overhead *op; 684 size_t newsize;
264 685 size_t mask;
265 if (cp == NULL) 686 size_t i;
266 return; 687 struct region_info *p;
267 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 688
268#ifdef DEBUG 689 if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 )
269 ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ 690 return 1;
270#else 691
271 if (op->ov_magic != MAGIC) 692 newbits = d->regions_bits + 1;
272 return; /* sanity */ 693 newtotal = d->regions_total * 2;
273#endif 694 newsize = newtotal * sizeof(struct region_info);
274#ifdef RCHECK 695 mask = newtotal - 1;
275 ASSERT(op->ov_rmagic == RMAGIC); 696
276 ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); 697 p = MMAP(newsize);
277#endif 698 if (p == MAP_FAILED)
278 size = op->ov_index; 699 return 1;
279 ASSERT(size < NBUCKETS); 700
280 op->ov_next = nextf[size]; /* also clobbers ov_magic */ 701 malloc_used += newsize;
281 nextf[size] = op; 702 memset(p, 0, newsize);
282#ifdef MSTATS 703 STATS_ZERO(d->inserts);
283 nmalloc[size]--; 704 STATS_ZERO(d->insert_collisions);
284#endif 705 for (i = 0; i < d->regions_total; i++) {
706 void *q = d->r[i].p;
707 if (q != NULL) {
708 size_t index = hash(q) & mask;
709 STATS_INC(d->inserts);
710 while (p[index].p != NULL) {
711 index = (index - 1) & mask;
712 STATS_INC(d->insert_collisions);
713 }
714 p[index] = d->r[i];
715 }
716 }
717 /* avoid pages containing meta info to end up in cache */
718 if (munmap(d->r, d->regions_total * sizeof(struct region_info)))
719 wrterror("munmap");
720 else
721 malloc_used -= d->regions_total * sizeof(struct region_info);
722 d->regions_free = d->regions_free + d->regions_total;
723 d->regions_total = newtotal;
724 d->regions_bits = newbits;
725 d->r = p;
726 return 0;
727}
728
729static struct chunk_info *
730alloc_chunk_info(struct dir_info *d)
731{
732 struct chunk_info *p;
733 int i;
734
735 if (d->chunk_info_list == NULL) {
736 p = MMAP(MALLOC_PAGESIZE);
737 if (p == MAP_FAILED)
738 return NULL;
739 malloc_used += MALLOC_PAGESIZE;
740 for (i = 0; i < MALLOC_PAGESIZE / sizeof(*p); i++) {
741 p[i].next = d->chunk_info_list;
742 d->chunk_info_list = &p[i];
743 }
744 }
745 p = d->chunk_info_list;
746 d->chunk_info_list = p->next;
747 memset(p, 0, sizeof *p);
748 p->canary = d->canary1;
749 return p;
750}
751
752
753static void
754put_chunk_info(struct dir_info *d, struct chunk_info *p)
755{
756 p->next = d->chunk_info_list;
757 d->chunk_info_list = p;
758}
759
760static int
761insert(struct dir_info *d, void *p, size_t sz)
762{
763 size_t index;
764 size_t mask;
765 void *q;
766
767 if (d->regions_free * 4 < d->regions_total) {
768 if (omalloc_grow(d))
769 return 1;
770 }
771 mask = d->regions_total - 1;
772 index = hash(p) & mask;
773 q = d->r[index].p;
774 STATS_INC(d->inserts);
775 while (q != NULL) {
776 index = (index - 1) & mask;
777 q = d->r[index].p;
778 STATS_INC(d->insert_collisions);
779 }
780 d->r[index].p = p;
781 d->r[index].size = sz;
782 d->regions_free--;
783 return 0;
285} 784}
286 785
786static struct region_info *
787find(struct dir_info *d, void *p)
788{
789 size_t index;
790 size_t mask = d->regions_total - 1;
791 void *q, *r;
792
793 if (d->canary1 != ~d->canary2)
794 wrterror("internal struct corrupt");
795 p = MASK_POINTER(p);
796 index = hash(p) & mask;
797 r = d->r[index].p;
798 q = MASK_POINTER(r);
799 STATS_INC(d->finds);
800 while (q != p && r != NULL) {
801 index = (index - 1) & mask;
802 r = d->r[index].p;
803 q = MASK_POINTER(r);
804 STATS_INC(d->find_collisions);
805 }
806 return q == p ? &d->r[index] : NULL;
807}
808
809static void
810delete(struct dir_info *d, struct region_info *ri)
811{
812 /* algorithm R, Knuth Vol III section 6.4 */
813 size_t mask = d->regions_total - 1;
814 size_t i, j, r;
815
816 if (d->regions_total & (d->regions_total - 1))
817 wrterror("regions_total not 2^x");
818 d->regions_free++;
819 STATS_INC(g_pool.deletes);
820
821 i = ri - d->r;
822 for (;;) {
823 d->r[i].p = NULL;
824 d->r[i].size = 0;
825 j = i;
826 for (;;) {
827 i = (i - 1) & mask;
828 if (d->r[i].p == NULL)
829 return;
830 r = hash(d->r[i].p) & mask;
831 if ((i <= r && r < j) || (r < j && j < i) ||
832 (j < i && i <= r))
833 continue;
834 d->r[j] = d->r[i];
835 STATS_INC(g_pool.delete_moves);
836 break;
837 }
838
839 }
840}
841
287/* 842/*
288 * When a program attempts "storage compaction" as mentioned in the 843 * Allocate a page of chunks
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 */ 844 */
298int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ 845static struct chunk_info *
846omalloc_make_chunks(struct dir_info *d, int bits)
847{
848 struct chunk_info *bp;
849 void *pp;
850 long i, k;
299 851
300void * 852 /* Allocate a new bucket */
301realloc(cp, nbytes) 853 pp = map(d, MALLOC_PAGESIZE, 0);
302 void *cp; 854 if (pp == MAP_FAILED)
303 size_t nbytes; 855 return NULL;
304{ 856
305 register u_long onb; 857 bp = alloc_chunk_info(d);
306 register long i; 858 if (bp == NULL) {
307 union overhead *op; 859 unmap(d, pp, MALLOC_PAGESIZE);
308 char *res; 860 return NULL;
309 int was_alloced = 0; 861 }
310 862
311 if (cp == NULL) 863 /* memory protect the page allocated in the malloc(0) case */
312 return (malloc(nbytes)); 864 if (bits == 0) {
313 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 865 bp->size = 0;
314 if (op->ov_magic == MAGIC) { 866 bp->shift = 1;
315 was_alloced++; 867 i = MALLOC_MINSIZE - 1;
316 i = op->ov_index; 868 while (i >>= 1)
317 } else { 869 bp->shift++;
318 /* 870 bp->total = bp->free = MALLOC_PAGESIZE >> bp->shift;
319 * Already free, doing "compaction". 871 bp->page = pp;
320 * 872
321 * Search for the old block of memory on the 873 k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE);
322 * free list. First, check the most common 874 if (k < 0) {
323 * case (last element free'd), then (this failing) 875 unmap(d, pp, MALLOC_PAGESIZE);
324 * the last ``realloc_srchlen'' items free'd. 876 put_chunk_info(d, bp);
325 * If all lookups fail, then assume the size of 877 return NULL;
326 * the memory block being realloc'd is the
327 * largest possible (so that all "nbytes" of new
328 * memory are copied into). Note that this could cause
329 * a memory fault if the old area was tiny, and the moon
330 * is gibbous. However, that is very unlikely.
331 */
332 if ((i = findbucket(op, 1)) < 0 &&
333 (i = findbucket(op, realloc_srchlen)) < 0)
334 i = NBUCKETS;
335 }
336 onb = 1 << (i + 3);
337 if (onb < pagesz)
338 onb -= sizeof (*op) + RSLOP;
339 else
340 onb += pagesz - sizeof (*op) - RSLOP;
341 /* avoid the copy if same size block */
342 if (was_alloced) {
343 if (i) {
344 i = 1 << (i + 2);
345 if (i < pagesz)
346 i -= sizeof (*op) + RSLOP;
347 else
348 i += pagesz - sizeof (*op) - RSLOP;
349 } 878 }
350 if (nbytes <= onb && nbytes > i) { 879 } else {
351#ifdef RCHECK 880 bp->size = (1UL << bits);
352 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 881 bp->shift = bits;
353 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 882 bp->total = bp->free = MALLOC_PAGESIZE >> bits;
354#endif 883 bp->page = pp;
355 return(cp); 884 }
356 } else 885
357 free(cp); 886 /* set all valid bits in the bitmap */
358 } 887 k = bp->total;
359 if ((res = malloc(nbytes)) == NULL) 888 i = 0;
360 return (NULL); 889
361 if (cp != res) /* common optimization if "compacting" */ 890 /* Do a bunch at a time */
362 bcopy(cp, res, (nbytes < onb) ? nbytes : onb); 891 for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS)
363 return (res); 892 bp->bits[i / MALLOC_BITS] = ~0UL;
893
894 for (; i < k; i++)
895 bp->bits[i / MALLOC_BITS] |= 1UL << (i % MALLOC_BITS);
896
897 bp->next = d->chunk_dir[bits];
898 d->chunk_dir[bits] = bp;
899
900 bits++;
901 if ((uintptr_t)pp & bits)
902 wrterror("pp & bits");
903
904 insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp);
905 return bp;
364} 906}
365 907
908
366/* 909/*
367 * Search ``srchlen'' elements of each free list for a block whose 910 * Allocate a chunk
368 * header starts at ``freep''. If srchlen is -1 search the whole list.
369 * Return bucket number, or -1 if not found.
370 */ 911 */
371static 912static void *
372findbucket(freep, srchlen) 913malloc_bytes(struct dir_info *d, size_t size)
373 union overhead *freep;
374 int srchlen;
375{ 914{
376 register union overhead *p; 915 int i, j;
377 register int i, j; 916 size_t k;
917 u_long u, *lp;
918 struct chunk_info *bp;
919
920 /* Don't bother with anything less than this */
921 /* unless we have a malloc(0) requests */
922 if (size != 0 && size < MALLOC_MINSIZE)
923 size = MALLOC_MINSIZE;
378 924
379 for (i = 0; i < NBUCKETS; i++) { 925 /* Find the right bucket */
926 if (size == 0)
380 j = 0; 927 j = 0;
381 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { 928 else {
382 if (p == freep) 929 j = MALLOC_MINSHIFT;
383 return (i); 930 i = (size - 1) >> (MALLOC_MINSHIFT - 1);
931 while (i >>= 1)
384 j++; 932 j++;
933 }
934
935 /* If it's empty, make a page more of that size chunks */
936 bp = d->chunk_dir[j];
937 if (bp == NULL && (bp = omalloc_make_chunks(d, j)) == NULL)
938 return NULL;
939
940 if (bp->canary != d->canary1)
941 wrterror("chunk info corrupted");
942 /* Find first word of bitmap which isn't empty */
943 for (lp = bp->bits; !*lp; lp++)
944 /* EMPTY */;
945
946 /* Find that bit, and tweak it */
947 u = 1;
948 k = 0;
949 while (!(*lp & u)) {
950 u += u;
951 k++;
952 }
953
954 /* advance a random # of positions */
955 i = (getrbyte() & (MALLOC_DELAYED_CHUNKS - 1)) % bp->free;
956 while (i > 0) {
957 u += u;
958 k++;
959 if (k >= MALLOC_BITS) {
960 lp++;
961 u = 1;
962 k = 0;
385 } 963 }
964 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) {
965 wrterror("chunk overflow");
966 errno = EFAULT;
967 return (NULL);
968 }
969 if (*lp & u)
970 i--;
386 } 971 }
387 return (-1); 972
973 *lp ^= u;
974
975 /* If there are no more free, remove from free-list */
976 if (!--bp->free) {
977 d->chunk_dir[j] = bp->next;
978 bp->next = NULL;
979 }
980 /* Adjust to the real offset of that chunk */
981 k += (lp - bp->bits) * MALLOC_BITS;
982 k <<= bp->shift;
983
984 if (malloc_junk && bp->size > 0)
985 memset((char *)bp->page + k, SOME_JUNK, bp->size);
986 return ((char *)bp->page + k);
388} 987}
389 988
390#ifdef MSTATS 989
391/* 990/*
392 * mstats - print out statistics about malloc 991 * Free a chunk, and possibly the page it's on, if the page becomes empty.
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 */ 992 */
398mstats(s) 993static void
399 char *s; 994free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
400{ 995{
401 register int i, j; 996 struct chunk_info *info, **mp;
402 register union overhead *p; 997 long i;
403 int totfree = 0, 998
404 totused = 0; 999 info = (struct chunk_info *)r->size;
405 1000 if (info->canary != d->canary1)
406 fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); 1001 wrterror("chunk info corrupted");
407 for (i = 0; i < NBUCKETS; i++) { 1002
408 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) 1003 /* Find the chunk number on the page */
409 ; 1004 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
410 fprintf(stderr, " %d", j); 1005
411 totfree += j * (1 << (i + 3)); 1006 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) {
412 } 1007 wrtwarning("modified chunk-pointer");
413 fprintf(stderr, "\nused:\t"); 1008 return;
414 for (i = 0; i < NBUCKETS; i++) { 1009 }
415 fprintf(stderr, " %d", nmalloc[i]); 1010 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) {
416 totused += nmalloc[i] * (1 << (i + 3)); 1011 wrtwarning("chunk is already free");
417 } 1012 return;
418 fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", 1013 }
419 totused, totfree); 1014
1015 info->bits[i / MALLOC_BITS] |= 1UL << (i % MALLOC_BITS);
1016 info->free++;
1017
1018 if (info->size != 0)
1019 mp = d->chunk_dir + info->shift;
1020 else
1021 mp = d->chunk_dir;
1022
1023 if (info->free == 1) {
1024 /* Page became non-full */
1025
1026 /* Insert in address order */
1027 while (*mp != NULL && (*mp)->next != NULL &&
1028 (*mp)->next->page < info->page)
1029 mp = &(*mp)->next;
1030 info->next = *mp;
1031 *mp = info;
1032 return;
1033 }
1034 if (info->free != info->total)
1035 return;
1036
1037 /* Find & remove this page in the queue */
1038 while (*mp != info) {
1039 mp = &((*mp)->next);
1040 if (!*mp) {
1041 wrterror("not on queue");
1042 errno = EFAULT;
1043 return;
1044 }
1045 }
1046 *mp = info->next;
1047
1048 if (info->size == 0 && !malloc_freeprot)
1049 mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE);
1050 unmap(d, info->page, MALLOC_PAGESIZE);
1051
1052 delete(d, r);
1053 put_chunk_info(d, info);
420} 1054}
1055
1056
1057
1058static void *
1059omalloc(size_t sz, int zero_fill)
1060{
1061 void *p;
1062 size_t psz;
1063
1064 if (sz > MALLOC_MAXCHUNK) {
1065 if (sz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
1066 errno = ENOMEM;
1067 return NULL;
1068 }
1069 sz += malloc_guard;
1070 psz = PAGEROUND(sz);
1071 p = map(&g_pool, psz, zero_fill);
1072 if (p == MAP_FAILED) {
1073 errno = ENOMEM;
1074 return NULL;
1075 }
1076 if (insert(&g_pool, p, sz)) {
1077 unmap(&g_pool, p, psz);
1078 errno = ENOMEM;
1079 return NULL;
1080 }
1081 if (malloc_guard) {
1082 if (mprotect((char *)p + psz - malloc_guard,
1083 malloc_guard, PROT_NONE))
1084 wrterror("mprotect");
1085 malloc_guarded += malloc_guard;
1086 }
1087
1088 if (malloc_move &&
1089 sz - malloc_guard < MALLOC_PAGESIZE - MALLOC_MINSIZE) {
1090 /* fill whole allocation */
1091 if (malloc_junk)
1092 memset(p, SOME_JUNK, psz - malloc_guard);
1093 /* shift towards the end */
1094 p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_MINSIZE -
1095 (sz - malloc_guard)) & ~(MALLOC_MINSIZE-1));
1096 /* fill zeros if needed and overwritten above */
1097 if (zero_fill && malloc_junk)
1098 memset(p, 0, sz - malloc_guard);
1099 } else {
1100 if (malloc_junk) {
1101 if (zero_fill)
1102 memset(p + sz - malloc_guard,
1103 SOME_JUNK, psz - sz);
1104 else
1105 memset(p,
1106 SOME_JUNK, psz - malloc_guard);
1107 }
1108 }
1109
1110 } else {
1111 /* takes care of SOME_JUNK */
1112 p = malloc_bytes(&g_pool, sz);
1113 if (zero_fill && p != NULL && sz > 0)
1114 memset(p, 0, sz);
1115 }
1116
1117 return p;
1118}
1119
1120/*
1121 * Common function for handling recursion. Only
1122 * print the error message once, to avoid making the problem
1123 * potentially worse.
1124 */
1125static void
1126malloc_recurse(void)
1127{
1128 static int noprint;
1129
1130 if (noprint == 0) {
1131 noprint = 1;
1132 wrtwarning("recursive call");
1133 }
1134 malloc_active--;
1135 _MALLOC_UNLOCK();
1136 errno = EDEADLK;
1137}
1138
1139void *
1140malloc(size_t size)
1141{
1142 void *r;
1143
1144 _MALLOC_LOCK();
1145 malloc_func = " in malloc():";
1146 if (!g_pool.regions_total) {
1147 if (omalloc_init(&g_pool)) {
1148 _MALLOC_UNLOCK();
1149 if (malloc_xmalloc)
1150 wrterror("out of memory");
1151 errno = ENOMEM;
1152 return NULL;
1153 }
1154 }
1155 if (malloc_active++) {
1156 malloc_recurse();
1157 return NULL;
1158 }
1159 r = omalloc(size, malloc_zero);
1160 malloc_active--;
1161 _MALLOC_UNLOCK();
1162 if (r == NULL && malloc_xmalloc) {
1163 wrterror("out of memory");
1164 errno = ENOMEM;
1165 }
1166 return r;
1167}
1168
1169static void
1170ofree(void *p)
1171{
1172 struct region_info *r;
1173 size_t sz;
1174
1175 r = find(&g_pool, p);
1176 if (r == NULL) {
1177 wrtwarning("bogus pointer (double free?)");
1178 return;
1179 }
1180 REALSIZE(sz, r);
1181 if (sz > MALLOC_MAXCHUNK) {
1182 if (sz - malloc_guard >= MALLOC_PAGESIZE - MALLOC_MINSIZE) {
1183 if (r->p != p)
1184 wrtwarning("bogus pointer");
1185 } else {
1186#if notyetbecause_of_realloc
1187 /* shifted towards the end */
1188 if (p != ((char *)r->p) + ((MALLOC_PAGESIZE -
1189 MALLOC_MINSIZE - sz - malloc_guard) &
1190 ~(MALLOC_MINSIZE-1))) {
1191 }
421#endif 1192#endif
1193 p = r->p;
1194 }
1195 if (malloc_guard) {
1196 if (sz < malloc_guard)
1197 wrtwarning("guard size");
1198 if (!malloc_freeprot) {
1199 if (mprotect((char *)p + PAGEROUND(sz) -
1200 malloc_guard, malloc_guard,
1201 PROT_READ | PROT_WRITE))
1202 wrterror("mprotect");
1203 }
1204 malloc_guarded -= malloc_guard;
1205 }
1206 if (malloc_junk)
1207 memset(p, SOME_FREEJUNK, PAGEROUND(sz) - malloc_guard);
1208 unmap(&g_pool, p, PAGEROUND(sz));
1209 delete(&g_pool, r);
1210 } else {
1211 void *tmp;
1212 int i;
1213
1214 if (malloc_junk && sz > 0)
1215 memset(p, SOME_FREEJUNK, sz);
1216 i = getrbyte() & (MALLOC_DELAYED_CHUNKS - 1);
1217 tmp = p;
1218 p = g_pool.delayed_chunks[i];
1219 g_pool.delayed_chunks[i] = tmp;
1220 if (p != NULL) {
1221 r = find(&g_pool, p);
1222 if (r == NULL) {
1223 wrtwarning("bogus pointer (double free?)");
1224 return;
1225 }
1226 free_bytes(&g_pool, r, p);
1227 }
1228 }
1229}
1230
1231void
1232free(void *ptr)
1233{
1234 /* This is legal. */
1235 if (ptr == NULL)
1236 return;
1237
1238 _MALLOC_LOCK();
1239 malloc_func = " in free():";
1240 if (malloc_active++) {
1241 malloc_recurse();
1242 return;
1243 }
1244 ofree(ptr);
1245 malloc_active--;
1246 _MALLOC_UNLOCK();
1247}
1248
1249
1250static void *
1251orealloc(void *p, size_t newsz)
1252{
1253 struct region_info *r;
1254 size_t oldsz, goldsz, gnewsz;
1255 void *q;
1256
1257 if (p == NULL)
1258 return omalloc(newsz, 0);
1259
1260 r = find(&g_pool, p);
1261 if (r == NULL) {
1262 wrtwarning("bogus pointer (double free?)");
1263 return NULL;
1264 }
1265 if (newsz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
1266 errno = ENOMEM;
1267 return NULL;
1268 }
1269
1270 REALSIZE(oldsz, r);
1271 goldsz = oldsz;
1272 if (oldsz > MALLOC_MAXCHUNK) {
1273 if (oldsz < malloc_guard)
1274 wrtwarning("guard size");
1275 oldsz -= malloc_guard;
1276 }
1277
1278 gnewsz = newsz;
1279 if (gnewsz > MALLOC_MAXCHUNK)
1280 gnewsz += malloc_guard;
1281
1282 if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p &&
1283 !malloc_realloc) {
1284 size_t roldsz = PAGEROUND(goldsz);
1285 size_t rnewsz = PAGEROUND(gnewsz);
1286
1287 if (rnewsz < roldsz) {
1288 if (malloc_guard) {
1289 if (mprotect((char *)p + roldsz - malloc_guard,
1290 malloc_guard, PROT_READ | PROT_WRITE))
1291 wrterror("mprotect");
1292 if (mprotect((char *)p + rnewsz - malloc_guard,
1293 malloc_guard, PROT_NONE))
1294 wrterror("mprotect");
1295 }
1296 unmap(&g_pool, (char *)p + rnewsz, roldsz - rnewsz);
1297 r->size = gnewsz;
1298 return p;
1299 } else if (rnewsz == roldsz) {
1300 if (newsz > oldsz && malloc_junk)
1301 memset((char *)p + newsz, SOME_JUNK,
1302 rnewsz - malloc_guard - newsz);
1303 r->size = gnewsz;
1304 return p;
1305 }
1306 }
1307 if (newsz <= oldsz && newsz > oldsz / 2 && !malloc_realloc) {
1308 if (malloc_junk && newsz > 0)
1309 memset((char *)p + newsz, SOME_JUNK, oldsz - newsz);
1310 return p;
1311 } else if (newsz != oldsz || malloc_realloc) {
1312 q = omalloc(newsz, 0);
1313 if (q == NULL)
1314 return NULL;
1315 if (newsz != 0 && oldsz != 0)
1316 memcpy(q, p, oldsz < newsz ? oldsz : newsz);
1317 ofree(p);
1318 return q;
1319 } else
1320 return p;
1321}
1322
1323void *
1324realloc(void *ptr, size_t size)
1325{
1326 void *r;
1327
1328 _MALLOC_LOCK();
1329 malloc_func = " in realloc():";
1330 if (!g_pool.regions_total) {
1331 if (omalloc_init(&g_pool)) {
1332 _MALLOC_UNLOCK();
1333 if (malloc_xmalloc)
1334 wrterror("out of memory");
1335 errno = ENOMEM;
1336 return NULL;
1337 }
1338 }
1339 if (malloc_active++) {
1340 malloc_recurse();
1341 return NULL;
1342 }
1343
1344 r = orealloc(ptr, size);
1345
1346 malloc_active--;
1347 _MALLOC_UNLOCK();
1348 if (r == NULL && malloc_xmalloc) {
1349 wrterror("out of memory");
1350 errno = ENOMEM;
1351 }
1352 return r;
1353}
1354
1355
1356#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
1357
1358void *
1359calloc(size_t nmemb, size_t size)
1360{
1361 void *r;
1362
1363 _MALLOC_LOCK();
1364 malloc_func = " in calloc():";
1365 if (!g_pool.regions_total) {
1366 if (omalloc_init(&g_pool)) {
1367 _MALLOC_UNLOCK();
1368 if (malloc_xmalloc)
1369 wrterror("out of memory");
1370 errno = ENOMEM;
1371 return NULL;
1372 }
1373 }
1374 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1375 nmemb > 0 && SIZE_MAX / nmemb < size) {
1376 _MALLOC_UNLOCK();
1377 if (malloc_xmalloc)
1378 wrterror("out of memory");
1379 errno = ENOMEM;
1380 return NULL;
1381 }
1382
1383 if (malloc_active++) {
1384 malloc_recurse();
1385 return NULL;
1386 }
1387
1388 size *= nmemb;
1389 r = omalloc(size, 1);
1390
1391 malloc_active--;
1392 _MALLOC_UNLOCK();
1393 if (r == NULL && malloc_xmalloc) {
1394 wrterror("out of memory");
1395 errno = ENOMEM;
1396 }
1397 return r;
1398}
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
index 381fdc0830..623f652134 100644
--- a/src/lib/libc/stdlib/merge.c
+++ b/src/lib/libc/stdlib/merge.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: merge.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1992, 1993 3 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -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 *
@@ -34,11 +31,6 @@
34 * SUCH DAMAGE. 31 * SUCH DAMAGE.
35 */ 32 */
36 33
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)merge.c 8.2 (Berkeley) 2/14/94";*/
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 */
41
42/* 34/*
43 * Hybrid exponential search/linear search merge sort with hybrid 35 * Hybrid exponential search/linear search merge sort with hybrid
44 * natural/pairwise first pass. Requires about .3% more comparisons 36 * natural/pairwise first pass. Requires about .3% more comparisons
@@ -59,8 +51,8 @@ static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
59#include <stdlib.h> 51#include <stdlib.h>
60#include <string.h> 52#include <string.h>
61 53
62static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); 54static void setup(u_char *, u_char *, size_t, size_t, int (*)());
63static void insertionsort __P((u_char *, size_t, size_t, int (*)())); 55static void insertionsort(u_char *, size_t, size_t, int (*)());
64 56
65#define ISIZE sizeof(int) 57#define ISIZE sizeof(int)
66#define PSIZE sizeof(u_char *) 58#define PSIZE sizeof(u_char *)
@@ -96,15 +88,12 @@ static void insertionsort __P((u_char *, size_t, size_t, int (*)()));
96 * Arguments are as for qsort. 88 * Arguments are as for qsort.
97 */ 89 */
98int 90int
99mergesort(base, nmemb, size, cmp) 91mergesort(void *base, size_t nmemb, size_t size,
100 void *base; 92 int (*cmp)(const void *, const void *))
101 size_t nmemb;
102 register size_t size;
103 int (*cmp) __P((const void *, const void *));
104{ 93{
105 register int i, sense; 94 int i, sense;
106 int big, iflag; 95 int big, iflag;
107 register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; 96 u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
108 u_char *list2, *list1, *p2, *p, *last, **p1; 97 u_char *list2, *list1, *p2, *p, *last, **p1;
109 98
110 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ 99 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
@@ -148,7 +137,7 @@ mergesort(base, nmemb, size, cmp)
148 sense = 0; 137 sense = 0;
149 } 138 }
150 if (!big) { /* here i = 0 */ 139 if (!big) { /* here i = 0 */
151LINEAR: while ((b += size) < t && cmp(q, b) >sense) 140 while ((b += size) < t && cmp(q, b) >sense)
152 if (++i == 6) { 141 if (++i == 6) {
153 big = 1; 142 big = 1;
154 goto EXPONENTIAL; 143 goto EXPONENTIAL;
@@ -169,7 +158,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1)
169 goto FASTCASE; 158 goto FASTCASE;
170 } else 159 } else
171 b = p; 160 b = p;
172SLOWCASE: while (t > b+size) { 161 while (t > b+size) {
173 i = (((t - b) / size) >> 1) * size; 162 i = (((t - b) / size) >> 1) * size;
174 if ((*cmp)(q, p = b + i) <= sense) 163 if ((*cmp)(q, p = b + i) <= sense)
175 t = p; 164 t = p;
@@ -256,10 +245,8 @@ COPY: b = t;
256 * is defined. Otherwise simple pairwise merging is used.) 245 * is defined. Otherwise simple pairwise merging is used.)
257 */ 246 */
258void 247void
259setup(list1, list2, n, size, cmp) 248setup(u_char *list1, u_char *list2, size_t n, size_t size,
260 size_t n, size; 249 int (*cmp)(const void *, const void *))
261 int (*cmp) __P((const void *, const void *));
262 u_char *list1, *list2;
263{ 250{
264 int i, length, size2, tmp, sense; 251 int i, length, size2, tmp, sense;
265 u_char *f1, *f2, *s, *l2, *last, *p2; 252 u_char *f1, *f2, *s, *l2, *last, *p2;
@@ -330,10 +317,8 @@ setup(list1, list2, n, size, cmp)
330 * last 4 elements. 317 * last 4 elements.
331 */ 318 */
332static void 319static void
333insertionsort(a, n, size, cmp) 320insertionsort(u_char *a, size_t n, size_t size,
334 u_char *a; 321 int (*cmp)(const void *, const void *))
335 size_t n, size;
336 int (*cmp) __P((const void *, const void *));
337{ 322{
338 u_char *ai, *s, *t, *u, tmp; 323 u_char *ai, *s, *t, *u, tmp;
339 int i; 324 int i;
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
index 43356e66b3..977264aba5 100644
--- a/src/lib/libc/stdlib/mrand48.c
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: mrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
deleted file mode 100644
index fe1cd5781b..0000000000
--- a/src/lib/libc/stdlib/multibyte.c
+++ /dev/null
@@ -1,131 +0,0 @@
1/*
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/
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 */
38
39#include <stdlib.h>
40
41/*
42 * Stub multibyte character functions.
43 * This cheezy implementation is fixed to the native single-byte
44 * character set.
45 */
46
47int
48mblen(s, n)
49 const char *s;
50 size_t n;
51{
52 if (s == NULL || *s == '\0')
53 return 0;
54 if (n == 0)
55 return -1;
56 return 1;
57}
58
59/*ARGSUSED*/
60int
61mbtowc(pwc, s, n)
62 wchar_t *pwc;
63 const char *s;
64 size_t n;
65{
66 if (s == NULL)
67 return 0;
68 if (n == 0)
69 return -1;
70 if (pwc)
71 *pwc = (wchar_t) *s;
72 return (*s != '\0');
73}
74
75/*ARGSUSED*/
76int
77#ifdef __STDC__
78wctomb(char *s, wchar_t wchar)
79#else
80wctomb(s, wchar)
81 char *s;
82 wchar_t wchar;
83#endif
84{
85 if (s == NULL)
86 return 0;
87
88 *s = (char) wchar;
89 return 1;
90}
91
92/*ARGSUSED*/
93size_t
94mbstowcs(pwcs, s, n)
95 wchar_t *pwcs;
96 const char *s;
97 size_t n;
98{
99 int count = 0;
100
101 if (n != 0) {
102 do {
103 if ((*pwcs++ = (wchar_t) *s++) == 0)
104 break;
105 count++;
106 } while (--n != 0);
107 }
108
109 return count;
110}
111
112/*ARGSUSED*/
113size_t
114wcstombs(s, pwcs, n)
115 char *s;
116 const wchar_t *pwcs;
117 size_t n;
118{
119 int count = 0;
120
121 if (n != 0) {
122 do {
123 if ((*s++ = (char) *pwcs++) == 0)
124 break;
125 count++;
126 } while (--n != 0);
127 }
128
129 return count;
130}
131
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
index 63f839cb05..f1f548c3af 100644
--- a/src/lib/libc/stdlib/nrand48.c
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: nrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
index 2194c2c608..54482f6a14 100644
--- a/src/lib/libc/stdlib/putenv.c
+++ b/src/lib/libc/stdlib/putenv.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: putenv.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1988 The Regents of the University of California. 3 * Copyright (c) 1988, 1993
3 * All rights reserved. 4 * The Regents of the University of California. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,29 +28,23 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)putenv.c 5.4 (Berkeley) 2/23/91";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
42int 34int
43putenv(str) 35putenv(const char *str)
44 const char *str;
45{ 36{
46 register char *p, *equal; 37 char *p, *equal;
47 int rval; 38 int rval;
48 39
49 if (!(p = strdup(str))) 40 if ((p = strdup(str)) == NULL)
50 return(1); 41 return (-1);
51 if (!(equal = strchr(p, '='))) { 42 if ((equal = strchr(p, '=')) == NULL) {
52 (void)free(p); 43 (void)free(p);
53 return(1); 44 return (-1);
54 } 45 }
55 *equal = '\0'; 46 *equal = '\0';
56 rval = setenv(p, equal + 1, 1); 47 rval = setenv(p, equal + 1, 1);
57 (void)free(p); 48 (void)free(p);
58 return(rval); 49 return (rval);
59} 50}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
index cb1e052191..e022e9c1f4 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,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: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qabs.3,v 1.11 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt QABS 3 35.Dt QABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,14 +44,14 @@
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 imaxabs 3 ,
54.Xr labs 3 ,
60.Xr math 3 55.Xr math 3
61.Sh BUGS 56.Sh BUGS
62The absolute value of the most negative integer remains negative. 57The 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..656b93c822 100644
--- a/src/lib/libc/stdlib/qabs.c
+++ b/src/lib/libc/stdlib/qabs.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: qabs.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,10 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)labs.c 5.2 (Berkeley) 5/17/90";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41quad_t 33quad_t
42qabs(j) 34qabs(quad_t j)
43 quad_t j;
44{ 35{
45 return(j < 0 ? -j : j); 36 return(j < 0 ? -j : j);
46} 37}
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
index 0efcfc96ef..59776bdf2d 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,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: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qdiv.3,v 1.8 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
40.Dt QDIV 3 35.Dt QDIV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,18 +44,19 @@
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 ,
59.Xr imaxdiv 3 ,
65.Xr ldiv 3 , 60.Xr ldiv 3 ,
61.Xr lldiv 3 ,
66.Xr math 3 62.Xr math 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
index 8f8e3f89c4..f3db0915ed 100644
--- a/src/lib/libc/stdlib/qdiv.c
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: qdiv.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1990 Regents of the University of California. 3 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -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 *
@@ -34,16 +31,10 @@
34 * SUCH DAMAGE. 31 * SUCH DAMAGE.
35 */ 32 */
36 33
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char *sccsid = "from: @(#)ldiv.c 5.2 (Berkeley) 4/16/91";*/
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 */
41
42#include <stdlib.h> /* qdiv_t */ 34#include <stdlib.h> /* qdiv_t */
43 35
44qdiv_t 36qdiv_t
45qdiv(num, denom) 37qdiv(quad_t num, quad_t denom)
46 quad_t num, denom;
47{ 38{
48 qdiv_t r; 39 qdiv_t r;
49 40
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
index eb122cde12..92c75d5365 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.15 2007/05/31 19:19:31 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 $Mdocdate: May 31 2007 $
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..bb4a9a11f2 100644
--- a/src/lib/libc/stdlib/qsort.c
+++ b/src/lib/libc/stdlib/qsort.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: qsort.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1992, 1993 3 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,16 +28,11 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char sccsid[] = "from: @(#)qsort.c 8.1 (Berkeley) 6/4/93";*/
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 */
38
39#include <sys/types.h> 31#include <sys/types.h>
40#include <stdlib.h> 32#include <stdlib.h>
41 33
42static inline char *med3 __P((char *, char *, char *, int (*)())); 34static __inline char *med3(char *, char *, char *, int (*)(const void *, const void *));
43static inline void swapfunc __P((char *, char *, int, int)); 35static __inline void swapfunc(char *, char *, int, int);
44 36
45#define min(a, b) (a) < (b) ? a : b 37#define min(a, b) (a) < (b) ? a : b
46 38
@@ -49,10 +41,10 @@ static inline void swapfunc __P((char *, char *, int, int));
49 */ 41 */
50#define swapcode(TYPE, parmi, parmj, n) { \ 42#define swapcode(TYPE, parmi, parmj, n) { \
51 long i = (n) / sizeof (TYPE); \ 43 long i = (n) / sizeof (TYPE); \
52 register TYPE *pi = (TYPE *) (parmi); \ 44 TYPE *pi = (TYPE *) (parmi); \
53 register TYPE *pj = (TYPE *) (parmj); \ 45 TYPE *pj = (TYPE *) (parmj); \
54 do { \ 46 do { \
55 register TYPE t = *pi; \ 47 TYPE t = *pi; \
56 *pi++ = *pj; \ 48 *pi++ = *pj; \
57 *pj++ = t; \ 49 *pj++ = t; \
58 } while (--i > 0); \ 50 } while (--i > 0); \
@@ -61,12 +53,10 @@ static inline void swapfunc __P((char *, char *, int, int));
61#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 53#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
62 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 54 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
63 55
64static inline void 56static __inline void
65swapfunc(a, b, n, swaptype) 57swapfunc(char *a, char *b, int n, int swaptype)
66 char *a, *b;
67 int n, swaptype;
68{ 58{
69 if(swaptype <= 1) 59 if (swaptype <= 1)
70 swapcode(long, a, b, n) 60 swapcode(long, a, b, n)
71 else 61 else
72 swapcode(char, a, b, n) 62 swapcode(char, a, b, n)
@@ -82,10 +72,8 @@ swapfunc(a, b, n, swaptype)
82 72
83#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) 73#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
84 74
85static inline char * 75static __inline char *
86med3(a, b, c, cmp) 76med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
87 char *a, *b, *c;
88 int (*cmp)();
89{ 77{
90 return cmp(a, b) < 0 ? 78 return cmp(a, b) < 0 ?
91 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) 79 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
@@ -93,27 +81,25 @@ med3(a, b, c, cmp)
93} 81}
94 82
95void 83void
96qsort(a, n, es, cmp) 84qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
97 void *a;
98 size_t n, es;
99 int (*cmp)();
100{ 85{
101 char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 86 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
102 int d, r, swaptype, swap_cnt; 87 int d, r, swaptype, swap_cnt;
88 char *a = aa;
103 89
104loop: SWAPINIT(a, es); 90loop: SWAPINIT(a, es);
105 swap_cnt = 0; 91 swap_cnt = 0;
106 if (n < 7) { 92 if (n < 7) {
107 for (pm = a + es; pm < (char *) a + n * es; pm += es) 93 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 94 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es) 95 pl -= es)
110 swap(pl, pl - es); 96 swap(pl, pl - es);
111 return; 97 return;
112 } 98 }
113 pm = a + (n / 2) * es; 99 pm = (char *)a + (n / 2) * es;
114 if (n > 7) { 100 if (n > 7) {
115 pl = a; 101 pl = (char *)a;
116 pn = a + (n - 1) * es; 102 pn = (char *)a + (n - 1) * es;
117 if (n > 40) { 103 if (n > 40) {
118 d = (n / 8) * es; 104 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp); 105 pl = med3(pl, pl + d, pl + 2 * d, cmp);
@@ -123,9 +109,9 @@ loop: SWAPINIT(a, es);
123 pm = med3(pl, pm, pn, cmp); 109 pm = med3(pl, pm, pn, cmp);
124 } 110 }
125 swap(a, pm); 111 swap(a, pm);
126 pa = pb = a + es; 112 pa = pb = (char *)a + es;
127 113
128 pc = pd = a + (n - 1) * es; 114 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) { 115 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) { 116 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) { 117 if (r == 0) {
@@ -151,14 +137,14 @@ loop: SWAPINIT(a, es);
151 pc -= es; 137 pc -= es;
152 } 138 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */ 139 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = a + es; pm < (char *) a + n * es; pm += es) 140 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 141 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es) 142 pl -= es)
157 swap(pl, pl - es); 143 swap(pl, pl - es);
158 return; 144 return;
159 } 145 }
160 146
161 pn = a + n * es; 147 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa); 148 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r); 149 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es); 150 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..b90a557718 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.11 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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 74equally; for example, providing a table with the same weights
80equally, for example, providing a table with the same weights 75for A\-Z as for a\-z will result in a case-insensitive sort.
81for 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..49d03b52d5 100644
--- a/src/lib/libc/stdlib/radixsort.c
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: radixsort.c,v 1.9 2007/09/02 15:19:17 deraadt Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990, 1993 3 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -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 *
@@ -34,11 +31,6 @@
34 * SUCH DAMAGE. 31 * SUCH DAMAGE.
35 */ 32 */
36 33
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)radixsort.c 8.1 (Berkeley) 6/4/93";*/
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 */
41
42/* 34/*
43 * Radixsort routines. 35 * Radixsort routines.
44 * 36 *
@@ -61,11 +53,11 @@ typedef struct {
61 int sn, si; 53 int sn, si;
62} stack; 54} stack;
63 55
64static inline void simplesort 56static __inline void simplesort
65 __P((const u_char **, int, int, const u_char *, u_int)); 57(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)); 58static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
67static void r_sort_b __P((const u_char **, 59static void r_sort_b(const u_char **,
68 const u_char **, int, int, const u_char *, u_int)); 60 const u_char **, int, int, const u_char *, u_int);
69 61
70#define THRESHOLD 20 /* Divert to simplesort(). */ 62#define THRESHOLD 20 /* Divert to simplesort(). */
71#define SIZE 512 /* Default stack size. */ 63#define SIZE 512 /* Default stack size. */
@@ -90,10 +82,7 @@ static void r_sort_b __P((const u_char **,
90} 82}
91 83
92int 84int
93radixsort(a, n, tab, endch) 85radixsort(const u_char **a, int n, const u_char *tab, u_int endch)
94 const u_char **a, *tab;
95 int n;
96 u_int endch;
97{ 86{
98 const u_char *tr; 87 const u_char *tr;
99 int c; 88 int c;
@@ -105,10 +94,7 @@ radixsort(a, n, tab, endch)
105} 94}
106 95
107int 96int
108sradixsort(a, n, tab, endch) 97sradixsort(const u_char **a, int n, const u_char *tab, u_int endch)
109 const u_char **a, *tab;
110 int n;
111 u_int endch;
112{ 98{
113 const u_char *tr, **ta; 99 const u_char *tr, **ta;
114 int c; 100 int c;
@@ -118,7 +104,7 @@ sradixsort(a, n, tab, endch)
118 if (n < THRESHOLD) 104 if (n < THRESHOLD)
119 simplesort(a, n, 0, tr, endch); 105 simplesort(a, n, 0, tr, endch);
120 else { 106 else {
121 if ((ta = malloc(n * sizeof(a))) == NULL) 107 if ((ta = calloc(n, sizeof(a))) == NULL)
122 return (-1); 108 return (-1);
123 r_sort_b(a, ta, n, 0, tr, endch); 109 r_sort_b(a, ta, n, 0, tr, endch);
124 free(ta); 110 free(ta);
@@ -133,15 +119,11 @@ sradixsort(a, n, tab, endch)
133 119
134/* Unstable, in-place sort. */ 120/* Unstable, in-place sort. */
135void 121void
136r_sort_a(a, n, i, tr, endch) 122r_sort_a(const u_char **a, int n, int i, const u_char *tr, u_int endch)
137 const u_char **a;
138 int n, i;
139 const u_char *tr;
140 u_int endch;
141{ 123{
142 static int count[256], nc, bmin; 124 static int count[256], nc, bmin;
143 register int c; 125 int c;
144 register const u_char **ak, *r; 126 const u_char **ak, *r;
145 stack s[SIZE], *sp, *sp0, *sp1, temp; 127 stack s[SIZE], *sp, *sp0, *sp1, temp;
146 int *cp, bigc; 128 int *cp, bigc;
147 const u_char **an, *t, **aj, **top[256]; 129 const u_char **an, *t, **aj, **top[256];
@@ -224,15 +206,12 @@ r_sort_a(a, n, i, tr, endch)
224 206
225/* Stable sort, requiring additional memory. */ 207/* Stable sort, requiring additional memory. */
226void 208void
227r_sort_b(a, ta, n, i, tr, endch) 209r_sort_b(const u_char **a, const u_char **ta, int n, int i, const u_char *tr,
228 const u_char **a, **ta; 210 u_int endch)
229 int n, i;
230 const u_char *tr;
231 u_int endch;
232{ 211{
233 static int count[256], nc, bmin; 212 static int count[256], nc, bmin;
234 register int c; 213 int c;
235 register const u_char **ak, **ai; 214 const u_char **ak, **ai;
236 stack s[512], *sp, *sp0, *sp1, temp; 215 stack s[512], *sp, *sp0, *sp1, temp;
237 const u_char **top[256]; 216 const u_char **top[256];
238 int *cp, bigc; 217 int *cp, bigc;
@@ -295,14 +274,11 @@ r_sort_b(a, ta, n, i, tr, endch)
295 } 274 }
296} 275}
297 276
298static inline void 277static __inline void
299simplesort(a, n, b, tr, endch) /* insertion sort */ 278simplesort(const u_char **a, int n, int b, const u_char *tr, u_int endch)
300 register const u_char **a; 279 /* insertion sort */
301 int n, b;
302 register const u_char *tr;
303 u_int endch;
304{ 280{
305 register u_char ch; 281 u_char ch;
306 const u_char **ak, **ai, *s, *t; 282 const u_char **ak, **ai, *s, *t;
307 283
308 for (ak = a+1; --n >= 1; ak++) 284 for (ak = a+1; --n >= 1; ak++)
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
index a0e7740e66..df4feaacdb 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,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: @(#)rand.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: rand.3,v 1.10 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
40.Dt RAND 3 35.Dt RAND 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -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..0f9c100807 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 *
@@ -31,25 +27,26 @@
31 * SUCH DAMAGE. 27 * SUCH DAMAGE.
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)rand.c 5.6 (Berkeley) 6/24/91";*/
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 */
38
39#include <sys/types.h> 30#include <sys/types.h>
40#include <stdlib.h> 31#include <stdlib.h>
41 32
42static u_long next = 1; 33static u_int next = 1;
34
35int
36rand_r(u_int *seed)
37{
38 *seed = *seed * 1103515245 + 12345;
39 return (*seed % ((u_int)RAND_MAX + 1));
40}
43 41
44int 42int
45rand() 43rand(void)
46{ 44{
47 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1)); 45 return (rand_r(&next));
48} 46}
49 47
50void 48void
51srand(seed) 49srand(u_int seed)
52u_int seed;
53{ 50{
54 next = seed; 51 next = seed;
55} 52}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
index 5a772c9a8c..0e8ca5389b 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,9 +9,9 @@
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.11 2007/05/31 19:19:31 jmc Exp $
13.\" 13.\"
14.Dd October 8, 1993 14.Dd $Mdocdate: May 31 2007 $
15.Dt RAND48 3 15.Dt RAND48 3
16.Os 16.Os
17.Sh NAME 17.Sh NAME
@@ -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..ed05df162b 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,105 @@
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.19 2007/05/31 19:19:31 jmc 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 $Mdocdate: May 31 2007 $
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
93random numbers obtained from the kernel,
94suitable for cryptographic use.
95Note that this particular seeding procedure can generate
96states which are impossible to reproduce by calling
97.Fn srandom
98with any value, since the succeeding terms in the
99state buffer are no longer derived from the LC algorithm applied to
100a fixed seed.
101.Pp
102The
99.Fn initstate 103.Fn initstate
100routine allows a state array, passed in as an argument, to be initialized 104routine 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 105for future use.
106The size of the state array (in bytes) is used by
102.Fn initstate 107.Fn initstate
103to decide how sophisticated a random number generator it should use \(em the 108to decide how sophisticated a random number generator it should use \(em the
104more state, the better the random numbers will be. 109more state, the better the random numbers will be.
105(Current "optimal" values for the amount of state information are 110(Current "optimal" values for the amount of state information are
1068, 32, 64, 128, and 256 bytes; other amounts will be rounded down to 1118, 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.) 112the nearest known amount.
113Using less than 8 bytes will cause an error.)
108The seed for the initialization (which specifies a starting point for 114The seed for the initialization (which specifies a starting point for
109the random number sequence, and provides for restarting at the same 115the random number sequence, and provides for restarting at the same
110point) is also an argument. 116point) is also an argument.
111The 117The
112.Fn initstate 118.Fn initstate
113function 119function returns a pointer to the previous state information array.
114returns a pointer to the previous state information array.
115.Pp 120.Pp
116Once a state has been initialized, the 121Once a state has been initialized, the
117.Fn setstate 122.Fn setstate
118routine provides for rapid switching between states. 123routine provides for rapid switching between states.
119The 124The
120.Fn setstate 125.Fn setstate
121function 126function 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 127argument state array is used for further random number generation
124until the next call to 128until the next call to
125.Fn initstate 129.Fn initstate
@@ -143,12 +147,8 @@ is that the size of the state array does not have to be remembered after
143it is initialized. 147it is initialized.
144.Pp 148.Pp
145With 256 bytes of state information, the period of the random number 149With 256 bytes of state information, the period of the random number
146generator is greater than 150generator 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. 151which should be sufficient for most purposes.
150.Sh AUTHOR
151Earl T. Cohen
152.Sh DIAGNOSTICS 152.Sh DIAGNOSTICS
153If 153If
154.Fn initstate 154.Fn initstate
@@ -157,11 +157,29 @@ is called with less than 8 bytes of state information, or if
157detects that the state information has been garbled, error 157detects that the state information has been garbled, error
158messages are printed on the standard error output. 158messages are printed on the standard error output.
159.Sh SEE ALSO 159.Sh SEE ALSO
160.Xr rand 3 160.Xr arc4random 3 ,
161.Xr drand48 3 ,
162.Xr rand 3 ,
163.Xr random 4
164.Sh STANDARDS
165The
166.Fn random ,
167.Fn srandom ,
168.Fn initstate ,
169and
170.Fn setstate
171functions conform to
172.St -xpg4.2 .
173.Pp
174The
175.Fn srandomdev
176function is an extension.
161.Sh HISTORY 177.Sh HISTORY
162These 178These
163functions appeared in 179functions appeared in
164.Bx 4.2 . 180.Bx 4.2 .
181.Sh AUTHORS
182.An Earl T. Cohen
165.Sh BUGS 183.Sh BUGS
166About 2/3 the speed of 184About 2/3 the speed of
167.Xr rand 3 . 185.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..48e892042b 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: random.c,v 1.15 2005/11/30 07:51:02 otto Exp $ */
1/* 2/*
2 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,13 +28,13 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <sys/param.h>
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 32#include <sys/sysctl.h>
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 33#include <sys/time.h>
37#endif /* LIBC_SCCS and not lint */ 34#include <fcntl.h>
38
39#include <stdio.h> 35#include <stdio.h>
40#include <stdlib.h> 36#include <stdlib.h>
37#include <unistd.h>
41 38
42/* 39/*
43 * random.c: 40 * random.c:
@@ -55,10 +52,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 52 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 53 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 54 *
58 * Internally, the state information is treated as an array of longs; the 55 * 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 56 * 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 57 * 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 58 * 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: 59 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 60 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 61 * stored in it -- see setstate() for details).
@@ -134,14 +131,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. 131 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 132 */
136 133
137static long randtbl[DEG_3 + 1] = { 134static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 135 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 136 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 137 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 138 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 139 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 140 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 141 0xf3bec5da,
145}; 142};
146 143
147/* 144/*
@@ -158,8 +155,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 155 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 156 * to point to randtbl[1] (as explained below).
160 */ 157 */
161static long *fptr = &randtbl[SEP_3 + 1]; 158static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 159static int32_t *rptr = &randtbl[1];
163 160
164/* 161/*
165 * The following things are the pointer to the state information table, the 162 * The following things are the pointer to the state information table, the
@@ -171,11 +168,11 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 168 * 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. 169 * the last element to see if the front and rear pointers have wrapped.
173 */ 170 */
174static long *state = &randtbl[1]; 171static int32_t *state = &randtbl[1];
172static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 173static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 174static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 175static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1];
179 176
180/* 177/*
181 * srandom: 178 * srandom:
@@ -190,18 +187,28 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
190 * for default usage relies on values produced by this routine. 187 * for default usage relies on values produced by this routine.
191 */ 188 */
192void 189void
193srandom(x) 190srandom(unsigned int x)
194 u_int x;
195{ 191{
196 register int i, j; 192 int i;
193 int32_t test;
194 div_t val;
197 195
198 if (rand_type == TYPE_0) 196 if (rand_type == TYPE_0)
199 state[0] = x; 197 state[0] = x;
200 else { 198 else {
201 j = 1;
202 state[0] = x; 199 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 200 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 201 /*
202 * Implement the following, without overflowing 31 bits:
203 *
204 * state[i] = (16807 * state[i - 1]) % 2147483647;
205 *
206 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
207 */
208 val = div(state[i-1], 127773);
209 test = 16807 * val.rem - 2836 * val.quot;
210 state[i] = test + (test < 0 ? 2147483647 : 0);
211 }
205 fptr = &state[rand_sep]; 212 fptr = &state[rand_sep];
206 rptr = &state[0]; 213 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 214 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +217,38 @@ srandom(x)
210} 217}
211 218
212/* 219/*
220 * srandomdev:
221 *
222 * Many programs choose the seed value in a totally predictable manner.
223 * This often causes problems. We seed the generator using random
224 * data from the kernel.
225 * Note that this particular seeding procedure can generate states
226 * which are impossible to reproduce by calling srandom() with any
227 * value, since the succeeding terms in the state buffer are no longer
228 * derived from the LC algorithm applied to a fixed seed.
229 */
230void
231srandomdev(void)
232{
233 int mib[2];
234 size_t len;
235
236 if (rand_type == TYPE_0)
237 len = sizeof(state[0]);
238 else
239 len = rand_deg * sizeof(state[0]);
240
241 mib[0] = CTL_KERN;
242 mib[1] = KERN_ARND;
243 sysctl(mib, 2, state, &len, NULL, 0);
244
245 if (rand_type != TYPE_0) {
246 fptr = &state[rand_sep];
247 rptr = &state[0];
248 }
249}
250
251/*
213 * initstate: 252 * initstate:
214 * 253 *
215 * Initialize the state information in the given array of n bytes for future 254 * Initialize the state information in the given array of n bytes for future
@@ -229,22 +268,16 @@ srandom(x)
229 * Returns a pointer to the old state. 268 * Returns a pointer to the old state.
230 */ 269 */
231char * 270char *
232initstate(seed, arg_state, n) 271initstate(u_int seed, char *arg_state, size_t n)
233 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */
236{ 272{
237 register char *ostate = (char *)(&state[-1]); 273 char *ostate = (char *)(&state[-1]);
238 274
239 if (rand_type == TYPE_0) 275 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 276 state[-1] = rand_type;
241 else 277 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 278 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 279 if (n < BREAK_0)
244 (void)fprintf(stderr, 280 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 281 if (n < BREAK_1) {
249 rand_type = TYPE_0; 282 rand_type = TYPE_0;
250 rand_deg = DEG_0; 283 rand_deg = DEG_0;
@@ -266,7 +299,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 299 rand_deg = DEG_4;
267 rand_sep = SEP_4; 300 rand_sep = SEP_4;
268 } 301 }
269 state = &(((long *)arg_state)[1]); /* first location */ 302 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 303 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 304 srandom(seed);
272 if (rand_type == TYPE_0) 305 if (rand_type == TYPE_0)
@@ -292,12 +325,11 @@ initstate(seed, arg_state, n)
292 * Returns a pointer to the old state information. 325 * Returns a pointer to the old state information.
293 */ 326 */
294char * 327char *
295setstate(arg_state) 328setstate(const char *arg_state)
296 char *arg_state;
297{ 329{
298 register long *new_state = (long *)arg_state; 330 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 331 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 332 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 333 char *ostate = (char *)(&state[-1]);
302 334
303 if (rand_type == TYPE_0) 335 if (rand_type == TYPE_0)
@@ -315,8 +347,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 347 rand_sep = seps[type];
316 break; 348 break;
317 default: 349 default:
318 (void)fprintf(stderr, 350 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 351 }
321 state = &new_state[1]; 352 state = &new_state[1];
322 if (rand_type != TYPE_0) { 353 if (rand_type != TYPE_0) {
@@ -345,9 +376,9 @@ setstate(arg_state)
345 * Returns a 31-bit random number. 376 * Returns a 31-bit random number.
346 */ 377 */
347long 378long
348random() 379random(void)
349{ 380{
350 long i; 381 int32_t i;
351 382
352 if (rand_type == TYPE_0) 383 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 384 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +391,5 @@ random()
360 } else if (++rptr >= end_ptr) 391 } else if (++rptr >= end_ptr)
361 rptr = state; 392 rptr = state;
362 } 393 }
363 return(i); 394 return((long)i);
364} 395}
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..c64fc3d637 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,20 +28,19 @@
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.15 2007/07/06 15:42:04 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 $Mdocdate: July 6 2007 $
39.Dt REALPATH 3 34.Dt REALPATH 3
40.Os 35.Os
41.Sh NAME 36.Sh NAME
42.Nm realpath 37.Nm realpath
43.Nd returns the canonicalized absolute pathname 38.Nd returns the canonicalized absolute pathname
44.Sh SYNOPSIS 39.Sh SYNOPSIS
45.Fd #include <sys/param.h> 40.Fd #include <limits.h>
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft "char *" 42.Ft "char *"
48.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]" 43.Fn realpath "const char *pathname" "char resolved[PATH_MAX]"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn realpath 46.Fn realpath
@@ -57,18 +52,17 @@ 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 56.Fa resolved .
62.Fa resolvedname .
63The 57The
64.Fa resolvedname 58.Fa resolved
65argument 59argument
66.Em must 60.Em must
67refer to a buffer capable of storing at least 61refer to a buffer capable of storing at least
68.Dv MAXPATHLEN 62.Dv PATH_MAX
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,33 +72,37 @@ 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 resolved
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 the contents of
92.Fa resolved_name 86.Fa resolved
93contains the pathname which caused the problem. 87are undefined.
94.Sh ERRORS 88.Sh ERRORS
95The function 89The function
96.Fn realpath 90.Fn realpath
97may fail and set the external variable 91may fail and set the external variable
98.Va errno 92.Va errno
99for any of the errors specified for the library functions 93for any of the errors specified for the library functions
100.Xr chdir 2 ,
101.Xr close 2 ,
102.Xr fchdir 2 ,
103.Xr lstat 2 , 94.Xr lstat 2 ,
104.Xr open 2 , 95.Xr readlink 2 ,
105.Xr readlink 2
106and 96and
107.Xr getcwd 3 . 97.Xr getcwd 3 .
98.Sh SEE ALSO
99.Xr readlink 1 ,
100.Xr getcwd 3
101.Sh HISTORY
102The
103.Fn realpath
104function call first appeared in
105.Bx 4.4 .
108.Sh CAVEATS 106.Sh CAVEATS
109This implementation of 107This implementation of
110.Fn realpath 108.Fn realpath
@@ -114,13 +112,6 @@ The
114version always returns absolute pathnames, 112version always returns absolute pathnames,
115whereas the Solaris implementation will, 113whereas the Solaris implementation will,
116under certain circumstances, return a relative 114under certain circumstances, return a relative
117.Fa resolved_path 115.Fa resolved
118when given a relative 116when given a relative
119.Fa pathname . 117.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..4cb847b313 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -1,9 +1,6 @@
1/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1994 3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 * 4 *
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
@@ -13,18 +10,14 @@
13 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 13 * 3. The names of the authors may not be used to endorse or promote
17 * must display the following acknowledgement: 14 * products derived from this software without specific prior written
18 * This product includes software developed by the University of 15 * permission.
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 * 16 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,126 +27,164 @@
34 * SUCH DAMAGE. 27 * SUCH DAMAGE.
35 */ 28 */
36 29
37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/
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 */
41
42#include <sys/param.h> 30#include <sys/param.h>
43#include <sys/stat.h> 31#include <sys/stat.h>
44 32
45#include <errno.h> 33#include <errno.h>
46#include <fcntl.h>
47#include <stdlib.h> 34#include <stdlib.h>
48#include <string.h> 35#include <string.h>
49#include <unistd.h> 36#include <unistd.h>
50 37
51/* 38/*
52 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); 39 * char *realpath(const char *path, char resolved[PATH_MAX]);
53 * 40 *
54 * Find the real name of path, by removing all ".", ".." and symlink 41 * Find the real name of path, by removing all ".", ".." and symlink
55 * components. Returns (resolved) on success, or (NULL) on failure, 42 * components. Returns (resolved) on success, or (NULL) on failure,
56 * in which case the path which caused trouble is left in (resolved). 43 * in which case the path which caused trouble is left in (resolved).
57 */ 44 */
58char * 45char *
59realpath(path, resolved) 46realpath(const char *path, char resolved[PATH_MAX])
60 const char *path;
61 char *resolved;
62{ 47{
63 struct stat sb; 48 struct stat sb;
64 int fd, n, rootd, serrno; 49 char *p, *q, *s;
65 char *p, *q, wbuf[MAXPATHLEN]; 50 size_t left_len, resolved_len;
51 unsigned symlinks;
52 int serrno, slen;
53 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
66 54
67 /* Save the starting point. */ 55 serrno = errno;
68 if ((fd = open(".", O_RDONLY)) < 0) { 56 symlinks = 0;
69 (void)strcpy(resolved, "."); 57 if (path[0] == '/') {
58 resolved[0] = '/';
59 resolved[1] = '\0';
60 if (path[1] == '\0')
61 return (resolved);
62 resolved_len = 1;
63 left_len = strlcpy(left, path + 1, sizeof(left));
64 } else {
65 if (getcwd(resolved, PATH_MAX) == NULL) {
66 strlcpy(resolved, ".", PATH_MAX);
67 return (NULL);
68 }
69 resolved_len = strlen(resolved);
70 left_len = strlcpy(left, path, sizeof(left));
71 }
72 if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
73 errno = ENAMETOOLONG;
70 return (NULL); 74 return (NULL);
71 } 75 }
72 76
73 /* 77 /*
74 * Find the dirname and basename from the path to be resolved. 78 * Iterate over path components in `left'.
75 * Change directory to the dirname component.
76 * lstat the basename part.
77 * if it is a symlink, read in the value and loop.
78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename.
80 */ 79 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1); 80 while (left_len != 0) {
82 resolved[MAXPATHLEN - 1] = '\0'; 81 /*
83loop: 82 * Extract the next path component and adjust `left'
84 q = strrchr(resolved, '/'); 83 * and its length.
85 if (q != NULL) { 84 */
86 p = q + 1; 85 p = strchr(left, '/');
87 if (q == resolved) 86 s = p ? p : left + left_len;
88 q = "/"; 87 if (s - left >= sizeof(next_token)) {
89 else { 88 errno = ENAMETOOLONG;
90 do { 89 return (NULL);
91 --q;
92 } while (q > resolved && *q == '/');
93 q[1] = '\0';
94 q = resolved;
95 } 90 }
96 if (chdir(q) < 0) 91 memcpy(next_token, left, s - left);
97 goto err1; 92 next_token[s - left] = '\0';
98 } else 93 left_len -= s - left;
99 p = resolved; 94 if (p != NULL)
100 95 memmove(left, s + 1, left_len + 1);
101 /* Deal with the last component. */ 96 if (resolved[resolved_len - 1] != '/') {
102 if (lstat(p, &sb) == 0) { 97 if (resolved_len + 1 >= PATH_MAX) {
103 if (S_ISLNK(sb.st_mode)) { 98 errno = ENAMETOOLONG;
104 n = readlink(p, resolved, MAXPATHLEN); 99 return (NULL);
105 if (n < 0) 100 }
106 goto err1; 101 resolved[resolved_len++] = '/';
107 resolved[n] = '\0'; 102 resolved[resolved_len] = '\0';
108 goto loop;
109 } 103 }
110 if (S_ISDIR(sb.st_mode)) { 104 if (next_token[0] == '\0')
111 if (chdir(p) < 0) 105 continue;
112 goto err1; 106 else if (strcmp(next_token, ".") == 0)
113 p = ""; 107 continue;
108 else if (strcmp(next_token, "..") == 0) {
109 /*
110 * Strip the last path component except when we have
111 * single "/"
112 */
113 if (resolved_len > 1) {
114 resolved[resolved_len - 1] = '\0';
115 q = strrchr(resolved, '/') + 1;
116 *q = '\0';
117 resolved_len = q - resolved;
118 }
119 continue;
114 } 120 }
115 }
116
117 /*
118 * Save the last component name and get the full pathname of
119 * the current directory.
120 */
121 (void)strcpy(wbuf, p);
122 if (getcwd(resolved, MAXPATHLEN) == 0)
123 goto err1;
124 121
125 /* 122 /*
126 * Join the two strings together, ensuring that the right thing 123 * Append the next path component and lstat() it. If
127 * happens if the last component is empty, or the dirname is root. 124 * lstat() fails we still can return successfully if
128 */ 125 * there are no more path components left.
129 if (resolved[0] == '/' && resolved[1] == '\0') 126 */
130 rootd = 1; 127 resolved_len = strlcat(resolved, next_token, PATH_MAX);
131 else 128 if (resolved_len >= PATH_MAX) {
132 rootd = 0;
133
134 if (*wbuf) {
135 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
136 errno = ENAMETOOLONG; 129 errno = ENAMETOOLONG;
137 goto err1; 130 return (NULL);
138 } 131 }
139 if (rootd == 0) 132 if (lstat(resolved, &sb) != 0) {
140 (void)strcat(resolved, "/"); 133 if (errno == ENOENT && p == NULL) {
141 (void)strcat(resolved, wbuf); 134 errno = serrno;
142 } 135 return (resolved);
136 }
137 return (NULL);
138 }
139 if (S_ISLNK(sb.st_mode)) {
140 if (symlinks++ > MAXSYMLINKS) {
141 errno = ELOOP;
142 return (NULL);
143 }
144 slen = readlink(resolved, symlink, sizeof(symlink) - 1);
145 if (slen < 0)
146 return (NULL);
147 symlink[slen] = '\0';
148 if (symlink[0] == '/') {
149 resolved[1] = 0;
150 resolved_len = 1;
151 } else if (resolved_len > 1) {
152 /* Strip the last path component. */
153 resolved[resolved_len - 1] = '\0';
154 q = strrchr(resolved, '/') + 1;
155 *q = '\0';
156 resolved_len = q - resolved;
157 }
143 158
144 /* Go back to where we came from. */ 159 /*
145 if (fchdir(fd) < 0) { 160 * If there are any path components left, then
146 serrno = errno; 161 * append them to symlink. The result is placed
147 goto err2; 162 * in `left'.
163 */
164 if (p != NULL) {
165 if (symlink[slen - 1] != '/') {
166 if (slen + 1 >= sizeof(symlink)) {
167 errno = ENAMETOOLONG;
168 return (NULL);
169 }
170 symlink[slen] = '/';
171 symlink[slen + 1] = 0;
172 }
173 left_len = strlcat(symlink, left, sizeof(left));
174 if (left_len >= sizeof(left)) {
175 errno = ENAMETOOLONG;
176 return (NULL);
177 }
178 }
179 left_len = strlcpy(left, symlink, sizeof(left));
180 }
148 } 181 }
149 182
150 /* It's okay if the close fails, what's an fd more or less? */ 183 /*
151 (void)close(fd); 184 * Remove trailing slash except when the resolved pathname
185 * is a single "/".
186 */
187 if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
188 resolved[resolved_len - 1] = '\0';
152 return (resolved); 189 return (resolved);
153
154err1: serrno = errno;
155 (void)fchdir(fd);
156err2: (void)close(fd);
157 errno = serrno;
158 return (NULL);
159} 190}
diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c
new file mode 100644
index 0000000000..ae249ae053
--- /dev/null
+++ b/src/lib/libc/stdlib/remque.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: remque.c,v 1.2 2005/08/08 08:05:37 espie 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#include <search.h>
32
33struct qelem {
34 struct qelem *q_forw;
35 struct qelem *q_back;
36};
37
38void
39remque(void *element)
40{
41 struct qelem *e = (struct qelem *) element;
42 e->q_forw->q_back = e->q_back;
43 e->q_back->q_forw = e->q_forw;
44}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
index e3d31901dd..583262f2d5 100644
--- a/src/lib/libc/stdlib/seed48.c
+++ b/src/lib/libc/stdlib/seed48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: seed48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..36540ebb0c 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: setenv.c,v 1.9 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1987 Regents of the University of California. 3 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,30 +28,24 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/
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 */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
34char *__findenv(const char *name, int *offset);
35
36extern char **environ;
37
42/* 38/*
43 * setenv -- 39 * setenv --
44 * Set the value of the environmental variable "name" to be 40 * Set the value of the environmental variable "name" to be
45 * "value". If rewrite is set, replace any current value. 41 * "value". If rewrite is set, replace any current value.
46 */ 42 */
47int 43int
48setenv(name, value, rewrite) 44setenv(const char *name, const char *value, int rewrite)
49 register const char *name;
50 register const char *value;
51 int rewrite;
52{ 45{
53 extern char **environ; 46 static char **lastenv; /* last value of environ */
54 static int alloced; /* if allocated space before */ 47 char *C;
55 register char *C;
56 int l_value, offset; 48 int l_value, offset;
57 char *__findenv();
58 49
59 if (*value == '=') /* no `=' in value */ 50 if (*value == '=') /* no `=' in value */
60 ++value; 51 ++value;
@@ -63,39 +54,34 @@ setenv(name, value, rewrite)
63 if (!rewrite) 54 if (!rewrite)
64 return (0); 55 return (0);
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 56 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 57 while ((*C++ = *value++))
58 ;
67 return (0); 59 return (0);
68 } 60 }
69 } else { /* create new slot */ 61 } else { /* create new slot */
70 register int cnt; 62 size_t cnt;
71 register char **P; 63 char **P;
72 64
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 65 for (P = environ; *P != NULL; P++)
74 if (alloced) { /* just increase size */ 66 ;
75 environ = (char **)realloc((char *)environ, 67 cnt = P - environ;
76 (size_t)(sizeof(char *) * (cnt + 2))); 68 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
77 if (!environ) 69 if (!P)
78 return (-1); 70 return (-1);
79 } 71 if (lastenv != environ)
80 else { /* get new space */ 72 memcpy(P, environ, cnt * sizeof(char *));
81 alloced = 1; /* copy old entries into it */ 73 lastenv = environ = P;
82 P = (char **)malloc((size_t)(sizeof(char *) *
83 (cnt + 2)));
84 if (!P)
85 return (-1);
86 bcopy(environ, P, cnt * sizeof(char *));
87 environ = P;
88 }
89 environ[cnt + 1] = NULL;
90 offset = cnt; 74 offset = cnt;
75 environ[cnt + 1] = NULL;
91 } 76 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ 77 for (C = (char *)name; *C && *C != '='; ++C)
78 ; /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */ 79 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2)))) 80 malloc((size_t)((int)(C - name) + l_value + 2))))
95 return (-1); 81 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 82 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 83 ;
98 for (*C++ = '='; *C++ = *value++; ) 84 for (*C++ = '='; (*C++ = *value++); )
99 ; 85 ;
100 return (0); 86 return (0);
101} 87}
@@ -105,15 +91,12 @@ setenv(name, value, rewrite)
105 * Delete environmental variable "name". 91 * Delete environmental variable "name".
106 */ 92 */
107void 93void
108unsetenv(name) 94unsetenv(const char *name)
109 const char *name;
110{ 95{
111 extern char **environ; 96 char **P;
112 register char **P;
113 int offset; 97 int offset;
114 char *__findenv();
115 98
116 while (__findenv(name, &offset)) /* if set multiple times */ 99 while (__findenv(name, &offset)) /* if set multiple times */
117 for (P = &environ[offset];; ++P) 100 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1))) 101 if (!(*P = *(P + 1)))
119 break; 102 break;
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
index daf733f93e..f76b6cca86 100644
--- a/src/lib/libc/stdlib/srand48.c
+++ b/src/lib/libc/stdlib/srand48.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: srand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1993 Martin Birgmeier 3 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved. 4 * All rights reserved.
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
index 0b7f973857..979334203e 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,44 +29,62 @@
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.12 2008/06/13 23:50:49 jmc 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 $Mdocdate: June 13 2008 $
40.Dt STRTOD 3 35.Dt STRTOD 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtod 38.Nm strtod ,
39.Nm strtof
44.Nd convert 40.Nd convert
45.Tn ASCII 41.Tn ASCII
46string to double 42string to double or float
47.Sh SYNOPSIS 43.Sh SYNOPSIS
44.Fd #include <math.h>
48.Fd #include <stdlib.h> 45.Fd #include <stdlib.h>
49.Ft double 46.Ft double
50.Fn strtod "const char *nptr" "char **endptr" 47.Fn strtod "const char *nptr" "char **endptr"
48.Pp
49.Ft float
50.Fn strtof "const char *nptr" "char **endptr"
51.Sh DESCRIPTION 51.Sh DESCRIPTION
52The 52The
53.Fn strtod 53.Fn strtod
54function converts the initial portion of the string 54function converts the initial portion of the string pointed to by
55pointed to by 55.Fa nptr
56to
57.Li double
58representation.
59The
60.Fn strtof
61function converts the initial portion of the string pointed to by
56.Fa nptr 62.Fa nptr
57to 63to
58.Em double 64.Li float
59representation. 65representation.
60.Pp 66.Pp
61The expected form of the string is an optional plus (``+'') or minus 67The expected form of the string is an optional plus
62sign (``-'') followed by a sequence of digits optionally containing 68.Pq Ql +
69or minus sign
70.Pq Ql -
71followed by a sequence of digits optionally containing
63a decimal-point character, optionally followed by an exponent. 72a decimal-point character, optionally followed by an exponent.
64An exponent consists of an ``E'' or ``e'', followed by an optional plus 73An exponent consists of an
65or minus sign, followed by a sequence of digits. 74.Sq E
75or
76.Sq e ,
77followed by an optional plus or minus sign, followed by a sequence of digits.
66.Pp 78.Pp
67Leading white-space characters in the string (as defined by the 79Leading whitespace characters in the string (as defined by the
68.Xr isspace 3 80.Xr isspace 3
69function) are skipped. 81function) are skipped.
70.Sh RETURN VALUES 82.Sh RETURN VALUES
71The 83The
72.Fn strtod 84.Fn strtod
73function returns the converted value, if any. 85and
86.Fn strtof
87functions return the converted value, if any.
74.Pp 88.Pp
75If 89If
76.Fa endptr 90.Fa endptr
@@ -88,18 +102,18 @@ is stored in the location referenced by
88If the correct value would cause overflow, plus or minus 102If the correct value would cause overflow, plus or minus
89.Dv HUGE_VAL 103.Dv HUGE_VAL
90is returned (according to the sign of the value), and 104is returned (according to the sign of the value), and
91.Dv ERANGE 105.Er ERANGE
92is stored in 106is stored in
93.Va errno . 107.Va errno .
94If the correct value would cause underflow, zero is 108If the correct value would cause underflow, zero is returned and
95returned and 109.Er ERANGE
96.Dv ERANGE 110is stored in
97is stored in
98.Va errno . 111.Va errno .
99.Sh ERRORS 112.Sh ERRORS
100.Bl -tag -width Er 113.Bl -tag -width Er
101.It Bq Er ERANGE 114.It Bq Er ERANGE
102Overflow or underflow occurred. 115Overflow or underflow occurred.
116.El
103.Sh SEE ALSO 117.Sh SEE ALSO
104.Xr atof 3 , 118.Xr atof 3 ,
105.Xr atoi 3 , 119.Xr atoi 3 ,
@@ -109,6 +123,7 @@ Overflow or underflow occurred.
109.Sh STANDARDS 123.Sh STANDARDS
110The 124The
111.Fn strtod 125.Fn strtod
112function 126and
113conforms to 127.Fn strtof
128functions conform to
114.St -ansiC . 129.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index b13fa128f5..4dc3d65a26 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtod.c,v 1.30 2006/10/30 18:30:52 deraadt Exp $ */
1/**************************************************************** 2/****************************************************************
2 * 3 *
3 * The author of this software is David M. Gay. 4 * The author of this software is David M. Gay.
@@ -79,7 +80,6 @@
79 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision 80 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
80 * integer arithmetic. Whether this speeds things up or slows things 81 * integer arithmetic. Whether this speeds things up or slows things
81 * down depends on the machine and the number being converted. 82 * down depends on the machine and the number being converted.
82 * #define KR_headers for old-style C function headers.
83 * #define Bad_float_h if your system lacks a float.h or if it does not 83 * #define Bad_float_h if your system lacks a float.h or if it does not
84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, 84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. 85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
@@ -89,13 +89,14 @@
89 * directly -- and assumed always to succeed. 89 * directly -- and assumed always to succeed.
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#include <sys/types.h>
93static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
94#endif /* LIBC_SCCS and not lint */
95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 93#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) 94 defined(__mips__) || defined(__mips64__) || defined(__ns32k__) || \
98#include <machine/endian.h> 95 defined(__alpha__) || defined(__powerpc__) || defined(__m88k__) || \
96 defined(__hppa__) || defined(__amd64__) || defined(__sh__) || \
97 defined(__sparc64__) || \
98 (defined(__arm__) && defined(__VFP_FP__))
99
99#if BYTE_ORDER == BIG_ENDIAN 100#if BYTE_ORDER == BIG_ENDIAN
100#define IEEE_BIG_ENDIAN 101#define IEEE_BIG_ENDIAN
101#else 102#else
@@ -103,7 +104,16 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
103#endif 104#endif
104#endif 105#endif
105 106
106#ifdef vax 107#if defined(__arm__) && !defined(__VFP_FP__)
108/*
109 * Although the CPU is little endian the FP has different
110 * byte and word endianness. The byte order is still little endian
111 * but the word order is big endian.
112 */
113#define IEEE_BIG_ENDIAN
114#endif
115
116#ifdef __vax__
107#define VAX 117#define VAX
108#endif 118#endif
109 119
@@ -115,26 +125,22 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
115#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} 125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
116#endif 126#endif
117 127
128#include "thread_private.h"
129
130_THREAD_PRIVATE_KEY(dtoa);
131_THREAD_PRIVATE_KEY(pow5mult);
132
118#ifdef __cplusplus 133#ifdef __cplusplus
119#include "malloc.h" 134#include "malloc.h"
120#include "memory.h" 135#include "memory.h"
121#else 136#else
122#ifndef KR_headers
123#include "stdlib.h" 137#include "stdlib.h"
124#include "string.h" 138#include "string.h"
125#include "locale.h" 139#include "locale.h"
126#else
127#include "malloc.h"
128#include "memory.h"
129#endif
130#endif 140#endif
131 141
132#ifdef MALLOC 142#ifdef MALLOC
133#ifdef KR_headers
134extern char *MALLOC();
135#else
136extern void *MALLOC(size_t); 143extern void *MALLOC(size_t);
137#endif
138#else 144#else
139#define MALLOC malloc 145#define MALLOC malloc
140#endif 146#endif
@@ -143,7 +149,6 @@ extern void *MALLOC(size_t);
143#include "errno.h" 149#include "errno.h"
144 150
145#ifdef Bad_float_h 151#ifdef Bad_float_h
146#undef __STDC__
147#ifdef IEEE_BIG_ENDIAN 152#ifdef IEEE_BIG_ENDIAN
148#define IEEE_ARITHMETIC 153#define IEEE_ARITHMETIC
149#endif 154#endif
@@ -193,12 +198,8 @@ extern "C" {
193#endif 198#endif
194 199
195#ifndef CONST 200#ifndef CONST
196#ifdef KR_headers
197#define CONST /* blank */
198#else
199#define CONST const 201#define CONST const
200#endif 202#endif
201#endif
202 203
203#ifdef Unsigned_Shifts 204#ifdef Unsigned_Shifts
204#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; 205#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
@@ -208,23 +209,27 @@ extern "C" {
208 209
209#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ 210#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
210 defined(IBM) != 1 211 defined(IBM) != 1
211Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or 212#error Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
212IBM should be defined.
213#endif 213#endif
214 214
215typedef union {
216 double d;
217 ULong ul[2];
218} _double;
219#define value(x) ((x).d)
215#ifdef IEEE_LITTLE_ENDIAN 220#ifdef IEEE_LITTLE_ENDIAN
216#define word0(x) ((ULong *)&x)[1] 221#define word0(x) ((x).ul[1])
217#define word1(x) ((ULong *)&x)[0] 222#define word1(x) ((x).ul[0])
218#else 223#else
219#define word0(x) ((ULong *)&x)[0] 224#define word0(x) ((x).ul[0])
220#define word1(x) ((ULong *)&x)[1] 225#define word1(x) ((x).ul[1])
221#endif 226#endif
222 227
223/* The following definition of Storeinc is appropriate for MIPS processors. 228/* The following definition of Storeinc is appropriate for MIPS processors.
224 * An alternative that might be better on some machines is 229 * An alternative that might be better on some machines is
225 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 230 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
226 */ 231 */
227#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) 232#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
228#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 233#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
229((unsigned short *)a)[0] = (unsigned short)c, a++) 234((unsigned short *)a)[0] = (unsigned short)c, a++)
230#else 235#else
@@ -326,11 +331,7 @@ IBM should be defined.
326#ifdef RND_PRODQUOT 331#ifdef RND_PRODQUOT
327#define rounded_product(a,b) a = rnd_prod(a, b) 332#define rounded_product(a,b) a = rnd_prod(a, b)
328#define rounded_quotient(a,b) a = rnd_quot(a, b) 333#define rounded_quotient(a,b) a = rnd_quot(a, b)
329#ifdef KR_headers
330extern double rnd_prod(), rnd_quot();
331#else
332extern double rnd_prod(double, double), rnd_quot(double, double); 334extern double rnd_prod(double, double), rnd_quot(double, double);
333#endif
334#else 335#else
335#define rounded_product(a,b) a *= b 336#define rounded_product(a,b) a *= b
336#define rounded_quotient(a,b) a /= b 337#define rounded_quotient(a,b) a /= b
@@ -369,54 +370,94 @@ Bigint {
369 370
370 static Bigint *freelist[Kmax+1]; 371 static Bigint *freelist[Kmax+1];
371 372
373#define PRIVATE_MEM 2304
374#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
375 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
376
372 static Bigint * 377 static Bigint *
373Balloc 378Balloc(int k)
374#ifdef KR_headers
375 (k) int k;
376#else
377 (int k)
378#endif
379{ 379{
380 int x; 380 int x;
381 unsigned int len;
381 Bigint *rv; 382 Bigint *rv;
382 383
383 if (rv = freelist[k]) { 384 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
385 if ((rv = freelist[k])) {
384 freelist[k] = rv->next; 386 freelist[k] = rv->next;
385 } 387 }
386 else { 388 else {
387 x = 1 << k; 389 x = 1 << k;
388 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); 390 len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1)
391 /sizeof(double);
392 if (pmem_next - private_mem + len <= PRIVATE_mem) {
393 rv = (Bigint *)pmem_next;
394 pmem_next += len;
395 }
396 else
397 rv = (Bigint *)MALLOC(len *sizeof(double));
389 rv->k = k; 398 rv->k = k;
390 rv->maxwds = x; 399 rv->maxwds = x;
391 } 400 }
401 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
392 rv->sign = rv->wds = 0; 402 rv->sign = rv->wds = 0;
393 return rv; 403 return rv;
394 } 404 }
395 405
396 static void 406 static void
397Bfree 407Bfree(Bigint *v)
398#ifdef KR_headers
399 (v) Bigint *v;
400#else
401 (Bigint *v)
402#endif
403{ 408{
404 if (v) { 409 if (v) {
410 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
405 v->next = freelist[v->k]; 411 v->next = freelist[v->k];
406 freelist[v->k] = v; 412 freelist[v->k] = v;
413 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
407 } 414 }
408 } 415 }
409 416
410#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ 417#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
411y->wds*sizeof(Long) + 2*sizeof(int)) 418y->wds*sizeof(Long) + 2*sizeof(int))
412 419
420/* return value is only used as a simple string, so mis-aligned parts
421 * inside the Bigint are not at risk on strict align architectures
422 */
423 static char *
424rv_alloc(int i)
425{
426 int j, k, *r;
427
428 j = sizeof(ULong);
429 for(k = 0;
430 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
431 j <<= 1)
432 k++;
433 r = (int*)Balloc(k);
434 *r = k;
435 return (char *)(r+1);
436 }
437
438 static char *
439nrv_alloc(char *s, char **rve, int n)
440{
441 char *rv, *t;
442
443 t = rv = rv_alloc(n);
444 while((*t = *s++) !=0)
445 t++;
446 if (rve)
447 *rve = t;
448 return rv;
449 }
450
451 void
452__freedtoa(char *s)
453{
454 Bigint *b = (Bigint *)((int *)s - 1);
455 b->maxwds = 1 << (b->k = *(int*)b);
456 Bfree(b);
457 }
458
413 static Bigint * 459 static Bigint *
414multadd 460multadd(Bigint *b, int m, int a) /* multiply by m and add a */
415#ifdef KR_headers
416 (b, m, a) Bigint *b; int m, a;
417#else
418 (Bigint *b, int m, int a) /* multiply by m and add a */
419#endif
420{ 461{
421 int i, wds; 462 int i, wds;
422 ULong *x, y; 463 ULong *x, y;
@@ -456,12 +497,7 @@ multadd
456 } 497 }
457 498
458 static Bigint * 499 static Bigint *
459s2b 500s2b(CONST char *s, int nd0, int nd, ULong y9)
460#ifdef KR_headers
461 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
462#else
463 (CONST char *s, int nd0, int nd, ULong y9)
464#endif
465{ 501{
466 Bigint *b; 502 Bigint *b;
467 int i, k; 503 int i, k;
@@ -494,14 +530,9 @@ s2b
494 } 530 }
495 531
496 static int 532 static int
497hi0bits 533hi0bits(ULong x)
498#ifdef KR_headers
499 (x) register ULong x;
500#else
501 (register ULong x)
502#endif
503{ 534{
504 register int k = 0; 535 int k = 0;
505 536
506 if (!(x & 0xffff0000)) { 537 if (!(x & 0xffff0000)) {
507 k = 16; 538 k = 16;
@@ -528,15 +559,10 @@ hi0bits
528 } 559 }
529 560
530 static int 561 static int
531lo0bits 562lo0bits(ULong *y)
532#ifdef KR_headers
533 (y) ULong *y;
534#else
535 (ULong *y)
536#endif
537{ 563{
538 register int k; 564 int k;
539 register ULong x = *y; 565 ULong x = *y;
540 566
541 if (x & 7) { 567 if (x & 7) {
542 if (x & 1) 568 if (x & 1)
@@ -568,7 +594,7 @@ lo0bits
568 if (!(x & 1)) { 594 if (!(x & 1)) {
569 k++; 595 k++;
570 x >>= 1; 596 x >>= 1;
571 if (!x & 1) 597 if (!(x & 1))
572 return 32; 598 return 32;
573 } 599 }
574 *y = x; 600 *y = x;
@@ -576,12 +602,7 @@ lo0bits
576 } 602 }
577 603
578 static Bigint * 604 static Bigint *
579i2b 605i2b(int i)
580#ifdef KR_headers
581 (i) int i;
582#else
583 (int i)
584#endif
585{ 606{
586 Bigint *b; 607 Bigint *b;
587 608
@@ -592,12 +613,7 @@ i2b
592 } 613 }
593 614
594 static Bigint * 615 static Bigint *
595mult 616mult(Bigint *a, Bigint *b)
596#ifdef KR_headers
597 (a, b) Bigint *a, *b;
598#else
599 (Bigint *a, Bigint *b)
600#endif
601{ 617{
602 Bigint *c; 618 Bigint *c;
603 int k, wa, wb, wc; 619 int k, wa, wb, wc;
@@ -628,7 +644,7 @@ mult
628 xc0 = c->x; 644 xc0 = c->x;
629#ifdef Pack_32 645#ifdef Pack_32
630 for(; xb < xbe; xb++, xc0++) { 646 for(; xb < xbe; xb++, xc0++) {
631 if (y = *xb & 0xffff) { 647 if ((y = *xb & 0xffff)) {
632 x = xa; 648 x = xa;
633 xc = xc0; 649 xc = xc0;
634 carry = 0; 650 carry = 0;
@@ -642,7 +658,7 @@ mult
642 while(x < xae); 658 while(x < xae);
643 *xc = carry; 659 *xc = carry;
644 } 660 }
645 if (y = *xb >> 16) { 661 if ((y = *xb >> 16)) {
646 x = xa; 662 x = xa;
647 xc = xc0; 663 xc = xc0;
648 carry = 0; 664 carry = 0;
@@ -682,26 +698,23 @@ mult
682 static Bigint *p5s; 698 static Bigint *p5s;
683 699
684 static Bigint * 700 static Bigint *
685pow5mult 701pow5mult(Bigint *b, int k)
686#ifdef KR_headers
687 (b, k) Bigint *b; int k;
688#else
689 (Bigint *b, int k)
690#endif
691{ 702{
692 Bigint *b1, *p5, *p51; 703 Bigint *b1, *p5, *p51;
693 int i; 704 int i;
694 static int p05[3] = { 5, 25, 125 }; 705 static int p05[3] = { 5, 25, 125 };
695 706
696 if (i = k & 3) 707 if ((i = k & 3))
697 b = multadd(b, p05[i-1], 0); 708 b = multadd(b, p05[i-1], 0);
698 709
699 if (!(k >>= 2)) 710 if (!(k >>= 2))
700 return b; 711 return b;
701 if (!(p5 = p5s)) { 712 if (!(p5 = p5s)) {
702 /* first time */ 713 /* first time */
714 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
703 p5 = p5s = i2b(625); 715 p5 = p5s = i2b(625);
704 p5->next = 0; 716 p5->next = 0;
717 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
705 } 718 }
706 for(;;) { 719 for(;;) {
707 if (k & 1) { 720 if (k & 1) {
@@ -712,8 +725,12 @@ pow5mult
712 if (!(k >>= 1)) 725 if (!(k >>= 1))
713 break; 726 break;
714 if (!(p51 = p5->next)) { 727 if (!(p51 = p5->next)) {
715 p51 = p5->next = mult(p5,p5); 728 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
716 p51->next = 0; 729 if (!(p51 = p5->next)) {
730 p51 = p5->next = mult(p5,p5);
731 p51->next = 0;
732 }
733 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
717 } 734 }
718 p5 = p51; 735 p5 = p51;
719 } 736 }
@@ -721,12 +738,7 @@ pow5mult
721 } 738 }
722 739
723 static Bigint * 740 static Bigint *
724lshift 741lshift(Bigint *b, int k)
725#ifdef KR_headers
726 (b, k) Bigint *b; int k;
727#else
728 (Bigint *b, int k)
729#endif
730{ 742{
731 int i, k1, n, n1; 743 int i, k1, n, n1;
732 Bigint *b1; 744 Bigint *b1;
@@ -756,7 +768,7 @@ lshift
756 z = *x++ >> k1; 768 z = *x++ >> k1;
757 } 769 }
758 while(x < xe); 770 while(x < xe);
759 if (*x1 = z) 771 if ((*x1 = z))
760 ++n1; 772 ++n1;
761 } 773 }
762#else 774#else
@@ -781,12 +793,7 @@ lshift
781 } 793 }
782 794
783 static int 795 static int
784cmp 796cmp(Bigint *a, Bigint *b)
785#ifdef KR_headers
786 (a, b) Bigint *a, *b;
787#else
788 (Bigint *a, Bigint *b)
789#endif
790{ 797{
791 ULong *xa, *xa0, *xb, *xb0; 798 ULong *xa, *xa0, *xb, *xb0;
792 int i, j; 799 int i, j;
@@ -815,12 +822,7 @@ cmp
815 } 822 }
816 823
817 static Bigint * 824 static Bigint *
818diff 825diff(Bigint *a, Bigint *b)
819#ifdef KR_headers
820 (a, b) Bigint *a, *b;
821#else
822 (Bigint *a, Bigint *b)
823#endif
824{ 826{
825 Bigint *c; 827 Bigint *c;
826 int i, wa, wb; 828 int i, wa, wb;
@@ -897,16 +899,13 @@ diff
897 } 899 }
898 900
899 static double 901 static double
900ulp 902ulp(double _x)
901#ifdef KR_headers
902 (x) double x;
903#else
904 (double x)
905#endif
906{ 903{
907 register Long L; 904 _double x;
908 double a; 905 Long L;
906 _double a;
909 907
908 value(x) = _x;
910 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 909 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
911#ifndef Sudden_Underflow 910#ifndef Sudden_Underflow
912 if (L > 0) { 911 if (L > 0) {
@@ -931,20 +930,15 @@ ulp
931 } 930 }
932 } 931 }
933#endif 932#endif
934 return a; 933 return value(a);
935 } 934 }
936 935
937 static double 936 static double
938b2d 937b2d(Bigint *a, int *e)
939#ifdef KR_headers
940 (a, e) Bigint *a; int *e;
941#else
942 (Bigint *a, int *e)
943#endif
944{ 938{
945 ULong *xa, *xa0, w, y, z; 939 ULong *xa, *xa0, w, y, z;
946 int k; 940 int k;
947 double d; 941 _double d;
948#ifdef VAX 942#ifdef VAX
949 ULong d0, d1; 943 ULong d0, d1;
950#else 944#else
@@ -1001,22 +995,22 @@ b2d
1001#undef d0 995#undef d0
1002#undef d1 996#undef d1
1003#endif 997#endif
1004 return d; 998 return value(d);
1005 } 999 }
1006 1000
1007 static Bigint * 1001 static Bigint *
1008d2b 1002d2b(double _d, int *e, int *bits)
1009#ifdef KR_headers
1010 (d, e, bits) double d; int *e, *bits;
1011#else
1012 (double d, int *e, int *bits)
1013#endif
1014{ 1003{
1015 Bigint *b; 1004 Bigint *b;
1016 int de, i, k; 1005 int de, i, k;
1017 ULong *x, y, z; 1006 ULong *x, y, z;
1007 _double d;
1018#ifdef VAX 1008#ifdef VAX
1019 ULong d0, d1; 1009 ULong d0, d1;
1010#endif
1011
1012 value(d) = _d;
1013#ifdef VAX
1020 d0 = word0(d) >> 16 | word0(d) << 16; 1014 d0 = word0(d) >> 16 | word0(d) << 16;
1021 d1 = word1(d) >> 16 | word1(d) << 16; 1015 d1 = word1(d) >> 16 | word1(d) << 16;
1022#else 1016#else
@@ -1134,18 +1128,13 @@ d2b
1134#undef d1 1128#undef d1
1135 1129
1136 static double 1130 static double
1137ratio 1131ratio(Bigint *a, Bigint *b)
1138#ifdef KR_headers
1139 (a, b) Bigint *a, *b;
1140#else
1141 (Bigint *a, Bigint *b)
1142#endif
1143{ 1132{
1144 double da, db; 1133 _double da, db;
1145 int k, ka, kb; 1134 int k, ka, kb;
1146 1135
1147 da = b2d(a, &ka); 1136 value(da) = b2d(a, &ka);
1148 db = b2d(b, &kb); 1137 value(db) = b2d(b, &kb);
1149#ifdef Pack_32 1138#ifdef Pack_32
1150 k = ka - kb + 32*(a->wds - b->wds); 1139 k = ka - kb + 32*(a->wds - b->wds);
1151#else 1140#else
@@ -1171,7 +1160,7 @@ ratio
1171 word0(db) += k*Exp_msk1; 1160 word0(db) += k*Exp_msk1;
1172 } 1161 }
1173#endif 1162#endif
1174 return da / db; 1163 return value(da) / value(db);
1175 } 1164 }
1176 1165
1177static CONST double 1166static CONST double
@@ -1201,32 +1190,29 @@ static CONST double tinytens[] = { 1e-16, 1e-32 };
1201#endif 1190#endif
1202 1191
1203 double 1192 double
1204strtod 1193strtod(CONST char *s00, char **se)
1205#ifdef KR_headers
1206 (s00, se) CONST char *s00; char **se;
1207#else
1208 (CONST char *s00, char **se)
1209#endif
1210{ 1194{
1211 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1195 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1212 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1196 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1213 CONST char *s, *s0, *s1; 1197 CONST char *s, *s0, *s1;
1214 double aadj, aadj1, adj, rv, rv0; 1198 double aadj, aadj1, adj;
1199 /*
1200 * volatile forces mem update for FPUs where reg size != sizeof double,
1201 * which should trigger ERANGE in the case of underflow.
1202 */
1203 volatile _double rv;
1204 _double rv0;
1215 Long L; 1205 Long L;
1216 ULong y, z; 1206 ULong y, z;
1217 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1207 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1218 1208
1219#ifndef KR_headers
1220 CONST char decimal_point = localeconv()->decimal_point[0]; 1209 CONST char decimal_point = localeconv()->decimal_point[0];
1221#else
1222 CONST char decimal_point = '.';
1223#endif
1224 1210
1225 sign = nz0 = nz = 0; 1211 sign = nz0 = nz = 0;
1226 rv = 0.; 1212 value(rv) = 0.;
1227 1213
1228 1214
1229 for(s = s00; isspace(*s); s++) 1215 for(s = s00; isspace((unsigned char) *s); s++)
1230 ; 1216 ;
1231 1217
1232 if (*s == '-') { 1218 if (*s == '-') {
@@ -1340,9 +1326,9 @@ strtod
1340 if (!nd0) 1326 if (!nd0)
1341 nd0 = nd; 1327 nd0 = nd;
1342 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1328 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1343 rv = y; 1329 value(rv) = y;
1344 if (k > 9) 1330 if (k > 9)
1345 rv = tens[k - 9] * rv + z; 1331 value(rv) = tens[k - 9] * value(rv) + z;
1346 bd0 = 0; 1332 bd0 = 0;
1347 if (nd <= DBL_DIG 1333 if (nd <= DBL_DIG
1348#ifndef RND_PRODQUOT 1334#ifndef RND_PRODQUOT
@@ -1356,7 +1342,8 @@ strtod
1356#ifdef VAX 1342#ifdef VAX
1357 goto vax_ovfl_check; 1343 goto vax_ovfl_check;
1358#else 1344#else
1359 /* rv = */ rounded_product(rv, tens[e]); 1345 /* value(rv) = */ rounded_product(value(rv),
1346 tens[e]);
1360 goto ret; 1347 goto ret;
1361#endif 1348#endif
1362 } 1349 }
@@ -1366,27 +1353,30 @@ strtod
1366 * this for larger i values. 1353 * this for larger i values.
1367 */ 1354 */
1368 e -= i; 1355 e -= i;
1369 rv *= tens[i]; 1356 value(rv) *= tens[i];
1370#ifdef VAX 1357#ifdef VAX
1371 /* VAX exponent range is so narrow we must 1358 /* VAX exponent range is so narrow we must
1372 * worry about overflow here... 1359 * worry about overflow here...
1373 */ 1360 */
1374 vax_ovfl_check: 1361 vax_ovfl_check:
1375 word0(rv) -= P*Exp_msk1; 1362 word0(rv) -= P*Exp_msk1;
1376 /* rv = */ rounded_product(rv, tens[e]); 1363 /* value(rv) = */ rounded_product(value(rv),
1364 tens[e]);
1377 if ((word0(rv) & Exp_mask) 1365 if ((word0(rv) & Exp_mask)
1378 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1366 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1379 goto ovfl; 1367 goto ovfl;
1380 word0(rv) += P*Exp_msk1; 1368 word0(rv) += P*Exp_msk1;
1381#else 1369#else
1382 /* rv = */ rounded_product(rv, tens[e]); 1370 /* value(rv) = */ rounded_product(value(rv),
1371 tens[e]);
1383#endif 1372#endif
1384 goto ret; 1373 goto ret;
1385 } 1374 }
1386 } 1375 }
1387#ifndef Inaccurate_Divide 1376#ifndef Inaccurate_Divide
1388 else if (e >= -Ten_pmax) { 1377 else if (e >= -Ten_pmax) {
1389 /* rv = */ rounded_quotient(rv, tens[-e]); 1378 /* value(rv) = */ rounded_quotient(value(rv),
1379 tens[-e]);
1390 goto ret; 1380 goto ret;
1391 } 1381 }
1392#endif 1382#endif
@@ -1397,13 +1387,13 @@ strtod
1397 1387
1398 if (e1 > 0) { 1388 if (e1 > 0) {
1399 if (i = e1 & 15) 1389 if (i = e1 & 15)
1400 rv *= tens[i]; 1390 value(rv) *= tens[i];
1401 if (e1 &= ~15) { 1391 if (e1 &= ~15) {
1402 if (e1 > DBL_MAX_10_EXP) { 1392 if (e1 > DBL_MAX_10_EXP) {
1403 ovfl: 1393 ovfl:
1404 errno = ERANGE; 1394 errno = ERANGE;
1405#ifdef __STDC__ 1395#ifndef Bad_float_h
1406 rv = HUGE_VAL; 1396 value(rv) = HUGE_VAL;
1407#else 1397#else
1408 /* Can't trust HUGE_VAL */ 1398 /* Can't trust HUGE_VAL */
1409#ifdef IEEE_Arith 1399#ifdef IEEE_Arith
@@ -1421,10 +1411,10 @@ strtod
1421 if (e1 >>= 4) { 1411 if (e1 >>= 4) {
1422 for(j = 0; e1 > 1; j++, e1 >>= 1) 1412 for(j = 0; e1 > 1; j++, e1 >>= 1)
1423 if (e1 & 1) 1413 if (e1 & 1)
1424 rv *= bigtens[j]; 1414 value(rv) *= bigtens[j];
1425 /* The last multiplication could overflow. */ 1415 /* The last multiplication could overflow. */
1426 word0(rv) -= P*Exp_msk1; 1416 word0(rv) -= P*Exp_msk1;
1427 rv *= bigtens[j]; 1417 value(rv) *= bigtens[j];
1428 if ((z = word0(rv) & Exp_mask) 1418 if ((z = word0(rv) & Exp_mask)
1429 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1419 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1430 goto ovfl; 1420 goto ovfl;
@@ -1443,23 +1433,23 @@ strtod
1443 else if (e1 < 0) { 1433 else if (e1 < 0) {
1444 e1 = -e1; 1434 e1 = -e1;
1445 if (i = e1 & 15) 1435 if (i = e1 & 15)
1446 rv /= tens[i]; 1436 value(rv) /= tens[i];
1447 if (e1 &= ~15) { 1437 if (e1 &= ~15) {
1448 e1 >>= 4; 1438 e1 >>= 4;
1449 if (e1 >= 1 << n_bigtens) 1439 if (e1 >= 1 << n_bigtens)
1450 goto undfl; 1440 goto undfl;
1451 for(j = 0; e1 > 1; j++, e1 >>= 1) 1441 for(j = 0; e1 > 1; j++, e1 >>= 1)
1452 if (e1 & 1) 1442 if (e1 & 1)
1453 rv *= tinytens[j]; 1443 value(rv) *= tinytens[j];
1454 /* The last multiplication could underflow. */ 1444 /* The last multiplication could underflow. */
1455 rv0 = rv; 1445 value(rv0) = value(rv);
1456 rv *= tinytens[j]; 1446 value(rv) *= tinytens[j];
1457 if (!rv) { 1447 if (!value(rv)) {
1458 rv = 2.*rv0; 1448 value(rv) = 2.*value(rv0);
1459 rv *= tinytens[j]; 1449 value(rv) *= tinytens[j];
1460 if (!rv) { 1450 if (!value(rv)) {
1461 undfl: 1451 undfl:
1462 rv = 0.; 1452 value(rv) = 0.;
1463 errno = ERANGE; 1453 errno = ERANGE;
1464 if (bd0) 1454 if (bd0)
1465 goto retfree; 1455 goto retfree;
@@ -1483,7 +1473,7 @@ strtod
1483 for(;;) { 1473 for(;;) {
1484 bd = Balloc(bd0->k); 1474 bd = Balloc(bd0->k);
1485 Bcopy(bd, bd0); 1475 Bcopy(bd, bd0);
1486 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ 1476 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1487 bs = i2b(1); 1477 bs = i2b(1);
1488 1478
1489 if (e >= 0) { 1479 if (e >= 0) {
@@ -1595,12 +1585,12 @@ strtod
1595 break; 1585 break;
1596#endif 1586#endif
1597 if (dsign) 1587 if (dsign)
1598 rv += ulp(rv); 1588 value(rv) += ulp(value(rv));
1599#ifndef ROUND_BIASED 1589#ifndef ROUND_BIASED
1600 else { 1590 else {
1601 rv -= ulp(rv); 1591 value(rv) -= ulp(value(rv));
1602#ifndef Sudden_Underflow 1592#ifndef Sudden_Underflow
1603 if (!rv) 1593 if (!value(rv))
1604 goto undfl; 1594 goto undfl;
1605#endif 1595#endif
1606 } 1596 }
@@ -1651,10 +1641,10 @@ strtod
1651 /* Check for overflow */ 1641 /* Check for overflow */
1652 1642
1653 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 1643 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1654 rv0 = rv; 1644 value(rv0) = value(rv);
1655 word0(rv) -= P*Exp_msk1; 1645 word0(rv) -= P*Exp_msk1;
1656 adj = aadj1 * ulp(rv); 1646 adj = aadj1 * ulp(value(rv));
1657 rv += adj; 1647 value(rv) += adj;
1658 if ((word0(rv) & Exp_mask) >= 1648 if ((word0(rv) & Exp_mask) >=
1659 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 1649 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1660 if (word0(rv0) == Big0 && word1(rv0) == Big1) 1650 if (word0(rv0) == Big0 && word1(rv0) == Big1)
@@ -1669,10 +1659,10 @@ strtod
1669 else { 1659 else {
1670#ifdef Sudden_Underflow 1660#ifdef Sudden_Underflow
1671 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 1661 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1672 rv0 = rv; 1662 value(rv0) = value(rv);
1673 word0(rv) += P*Exp_msk1; 1663 word0(rv) += P*Exp_msk1;
1674 adj = aadj1 * ulp(rv); 1664 adj = aadj1 * ulp(value(rv));
1675 rv += adj; 1665 value(rv) += adj;
1676#ifdef IBM 1666#ifdef IBM
1677 if ((word0(rv) & Exp_mask) < P*Exp_msk1) 1667 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1678#else 1668#else
@@ -1690,8 +1680,8 @@ strtod
1690 word0(rv) -= P*Exp_msk1; 1680 word0(rv) -= P*Exp_msk1;
1691 } 1681 }
1692 else { 1682 else {
1693 adj = aadj1 * ulp(rv); 1683 adj = aadj1 * ulp(value(rv));
1694 rv += adj; 1684 value(rv) += adj;
1695 } 1685 }
1696#else 1686#else
1697 /* Compute adj so that the IEEE rounding rules will 1687 /* Compute adj so that the IEEE rounding rules will
@@ -1706,8 +1696,8 @@ strtod
1706 if (!dsign) 1696 if (!dsign)
1707 aadj1 = -aadj1; 1697 aadj1 = -aadj1;
1708 } 1698 }
1709 adj = aadj1 * ulp(rv); 1699 adj = aadj1 * ulp(value(rv));
1710 rv += adj; 1700 value(rv) += adj;
1711#endif 1701#endif
1712 } 1702 }
1713 z = word0(rv) & Exp_mask; 1703 z = word0(rv) & Exp_mask;
@@ -1738,16 +1728,11 @@ strtod
1738 ret: 1728 ret:
1739 if (se) 1729 if (se)
1740 *se = (char *)s; 1730 *se = (char *)s;
1741 return sign ? -rv : rv; 1731 return sign ? -value(rv) : value(rv);
1742 } 1732 }
1743 1733
1744 static int 1734 static int
1745quorem 1735quorem(Bigint *b, Bigint *S)
1746#ifdef KR_headers
1747 (b, S) Bigint *b, *S;
1748#else
1749 (Bigint *b, Bigint *S)
1750#endif
1751{ 1736{
1752 int n; 1737 int n;
1753 Long borrow, y; 1738 Long borrow, y;
@@ -1882,13 +1867,7 @@ quorem
1882 */ 1867 */
1883 1868
1884 char * 1869 char *
1885__dtoa 1870__dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1886#ifdef KR_headers
1887 (d, mode, ndigits, decpt, sign, rve)
1888 double d; int mode, ndigits, *decpt, *sign; char **rve;
1889#else
1890 (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1891#endif
1892{ 1871{
1893 /* Arguments ndigits, decpt, sign are similar to those 1872 /* Arguments ndigits, decpt, sign are similar to those
1894 of ecvt and fcvt; trailing zeros are suppressed from 1873 of ecvt and fcvt; trailing zeros are suppressed from
@@ -1933,17 +1912,11 @@ __dtoa
1933 ULong x; 1912 ULong x;
1934#endif 1913#endif
1935 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1914 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1936 double d2, ds, eps; 1915 double ds;
1937 char *s, *s0; 1916 char *s, *s0;
1938 static Bigint *result; 1917 _double d, d2, eps;
1939 static int result_k;
1940 1918
1941 if (result) { 1919 value(d) = _d;
1942 result->k = result_k;
1943 result->maxwds = 1 << result_k;
1944 Bfree(result);
1945 result = 0;
1946 }
1947 1920
1948 if (word0(d) & Sign_bit) { 1921 if (word0(d) & Sign_bit) {
1949 /* set sign for everything, including 0's and NaNs */ 1922 /* set sign for everything, including 0's and NaNs */
@@ -1962,43 +1935,33 @@ __dtoa
1962 { 1935 {
1963 /* Infinity or NaN */ 1936 /* Infinity or NaN */
1964 *decpt = 9999; 1937 *decpt = 9999;
1965 s =
1966#ifdef IEEE_Arith 1938#ifdef IEEE_Arith
1967 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : 1939 if (!word1(d) && !(word0(d) & 0xfffff))
1940 return nrv_alloc("Infinity", rve, 8);
1968#endif 1941#endif
1969 "NaN"; 1942 return nrv_alloc("NaN", rve, 3);
1970 if (rve)
1971 *rve =
1972#ifdef IEEE_Arith
1973 s[3] ? s + 8 :
1974#endif
1975 s + 3;
1976 return s;
1977 } 1943 }
1978#endif 1944#endif
1979#ifdef IBM 1945#ifdef IBM
1980 d += 0; /* normalize */ 1946 value(d) += 0; /* normalize */
1981#endif 1947#endif
1982 if (!d) { 1948 if (!value(d)) {
1983 *decpt = 1; 1949 *decpt = 1;
1984 s = "0"; 1950 return nrv_alloc("0", rve, 1);
1985 if (rve)
1986 *rve = s + 1;
1987 return s;
1988 } 1951 }
1989 1952
1990 b = d2b(d, &be, &bbits); 1953 b = d2b(value(d), &be, &bbits);
1991#ifdef Sudden_Underflow 1954#ifdef Sudden_Underflow
1992 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 1955 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1993#else 1956#else
1994 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 1957 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
1995#endif 1958#endif
1996 d2 = d; 1959 value(d2) = value(d);
1997 word0(d2) &= Frac_mask1; 1960 word0(d2) &= Frac_mask1;
1998 word0(d2) |= Exp_11; 1961 word0(d2) |= Exp_11;
1999#ifdef IBM 1962#ifdef IBM
2000 if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 1963 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2001 d2 /= 1 << j; 1964 value(d2) /= 1 << j;
2002#endif 1965#endif
2003 1966
2004 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 1967 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2037,19 +2000,20 @@ __dtoa
2037 i = bbits + be + (Bias + (P-1) - 1); 2000 i = bbits + be + (Bias + (P-1) - 1);
2038 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2001 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2039 : word1(d) << 32 - i; 2002 : word1(d) << 32 - i;
2040 d2 = x; 2003 value(d2) = x;
2041 word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2004 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2042 i -= (Bias + (P-1) - 1) + 1; 2005 i -= (Bias + (P-1) - 1) + 1;
2043 denorm = 1; 2006 denorm = 1;
2044 } 2007 }
2045#endif 2008#endif
2046 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2009 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2010 i*0.301029995663981;
2047 k = (int)ds; 2011 k = (int)ds;
2048 if (ds < 0. && ds != k) 2012 if (ds < 0. && ds != k)
2049 k--; /* want k = floor(ds) */ 2013 k--; /* want k = floor(ds) */
2050 k_check = 1; 2014 k_check = 1;
2051 if (k >= 0 && k <= Ten_pmax) { 2015 if (k >= 0 && k <= Ten_pmax) {
2052 if (d < tens[k]) 2016 if (value(d) < tens[k])
2053 k--; 2017 k--;
2054 k_check = 0; 2018 k_check = 0;
2055 } 2019 }
@@ -2105,18 +2069,14 @@ __dtoa
2105 if (i <= 0) 2069 if (i <= 0)
2106 i = 1; 2070 i = 1;
2107 } 2071 }
2108 j = sizeof(ULong); 2072 s = s0 = rv_alloc(i);
2109 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2110 j <<= 1) result_k++;
2111 result = Balloc(result_k);
2112 s = s0 = (char *)result;
2113 2073
2114 if (ilim >= 0 && ilim <= Quick_max && try_quick) { 2074 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2115 2075
2116 /* Try to get by with floating-point arithmetic. */ 2076 /* Try to get by with floating-point arithmetic. */
2117 2077
2118 i = 0; 2078 i = 0;
2119 d2 = d; 2079 value(d2) = value(d);
2120 k0 = k; 2080 k0 = k;
2121 ilim0 = ilim; 2081 ilim0 = ilim;
2122 ieps = 2; /* conservative */ 2082 ieps = 2; /* conservative */
@@ -2126,7 +2086,7 @@ __dtoa
2126 if (j & Bletch) { 2086 if (j & Bletch) {
2127 /* prevent overflows */ 2087 /* prevent overflows */
2128 j &= Bletch - 1; 2088 j &= Bletch - 1;
2129 d /= bigtens[n_bigtens-1]; 2089 value(d) /= bigtens[n_bigtens-1];
2130 ieps++; 2090 ieps++;
2131 } 2091 }
2132 for(; j; j >>= 1, i++) 2092 for(; j; j >>= 1, i++)
@@ -2134,32 +2094,32 @@ __dtoa
2134 ieps++; 2094 ieps++;
2135 ds *= bigtens[i]; 2095 ds *= bigtens[i];
2136 } 2096 }
2137 d /= ds; 2097 value(d) /= ds;
2138 } 2098 }
2139 else if (j1 = -k) { 2099 else if (j1 = -k) {
2140 d *= tens[j1 & 0xf]; 2100 value(d) *= tens[j1 & 0xf];
2141 for(j = j1 >> 4; j; j >>= 1, i++) 2101 for(j = j1 >> 4; j; j >>= 1, i++)
2142 if (j & 1) { 2102 if (j & 1) {
2143 ieps++; 2103 ieps++;
2144 d *= bigtens[i]; 2104 value(d) *= bigtens[i];
2145 } 2105 }
2146 } 2106 }
2147 if (k_check && d < 1. && ilim > 0) { 2107 if (k_check && value(d) < 1. && ilim > 0) {
2148 if (ilim1 <= 0) 2108 if (ilim1 <= 0)
2149 goto fast_failed; 2109 goto fast_failed;
2150 ilim = ilim1; 2110 ilim = ilim1;
2151 k--; 2111 k--;
2152 d *= 10.; 2112 value(d) *= 10.;
2153 ieps++; 2113 ieps++;
2154 } 2114 }
2155 eps = ieps*d + 7.; 2115 value(eps) = ieps*value(d) + 7.;
2156 word0(eps) -= (P-1)*Exp_msk1; 2116 word0(eps) -= (P-1)*Exp_msk1;
2157 if (ilim == 0) { 2117 if (ilim == 0) {
2158 S = mhi = 0; 2118 S = mhi = 0;
2159 d -= 5.; 2119 value(d) -= 5.;
2160 if (d > eps) 2120 if (value(d) > value(eps))
2161 goto one_digit; 2121 goto one_digit;
2162 if (d < -eps) 2122 if (value(d) < -value(eps))
2163 goto no_digits; 2123 goto no_digits;
2164 goto fast_failed; 2124 goto fast_failed;
2165 } 2125 }
@@ -2168,33 +2128,33 @@ __dtoa
2168 /* Use Steele & White method of only 2128 /* Use Steele & White method of only
2169 * generating digits needed. 2129 * generating digits needed.
2170 */ 2130 */
2171 eps = 0.5/tens[ilim-1] - eps; 2131 value(eps) = 0.5/tens[ilim-1] - value(eps);
2172 for(i = 0;;) { 2132 for(i = 0;;) {
2173 L = d; 2133 L = value(d);
2174 d -= L; 2134 value(d) -= L;
2175 *s++ = '0' + (int)L; 2135 *s++ = '0' + (int)L;
2176 if (d < eps) 2136 if (value(d) < value(eps))
2177 goto ret1; 2137 goto ret1;
2178 if (1. - d < eps) 2138 if (1. - value(d) < value(eps))
2179 goto bump_up; 2139 goto bump_up;
2180 if (++i >= ilim) 2140 if (++i >= ilim)
2181 break; 2141 break;
2182 eps *= 10.; 2142 value(eps) *= 10.;
2183 d *= 10.; 2143 value(d) *= 10.;
2184 } 2144 }
2185 } 2145 }
2186 else { 2146 else {
2187#endif 2147#endif
2188 /* Generate ilim digits, then fix them up. */ 2148 /* Generate ilim digits, then fix them up. */
2189 eps *= tens[ilim-1]; 2149 value(eps) *= tens[ilim-1];
2190 for(i = 1;; i++, d *= 10.) { 2150 for(i = 1;; i++, value(d) *= 10.) {
2191 L = d; 2151 L = value(d);
2192 d -= L; 2152 value(d) -= L;
2193 *s++ = '0' + (int)L; 2153 *s++ = '0' + (int)L;
2194 if (i == ilim) { 2154 if (i == ilim) {
2195 if (d > 0.5 + eps) 2155 if (value(d) > 0.5 + value(eps))
2196 goto bump_up; 2156 goto bump_up;
2197 else if (d < 0.5 - eps) { 2157 else if (value(d) < 0.5 - value(eps)) {
2198 while(*--s == '0'); 2158 while(*--s == '0');
2199 s++; 2159 s++;
2200 goto ret1; 2160 goto ret1;
@@ -2207,7 +2167,7 @@ __dtoa
2207#endif 2167#endif
2208 fast_failed: 2168 fast_failed:
2209 s = s0; 2169 s = s0;
2210 d = d2; 2170 value(d) = value(d2);
2211 k = k0; 2171 k = k0;
2212 ilim = ilim0; 2172 ilim = ilim0;
2213 } 2173 }
@@ -2219,24 +2179,24 @@ __dtoa
2219 ds = tens[k]; 2179 ds = tens[k];
2220 if (ndigits < 0 && ilim <= 0) { 2180 if (ndigits < 0 && ilim <= 0) {
2221 S = mhi = 0; 2181 S = mhi = 0;
2222 if (ilim < 0 || d <= 5*ds) 2182 if (ilim < 0 || value(d) <= 5*ds)
2223 goto no_digits; 2183 goto no_digits;
2224 goto one_digit; 2184 goto one_digit;
2225 } 2185 }
2226 for(i = 1;; i++) { 2186 for(i = 1;; i++) {
2227 L = d / ds; 2187 L = value(d) / ds;
2228 d -= L*ds; 2188 value(d) -= L*ds;
2229#ifdef Check_FLT_ROUNDS 2189#ifdef Check_FLT_ROUNDS
2230 /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2190 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2231 if (d < 0) { 2191 if (value(d) < 0) {
2232 L--; 2192 L--;
2233 d += ds; 2193 value(d) += ds;
2234 } 2194 }
2235#endif 2195#endif
2236 *s++ = '0' + (int)L; 2196 *s++ = '0' + (int)L;
2237 if (i == ilim) { 2197 if (i == ilim) {
2238 d += d; 2198 value(d) += value(d);
2239 if (d > ds || d == ds && L & 1) { 2199 if (value(d) > ds || value(d) == ds && L & 1) {
2240 bump_up: 2200 bump_up:
2241 while(*--s == '9') 2201 while(*--s == '9')
2242 if (s == s0) { 2202 if (s == s0) {
@@ -2248,7 +2208,7 @@ __dtoa
2248 } 2208 }
2249 break; 2209 break;
2250 } 2210 }
2251 if (!(d *= 10.)) 2211 if (!(value(d) *= 10.))
2252 break; 2212 break;
2253 } 2213 }
2254 goto ret1; 2214 goto ret1;
diff --git a/src/lib/libc/stdlib/strtof.c b/src/lib/libc/stdlib/strtof.c
new file mode 100644
index 0000000000..8c8db47ad8
--- /dev/null
+++ b/src/lib/libc/stdlib/strtof.c
@@ -0,0 +1,39 @@
1/* $OpenBSD: strtof.c,v 1.1 2008/06/13 21:04:24 landry Exp $ */
2
3/*
4 * Copyright (c) 2008 Landry Breuil
5 * All rights reserved.
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
20#include <errno.h>
21#include <limits.h>
22#include <stdlib.h>
23#include <math.h>
24
25float
26strtof(const char *s00, char **se)
27{
28 double d;
29
30 d = strtod(s00, se);
31 if (d > FLT_MAX) {
32 errno = ERANGE;
33 return (FLT_MAX);
34 } else if (d < -FLT_MAX) {
35 errno = ERANGE;
36 return (-FLT_MAX);
37 }
38 return ((float) d);
39}
diff --git a/src/lib/libc/stdlib/strtoimax.c b/src/lib/libc/stdlib/strtoimax.c
new file mode 100644
index 0000000000..2c77f41650
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoimax.c
@@ -0,0 +1,140 @@
1/* $OpenBSD: strtoimax.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2
3/*-
4 * Copyright (c) 1992 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. 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#include <ctype.h>
33#include <errno.h>
34#include <inttypes.h>
35
36/*
37 * Convert a string to an intmax_t
38 *
39 * Ignores `locale' stuff. Assumes that the upper and lower case
40 * alphabets and digits are each contiguous.
41 */
42intmax_t
43strtoimax(const char *nptr, char **endptr, int base)
44{
45 const char *s;
46 intmax_t acc, cutoff;
47 int c;
48 int neg, any, cutlim;
49
50 /*
51 * Skip white space and pick up leading +/- sign if any.
52 * If base is 0, allow 0x for hex and 0 for octal, else
53 * assume decimal; if base is already 16, allow 0x.
54 */
55 s = nptr;
56 do {
57 c = (unsigned char) *s++;
58 } while (isspace(c));
59 if (c == '-') {
60 neg = 1;
61 c = *s++;
62 } else {
63 neg = 0;
64 if (c == '+')
65 c = *s++;
66 }
67 if ((base == 0 || base == 16) &&
68 c == '0' && (*s == 'x' || *s == 'X')) {
69 c = s[1];
70 s += 2;
71 base = 16;
72 }
73 if (base == 0)
74 base = c == '0' ? 8 : 10;
75
76 /*
77 * Compute the cutoff value between legal numbers and illegal
78 * numbers. That is the largest legal value, divided by the
79 * base. An input number that is greater than this value, if
80 * followed by a legal input character, is too big. One that
81 * is equal to this value may be valid or not; the limit
82 * between valid and invalid numbers is then based on the last
83 * digit. For instance, if the range for intmax_t is
84 * [-9223372036854775808..9223372036854775807] and the input base
85 * is 10, cutoff will be set to 922337203685477580 and cutlim to
86 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
87 * accumulated a value > 922337203685477580, or equal but the
88 * next digit is > 7 (or 8), the number is too big, and we will
89 * return a range error.
90 *
91 * Set any if any `digits' consumed; make it negative to indicate
92 * overflow.
93 */
94 cutoff = neg ? INTMAX_MIN : INTMAX_MAX;
95 cutlim = cutoff % base;
96 cutoff /= base;
97 if (neg) {
98 if (cutlim > 0) {
99 cutlim -= base;
100 cutoff += 1;
101 }
102 cutlim = -cutlim;
103 }
104 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
105 if (isdigit(c))
106 c -= '0';
107 else if (isalpha(c))
108 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
109 else
110 break;
111 if (c >= base)
112 break;
113 if (any < 0)
114 continue;
115 if (neg) {
116 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
117 any = -1;
118 acc = INTMAX_MIN;
119 errno = ERANGE;
120 } else {
121 any = 1;
122 acc *= base;
123 acc -= c;
124 }
125 } else {
126 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
127 any = -1;
128 acc = INTMAX_MAX;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc += c;
134 }
135 }
136 }
137 if (endptr != 0)
138 *endptr = (char *) (any ? s - 1 : nptr);
139 return (acc);
140}
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
index 808ba90165..84d9a0c427 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,67 @@
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.19 2007/11/13 18:30:04 tobias 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 $Mdocdate: November 13 2007 $
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 strtoimax ,
41.Nm strtoq ,
42.Nd "convert string value to a long, long long or intmax_t integer"
45.Sh SYNOPSIS 43.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
45.Fd #include <stdlib.h>
48.Ft long 46.Ft long
49.Fn strtol "char *nptr" "char **endptr" "int base" 47.Fn strtol "const char *nptr" "char **endptr" "int base"
50 48.Pp
49.Ft long long
50.Fn strtoll "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <inttypes.h>
53.Ft intmax_t
54.Fn strtoimax "const char *nptr" "char **endptr" "int base"
55.Pp
51.Fd #include <sys/types.h> 56.Fd #include <sys/types.h>
52.Fd #include <stdlib.h>
53.Fd #include <limits.h> 57.Fd #include <limits.h>
58.Fd #include <stdlib.h>
54.Ft quad_t 59.Ft quad_t
55.Fn strtoq "char *nptr" "char **endptr" "int base" 60.Fn strtoq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 61.Sh DESCRIPTION
57The 62The
58.Fn strtol 63.Fn strtol
59function 64function converts the string in
60converts the string in
61.Fa nptr 65.Fa nptr
62to a 66to a
63.Em long 67.Li long
64value. 68value.
65The 69The
66.Fn strtoq 70.Fn strtoll
67function 71function converts the string in
68converts the string in
69.Fa nptr 72.Fa nptr
70to a 73to a
71.Em quad_t 74.Li long long
72value. 75value.
76The
77.Fn strtoimax
78function converts the string in
79.Fa nptr
80to an
81.Li intmax_t
82value.
83The
84.Fn strtoq
85function is a deprecated equivalent of
86.Fn strtoll
87and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 88The conversion is done according to the given
74.Fa base , 89.Fa base ,
75which must be between 2 and 36 inclusive, 90which must be a number between 2 and 36 inclusive or the special value 0.
76or be the special value 0.
77.Pp 91.Pp
78The string may begin with an arbitrary amount of white space 92The string may begin with an arbitrary amount of whitespace
79(as determined by 93(as determined by
80.Xr isspace 3 ) 94.Xr isspace 3 )
81followed by a single optional 95followed by a single optional
@@ -85,25 +99,25 @@ or
85sign. 99sign.
86If 100If
87.Fa base 101.Fa base
88is zero or 16, 102is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 103.Ql 0x
91prefix, 104prefix, 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 105.Fa base
94is taken as 10 (decimal) unless the next character is 106is taken as 10 (decimal) unless the next character is
95.Ql 0 , 107.Ql 0 ,
96in which case it is taken as 8 (octal). 108in which case it is taken as 8 (octal).
97.Pp 109.Pp
98The remainder of the string is converted to a 110The remainder of the string is converted to a
99.Em long 111.Li long ,
112.Li long long ,
113or
114.Li intmax_t ,
100value in the obvious manner, 115value in the obvious manner,
101stopping at the first character which is not a valid digit 116stopping at the first character which is not a valid digit
102in the given base. 117in the given base.
103(In bases above 10, the letter 118(In bases above 10, the letter
104.Ql A 119.Ql A
105in either upper or lower case 120in either upper or lower case represents 10,
106represents 10,
107.Ql B 121.Ql B
108represents 11, and so forth, with 122represents 11, and so forth, with
109.Ql Z 123.Ql Z
@@ -111,7 +125,7 @@ representing 35.)
111.Pp 125.Pp
112If 126If
113.Fa endptr 127.Fa endptr
114is non nil, 128is non-null,
115.Fn strtol 129.Fn strtol
116stores the address of the first invalid character in 130stores the address of the first invalid character in
117.Fa *endptr . 131.Fa *endptr .
@@ -132,22 +146,93 @@ is
132on return, the entire string was valid.) 146on return, the entire string was valid.)
133.Sh RETURN VALUES 147.Sh RETURN VALUES
134The 148The
135.Fn strtol 149.Fn strtol ,
136function 150.Fn strtoll ,
137returns the result of the conversion, 151.Fn strtoimax ,
152and
153.Fn strtoq
154functions return the result of the conversion,
138unless the value would underflow or overflow. 155unless the value would underflow or overflow.
139If an underflow occurs, 156If no conversion could be performed, 0 is returned;
140.Fn strtol 157the global variable
141returns 158.Va errno
142.Dv LONG_MIN . 159is also set to
143If an overflow occurs, 160.Er EINVAL,
144.Fn strtol 161though this is not portable across all platforms.
145returns 162If overflow or underflow occurs,
146.Dv LONG_MAX .
147In both cases,
148.Va errno 163.Va errno
149is set to 164is set to
150.Er ERANGE . 165.Er ERANGE
166and the function return value is as follows:
167.Bl -column -offset indent "strtoimax" "overflow" "underflow"
168.It Sy Function Ta Sy underflow Ta Sy overflow
169.It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX
170.It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX
171.It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX
172.It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX
173.El
174.Sh EXAMPLES
175Ensuring that a string is a valid number (i.e., in range and containing no
176trailing characters) requires clearing
177.Va errno
178beforehand explicitly since
179.Va errno
180is not changed on a successful call to
181.Fn strtol ,
182and the return value of
183.Fn strtol
184cannot be used unambiguously to signal an error:
185.Bd -literal -offset indent
186char *ep;
187long lval;
188
189\&...
190
191errno = 0;
192lval = strtol(buf, &ep, 10);
193if (buf[0] == '\e0' || *ep != '\e0')
194 goto not_a_number;
195if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
196 goto out_of_range;
197.Ed
198.Pp
199This example will accept
200.Dq 12
201but not
202.Dq 12foo
203or
204.Dq 12\en .
205If trailing whitespace is acceptable, further checks must be done on
206.Va *ep ;
207alternately, use
208.Xr sscanf 3 .
209.Pp
210If
211.Fn strtol
212is being used instead of
213.Xr atoi 3 ,
214error checking is further complicated because the desired return value is an
215.Li int
216rather than a
217.Li long ;
218however, on some architectures integers and long integers are the same size.
219Thus the following is necessary:
220.Bd -literal -offset indent
221char *ep;
222int ival;
223long lval;
224
225\&...
226
227errno = 0;
228lval = strtol(buf, &ep, 10);
229if (buf[0] == '\e0' || *ep != '\e0')
230 goto not_a_number;
231if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
232 (lval > INT_MAX || lval < INT_MIN))
233 goto out_of_range;
234ival = lval;
235.Ed
151.Sh ERRORS 236.Sh ERRORS
152.Bl -tag -width Er 237.Bl -tag -width Er
153.It Bq Er ERANGE 238.It Bq Er ERANGE
@@ -157,13 +242,23 @@ The given string was out of range; the value converted has been clamped.
157.Xr atof 3 , 242.Xr atof 3 ,
158.Xr atoi 3 , 243.Xr atoi 3 ,
159.Xr atol 3 , 244.Xr atol 3 ,
245.Xr atoll 3 ,
246.Xr sscanf 3 ,
160.Xr strtod 3 , 247.Xr strtod 3 ,
248.Xr strtonum 3 ,
161.Xr strtoul 3 249.Xr strtoul 3
162.Sh STANDARDS 250.Sh STANDARDS
163The 251The
164.Fn strtol 252.Fn strtol ,
165function 253.Fn strtoll ,
166conforms to 254and
167.St -ansiC . 255.Fn strtoimax
256functions conform to
257.St -ansiC-99 .
258The
259.Fn strtoq
260function is a
261.Bx
262extension and is provided for backwards compatibility with legacy programs.
168.Sh BUGS 263.Sh BUGS
169Ignores the current locale. 264Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..5a244766db 100644
--- a/src/lib/libc/stdlib/strtol.c
+++ b/src/lib/libc/stdlib/strtol.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtol.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,14 +28,9 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/
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 */
38
39#include <limits.h>
40#include <ctype.h> 31#include <ctype.h>
41#include <errno.h> 32#include <errno.h>
33#include <limits.h>
42#include <stdlib.h> 34#include <stdlib.h>
43 35
44 36
@@ -49,30 +41,30 @@ static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"
49 * alphabets and digits are each contiguous. 41 * alphabets and digits are each contiguous.
50 */ 42 */
51long 43long
52strtol(nptr, endptr, base) 44strtol(const char *nptr, char **endptr, int base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{ 45{
57 register const char *s = nptr; 46 const char *s;
58 register unsigned long acc; 47 long acc, cutoff;
59 register int c; 48 int c;
60 register unsigned long cutoff; 49 int neg, any, cutlim;
61 register int neg = 0, any, cutlim;
62 50
63 /* 51 /*
64 * Skip white space and pick up leading +/- sign if any. 52 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 53 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 54 * assume decimal; if base is already 16, allow 0x.
67 */ 55 */
56 s = nptr;
68 do { 57 do {
69 c = *s++; 58 c = (unsigned char) *s++;
70 } while (isspace(c)); 59 } while (isspace(c));
71 if (c == '-') { 60 if (c == '-') {
72 neg = 1; 61 neg = 1;
73 c = *s++; 62 c = *s++;
74 } else if (c == '+') 63 } else {
75 c = *s++; 64 neg = 0;
65 if (c == '+')
66 c = *s++;
67 }
76 if ((base == 0 || base == 16) && 68 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 69 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 70 c = s[1];
@@ -99,10 +91,17 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 91 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 92 * overflow.
101 */ 93 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 94 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 95 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 96 cutoff /= base;
105 for (acc = 0, any = 0;; c = *s++) { 97 if (neg) {
98 if (cutlim > 0) {
99 cutlim -= base;
100 cutoff += 1;
101 }
102 cutlim = -cutlim;
103 }
104 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
106 if (isdigit(c)) 105 if (isdigit(c))
107 c -= '0'; 106 c -= '0';
108 else if (isalpha(c)) 107 else if (isalpha(c))
@@ -111,19 +110,30 @@ strtol(nptr, endptr, base)
111 break; 110 break;
112 if (c >= base) 111 if (c >= base)
113 break; 112 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 113 if (any < 0)
115 any = -1; 114 continue;
116 else { 115 if (neg) {
117 any = 1; 116 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 117 any = -1;
119 acc += c; 118 acc = LONG_MIN;
119 errno = ERANGE;
120 } else {
121 any = 1;
122 acc *= base;
123 acc -= c;
124 }
125 } else {
126 if (acc > cutoff || acc == cutoff && c > cutlim) {
127 any = -1;
128 acc = LONG_MAX;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc += c;
134 }
120 } 135 }
121 } 136 }
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) 137 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 138 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 139 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoll.c
index fc559e9d7f..37379252e3 100644
--- a/src/lib/libc/stdlib/strtoq.c
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtoll.c,v 1.6 2005/11/10 10:00:17 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1992 The Regents of the University of California. 3 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,34 +28,26 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h> 31#include <sys/types.h>
39 32
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 33#include <ctype.h>
34#include <errno.h>
35#include <limits.h>
43#include <stdlib.h> 36#include <stdlib.h>
44 37
45/* 38/*
46 * Convert a string to a quad integer. 39 * Convert a string to a long long.
47 * 40 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 41 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 42 * alphabets and digits are each contiguous.
50 */ 43 */
51quad_t 44long long
52strtoq(nptr, endptr, base) 45strtoll(const char *nptr, char **endptr, int base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{ 46{
57 register const char *s; 47 const char *s;
58 register u_quad_t acc; 48 long long acc, cutoff;
59 register int c; 49 int c;
60 register u_quad_t qbase, cutoff; 50 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 51
63 /* 52 /*
64 * Skip white space and pick up leading +/- sign if any. 53 * Skip white space and pick up leading +/- sign if any.
@@ -67,7 +56,7 @@ strtoq(nptr, endptr, base)
67 */ 56 */
68 s = nptr; 57 s = nptr;
69 do { 58 do {
70 c = *s++; 59 c = (unsigned char) *s++;
71 } while (isspace(c)); 60 } while (isspace(c));
72 if (c == '-') { 61 if (c == '-') {
73 neg = 1; 62 neg = 1;
@@ -93,7 +82,7 @@ strtoq(nptr, endptr, base)
93 * followed by a legal input character, is too big. One that 82 * followed by a legal input character, is too big. One that
94 * is equal to this value may be valid or not; the limit 83 * is equal to this value may be valid or not; the limit
95 * between valid and invalid numbers is then based on the last 84 * between valid and invalid numbers is then based on the last
96 * digit. For instance, if the range for quads is 85 * digit. For instance, if the range for long longs is
97 * [-9223372036854775808..9223372036854775807] and the input base 86 * [-9223372036854775808..9223372036854775807] and the input base
98 * is 10, cutoff will be set to 922337203685477580 and cutlim to 87 * 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 88 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
@@ -104,11 +93,17 @@ strtoq(nptr, endptr, base)
104 * Set any if any `digits' consumed; make it negative to indicate 93 * Set any if any `digits' consumed; make it negative to indicate
105 * overflow. 94 * overflow.
106 */ 95 */
107 qbase = (unsigned)base; 96 cutoff = neg ? LLONG_MIN : LLONG_MAX;
108 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 97 cutlim = cutoff % base;
109 cutlim = cutoff % qbase; 98 cutoff /= base;
110 cutoff /= qbase; 99 if (neg) {
111 for (acc = 0, any = 0;; c = *s++) { 100 if (cutlim > 0) {
101 cutlim -= base;
102 cutoff += 1;
103 }
104 cutlim = -cutlim;
105 }
106 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
112 if (isdigit(c)) 107 if (isdigit(c))
113 c -= '0'; 108 c -= '0';
114 else if (isalpha(c)) 109 else if (isalpha(c))
@@ -117,20 +112,42 @@ strtoq(nptr, endptr, base)
117 break; 112 break;
118 if (c >= base) 113 if (c >= base)
119 break; 114 break;
120 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 115 if (any < 0)
121 any = -1; 116 continue;
122 else { 117 if (neg) {
123 any = 1; 118 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
124 acc *= qbase; 119 any = -1;
125 acc += c; 120 acc = LLONG_MIN;
121 errno = ERANGE;
122 } else {
123 any = 1;
124 acc *= base;
125 acc -= c;
126 }
127 } else {
128 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
129 any = -1;
130 acc = LLONG_MAX;
131 errno = ERANGE;
132 } else {
133 any = 1;
134 acc *= base;
135 acc += c;
136 }
126 } 137 }
127 } 138 }
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) 139 if (endptr != 0)
134 *endptr = (char *) (any ? s - 1 : nptr); 140 *endptr = (char *) (any ? s - 1 : nptr);
135 return (acc); 141 return (acc);
136} 142}
143
144#ifdef __weak_alias
145__weak_alias(strtoq, strtoll);
146#else
147quad_t
148strtoq(const char *nptr, char **endptr, int base)
149{
150
151 return ((quad_t)strtoll(nptr, endptr, base));
152}
153#endif
diff --git a/src/lib/libc/stdlib/strtonum.3 b/src/lib/libc/stdlib/strtonum.3
new file mode 100644
index 0000000000..58b4112ac3
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.3
@@ -0,0 +1,152 @@
1.\" $OpenBSD: strtonum.3,v 1.14 2007/05/31 19:19:31 jmc Exp $
2.\"
3.\" Copyright (c) 2004 Ted Unangst
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 $Mdocdate: May 31 2007 $
18.Dt STRTONUM 3
19.Os
20.Sh NAME
21.Nm strtonum
22.Nd "reliably convert string value to an integer"
23.Sh SYNOPSIS
24.Fd #include <stdlib.h>
25.Ft long long
26.Fo strtonum
27.Fa "const char *nptr"
28.Fa "long long minval"
29.Fa "long long maxval"
30.Fa "const char **errstr"
31.Fc
32.Sh DESCRIPTION
33The
34.Fn strtonum
35function converts the string in
36.Fa nptr
37to a
38.Li long long
39value.
40The
41.Fn strtonum
42function was designed to facilitate safe, robust programming
43and overcome the shortcomings of the
44.Xr atoi 3
45and
46.Xr strtol 3
47family of interfaces.
48.Pp
49The string may begin with an arbitrary amount of whitespace
50(as determined by
51.Xr isspace 3 )
52followed by a single optional
53.Ql +
54or
55.Ql -
56sign.
57.Pp
58The remainder of the string is converted to a
59.Li long long
60value according to base 10.
61.Pp
62The value obtained is then checked against the provided
63.Fa minval
64and
65.Fa maxval
66bounds.
67If
68.Fa errstr
69is non-null,
70.Fn strtonum
71stores an error string in
72.Fa *errstr
73indicating the failure.
74.Sh RETURN VALUES
75The
76.Fn strtonum
77function returns the result of the conversion,
78unless the value would exceed the provided bounds or is invalid.
79On error, 0 is returned,
80.Va errno
81is set, and
82.Fa errstr
83will point to an error message.
84.Fa *errstr
85will be set to
86.Dv NULL
87on success;
88this fact can be used to differentiate
89a successful return of 0 from an error.
90.Sh EXAMPLES
91Using
92.Fn strtonum
93correctly is meant to be simpler than the alternative functions.
94.Bd -literal -offset indent
95int iterations;
96const char *errstr;
97
98iterations = strtonum(optarg, 1, 64, &errstr);
99if (errstr)
100 errx(1, "number of iterations is %s: %s", errstr, optarg);
101.Ed
102.Pp
103The above example will guarantee that the value of iterations is between
1041 and 64 (inclusive).
105.Sh ERRORS
106.Bl -tag -width Er
107.It Bq Er ERANGE
108The given string was out of range.
109.It Bq Er EINVAL
110The given string did not consist solely of digit characters.
111.It Bq Er EINVAL
112.Ar minval
113was larger than
114.Ar maxval .
115.El
116.Pp
117If an error occurs,
118.Fa errstr
119will be set to one of the following strings:
120.Pp
121.Bl -tag -width "too largeXX" -compact
122.It too large
123The result was larger than the provided maximum value.
124.It too small
125The result was smaller than the provided minimum value.
126.It invalid
127The string did not consist solely of digit characters.
128.El
129.Sh SEE ALSO
130.Xr atof 3 ,
131.Xr atoi 3 ,
132.Xr atol 3 ,
133.Xr atoll 3 ,
134.Xr sscanf 3 ,
135.Xr strtod 3 ,
136.Xr strtol 3 ,
137.Xr strtoul 3
138.Sh STANDARDS
139.Fn strtonum
140is an
141.Ox
142extension.
143The existing alternatives, such as
144.Xr atoi 3
145and
146.Xr strtol 3 ,
147are either impossible or difficult to use safely.
148.Sh HISTORY
149The
150.Fn strtonum
151function first appeared in
152.Ox 3.6 .
diff --git a/src/lib/libc/stdlib/strtonum.c b/src/lib/libc/stdlib/strtonum.c
new file mode 100644
index 0000000000..e426388ed0
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.c
@@ -0,0 +1,65 @@
1/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
2
3/*
4 * Copyright (c) 2004 Ted Unangst and Todd Miller
5 * All rights reserved.
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
20#include <errno.h>
21#include <limits.h>
22#include <stdlib.h>
23
24#define INVALID 1
25#define TOOSMALL 2
26#define TOOLARGE 3
27
28long long
29strtonum(const char *numstr, long long minval, long long maxval,
30 const char **errstrp)
31{
32 long long ll = 0;
33 char *ep;
34 int error = 0;
35 struct errval {
36 const char *errstr;
37 int err;
38 } ev[4] = {
39 { NULL, 0 },
40 { "invalid", EINVAL },
41 { "too small", ERANGE },
42 { "too large", ERANGE },
43 };
44
45 ev[0].err = errno;
46 errno = 0;
47 if (minval > maxval)
48 error = INVALID;
49 else {
50 ll = strtoll(numstr, &ep, 10);
51 if (numstr == ep || *ep != '\0')
52 error = INVALID;
53 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54 error = TOOSMALL;
55 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56 error = TOOLARGE;
57 }
58 if (errstrp != NULL)
59 *errstrp = ev[error].errstr;
60 errno = ev[error].err;
61 if (error)
62 ll = 0;
63
64 return (ll);
65}
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
index db551b0141..a7c6bbfa18 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,49 +29,73 @@
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.19 2007/11/13 18:30:04 tobias 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 $Mdocdate: November 13 2007 $
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 strtoumax ,
41.Nm strtouq
42.Nd "convert a string to an unsigned long, unsigned long long or uintmax_t integer"
45.Sh SYNOPSIS 43.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
45.Fd #include <stdlib.h>
48.Ft unsigned long 46.Ft unsigned long
49.Fn strtoul "const char *nptr" "char **endptr" "int base" 47.Fn strtoul "const char *nptr" "char **endptr" "int base"
50 48.Pp
49.Ft unsigned long long
50.Fn strtoull "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <inttypes.h>
53.Ft uintmax_t
54.Fn strtoumax "const char *nptr" "char **endptr" "int base"
55.Pp
51.Fd #include <sys/types.h> 56.Fd #include <sys/types.h>
52.Fd #include <stdlib.h>
53.Fd #include <limits.h> 57.Fd #include <limits.h>
58.Fd #include <stdlib.h>
54.Ft u_quad_t 59.Ft u_quad_t
55.Fn strtouq "const char *nptr" "char **endptr" "int base" 60.Fn strtouq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 61.Sh DESCRIPTION
57The 62The
58.Fn strtoul 63.Fn strtoul
59function 64function converts the string in
60converts the string in
61.Fa nptr 65.Fa nptr
62to an 66to an
63.Em unsigned long 67.Li unsigned long
64value. 68value.
65The 69The
66.Fn strtouq 70.Fn strtoull
67function 71function converts the string in
68converts the string in 72.Fa nptr
73to an
74.Li unsigned long long
75value.
76The
77.Fn strtoumax
78function converts the string in
69.Fa nptr 79.Fa nptr
70to a 80to a
71.Em u_quad_t 81.Li umaxint_t
72value. 82value.
83The
84.Fn strtouq
85function is a deprecated equivalent of
86.Fn strtoull
87and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 88The conversion is done according to the given
74.Fa base , 89.Fa base ,
75which must be between 2 and 36 inclusive, 90which must be a number between 2 and 36 inclusive
76or be the special value 0. 91or the special value 0.
92If the string in
93.Fa nptr
94represents a negative number, it will be converted to its unsigned equivalent.
95This behavior is consistent with what happens when a signed integer type is
96cast to its unsigned counterpart.
77.Pp 97.Pp
78The string may begin with an arbitrary amount of white space 98The string may begin with an arbitrary amount of whitespace
79(as determined by 99(as determined by
80.Xr isspace 3 ) 100.Xr isspace 3 )
81followed by a single optional 101followed by a single optional
@@ -85,26 +105,22 @@ or
85sign. 105sign.
86If 106If
87.Fa base 107.Fa base
88is zero or 16, 108is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 109.Ql 0x
91prefix, 110prefix, 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 111.Fa base
94is taken as 10 (decimal) unless the next character is 112is taken as 10 (decimal) unless the next character is
95.Ql 0 , 113.Ql 0 ,
96in which case it is taken as 8 (octal). 114in which case it is taken as 8 (octal).
97.Pp 115.Pp
98The remainder of the string is converted to an 116The remainder of the string is converted to an
99.Em unsigned long 117.Li unsigned long
100value in the obvious manner, 118value 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 119or at the first character that does not produce a valid digit
103in the given base. 120in the given base.
104(In bases above 10, the letter 121(In bases above 10, the letter
105.Ql A 122.Ql A
106in either upper or lower case 123in either upper or lower case represents 10,
107represents 10,
108.Ql B 124.Ql B
109represents 11, and so forth, with 125represents 11, and so forth, with
110.Ql Z 126.Ql Z
@@ -112,7 +128,7 @@ representing 35.)
112.Pp 128.Pp
113If 129If
114.Fa endptr 130.Fa endptr
115is non nil, 131is non-null,
116.Fn strtoul 132.Fn strtoul
117stores the address of the first invalid character in 133stores the address of the first invalid character in
118.Fa *endptr . 134.Fa *endptr .
@@ -133,32 +149,100 @@ is
133on return, the entire string was valid.) 149on return, the entire string was valid.)
134.Sh RETURN VALUES 150.Sh RETURN VALUES
135The 151The
136.Fn strtoul 152.Fn strtoul ,
137function 153.Fn strtoull ,
138returns either the result of the conversion 154.Fn strtoumax
139or, if there was a leading minus sign, 155and
156.Fn strtouq
157functions return either the result of the conversion or,
158if there was a leading minus sign,
140the negation of the result of the conversion, 159the negation of the result of the conversion,
141unless the original (non-negated) value would overflow; 160unless the original (non-negated) value would overflow.
142in the latter case, 161If overflow occurs,
143.Fn strtoul 162.Fn strtoul
144returns 163returns
145.Dv ULONG_MAX 164.Dv ULONG_MAX ,
146and sets the global variable 165.Fn strtoull
166returns
167.Dv ULLONG_MAX ,
168.Fn strtoumax
169returns
170.Dv UINTMAX_MAX ,
171.Fn strtouq
172returns
173.Dv ULLONG_MAX
174and the global variable
147.Va errno 175.Va errno
148to 176is set to
149.Er ERANGE . 177.Er ERANGE .
178If no conversion could be performed, 0 is returned;
179the global variable
180.Va errno
181is also set to
182.Er EINVAL,
183though this is not portable across all platforms.
184.Pp
185There is no way to determine if
186.Fn strtoul
187has processed a negative number (and returned an unsigned value) short of
188examining the string in
189.Fa nptr
190directly.
191.Sh EXAMPLES
192Ensuring that a string is a valid number (i.e., in range and containing no
193trailing characters) requires clearing
194.Va errno
195beforehand explicitly since
196.Va errno
197is not changed on a successful call to
198.Fn strtoul ,
199and the return value of
200.Fn strtoul
201cannot be used unambiguously to signal an error:
202.Bd -literal -offset indent
203char *ep;
204unsigned long ulval;
205
206\&...
207
208errno = 0;
209ulval = strtoul(buf, &ep, 10);
210if (buf[0] == '\e0' || *ep != '\e0')
211 goto not_a_number;
212if (errno == ERANGE && ulval == ULONG_MAX)
213 goto out_of_range;
214.Ed
215.Pp
216This example will accept
217.Dq 12
218but not
219.Dq 12foo
220or
221.Dq 12\en .
222If trailing whitespace is acceptable, further checks must be done on
223.Va *ep ;
224alternately, use
225.Xr sscanf 3 .
150.Sh ERRORS 226.Sh ERRORS
151.Bl -tag -width Er 227.Bl -tag -width Er
152.It Bq Er ERANGE 228.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped. 229The given string was out of range; the value converted has been clamped.
154.El 230.El
155.Sh SEE ALSO 231.Sh SEE ALSO
232.Xr sscanf 3 ,
156.Xr strtol 3 233.Xr strtol 3
157.Sh STANDARDS 234.Sh STANDARDS
158The 235The
159.Fn strtoul 236.Fn strtoul ,
160function 237.Fn strtoull ,
161conforms to 238and
162.St -ansiC . 239.Fn strtoumax
240functions conform to
241.St -ansiC-99 .
242The
243.Fn strtouq
244function is a
245.Bx
246extension and is provided for backwards compatibility with legacy programs.
163.Sh BUGS 247.Sh BUGS
164Ignores the current locale. 248Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..d7dddab778 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtoul.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1990 Regents of the University of California. 3 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,14 +28,9 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/
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 */
38
39#include <limits.h>
40#include <ctype.h> 31#include <ctype.h>
41#include <errno.h> 32#include <errno.h>
33#include <limits.h>
42#include <stdlib.h> 34#include <stdlib.h>
43 35
44/* 36/*
@@ -48,28 +40,28 @@ static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
48 * alphabets and digits are each contiguous. 40 * alphabets and digits are each contiguous.
49 */ 41 */
50unsigned long 42unsigned long
51strtoul(nptr, endptr, base) 43strtoul(const char *nptr, char **endptr, int base)
52 const char *nptr;
53 char **endptr;
54 register int base;
55{ 44{
56 register const char *s = nptr; 45 const char *s;
57 register unsigned long acc; 46 unsigned long acc, cutoff;
58 register int c; 47 int c;
59 register unsigned long cutoff; 48 int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 49
62 /* 50 /*
63 * See strtol for comments as to the logic used. 51 * See strtol for comments as to the logic used.
64 */ 52 */
53 s = nptr;
65 do { 54 do {
66 c = *s++; 55 c = (unsigned char) *s++;
67 } while (isspace(c)); 56 } while (isspace(c));
68 if (c == '-') { 57 if (c == '-') {
69 neg = 1; 58 neg = 1;
70 c = *s++; 59 c = *s++;
71 } else if (c == '+') 60 } else {
72 c = *s++; 61 neg = 0;
62 if (c == '+')
63 c = *s++;
64 }
73 if ((base == 0 || base == 16) && 65 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 66 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 67 c = s[1];
@@ -78,9 +70,10 @@ strtoul(nptr, endptr, base)
78 } 70 }
79 if (base == 0) 71 if (base == 0)
80 base = c == '0' ? 8 : 10; 72 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 73
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 74 cutoff = ULONG_MAX / (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 75 cutlim = ULONG_MAX % (unsigned long)base;
76 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
84 if (isdigit(c)) 77 if (isdigit(c))
85 c -= '0'; 78 c -= '0';
86 else if (isalpha(c)) 79 else if (isalpha(c))
@@ -89,18 +82,19 @@ strtoul(nptr, endptr, base)
89 break; 82 break;
90 if (c >= base) 83 if (c >= base)
91 break; 84 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 85 if (any < 0)
86 continue;
87 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 88 any = -1;
94 else { 89 acc = ULONG_MAX;
90 errno = ERANGE;
91 } else {
95 any = 1; 92 any = 1;
96 acc *= base; 93 acc *= (unsigned long)base;
97 acc += c; 94 acc += c;
98 } 95 }
99 } 96 }
100 if (any < 0) { 97 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 98 acc = -acc;
105 if (endptr != 0) 99 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 100 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtoull.c
index cc647d8d28..37859776f9 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtoull.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
1/*- 2/*-
2 * Copyright (c) 1992 The Regents of the University of California. 3 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,41 +28,33 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h> 31#include <sys/types.h>
39 32
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 33#include <ctype.h>
34#include <errno.h>
35#include <limits.h>
43#include <stdlib.h> 36#include <stdlib.h>
44 37
45/* 38/*
46 * Convert a string to an unsigned quad integer. 39 * Convert a string to an unsigned long long.
47 * 40 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 41 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 42 * alphabets and digits are each contiguous.
50 */ 43 */
51u_quad_t 44unsigned long long
52strtouq(nptr, endptr, base) 45strtoull(const char *nptr, char **endptr, int base)
53 const char *nptr;
54 char **endptr;
55 register int base;
56{ 46{
57 register const char *s = nptr; 47 const char *s;
58 register u_quad_t acc; 48 unsigned long long acc, cutoff;
59 register int c; 49 int c;
60 register u_quad_t qbase, cutoff; 50 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 51
63 /* 52 /*
64 * See strtoq for comments as to the logic used. 53 * See strtoq for comments as to the logic used.
65 */ 54 */
66 s = nptr; 55 s = nptr;
67 do { 56 do {
68 c = *s++; 57 c = (unsigned char) *s++;
69 } while (isspace(c)); 58 } while (isspace(c));
70 if (c == '-') { 59 if (c == '-') {
71 neg = 1; 60 neg = 1;
@@ -83,10 +72,10 @@ strtouq(nptr, endptr, base)
83 } 72 }
84 if (base == 0) 73 if (base == 0)
85 base = c == '0' ? 8 : 10; 74 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 75
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 76 cutoff = ULLONG_MAX / (unsigned long long)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 77 cutlim = ULLONG_MAX % (unsigned long long)base;
89 for (acc = 0, any = 0;; c = *s++) { 78 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
90 if (isdigit(c)) 79 if (isdigit(c))
91 c -= '0'; 80 c -= '0';
92 else if (isalpha(c)) 81 else if (isalpha(c))
@@ -95,20 +84,32 @@ strtouq(nptr, endptr, base)
95 break; 84 break;
96 if (c >= base) 85 if (c >= base)
97 break; 86 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 87 if (any < 0)
88 continue;
89 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
99 any = -1; 90 any = -1;
100 else { 91 acc = ULLONG_MAX;
92 errno = ERANGE;
93 } else {
101 any = 1; 94 any = 1;
102 acc *= qbase; 95 acc *= (unsigned long long)base;
103 acc += c; 96 acc += c;
104 } 97 }
105 } 98 }
106 if (any < 0) { 99 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 100 acc = -acc;
111 if (endptr != 0) 101 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 102 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc); 103 return (acc);
114} 104}
105
106#ifdef __weak_alias
107__weak_alias(strtouq, strtoull);
108#else
109u_quad_t
110strtouq(const char *nptr, char **endptr, int base)
111{
112
113 return ((u_quad_t)strtoull(nptr, endptr, base));
114}
115#endif
diff --git a/src/lib/libc/stdlib/strtoumax.c b/src/lib/libc/stdlib/strtoumax.c
new file mode 100644
index 0000000000..ce6e2c00f1
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoumax.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: strtoumax.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2
3/*-
4 * Copyright (c) 1992 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. 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#include <ctype.h>
33#include <errno.h>
34#include <inttypes.h>
35
36/*
37 * Convert a string to a uintmax_t.
38 *
39 * Ignores `locale' stuff. Assumes that the upper and lower case
40 * alphabets and digits are each contiguous.
41 */
42uintmax_t
43strtoumax(const char *nptr, char **endptr, int base)
44{
45 const char *s;
46 uintmax_t acc, cutoff;
47 int c;
48 int neg, any, cutlim;
49
50 /*
51 * See strtoq for comments as to the logic used.
52 */
53 s = nptr;
54 do {
55 c = (unsigned char) *s++;
56 } while (isspace(c));
57 if (c == '-') {
58 neg = 1;
59 c = *s++;
60 } else {
61 neg = 0;
62 if (c == '+')
63 c = *s++;
64 }
65 if ((base == 0 || base == 16) &&
66 c == '0' && (*s == 'x' || *s == 'X')) {
67 c = s[1];
68 s += 2;
69 base = 16;
70 }
71 if (base == 0)
72 base = c == '0' ? 8 : 10;
73
74 cutoff = UINTMAX_MAX / (uintmax_t)base;
75 cutlim = UINTMAX_MAX % (uintmax_t)base;
76 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
77 if (isdigit(c))
78 c -= '0';
79 else if (isalpha(c))
80 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
81 else
82 break;
83 if (c >= base)
84 break;
85 if (any < 0)
86 continue;
87 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
88 any = -1;
89 acc = UINTMAX_MAX;
90 errno = ERANGE;
91 } else {
92 any = 1;
93 acc *= (uintmax_t)base;
94 acc += c;
95 }
96 }
97 if (neg && any > 0)
98 acc = -acc;
99 if (endptr != 0)
100 *endptr = (char *) (any ? s - 1 : nptr);
101 return (acc);
102}
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
index 520f51db0a..a49e595bc0 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,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: @(#)system.3 6.5 (Berkeley) 6/29/91 32.\" $OpenBSD: system.3,v 1.11 2008/04/04 19:30:41 kurt 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 $Mdocdate: April 4 2008 $
40.Dt SYSTEM 3 35.Dt SYSTEM 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -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,47 @@ 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.Pp
70Note that fork handlers established using
71.Xr pthread_atfork 3
72are not called when a multithreaded program calls
73.Fn system .
74.Sh RETURN VALUES
77If a child process cannot be created, or the termination status of 75If a child process cannot be created, or the termination status of
78the shell cannot be obtained, 76the shell cannot be obtained,
79.Fn system 77.Fn system
80returns -1 and sets 78returns \-1 and sets
81.Va errno 79.Va errno
82to indicate the error. 80to indicate the error.
83If execution of the shell fails, 81If execution of the shell fails,
84.Fn system 82.Fn system
85returns the termination status for a program that terminates with a call of 83returns the termination status for a program that terminates with a call of
86.Fn exit 127 . 84.Fn exit 127 .
87.Sh SEE ALSO 85.Sh SEE ALSO
88.Xr sh 1 , 86.Xr sh 1 ,
89.Xr execve 2 , 87.Xr execve 2 ,
90.Xr popen 3 , 88.Xr waitpid 2 ,
91.Xr waitpid 3 , 89.Xr popen 3
92.Sh STANDARDS 90.Sh STANDARDS
93The 91The
94.Fn system 92.Fn system
95function 93function conforms to
96conforms to 94.St -ansiC
97.St -ansiC
98and 95and
99.St -1003.2-92 . 96.St -p1003.2-92 .
97.Sh CAVEATS
98Never supply the
99.Fn system
100function with a command containing any part of an unsanitized user-supplied
101string.
102Shell meta-characters present will be honored by the
103.Xr sh 1
104command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index c2f39325f6..14ddcae8d3 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1988 The Regents of the University of California. 3 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 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
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 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,11 +28,6 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/
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 */
38
39#include <sys/types.h> 31#include <sys/types.h>
40#include <sys/wait.h> 32#include <sys/wait.h>
41#include <signal.h> 33#include <signal.h>
@@ -46,25 +38,28 @@ static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"
46extern char **environ; 38extern char **environ;
47 39
48int 40int
49system(command) 41system(const char *command)
50 const char *command;
51{ 42{
52 pid_t pid; 43 pid_t pid;
53 sig_t intsave, quitsave; 44 sig_t intsave, quitsave;
54 int omask; 45 sigset_t mask, omask;
55 int pstat; 46 int pstat;
56 char *argp[] = {"sh", "-c", (char *) command, NULL}; 47 char *argp[] = {"sh", "-c", NULL, NULL};
57 48
58 if (!command) /* just checking... */ 49 if (!command) /* just checking... */
59 return(1); 50 return(1);
60 51
61 omask = sigblock(sigmask(SIGCHLD)); 52 argp[2] = (char *)command;
62 switch(pid = vfork()) { 53
54 sigemptyset(&mask);
55 sigaddset(&mask, SIGCHLD);
56 sigprocmask(SIG_BLOCK, &mask, &omask);
57 switch (pid = vfork()) {
63 case -1: /* error */ 58 case -1: /* error */
64 (void)sigsetmask(omask); 59 sigprocmask(SIG_SETMASK, &omask, NULL);
65 return(-1); 60 return(-1);
66 case 0: /* child */ 61 case 0: /* child */
67 (void)sigsetmask(omask); 62 sigprocmask(SIG_SETMASK, &omask, NULL);
68 execve(_PATH_BSHELL, argp, environ); 63 execve(_PATH_BSHELL, argp, environ);
69 _exit(127); 64 _exit(127);
70 } 65 }
@@ -72,8 +67,8 @@ system(command)
72 intsave = signal(SIGINT, SIG_IGN); 67 intsave = signal(SIGINT, SIG_IGN);
73 quitsave = signal(SIGQUIT, SIG_IGN); 68 quitsave = signal(SIGQUIT, SIG_IGN);
74 pid = waitpid(pid, (int *)&pstat, 0); 69 pid = waitpid(pid, (int *)&pstat, 0);
75 (void)sigsetmask(omask); 70 sigprocmask(SIG_SETMASK, &omask, NULL);
76 (void)signal(SIGINT, intsave); 71 (void)signal(SIGINT, intsave);
77 (void)signal(SIGQUIT, quitsave); 72 (void)signal(SIGQUIT, quitsave);
78 return(pid == -1 ? -1 : pstat); 73 return (pid == -1 ? -1 : pstat);
79} 74}
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..ff6bcd742d
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/* $OpenBSD: tfind.c,v 1.5 2005/03/30 18:51:49 pat Exp $ */
2
3/*
4 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
5 * the AT&T man page says.
6 *
7 * The node_t structure is for internal use only, lint doesn't grok it.
8 *
9 * Written by reading the System V Interface Definition, not the code.
10 *
11 * Totally public domain.
12 */
13/*LINTLIBRARY*/
14#include <search.h>
15
16typedef struct node_t
17{
18 char *key;
19 struct node_t *llink, *rlink;
20} node;
21
22/* find a node, or return 0 */
23void *
24tfind(const void *vkey, void * const *vrootp,
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..0a52822620
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,127 @@
1.\" $OpenBSD: tsearch.3,v 1.16 2007/05/31 19:19:32 jmc 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 $Mdocdate: May 31 2007 $
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 and a pointer to the new root will be returned.
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
117.Sh STANDARDS
118These functions conform to
119.St -p1003.1-2004 .
120.Sh CAVEATS
121The
122.St -p1003.1-2004
123standard does not specify what value should be returned when deleting the
124root node.
125Since implementations vary, the user of the
126.Fn tdelete
127function should not rely on a specific behaviour.
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..667c57731b
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,121 @@
1/* $OpenBSD: tsearch.c,v 1.6 2006/04/04 11:21:50 moritz Exp $ */
2
3/*
4 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
5 * the AT&T man page says.
6 *
7 * The node_t structure is for internal use only, lint doesn't grok it.
8 *
9 * Written by reading the System V Interface Definition, not the code.
10 *
11 * Totally public domain.
12 */
13/*LINTLIBRARY*/
14
15#include <search.h>
16#include <stdlib.h>
17
18typedef struct node_t {
19 char *key;
20 struct node_t *left, *right;
21} node;
22
23/* find or insert datum into search tree */
24void *
25tsearch(const void *vkey, void **vrootp,
26 int (*compar)(const void *, const void *))
27{
28 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(const void *vkey, void **vrootp,
55 int (*compar)(const void *, const void *))
56{
57 node **rootp = (node **)vrootp;
58 char *key = (char *)vkey;
59 node *p;
60 node *q;
61 node *r;
62 int cmp;
63
64 if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
65 return ((struct node_t *)0);
66 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
67 p = *rootp;
68 rootp = (cmp < 0) ?
69 &(*rootp)->left : /* follow left branch */
70 &(*rootp)->right; /* follow right branch */
71 if (*rootp == (struct node_t *)0)
72 return ((void *)0); /* key not found */
73 }
74 r = (*rootp)->right; /* D1: */
75 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
76 q = r;
77 else if (r != (struct node_t *)0) { /* Right link is null? */
78 if (r->left == (struct node_t *)0) { /* D2: Find successor */
79 r->left = q;
80 q = r;
81 } else { /* D3: Find (struct node_t *)0 link */
82 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
83 r = q;
84 r->left = q->right;
85 q->left = (*rootp)->left;
86 q->right = (*rootp)->right;
87 }
88 }
89 if (p == *rootp)
90 p = q;
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(node *root, void (*action)(const void *, VISIT, int), int level)
99{
100 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
101 (*action)(root, leaf, level);
102 else {
103 (*action)(root, preorder, level);
104 if (root->left != (struct node_t *)0)
105 trecurse(root->left, action, level + 1);
106 (*action)(root, postorder, level);
107 if (root->right != (struct node_t *)0)
108 trecurse(root->right, action, level + 1);
109 (*action)(root, endorder, level);
110 }
111}
112
113/* Walk the nodes of a tree */
114void
115twalk(const void *vroot, void (*action)(const void *, VISIT, int))
116{
117 node *root = (node *)vroot;
118
119 if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
120 trecurse(root, action, 0);
121}