From eb8dd9dca1228af0cd132f515509051ecfabf6f6 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 14 Apr 2025 17:32:06 +0000 Subject: This commit was manufactured by cvs2git to create tag 'tb_20250414'. --- src/lib/libc/stdlib/Makefile.inc | 33 - src/lib/libc/stdlib/_Exit.c | 22 - src/lib/libc/stdlib/__mktemp4.c | 83 - src/lib/libc/stdlib/_rand48.c | 47 - src/lib/libc/stdlib/a64l.3 | 133 -- src/lib/libc/stdlib/a64l.c | 42 - src/lib/libc/stdlib/abort.3 | 77 - src/lib/libc/stdlib/abort.c | 64 - src/lib/libc/stdlib/abs.3 | 75 - src/lib/libc/stdlib/abs.c | 38 - src/lib/libc/stdlib/alloca.3 | 74 - src/lib/libc/stdlib/atexit.3 | 97 -- src/lib/libc/stdlib/atexit.c | 256 ---- src/lib/libc/stdlib/atexit.h | 61 - src/lib/libc/stdlib/atof.3 | 81 - src/lib/libc/stdlib/atof.c | 37 - src/lib/libc/stdlib/atoi.3 | 89 -- src/lib/libc/stdlib/atoi.c | 38 - src/lib/libc/stdlib/atol.3 | 68 - src/lib/libc/stdlib/atol.c | 37 - src/lib/libc/stdlib/atoll.3 | 68 - src/lib/libc/stdlib/atoll.c | 37 - src/lib/libc/stdlib/bsearch.3 | 84 - src/lib/libc/stdlib/bsearch.c | 69 - src/lib/libc/stdlib/div.3 | 63 - src/lib/libc/stdlib/div.c | 72 - src/lib/libc/stdlib/drand48.c | 30 - src/lib/libc/stdlib/ecvt.3 | 166 -- src/lib/libc/stdlib/ecvt.c | 104 -- src/lib/libc/stdlib/erand48.c | 26 - src/lib/libc/stdlib/exit.3 | 102 -- src/lib/libc/stdlib/exit.c | 57 - src/lib/libc/stdlib/gcvt.c | 123 -- src/lib/libc/stdlib/getenv.3 | 191 --- src/lib/libc/stdlib/getenv.c | 78 - src/lib/libc/stdlib/getopt.3 | 365 ----- src/lib/libc/stdlib/getopt_long.3 | 460 ------ src/lib/libc/stdlib/getopt_long.c | 513 ------- src/lib/libc/stdlib/getsubopt.3 | 162 -- src/lib/libc/stdlib/getsubopt.c | 92 -- src/lib/libc/stdlib/hcreate.3 | 234 --- src/lib/libc/stdlib/hcreate.c | 189 --- src/lib/libc/stdlib/heapsort.c | 175 --- src/lib/libc/stdlib/icdb.c | 391 ----- src/lib/libc/stdlib/icdb_new.3 | 68 - src/lib/libc/stdlib/imaxabs.3 | 70 - src/lib/libc/stdlib/imaxabs.c | 38 - src/lib/libc/stdlib/imaxdiv.3 | 65 - src/lib/libc/stdlib/imaxdiv.c | 50 - src/lib/libc/stdlib/insque.3 | 103 -- src/lib/libc/stdlib/insque.c | 54 - src/lib/libc/stdlib/jrand48.c | 22 - src/lib/libc/stdlib/l64a.c | 42 - src/lib/libc/stdlib/labs.3 | 88 -- src/lib/libc/stdlib/labs.c | 37 - src/lib/libc/stdlib/lcong48.c | 36 - src/lib/libc/stdlib/ldiv.3 | 71 - src/lib/libc/stdlib/ldiv.c | 50 - src/lib/libc/stdlib/llabs.c | 40 - src/lib/libc/stdlib/lldiv.3 | 73 - src/lib/libc/stdlib/lldiv.c | 52 - src/lib/libc/stdlib/lrand48.c | 24 - src/lib/libc/stdlib/lsearch.3 | 106 -- src/lib/libc/stdlib/lsearch.c | 70 - src/lib/libc/stdlib/malloc.3 | 860 ----------- src/lib/libc/stdlib/malloc.c | 2781 ---------------------------------- src/lib/libc/stdlib/merge.c | 336 ---- src/lib/libc/stdlib/mkdtemp.c | 41 - src/lib/libc/stdlib/mkstemp.c | 64 - src/lib/libc/stdlib/mktemp.3 | 431 ------ src/lib/libc/stdlib/mktemp.c | 48 - src/lib/libc/stdlib/mrand48.c | 24 - src/lib/libc/stdlib/nrand48.c | 22 - src/lib/libc/stdlib/posix_memalign.3 | 97 -- src/lib/libc/stdlib/posix_openpt.3 | 102 -- src/lib/libc/stdlib/posix_pty.c | 120 -- src/lib/libc/stdlib/ptsname.3 | 160 -- src/lib/libc/stdlib/qsort.3 | 276 ---- src/lib/libc/stdlib/qsort.c | 238 --- src/lib/libc/stdlib/radixsort.3 | 151 -- src/lib/libc/stdlib/radixsort.c | 294 ---- src/lib/libc/stdlib/rand.3 | 135 -- src/lib/libc/stdlib/rand.c | 74 - src/lib/libc/stdlib/rand48.3 | 240 --- src/lib/libc/stdlib/rand48.h | 38 - src/lib/libc/stdlib/random.3 | 197 --- src/lib/libc/stdlib/random.c | 419 ----- src/lib/libc/stdlib/reallocarray.c | 39 - src/lib/libc/stdlib/realpath.3 | 165 -- src/lib/libc/stdlib/realpath.c | 42 - src/lib/libc/stdlib/recallocarray.c | 81 - src/lib/libc/stdlib/remque.c | 48 - src/lib/libc/stdlib/seed48.c | 45 - src/lib/libc/stdlib/setenv.c | 185 --- src/lib/libc/stdlib/srand48.c | 38 - src/lib/libc/stdlib/strtod.3 | 176 --- src/lib/libc/stdlib/strtoimax.c | 151 -- src/lib/libc/stdlib/strtol.3 | 273 ---- src/lib/libc/stdlib/strtol.c | 151 -- src/lib/libc/stdlib/strtoll.c | 156 -- src/lib/libc/stdlib/strtonum.3 | 152 -- src/lib/libc/stdlib/strtonum.c | 66 - src/lib/libc/stdlib/strtoul.3 | 260 ---- src/lib/libc/stdlib/strtoul.c | 110 -- src/lib/libc/stdlib/strtoull.c | 114 -- src/lib/libc/stdlib/strtoumax.c | 109 -- src/lib/libc/stdlib/system.3 | 116 -- src/lib/libc/stdlib/system.c | 89 -- src/lib/libc/stdlib/tfind.c | 40 - src/lib/libc/stdlib/thread_atexit.c | 44 - src/lib/libc/stdlib/tsearch.3 | 126 -- src/lib/libc/stdlib/tsearch.c | 118 -- 112 files changed, 16504 deletions(-) delete mode 100644 src/lib/libc/stdlib/Makefile.inc delete mode 100644 src/lib/libc/stdlib/_Exit.c delete mode 100644 src/lib/libc/stdlib/__mktemp4.c delete mode 100644 src/lib/libc/stdlib/_rand48.c delete mode 100644 src/lib/libc/stdlib/a64l.3 delete mode 100644 src/lib/libc/stdlib/a64l.c delete mode 100644 src/lib/libc/stdlib/abort.3 delete mode 100644 src/lib/libc/stdlib/abort.c delete mode 100644 src/lib/libc/stdlib/abs.3 delete mode 100644 src/lib/libc/stdlib/abs.c delete mode 100644 src/lib/libc/stdlib/alloca.3 delete mode 100644 src/lib/libc/stdlib/atexit.3 delete mode 100644 src/lib/libc/stdlib/atexit.c delete mode 100644 src/lib/libc/stdlib/atexit.h delete mode 100644 src/lib/libc/stdlib/atof.3 delete mode 100644 src/lib/libc/stdlib/atof.c delete mode 100644 src/lib/libc/stdlib/atoi.3 delete mode 100644 src/lib/libc/stdlib/atoi.c delete mode 100644 src/lib/libc/stdlib/atol.3 delete mode 100644 src/lib/libc/stdlib/atol.c delete mode 100644 src/lib/libc/stdlib/atoll.3 delete mode 100644 src/lib/libc/stdlib/atoll.c delete mode 100644 src/lib/libc/stdlib/bsearch.3 delete mode 100644 src/lib/libc/stdlib/bsearch.c delete mode 100644 src/lib/libc/stdlib/div.3 delete mode 100644 src/lib/libc/stdlib/div.c delete mode 100644 src/lib/libc/stdlib/drand48.c delete mode 100644 src/lib/libc/stdlib/ecvt.3 delete mode 100644 src/lib/libc/stdlib/ecvt.c delete mode 100644 src/lib/libc/stdlib/erand48.c delete mode 100644 src/lib/libc/stdlib/exit.3 delete mode 100644 src/lib/libc/stdlib/exit.c delete mode 100644 src/lib/libc/stdlib/gcvt.c delete mode 100644 src/lib/libc/stdlib/getenv.3 delete mode 100644 src/lib/libc/stdlib/getenv.c delete mode 100644 src/lib/libc/stdlib/getopt.3 delete mode 100644 src/lib/libc/stdlib/getopt_long.3 delete mode 100644 src/lib/libc/stdlib/getopt_long.c delete mode 100644 src/lib/libc/stdlib/getsubopt.3 delete mode 100644 src/lib/libc/stdlib/getsubopt.c delete mode 100644 src/lib/libc/stdlib/hcreate.3 delete mode 100644 src/lib/libc/stdlib/hcreate.c delete mode 100644 src/lib/libc/stdlib/heapsort.c delete mode 100644 src/lib/libc/stdlib/icdb.c delete mode 100644 src/lib/libc/stdlib/icdb_new.3 delete mode 100644 src/lib/libc/stdlib/imaxabs.3 delete mode 100644 src/lib/libc/stdlib/imaxabs.c delete mode 100644 src/lib/libc/stdlib/imaxdiv.3 delete mode 100644 src/lib/libc/stdlib/imaxdiv.c delete mode 100644 src/lib/libc/stdlib/insque.3 delete mode 100644 src/lib/libc/stdlib/insque.c delete mode 100644 src/lib/libc/stdlib/jrand48.c delete mode 100644 src/lib/libc/stdlib/l64a.c delete mode 100644 src/lib/libc/stdlib/labs.3 delete mode 100644 src/lib/libc/stdlib/labs.c delete mode 100644 src/lib/libc/stdlib/lcong48.c delete mode 100644 src/lib/libc/stdlib/ldiv.3 delete mode 100644 src/lib/libc/stdlib/ldiv.c delete mode 100644 src/lib/libc/stdlib/llabs.c delete mode 100644 src/lib/libc/stdlib/lldiv.3 delete mode 100644 src/lib/libc/stdlib/lldiv.c delete mode 100644 src/lib/libc/stdlib/lrand48.c delete mode 100644 src/lib/libc/stdlib/lsearch.3 delete mode 100644 src/lib/libc/stdlib/lsearch.c delete mode 100644 src/lib/libc/stdlib/malloc.3 delete mode 100644 src/lib/libc/stdlib/malloc.c delete mode 100644 src/lib/libc/stdlib/merge.c delete mode 100644 src/lib/libc/stdlib/mkdtemp.c delete mode 100644 src/lib/libc/stdlib/mkstemp.c delete mode 100644 src/lib/libc/stdlib/mktemp.3 delete mode 100644 src/lib/libc/stdlib/mktemp.c delete mode 100644 src/lib/libc/stdlib/mrand48.c delete mode 100644 src/lib/libc/stdlib/nrand48.c delete mode 100644 src/lib/libc/stdlib/posix_memalign.3 delete mode 100644 src/lib/libc/stdlib/posix_openpt.3 delete mode 100644 src/lib/libc/stdlib/posix_pty.c delete mode 100644 src/lib/libc/stdlib/ptsname.3 delete mode 100644 src/lib/libc/stdlib/qsort.3 delete mode 100644 src/lib/libc/stdlib/qsort.c delete mode 100644 src/lib/libc/stdlib/radixsort.3 delete mode 100644 src/lib/libc/stdlib/radixsort.c delete mode 100644 src/lib/libc/stdlib/rand.3 delete mode 100644 src/lib/libc/stdlib/rand.c delete mode 100644 src/lib/libc/stdlib/rand48.3 delete mode 100644 src/lib/libc/stdlib/rand48.h delete mode 100644 src/lib/libc/stdlib/random.3 delete mode 100644 src/lib/libc/stdlib/random.c delete mode 100644 src/lib/libc/stdlib/reallocarray.c delete mode 100644 src/lib/libc/stdlib/realpath.3 delete mode 100644 src/lib/libc/stdlib/realpath.c delete mode 100644 src/lib/libc/stdlib/recallocarray.c delete mode 100644 src/lib/libc/stdlib/remque.c delete mode 100644 src/lib/libc/stdlib/seed48.c delete mode 100644 src/lib/libc/stdlib/setenv.c delete mode 100644 src/lib/libc/stdlib/srand48.c delete mode 100644 src/lib/libc/stdlib/strtod.3 delete mode 100644 src/lib/libc/stdlib/strtoimax.c delete mode 100644 src/lib/libc/stdlib/strtol.3 delete mode 100644 src/lib/libc/stdlib/strtol.c delete mode 100644 src/lib/libc/stdlib/strtoll.c delete mode 100644 src/lib/libc/stdlib/strtonum.3 delete mode 100644 src/lib/libc/stdlib/strtonum.c delete mode 100644 src/lib/libc/stdlib/strtoul.3 delete mode 100644 src/lib/libc/stdlib/strtoul.c delete mode 100644 src/lib/libc/stdlib/strtoull.c delete mode 100644 src/lib/libc/stdlib/strtoumax.c delete mode 100644 src/lib/libc/stdlib/system.3 delete mode 100644 src/lib/libc/stdlib/system.c delete mode 100644 src/lib/libc/stdlib/tfind.c delete mode 100644 src/lib/libc/stdlib/thread_atexit.c delete mode 100644 src/lib/libc/stdlib/tsearch.3 delete mode 100644 src/lib/libc/stdlib/tsearch.c (limited to 'src/lib/libc/stdlib') diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc deleted file mode 100644 index f5e9a9fe4e..0000000000 --- a/src/lib/libc/stdlib/Makefile.inc +++ /dev/null @@ -1,33 +0,0 @@ -# $OpenBSD: Makefile.inc,v 1.66 2024/01/19 19:45:02 millert Exp $ - -# stdlib sources -.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib - -SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ - exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ - getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c \ - l64a.c llabs.c lldiv.c lsearch.c malloc.c __mktemp4.c mkdtemp.c \ - mkstemp.c mktemp.c reallocarray.c merge.c posix_pty.c qsort.c \ - radixsort.c rand.c random.c realpath.c remque.c setenv.c strtoimax.c \ - strtol.c strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c \ - system.c \ - tfind.c thread_atexit.c tsearch.c \ - _rand48.c drand48.c erand48.c jrand48.c \ - lcong48.c lrand48.c mrand48.c nrand48.c seed48.c srand48.c \ - _Exit.c icdb.c - -.if (${MACHINE_CPU} == "i386") -SRCS+= abs.S div.S labs.S ldiv.S -.elif (${MACHINE_CPU} == "alpha") -# XXX should be .S's -SRCS+= abs.c div.c labs.c ldiv.c -.else -SRCS+= abs.c div.c labs.c ldiv.c -.endif - -MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \ - bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \ - getsubopt.3 hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 \ - lldiv.3 lsearch.3 malloc.3 mktemp.3 posix_memalign.3 posix_openpt.3 \ - ptsname.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \ - strtod.3 strtonum.3 strtol.3 strtoul.3 system.3 tsearch.3 diff --git a/src/lib/libc/stdlib/_Exit.c b/src/lib/libc/stdlib/_Exit.c deleted file mode 100644 index ccf64c2e87..0000000000 --- a/src/lib/libc/stdlib/_Exit.c +++ /dev/null @@ -1,22 +0,0 @@ -/* $OpenBSD: _Exit.c,v 1.3 2013/04/03 03:39:29 guenther Exp $ */ - -/* - * Placed in the public domain by Todd C. Miller on January 21, 2004. - */ - -#include -#include - -/* - * _Exit() is the ISO/ANSI C99 equivalent of the POSIX _exit() function. - * No atexit() handlers are called and no signal handlers are run. - * Whether or not stdio buffers are flushed or temporary files are removed - * is implementation-dependent in C99. Indeed, POSIX specifies that - * _Exit() must *not* flush stdio buffers or remove temporary files, but - * rather must behave exactly like _exit() - */ -void -_Exit(int status) -{ - _exit(status); -} diff --git a/src/lib/libc/stdlib/__mktemp4.c b/src/lib/libc/stdlib/__mktemp4.c deleted file mode 100644 index 4b4500018b..0000000000 --- a/src/lib/libc/stdlib/__mktemp4.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $OpenBSD: __mktemp4.c,v 1.1 2024/01/19 19:45:02 millert Exp $ */ -/* - * Copyright (c) 1996-1998, 2008 Theo de Raadt - * Copyright (c) 1997, 2008-2009, 2024 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" -#define NUM_CHARS (sizeof(TEMPCHARS) - 1) -#define MIN_X 6 - -#ifndef nitems -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) -#endif - -/* - * Internal driver for the mktemp(3) family of functions. - * The supplied callback does the actual work of testing or - * creating the file/directory. - */ -int -__mktemp4(char *path, int slen, int flags, int (*cb)(const char *, int)) -{ - char *start, *cp, *ep; - const char tempchars[] = TEMPCHARS; - unsigned int tries; - size_t len; - int ret; - - len = strlen(path); - if (len < MIN_X || slen < 0 || (size_t)slen > len - MIN_X) { - errno = EINVAL; - return -1; - } - ep = path + len - slen; - - for (start = ep; start > path && start[-1] == 'X'; start--) - ; - if (ep - start < MIN_X) { - errno = EINVAL; - return -1; - } - - tries = INT_MAX; - do { - cp = start; - do { - unsigned short rbuf[16]; - unsigned int i; - - /* - * Avoid lots of arc4random() calls by using - * a buffer sized for up to 16 Xs at a time. - */ - arc4random_buf(rbuf, sizeof(rbuf)); - for (i = 0; i < nitems(rbuf) && cp != ep; i++) - *cp++ = tempchars[rbuf[i] % NUM_CHARS]; - } while (cp != ep); - - ret = cb(path, flags); - if (ret != -1 || errno != EEXIST) - return ret; - } while (--tries); - - errno = EEXIST; - return -1; -} diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c deleted file mode 100644 index 7c950f7cee..0000000000 --- a/src/lib/libc/stdlib/_rand48.c +++ /dev/null @@ -1,47 +0,0 @@ -/* $OpenBSD: _rand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -unsigned short __rand48_seed[3] = { - RAND48_SEED_0, - RAND48_SEED_1, - RAND48_SEED_2 -}; -unsigned short __rand48_mult[3] = { - RAND48_MULT_0, - RAND48_MULT_1, - RAND48_MULT_2 -}; -unsigned short __rand48_add = RAND48_ADD; - -void -__dorand48(unsigned short xseed[3]) -{ - unsigned long accu; - unsigned short temp[2]; - - accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] + - (unsigned long) __rand48_add; - temp[0] = (unsigned short) accu; /* lower 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] + - (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0]; - temp[1] = (unsigned short) accu; /* middle 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0]; - xseed[0] = temp[0]; - xseed[1] = temp[1]; - xseed[2] = (unsigned short) accu; -} diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3 deleted file mode 100644 index c34af99c88..0000000000 --- a/src/lib/libc/stdlib/a64l.3 +++ /dev/null @@ -1,133 +0,0 @@ -.\" $OpenBSD: a64l.3,v 1.13 2019/01/25 00:19:25 millert Exp $ -.\" -.\" Copyright (c) 1997 Todd C. Miller -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.Dd $Mdocdate: January 25 2019 $ -.Dt A64L 3 -.Os -.Sh NAME -.Nm a64l , -.Nm l64a -.Nd convert between 32-bit integer and radix-64 ASCII string -.Sh SYNOPSIS -.In stdlib.h -.Ft long -.Fn a64l "const char *s" -.Ft char * -.Fn l64a "long l" -.Sh DESCRIPTION -The -.Fn a64l -and -.Fn l64a -functions are used to maintain numbers stored in radix-64 -.Tn ASCII -characters. -This is a notation by which 32-bit integers -can be represented by up to six characters; each character represents a -.Dq digit -in a radix-64 notation. -.Pp -The characters used to represent digits are -.Ql \&. -for 0, -.Ql / -for 1, -.Ql 0 -through -.Ql 9 -for 2-11, -.Ql A -through -.Ql Z -for 12-37, and -.Ql a -through -.Ql z -for 38-63. -.Pp -The -.Fn a64l -function takes a pointer to a NUL-terminated radix-64 representation -and returns a corresponding 32-bit value. -If the string pointed to by -.Fa s -contains more than six characters, -.Fn a64l -will use the first six. -.Fn a64l -scans the character string from left to right, decoding -each character as a 6-bit radix-64 number. -If a long integer is -larger than 32 bits, the return value will be sign-extended. -.Pp -.Fn l64a -takes a long integer argument -.Fa l -and returns a pointer to the corresponding radix-64 representation. -.Sh RETURN VALUES -On success, -.Fn a64l -returns a 32-bit representation of -.Fa s . -If -.Fa s -is a null pointer or if it contains digits other than those described above, -.Fn a64l -returns \-1 and sets the global variable -.Va errno -to -.Er EINVAL . -.Pp -On success, -.Fn l64a -returns a pointer to a string containing the radix-64 representation of -.Fa l . -If -.Fa l -is 0, -.Fn l64a -returns a pointer to the empty string. -If -.Fa l -is negative, -.Fn l64a -returns a null pointer and sets the global variable -.Va errno -to -.Er EINVAL . -.Sh STANDARDS -The -.Fn a64l -and -.Fn l64a -functions conform to -.St -xpg4.2 . -.Sh CAVEATS -The value returned by -.Fn l64a -is a pointer into a static buffer, the contents of which -will be overwritten by subsequent calls. -.Pp -The value returned by -.Fn a64l -may be incorrect if the value is too large; for that reason, only strings -that resulted from a call to -.Fn l64a -should be used to call -.Fn a64l . -.Pp -If a long integer is larger than 32 bits, only the low-order -32 bits are used. diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c deleted file mode 100644 index 5312929c6f..0000000000 --- a/src/lib/libc/stdlib/a64l.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $OpenBSD: a64l.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -long -a64l(const char *s) -{ - long value, digit, shift; - int i; - - if (s == NULL) { - errno = EINVAL; - return(-1L); - } - - value = 0; - shift = 0; - for (i = 0; *s && i < 6; i++, s++) { - if (*s >= '.' && *s <= '/') - digit = *s - '.'; - else if (*s >= '0' && *s <= '9') - digit = *s - '0' + 2; - else if (*s >= 'A' && *s <= 'Z') - digit = *s - 'A' + 12; - else if (*s >= 'a' && *s <= 'z') - digit = *s - 'a' + 38; - else { - errno = EINVAL; - return(-1L); - } - - value |= digit << shift; - shift += 6; - } - - return(value); -} diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3 deleted file mode 100644 index 2f15cd827c..0000000000 --- a/src/lib/libc/stdlib/abort.3 +++ /dev/null @@ -1,77 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: abort.3,v 1.11 2014/05/14 21:54:20 tedu Exp $ -.\" -.Dd $Mdocdate: May 14 2014 $ -.Dt ABORT 3 -.Os -.Sh NAME -.Nm abort -.Nd cause abnormal program termination -.Sh SYNOPSIS -.In stdlib.h -.Ft void -.Fn abort void -.Sh DESCRIPTION -The -.Fn abort -function causes abnormal program termination to occur, unless the signal -.Dv SIGABRT -is being caught and the signal handler does not return. -.Pp -Some implementations may flush output streams before terminating. -This implementation does not. -.Sh RETURN VALUES -The -.Fn abort -function never returns. -.Sh SEE ALSO -.Xr sigaction 2 , -.Xr exit 3 -.Sh STANDARDS -The -.Fn abort -function conforms to -.St -p1003.1-90 . -.Sh HISTORY -The -.Fn abort -function first appeared in -.At v5 . -.Pp -Historically, previous standards required -.Fn abort -to flush and close output streams, but this conflicted with the requirement -that -.Fn abort -be async signal safe. -As a result, the flushing requirement was dropped. diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c deleted file mode 100644 index 6c22ecd2b0..0000000000 --- a/src/lib/libc/stdlib/abort.c +++ /dev/null @@ -1,64 +0,0 @@ -/* $OpenBSD: abort.c,v 1.21 2017/08/12 22:59:52 guenther Exp $ */ -/* - * Copyright (c) 1985 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - - -void -abort(void) -{ - sigset_t mask; - struct sigaction sa; - - sigfillset(&mask); - /* - * don't block SIGABRT to give any handler a chance; we ignore - * any errors -- X311J doesn't allow abort to return anyway. - */ - sigdelset(&mask, SIGABRT); - (void)sigprocmask(SIG_SETMASK, &mask, NULL); - - (void)raise(SIGABRT); - - /* - * if SIGABRT ignored, or caught and the handler returns, do - * it again, only harder. - */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - (void)sigaction(SIGABRT, &sa, NULL); - (void)sigprocmask(SIG_SETMASK, &mask, NULL); - (void)raise(SIGABRT); - _exit(1); -} -DEF_STRONG(abort); diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3 deleted file mode 100644 index afacc985df..0000000000 --- a/src/lib/libc/stdlib/abs.3 +++ /dev/null @@ -1,75 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: abs.3,v 1.12 2019/01/18 07:32:17 schwarze Exp $ -.\" -.Dd $Mdocdate: January 18 2019 $ -.Dt ABS 3 -.Os -.Sh NAME -.Nm abs -.Nd integer absolute value function -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft int -.Fn abs "int j" -.Sh DESCRIPTION -The -.Fn abs -function computes the absolute value of the integer -.Fa j . -.Sh RETURN VALUES -The -.Fn abs -function returns the absolute value. -.Sh SEE ALSO -.Xr cabs 3 , -.Xr floor 3 , -.Xr hypot 3 , -.Xr imaxabs 3 , -.Xr labs 3 -.Sh STANDARDS -The -.Fn abs -function conforms to -.St -ansiC . -.Sh HISTORY -The -.Fn abs -function first appeared in -.At v6 . -.Sh CAVEATS -The result of applying -.Fn abs -to -.Dv INT_MIN -is undefined. diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c deleted file mode 100644 index 0e39cc5536..0000000000 --- a/src/lib/libc/stdlib/abs.c +++ /dev/null @@ -1,38 +0,0 @@ -/* $OpenBSD: abs.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -int -abs(int j) -{ - return(j < 0 ? -j : j); -} -DEF_STRONG(abs); diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3 deleted file mode 100644 index 5252ba586f..0000000000 --- a/src/lib/libc/stdlib/alloca.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 1980, 1991 Regents of the University of California. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: alloca.3,v 1.14 2015/01/17 18:01:43 tedu Exp $ -.\" -.Dd $Mdocdate: January 17 2015 $ -.Dt ALLOCA 3 -.Os -.Sh NAME -.Nm alloca -.Nd memory allocator -.Sh SYNOPSIS -.In stdlib.h -.Ft void * -.Fn alloca "size_t size" -.Sh DESCRIPTION -The -.Fn alloca -function allocates -.Fa size -bytes of space in the stack frame of the caller. -This temporary space is automatically freed on return. -.Sh RETURN VALUES -The -.Fn alloca -function returns a pointer to the beginning of the allocated space. -.Sh SEE ALSO -.Xr pagesize 1 , -.Xr brk 2 , -.Xr malloc 3 -.\" .Sh HISTORY -.\" The -.\" .Fn alloca -.\" function appeared in -.\" .Bx ?? . -.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd -.\" The first man page (or link to a man page that I can find at the -.\" moment is 4.3... -.Sh CAVEATS -The -.Fn alloca -function is unsafe because it cannot ensure that the pointer -returned points to a valid and usable block of memory. -The allocation made may exceed the bounds of the stack, or even go -further into other objects in memory, and -.Fn alloca -cannot determine such an error. -Avoid -.Fn alloca -with large unbounded allocations. diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3 deleted file mode 100644 index 3a7e0d978a..0000000000 --- a/src/lib/libc/stdlib/atexit.3 +++ /dev/null @@ -1,97 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: atexit.3,v 1.13 2022/02/06 00:29:02 jsg Exp $ -.\" -.Dd $Mdocdate: February 6 2022 $ -.Dt ATEXIT 3 -.Os -.Sh NAME -.Nm atexit -.Nd register a function to be called on exit -.Sh SYNOPSIS -.In stdlib.h -.Ft int -.Fn atexit "void (*function)(void)" -.Sh DESCRIPTION -The -.Fn atexit -function registers the given -.Fa function -to be called at program exit, whether via -.Xr exit 3 -or via return from the program's -.Fn main . -Functions so registered are called in reverse order; -no arguments are passed. -At least 32 functions can always be registered, -and more are allowed as long as sufficient memory can be allocated. -.Pp -If a shared object is unloaded from process memory using -.Xr dlclose 3 , -then any functions registered by calling -.Fn atexit -from that shared object will be called in reverse order and unregistered. -Note that it is the source of the call to -.Fn atexit -that matters, not the source of the function that was registered. -.Pp -.Fn atexit -is very difficult to use correctly without creating -.Xr exit 3 Ns -time -races. -Unless absolutely necessary, avoid using it. -.Sh RETURN VALUES -The -.Nm -function returns the value 0 if successful; otherwise a non-zero -value is returned and the global variable -.Va errno -is set to indicate the error. -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er ENOMEM -No memory was available to add the function to the list. -The existing list of functions is unmodified. -.El -.Sh SEE ALSO -.Xr dlclose 3 , -.Xr exit 3 -.Sh STANDARDS -The -.Fn atexit -function conforms to -.St -ansiC . -.Pp -Setting -.Va errno -on error and the behavior when a shared object is unloaded -are extensions to that standard. diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c deleted file mode 100644 index 3334617b65..0000000000 --- a/src/lib/libc/stdlib/atexit.c +++ /dev/null @@ -1,256 +0,0 @@ -/* $OpenBSD: atexit.c,v 1.29 2022/12/27 17:10:06 jmc Exp $ */ -/* - * Copyright (c) 2002 Daniel Hartmeier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "atexit.h" -#include "atfork.h" -#include "thread_private.h" - -struct atexit *__atexit; -static int restartloop; - -/* define and initialize the list */ -struct atfork_listhead _atfork_list = TAILQ_HEAD_INITIALIZER(_atfork_list); - - -/* - * Function pointers are stored in a linked list of pages. The list - * is initially empty, and pages are allocated on demand. The first - * function pointer in the first allocated page (the last one in - * the linked list) is reserved for the cleanup function. - * - * Outside the following functions, all pages are mprotect()'ed - * to prevent unintentional/malicious corruption. - */ - -/* - * Register a function to be performed at exit or when a shared object - * with the given dso handle is unloaded dynamically. Also used as - * the backend for atexit(). For more info on this API, see: - * - * http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor - */ -int -__cxa_atexit(void (*func)(void *), void *arg, void *dso) -{ - struct atexit *p; - struct atexit_fn *fnp; - int pgsize = getpagesize(); - int ret = -1; - - if (pgsize < sizeof(*p)) - return (-1); - _ATEXIT_LOCK(); - p = __atexit; - if (p != NULL) { - if (p->ind + 1 >= p->max) - p = NULL; - else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) - goto unlock; - } - if (p == NULL) { - p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - if (p == MAP_FAILED) - goto unlock; - if (__atexit == NULL) { - memset(&p->fns[0], 0, sizeof(p->fns[0])); - p->ind = 1; - } else - p->ind = 0; - p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) / - sizeof(p->fns[0]); - p->next = __atexit; - __atexit = p; - } - fnp = &p->fns[p->ind++]; - fnp->fn_ptr = func; - fnp->fn_arg = arg; - fnp->fn_dso = dso; - if (mprotect(p, pgsize, PROT_READ)) - goto unlock; - restartloop = 1; - ret = 0; -unlock: - _ATEXIT_UNLOCK(); - return (ret); -} -DEF_STRONG(__cxa_atexit); - -/* - * Copy of atexit() used by libc and anything statically linked into the - * executable. This passes NULL for the dso, so the callbacks are only - * invoked by exit() and not dlclose() - */ -int -atexit(void (*fn)(void)) -{ - return (__cxa_atexit((void (*)(void *))fn, NULL, NULL)); -} -DEF_STRONG(atexit); - -void -_thread_finalize(void) -{ - struct tib *tib = TIB_GET(); - - while (tib->tib_atexit) { - struct thread_atexit_fn *fnp = tib->tib_atexit; - tib->tib_atexit = fnp->next; - fnp->func(fnp->arg); - free(fnp); - } -} - -/* - * Call all handlers registered with __cxa_atexit() for the shared - * object owning 'dso'. - * Note: if 'dso' is NULL, then all remaining handlers are called. - */ -void -__cxa_finalize(void *dso) -{ - struct atexit *p, *q; - struct atexit_fn fn; - int n, pgsize = getpagesize(); - static int call_depth; - - if (dso == NULL) - _thread_finalize(); - - _ATEXIT_LOCK(); - call_depth++; - -restart: - restartloop = 0; - for (p = __atexit; p != NULL; p = p->next) { - for (n = p->ind; --n >= 0;) { - if (p->fns[n].fn_ptr == NULL) - continue; /* already called */ - if (dso != NULL && dso != p->fns[n].fn_dso) - continue; /* wrong DSO */ - - /* - * Mark handler as having been already called to avoid - * dupes and loops, then call the appropriate function. - */ - fn = p->fns[n]; - if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) { - p->fns[n].fn_ptr = NULL; - mprotect(p, pgsize, PROT_READ); - } - _ATEXIT_UNLOCK(); - (*fn.fn_ptr)(fn.fn_arg); - _ATEXIT_LOCK(); - if (restartloop) - goto restart; - } - } - - call_depth--; - - /* - * If called via exit(), unmap the pages since we have now run - * all the handlers. We defer this until calldepth == 0 so that - * we don't unmap things prematurely if called recursively. - */ - if (dso == NULL && call_depth == 0) { - for (p = __atexit; p != NULL; ) { - q = p; - p = p->next; - munmap(q, pgsize); - } - __atexit = NULL; - } - _ATEXIT_UNLOCK(); - - /* - * If unloading a DSO, unregister any atfork handlers registered - * by it. Skip the locking if the list is currently empty. - */ - if (dso != NULL && TAILQ_FIRST(&_atfork_list) != NULL) { - struct atfork_fn *af, *afnext; - - _ATFORK_LOCK(); - TAILQ_FOREACH_SAFE(af, &_atfork_list, fn_next, afnext) - if (af->fn_dso == dso) { - TAILQ_REMOVE(&_atfork_list, af, fn_next); - free(af); - } - _ATFORK_UNLOCK(); - - } -} -DEF_STRONG(__cxa_finalize); - -/* - * Register the cleanup function - */ -void -__atexit_register_cleanup(void (*func)(void)) -{ - struct atexit *p; - int pgsize = getpagesize(); - - if (pgsize < sizeof(*p)) - return; - _ATEXIT_LOCK(); - p = __atexit; - while (p != NULL && p->next != NULL) - p = p->next; - if (p == NULL) { - p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - if (p == MAP_FAILED) - goto unlock; - p->ind = 1; - p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) / - sizeof(p->fns[0]); - p->next = NULL; - __atexit = p; - } else { - if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) - goto unlock; - } - p->fns[0].fn_ptr = (void (*)(void *))func; - p->fns[0].fn_arg = NULL; - p->fns[0].fn_dso = NULL; - mprotect(p, pgsize, PROT_READ); - restartloop = 1; -unlock: - _ATEXIT_UNLOCK(); -} diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h deleted file mode 100644 index f2fa7bd83f..0000000000 --- a/src/lib/libc/stdlib/atexit.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $OpenBSD: atexit.h,v 1.12 2017/12/16 20:06:56 guenther Exp $ */ - -/* - * Copyright (c) 2002 Daniel Hartmeier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -struct atexit { - struct atexit *next; /* next in list */ - int ind; /* next index in this table */ - int max; /* max entries >= ATEXIT_SIZE */ - struct atexit_fn { - void (*fn_ptr)(void *); - void *fn_arg; /* argument for CXA callback */ - void *fn_dso; /* shared module handle */ - } fns[1]; /* the table itself */ -}; - -/* a chain of these are hung off each thread's TIB's tib_atexit member */ -struct thread_atexit_fn { - void (*func)(void *); - void *arg; - struct thread_atexit_fn *next; -}; - -__BEGIN_HIDDEN_DECLS -extern struct atexit *__atexit; /* points to head of LIFO stack */ -__END_HIDDEN_DECLS - -int __cxa_atexit(void (*)(void *), void *, void *); -int __cxa_thread_atexit(void (*)(void *), void *, void *); -void __cxa_finalize(void *); - -PROTO_NORMAL(__cxa_atexit); -PROTO_STD_DEPRECATED(__cxa_thread_atexit); -PROTO_NORMAL(__cxa_finalize); diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3 deleted file mode 100644 index 7d1f09d1a4..0000000000 --- a/src/lib/libc/stdlib/atof.3 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: atof.3,v 1.10 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt ATOF 3 -.Os -.Sh NAME -.Nm atof -.Nd convert ASCII string to double -.Sh SYNOPSIS -.In stdlib.h -.Ft double -.Fn atof "const char *nptr" -.Sh DESCRIPTION -The -.Fn atof -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt double -representation. -.Pp -It is equivalent to: -.Bd -literal -offset indent -strtod(nptr, (char **)NULL); -.Ed -.Sh SEE ALSO -.Xr atoi 3 , -.Xr atol 3 , -.Xr strtod 3 , -.Xr strtol 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn atof -function conforms to -.St -ansiC . -.Sh HISTORY -An -.Fn atof -function first appeared in -.At v1 . -.Sh CAVEATS -On systems other than -.Ox , -the -.Dv LC_NUMERIC -.Xr locale 1 -category can cause parsing failures; see CAVEATS in -.Xr setlocale 3 -for details. diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c deleted file mode 100644 index d14b58b070..0000000000 --- a/src/lib/libc/stdlib/atof.c +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: atof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/* - * Copyright (c) 1988 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -double -atof(const char *ascii) -{ - return(strtod(ascii, (char **)NULL)); -} diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3 deleted file mode 100644 index 92d8de93a6..0000000000 --- a/src/lib/libc/stdlib/atoi.3 +++ /dev/null @@ -1,89 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: atoi.3,v 1.13 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt ATOI 3 -.Os -.Sh NAME -.Nm atoi -.Nd convert ASCII string to integer -.Sh SYNOPSIS -.In stdlib.h -.Ft int -.Fn atoi "const char *nptr" -.Sh DESCRIPTION -The -.Fn atoi -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt integer -representation. -.Pp -It is equivalent to: -.Bd -literal -offset indent -(int)strtol(nptr, (char **)NULL, 10); -.Ed -.Sh SEE ALSO -.Xr atof 3 , -.Xr atol 3 , -.Xr strtod 3 , -.Xr strtol 3 , -.Xr strtonum 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn atoi -function conforms to -.St -ansiC . -.Sh HISTORY -An -.Fn atoi -function first appeared in -.At v1 . -.Sh CAVEATS -.Nm -does no overflow checking, handles unsigned numbers poorly, -and handles strings containing trailing extra characters -(like -.Dq "123abc" ) -poorly. -Careful use of -.Xr strtol 3 -and -.Xr strtoul 3 -can alleviate these problems, -but -.Xr strtonum 3 -can be used to convert numbers from strings much more safely -and easily. diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c deleted file mode 100644 index 7c9eb1331b..0000000000 --- a/src/lib/libc/stdlib/atoi.c +++ /dev/null @@ -1,38 +0,0 @@ -/* $OpenBSD: atoi.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */ -/* - * Copyright (c) 1988 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -int -atoi(const char *str) -{ - return((int)strtol(str, (char **)NULL, 10)); -} -DEF_STRONG(atoi); diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3 deleted file mode 100644 index f67ca7da6c..0000000000 --- a/src/lib/libc/stdlib/atol.3 +++ /dev/null @@ -1,68 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: atol.3,v 1.11 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt ATOL 3 -.Os -.Sh NAME -.Nm atol -.Nd convert ASCII string to long integer -.Sh SYNOPSIS -.In stdlib.h -.Ft long -.Fn atol "const char *nptr" -.Sh DESCRIPTION -The -.Fn atol -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt long integer -representation. -.Pp -It is equivalent to: -.Bd -literal -offset indent -strtol(nptr, (char **)NULL, 10); -.Ed -.Sh SEE ALSO -.Xr atof 3 , -.Xr atoi 3 , -.Xr atoll 3 , -.Xr strtod 3 , -.Xr strtol 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn atol -function conforms to -.St -isoC-99 . diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c deleted file mode 100644 index 1970804401..0000000000 --- a/src/lib/libc/stdlib/atol.c +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: atol.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/* - * Copyright (c) 1988 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -long -atol(const char *str) -{ - return(strtol(str, (char **)NULL, 10)); -} diff --git a/src/lib/libc/stdlib/atoll.3 b/src/lib/libc/stdlib/atoll.3 deleted file mode 100644 index c2b606dda9..0000000000 --- a/src/lib/libc/stdlib/atoll.3 +++ /dev/null @@ -1,68 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: atoll.3,v 1.9 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt ATOLL 3 -.Os -.Sh NAME -.Nm atoll -.Nd convert ASCII string to long long integer -.Sh SYNOPSIS -.In stdlib.h -.Ft long long -.Fn atoll "const char *nptr" -.Sh DESCRIPTION -The -.Fn atoll -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt long long integer -representation. -.Pp -It is equivalent to: -.Bd -literal -offset indent -strtoll(nptr, (char **)NULL, 10); -.Ed -.Sh SEE ALSO -.Xr atof 3 , -.Xr atoi 3 , -.Xr atol 3 , -.Xr strtod 3 , -.Xr strtol 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn atoll -function conforms to -.St -isoC-99 . diff --git a/src/lib/libc/stdlib/atoll.c b/src/lib/libc/stdlib/atoll.c deleted file mode 100644 index 32caf299e4..0000000000 --- a/src/lib/libc/stdlib/atoll.c +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: atoll.c,v 1.4 2021/10/24 10:05:23 jsg Exp $ */ -/* - * Copyright (c) 1988 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -long long -atoll(const char *str) -{ - return(strtoll(str, (char **)NULL, 10)); -} diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3 deleted file mode 100644 index 9c66eac0fe..0000000000 --- a/src/lib/libc/stdlib/bsearch.3 +++ /dev/null @@ -1,84 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993, 1994 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: bsearch.3,v 1.10 2015/11/30 17:03:05 jmc Exp $ -.\" -.Dd $Mdocdate: November 30 2015 $ -.Dt BSEARCH 3 -.Os -.Sh NAME -.Nm bsearch -.Nd binary search of a sorted table -.Sh SYNOPSIS -.In stdlib.h -.Ft void * -.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" -.Sh DESCRIPTION -The -.Fn bsearch -function searches an array of -.Fa nmemb -objects, the initial member of which is -pointed to by -.Fa base , -for a member that matches the object pointed to by -.Fa key . -The size of each member of the array is specified by -.Fa size . -.Pp -The contents of the array should be in ascending sorted order according -to the comparison function referenced by -.Fa compar . -The -.Fa compar -routine is expected to have two arguments which point to the -.Fa key -object and to an array member, in that order, and should return an integer -less than, equal to, or greater than zero if the -.Fa key -object is found, respectively, to be less than, to match, or be -greater than the array member. -.Sh RETURN VALUES -The -.Fn bsearch -function returns a pointer to a matching member of the array, or a null -pointer if no match is found. -If two members compare as equal, which member is matched is unspecified. -.Sh SEE ALSO -.Xr dbopen 3 , -.Xr lsearch 3 , -.Xr qsort 3 , -.Xr tsearch 3 -.Sh STANDARDS -The -.Fn bsearch -function conforms to -.St -ansiC . diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c deleted file mode 100644 index 6df44d6b4f..0000000000 --- a/src/lib/libc/stdlib/bsearch.c +++ /dev/null @@ -1,69 +0,0 @@ -/* $OpenBSD: bsearch.c,v 1.9 2021/12/02 20:58:01 cheloha Exp $ */ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -/* - * Perform a binary search. - * - * The code below is a bit sneaky. After a comparison fails, we - * divide the work in half by moving either left or right. If lim - * is odd, moving left simply involves halving lim: e.g., when lim - * is 5 we look at item 2, so we change lim to 2 so that we will - * look at items 0 & 1. If lim is even, the same applies. If lim - * is odd, moving right again involves halving lim, this time moving - * the base up one item past p: e.g., when lim is 5 we change base - * to item 3 and make lim 2 so that we will look at items 3 and 4. - * If lim is even, however, we have to shrink it by one before - * halving: e.g., when lim is 4, we still looked at item 2, so we - * have to make lim 3, then halve, obtaining 1, so that we will only - * look at item 3. - */ -void * -bsearch(const void *key, const void *base0, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)) -{ - const char *base = base0; - const void *p; - size_t lim; - int cmp; - - for (lim = nmemb; lim != 0; lim >>= 1) { - p = base + (lim >> 1) * size; - cmp = (*compar)(key, p); - if (cmp == 0) - return ((void *)p); - if (cmp > 0) { /* key > p: move right */ - base = (char *)p + size; - lim--; - } /* else move left */ - } - return (NULL); -} diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3 deleted file mode 100644 index b4b42ba8ec..0000000000 --- a/src/lib/libc/stdlib/div.3 +++ /dev/null @@ -1,63 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek. -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: div.3,v 1.13 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt DIV 3 -.Os -.Sh NAME -.Nm div -.Nd return quotient and remainder from division -.Sh SYNOPSIS -.In stdlib.h -.Ft div_t -.Fn div "int num" "int denom" -.Sh DESCRIPTION -The -.Fn div -function computes the value -.Fa num Ns / Ns Fa denom -and returns the quotient and remainder in a structure named -.Fa div_t -that contains two -.Vt int -members named -.Fa quot -and -.Fa rem . -.Sh SEE ALSO -.Xr imaxdiv 3 , -.Xr ldiv 3 , -.Xr lldiv 3 -.Sh STANDARDS -The -.Fn div -function conforms to -.St -ansiC . diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c deleted file mode 100644 index 5e6164f0bb..0000000000 --- a/src/lib/libc/stdlib/div.c +++ /dev/null @@ -1,72 +0,0 @@ -/* $OpenBSD: div.c,v 1.7 2022/12/27 17:10:06 jmc Exp $ */ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include /* div_t */ - -div_t -div(int num, int denom) -{ - div_t r; - - r.quot = num / denom; - r.rem = num % denom; - /* - * The ANSI standard says that |r.quot| <= |n/d|, where - * n/d is to be computed in infinite precision. In other - * words, we should always truncate the quotient towards - * 0, never -infinity. - * - * Machine division and remainder may work either way when - * one or both of n or d is negative. If only one is - * negative and r.quot has been truncated towards -inf, - * r.rem will have the same sign as denom and the opposite - * sign of num; if both are negative and r.quot has been - * truncated towards -inf, r.rem will be positive (will - * have the opposite sign of num). These are considered - * `wrong'. - * - * If both are num and denom are positive, r will always - * be positive. - * - * This all boils down to: - * if num >= 0, but r.rem < 0, we got the wrong answer. - * In that case, to get the right answer, add 1 to r.quot and - * subtract denom from r.rem. - */ - if (num >= 0 && r.rem < 0) { - r.quot++; - r.rem -= denom; - } - return (r); -} -DEF_STRONG(div); diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c deleted file mode 100644 index 429e4cf378..0000000000 --- a/src/lib/libc/stdlib/drand48.c +++ /dev/null @@ -1,30 +0,0 @@ -/* $OpenBSD: drand48.c,v 1.7 2015/09/14 13:30:17 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include -#include "rand48.h" - -double -drand48(void) -{ - if (__rand48_deterministic == 0) { - unsigned short rseed[3]; - - arc4random_buf(rseed, sizeof rseed); - return ldexp((double) rseed[0], -48) + - ldexp((double) rseed[1], -32) + - ldexp((double) rseed[2], -16); - } - return erand48(__rand48_seed); -} diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3 deleted file mode 100644 index f478f8e4b0..0000000000 --- a/src/lib/libc/stdlib/ecvt.3 +++ /dev/null @@ -1,166 +0,0 @@ -.\" $OpenBSD: ecvt.3,v 1.13 2019/01/25 00:19:25 millert Exp $ -.\" -.\" Copyright (c) 2002 Todd C. Miller -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.\" Sponsored in part by the Defense Advanced Research Projects -.\" Agency (DARPA) and Air Force Research Laboratory, Air Force -.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. -.\" -.Dd $Mdocdate: January 25 2019 $ -.Dt ECVT 3 -.Os -.Sh NAME -.Nm ecvt , -.Nm fcvt , -.Nm gcvt -.Nd convert double to ASCII string -.Sh SYNOPSIS -.In stdlib.h -.Ft char * -.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign" -.Ft char * -.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign" -.Ft char * -.Fn gcvt "double value" "int ndigit" "char *buf" -.Sh DESCRIPTION -.Bf -symbolic -These functions are provided for compatibility with legacy code. -New code should use the -.Xr snprintf 3 -function for improved safety and portability. -.Ef -.Pp -The -.Fn ecvt , -.Fn fcvt -and -.Fn gcvt -functions convert the double precision floating-point number -.Fa value -to a NUL-terminated -.Tn ASCII -string. -.Pp -The -.Fn ecvt -function converts -.Fa value -to a NUL-terminated string of exactly -.Fa ndigit -digits and returns a pointer to that string. -The result is padded with zeroes from left to right as needed. -There are no leading zeroes unless -.Fa value -itself is 0. -The least significant digit is rounded in an implementation-dependent manner. -The position of the decimal point relative to the beginning of the string -is stored in -.Fa decpt . -A negative value indicates that the decimal point is located -to the left of the returned digits (this occurs when there is no -whole number component to -.Fa value ) . -If -.Fa value -is zero, it is unspecified whether the integer pointed to by -.Fa decpt -will be 0 or 1. -The decimal point itself is not included in the returned string. -If the sign of the result is negative, the integer pointed to by -.Fa sign -is non-zero; otherwise, it is 0. -.Pp -If the converted value is out of range or is not representable, -the contents of the returned string are unspecified. -.Pp -The -.Fn fcvt -function is identical to -.Fn ecvt -with the exception that -.Fa ndigit -specifies the number of digits after the decimal point (zero-padded as -needed). -.Pp -The -.Fn gcvt -function converts -.Fa value -to a NUL-terminated string similar to the %g -.Xr printf 3 -format specifier and stores the result in -.Fa buf . -It produces -.Fa ndigit -significant digits similar to the %f -.Xr printf 3 -format specifier where possible. -If -.Fa ndigit -does allow sufficient precision, the result is stored in -exponential notation similar to the %e -.Xr printf 3 -format specifier. -If -.Fa value -is less than zero, -.Fa buf -will be prefixed with a minus sign. -A decimal point is included in the returned string if -.Fa value -is not a whole number. -Unlike the -.Fn ecvt -and -.Fn fcvt -functions, -.Fa buf -is not zero-padded. -.Sh RETURN VALUES -The -.Fn ecvt , -.Fn fcvt -and -.Fn gcvt -functions return a NUL-terminated string representation of -.Fa value . -.Sh SEE ALSO -.Xr printf 3 , -.Xr strtod 3 -.Sh STANDARDS -The -.Fn ecvt , -.Fn fcvt -and -.Fn gcvt -functions conform to -.St -p1003.1-2001 ; -as of -.St -p1003.1-2008 -they are no longer a part of the standard. -.Sh CAVEATS -The -.Fn ecvt -and -.Fn fcvt -functions return a pointer to internal storage space that will be -overwritten by subsequent calls to either function. -.Pp -The maximum possible precision of the return value is limited by the -precision of a double and may not be the same on all architectures. -.Pp -The -.Xr snprintf 3 -function is preferred over these functions for new code. diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c deleted file mode 100644 index a6b1d748fe..0000000000 --- a/src/lib/libc/stdlib/ecvt.c +++ /dev/null @@ -1,104 +0,0 @@ -/* $OpenBSD: ecvt.c,v 1.11 2019/01/25 00:19:25 millert Exp $ */ - -/* - * Copyright (c) 2002, 2006 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -#include -#include -#include -#include "gdtoa.h" - -static char *__cvt(double, int, int *, int *, int, int); - -static char * -__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad) -{ - static char *s; - char *p, *rve, c; - size_t siz; - - if (ndigit == 0) { - *sign = value < 0.0; - *decpt = 0; - return (""); - } - - free(s); - s = NULL; - - if (ndigit < 0) - siz = -ndigit + 1; - else - siz = ndigit + 1; - - - /* __dtoa() doesn't allocate space for 0 so we do it by hand */ - if (value == 0.0) { - *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */ - *sign = 0; - if ((rve = s = malloc(siz)) == NULL) - return(NULL); - *rve++ = '0'; - *rve = '\0'; - } else { - p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve); - if (p == NULL) - return (NULL); - if (*decpt == 9999) { - /* Infinity or Nan, convert to inf or nan like printf */ - *decpt = 0; - c = *p; - __freedtoa(p); - return(c == 'I' ? "inf" : "nan"); - } - /* Make a local copy and adjust rve to be in terms of s */ - if (pad && fmode) - siz += *decpt; - if ((s = malloc(siz)) == NULL) { - __freedtoa(p); - return(NULL); - } - (void) strlcpy(s, p, siz); - rve = s + (rve - p); - __freedtoa(p); - } - - /* Add trailing zeros */ - if (pad) { - siz -= rve - s; - while (--siz) - *rve++ = '0'; - *rve = '\0'; - } - - return(s); -} - -char * -ecvt(double value, int ndigit, int *decpt, int *sign) -{ - return(__cvt(value, ndigit, decpt, sign, 0, 1)); -} - -char * -fcvt(double value, int ndigit, int *decpt, int *sign) -{ - return(__cvt(value, ndigit, decpt, sign, 1, 1)); -} diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c deleted file mode 100644 index db0529f4a0..0000000000 --- a/src/lib/libc/stdlib/erand48.c +++ /dev/null @@ -1,26 +0,0 @@ -/* $OpenBSD: erand48.c,v 1.5 2015/09/14 13:30:17 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include -#include "rand48.h" - -double -erand48(unsigned short xseed[3]) -{ - __dorand48(xseed); - return ldexp((double) xseed[0], -48) + - ldexp((double) xseed[1], -32) + - ldexp((double) xseed[2], -16); -} -DEF_WEAK(erand48); diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3 deleted file mode 100644 index 22acade86c..0000000000 --- a/src/lib/libc/stdlib/exit.3 +++ /dev/null @@ -1,102 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: exit.3,v 1.18 2024/08/30 03:44:48 guenther Exp $ -.\" -.Dd $Mdocdate: August 30 2024 $ -.Dt EXIT 3 -.Os -.Sh NAME -.Nm exit -.Nd perform normal program termination -.Sh SYNOPSIS -.In stdlib.h -.Ft void -.Fn exit "int status" -.Sh DESCRIPTION -The -.Fn exit -function terminates a process. -.Pp -Before termination it performs the following functions in the -order listed: -.Bl -enum -offset indent -.It -Call the functions registered with the -.Xr atexit 3 -function, in the reverse order of their registration. -.It -Flush all open output streams. -.It -Close all open streams. -.It -Unlink all files created with the -.Xr tmpfile 3 -function. -.El -.Pp -Following this, -.Fn exit -calls -.Xr _exit 2 . -Note that typically -.Xr _exit 2 -only passes the lower 8 bits of -.Fa status -on to the parent, thus negative values have less meaning. -.Sh RETURN VALUES -The -.Fn exit -function never returns. -.Sh SEE ALSO -.Xr _exit 2 , -.Xr atexit 3 , -.Xr intro 3 , -.Xr sysexits 3 , -.Xr tmpfile 3 -.Sh STANDARDS -The -.Fn exit -function conforms to -.St -isoC-99 . -.Sh HISTORY -An -.Fn exit -function first appeared as a system call in -.At v1 . -It has accepted the -.Fa status -argument since -.At v2 . -In -.At v7 , -the bare system call was renamed to -.Xr _exit 2 . diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c deleted file mode 100644 index e93d4313e3..0000000000 --- a/src/lib/libc/stdlib/exit.c +++ /dev/null @@ -1,57 +0,0 @@ -/* $OpenBSD: exit.c,v 1.14 2017/08/12 22:59:52 guenther Exp $ */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include "atexit.h" - -/* - * This variable is zero until a process has created a thread. - * It is used to avoid calling locking functions in libc when they - * are not required. By default, libc is intended to be(come) - * thread-safe, but without a (significant) penalty to non-threaded - * processes. - */ -int __isthreaded = 0; - -/* - * Exit, flushing stdio buffers if necessary. - */ -void -exit(int status) -{ - /* - * Call functions registered by atexit() or _cxa_atexit() - * (including the stdio cleanup routine) and then _exit(). - */ - __cxa_finalize(NULL); - _exit(status); -} -DEF_STRONG(exit); diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c deleted file mode 100644 index d3ab1b0415..0000000000 --- a/src/lib/libc/stdlib/gcvt.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $OpenBSD: gcvt.c,v 1.15 2022/12/27 17:10:06 jmc Exp $ */ - -/* - * Copyright (c) 2002, 2003, 2006, 2010 - * Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -#include -#include -#include -#include -#include "gdtoa.h" - -#define DEFPREC 6 - -char * -gcvt(double value, int ndigit, char *buf) -{ - char *digits, *dst, *src; - int i, decpt, sign; - struct lconv *lconv; - - lconv = localeconv(); - if (ndigit <= 0) { - /* Match printf(3) behavior. */ - ndigit = ndigit ? DEFPREC : 1; - } - - digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); - if (digits == NULL) - return (NULL); - if (decpt == 9999) { - /* - * Infinity or NaN, convert to inf or nan with sign. - * We can't infer buffer size based on ndigit. - * We have to assume it is at least 5 chars. - */ - snprintf(buf, 5, "%s%s", sign ? "-" : "", - *digits == 'I' ? "inf" : "nan"); - __freedtoa(digits); - return (buf); - } - - dst = buf; - if (sign) - *dst++ = '-'; - - /* Match printf(3) behavior for exponential vs. regular formatting. */ - if (decpt <= -4 || decpt > ndigit) { - /* exponential format (e.g. 1.2345e+13) */ - if (--decpt < 0) { - sign = 1; - decpt = -decpt; - } else - sign = 0; - src = digits; - *dst++ = *src++; - if (*src != '\0') { - *dst++ = *lconv->decimal_point; - do { - *dst++ = *src++; - } while (*src != '\0'); - } - *dst++ = 'e'; - if (sign) - *dst++ = '-'; - else - *dst++ = '+'; - if (decpt < 10) { - *dst++ = '0'; - *dst++ = '0' + decpt; - *dst = '\0'; - } else { - /* XXX - optimize */ - for (sign = decpt, i = 0; (sign /= 10) != 0; i++) - continue; - dst[i + 1] = '\0'; - while (decpt != 0) { - dst[i--] = '0' + decpt % 10; - decpt /= 10; - } - } - } else { - /* standard format */ - for (i = 0, src = digits; i < decpt; i++) { - if (*src != '\0') - *dst++ = *src++; - else - *dst++ = '0'; - } - if (*src != '\0') { - if (src == digits) - *dst++ = '0'; /* zero before decimal point */ - *dst++ = *lconv->decimal_point; - while (decpt < 0) { - *dst++ = '0'; - decpt++; - } - for (i = decpt; digits[i] != '\0'; i++) { - *dst++ = digits[i]; - } - } - *dst = '\0'; - } - __freedtoa(digits); - return (buf); -} diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3 deleted file mode 100644 index 5a219a5c03..0000000000 --- a/src/lib/libc/stdlib/getenv.3 +++ /dev/null @@ -1,191 +0,0 @@ -.\" Copyright (c) 1988, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: getenv.3,v 1.23 2022/08/08 22:40:03 millert Exp $ -.\" -.Dd $Mdocdate: August 8 2022 $ -.Dt GETENV 3 -.Os -.Sh NAME -.Nm getenv , -.Nm putenv , -.Nm setenv , -.Nm unsetenv -.Nd environment variable functions -.Sh SYNOPSIS -.In stdlib.h -.Ft char * -.Fn getenv "const char *name" -.Ft int -.Fn setenv "const char *name" "const char *value" "int overwrite" -.Ft int -.Fn putenv "char *string" -.Ft int -.Fn unsetenv "const char *name" -.Sh DESCRIPTION -These functions set, unset, and fetch environment variables from the host -.Em environment list . -.Pp -The -.Fn getenv -function obtains the current value of the environment variable -.Fa name . -If the variable -.Fa name -is not in the current environment, a null pointer is returned. -.Pp -The -.Fn setenv -function inserts or resets the environment variable -.Fa name -in the current environment list. -If the variable -.Fa name -does not exist in the list, it is inserted with the given -.Fa value . -If the variable does exist, the argument -.Fa overwrite -is tested; if -.Fa overwrite -is zero, the variable is not reset, otherwise it is reset to the given -.Fa value . -.Pp -The -.Fn putenv -function takes an argument of the form -.Ar name Ns = Ns Ar value . -The memory pointed to by -.Ar string -becomes part of the environment and must not be deallocated by the caller. -If the variable already exists, it will be overwritten. -A common source of bugs is to pass a -.Ar string -argument that is a locally scoped string buffer. -This will result in corruption of the environment after leaving -the scope in which the variable is defined. -For this reason, the -.Fn setenv -function is preferred over -.Fn putenv . -.Pp -The -.Fn unsetenv -function deletes all instances of the variable name pointed to by -.Fa name -from the list. -.Sh RETURN VALUES -.Rv -std putenv setenv unsetenv -.Pp -The -.Fn getenv -function returns a pointer to the requested value, or -.Dv NULL -if it could not be found. -If -.Fn getenv -is successful, the string returned should be considered read-only. -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fn setenv -or -.Fn unsetenv -function was passed an empty -.Ar name -or a NULL pointer, or was passed a -.Ar name -containing an -.Sq = -character. -.Pp -The -.Fn putenv -function was passed a -.Ar string -that did not contain an -.Sq = -character, or was passed a -.Ar string -that started with the -.Sq = -character. -.It Bq Er ENOMEM -The -.Fn setenv -or -.Fn putenv -function failed because it was unable to allocate memory for the environment. -.El -.Sh SEE ALSO -.Xr csh 1 , -.Xr sh 1 , -.Xr execve 2 , -.Xr issetugid 2 , -.Xr environ 7 -.Sh STANDARDS -The -.Fn getenv -function conforms to -.St -ansiC . -The -.Fn putenv , -.Fn setenv , -and -.Fn unsetenv -functions conform to -.St -p1003.1-2008 . -.Sh HISTORY -The function -.Fn getenv -appeared in -.At v7 -and -.Bx 3 . -The functions -.Fn setenv -and -.Fn unsetenv -appeared in -.Bx 4.3 Tahoe . -The -.Fn putenv -function first appeared in -.At V.2 -and was reimplemented for -.Bx 4.3 Reno . -.Sh CAVEATS -Library code must be careful about using -.Fn getenv -to read untrusted environment variables in setuid programs. -The -.Fn issetugid -function is provided for this purpose. diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c deleted file mode 100644 index 068d70a999..0000000000 --- a/src/lib/libc/stdlib/getenv.c +++ /dev/null @@ -1,78 +0,0 @@ -/* $OpenBSD: getenv.c,v 1.13 2024/07/10 14:17:58 jca Exp $ */ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - - -/* - * __findenv -- - * Returns pointer to value associated with name, if any, else NULL. - * Starts searching within the environmental array at offset. - * Sets offset to be the offset of the name/value combination in the - * environmental array, for use by putenv(3), setenv(3) and unsetenv(3). - * Explicitly removes '=' in argument name. - */ -char * -__findenv(const char *name, int len, int *offset) -{ - int i; - const char *np; - char **p, *cp; - - if (name == NULL || environ == NULL) - return (NULL); - for (p = environ + *offset; (cp = *p) != NULL; ++p) { - for (np = name, i = len; i && *cp; i--) - if (*cp++ != *np++) - break; - if (i == 0 && *cp++ == '=') { - *offset = p - environ; - return (cp); - } - } - return (NULL); -} - -/* - * getenv -- - * Returns ptr to value associated with name, if any, else NULL. - */ -char * -getenv(const char *name) -{ - int offset = 0; - const char *np; - - for (np = name; *np && *np != '='; ++np) - ; - return (__findenv(name, (int)(np - name), &offset)); -} -DEF_STRONG(getenv); diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3 deleted file mode 100644 index c7e28ff91f..0000000000 --- a/src/lib/libc/stdlib/getopt.3 +++ /dev/null @@ -1,365 +0,0 @@ -.\" Copyright (c) 1988, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: getopt.3,v 1.48 2022/07/25 02:25:55 jsg Exp $ -.\" -.Dd $Mdocdate: July 25 2022 $ -.Dt GETOPT 3 -.Os -.Sh NAME -.Nm getopt -.Nd get option character from command line argument list -.Sh SYNOPSIS -.In unistd.h -.Vt extern char *optarg; -.Vt extern int opterr; -.Vt extern int optind; -.Vt extern int optopt; -.Vt extern int optreset; -.Ft int -.Fn getopt "int argc" "char * const *argv" "const char *optstring" -.Sh DESCRIPTION -The -.Fn getopt -function incrementally parses a command line argument list -.Fa argv -and returns the next -.Em known -option character. -An option character is -.Em known -if it has been specified in the string of accepted option characters, -.Fa optstring . -.Pp -The option string -.Fa optstring -may contain the following elements: individual characters, -characters followed by a colon, and characters followed by two colons. -A character followed by a single colon indicates that an argument -is to follow the option on the command line. -Two colons indicates that the argument is optional \- this is an -extension not covered by POSIX. -For example, an option string -.Qq x -recognizes an option -.Fl x , -and an option string -.Qq Li x: -recognizes an option and argument -.Fl x Ar argument . -It does not matter to -.Fn getopt -if a following argument has leading whitespace; except in the case where -the argument is optional, denoted with two colons, no leading whitespace -is permitted. -.Pp -On return from -.Fn getopt , -.Va optarg -points to an option argument, if it is anticipated, -and the variable -.Va optind -contains the index to the next -.Fa argv -argument for a subsequent call -to -.Fn getopt . -.Pp -The variables -.Va opterr -and -.Va optind -are both initialized to 1. -The -.Va optind -variable may be set to another value larger than 0 before a set of calls to -.Fn getopt -in order to skip over more or less -.Fa argv -entries. -An -.Va optind -value of 0 is reserved for compatibility with GNU -.Fn getopt . -.Pp -In order to use -.Fn getopt -to evaluate multiple sets of arguments, or to evaluate a single set of -arguments multiple times, -the variable -.Va optreset -must be set to 1 before the second and each additional set of calls to -.Fn getopt , -and the variable -.Va optind -must be reinitialized. -.Pp -The -.Fn getopt -function returns \-1 when the argument list is exhausted. -The interpretation of options in the argument list may be cancelled -by the option -.Ql -- -(double dash) which causes -.Fn getopt -to signal the end of argument processing and return \-1. -When all options have been processed (i.e., up to the first non-option -argument), -.Fn getopt -returns \-1. -.Sh RETURN VALUES -The -.Fn getopt -function returns the next known option character in -.Fa optstring . -If -.Fn getopt -encounters a character not found in -.Fa optstring -or if it detects a missing option argument, -it returns -.Sq \&? -(question mark). -If -.Fa optstring -has a leading -.Sq \&: -then a missing option argument causes -.Sq \&: -to be returned instead of -.Sq \&? . -In either case, the variable -.Va optopt -is set to the character that caused the error. -The -.Fn getopt -function returns \-1 when the argument list is exhausted. -.Sh EXAMPLES -The following code accepts the options -.Fl b -and -.Fl f Ar argument -and adjusts -.Va argc -and -.Va argv -after option argument processing has completed. -.Bd -literal -offset indent -int bflag, ch, fd; - -bflag = 0; -while ((ch = getopt(argc, argv, "bf:")) != -1) { - switch (ch) { - case 'b': - bflag = 1; - break; - case 'f': - if ((fd = open(optarg, O_RDONLY)) == -1) - err(1, "%s", optarg); - break; - default: - usage(); - } -} -argc -= optind; -argv += optind; -.Ed -.Sh DIAGNOSTICS -If the -.Fn getopt -function encounters a character not found in the string -.Fa optstring -or detects -a missing option argument, it writes an error message to -.Em stderr -and returns -.Ql \&? . -Setting -.Va opterr -to a zero will disable these error messages. -If -.Fa optstring -has a leading -.Ql \&: -then a missing option argument causes a -.Ql \&: -to be returned in addition to suppressing any error messages. -.Pp -Option arguments are allowed to begin with -.Ql - ; -this is reasonable but reduces the amount of error checking possible. -.Sh SEE ALSO -.Xr getopt 1 , -.Xr getopt_long 3 , -.Xr getsubopt 3 -.Sh STANDARDS -The -.Fn getopt -function implements a superset of the functionality specified by -.St -p1003.1 . -.Pp -The following extensions are supported: -.Bl -bullet -.It -The -.Va optreset -variable was added to make it possible to call the -.Fn getopt -function multiple times. -.It -If the -.Va optind -variable is set to 0, -.Fn getopt -will behave as if the -.Va optreset -variable has been set. -This is for compatibility with -.Tn GNU -.Fn getopt . -New code should use -.Va optreset -instead. -.It -If the first character of -.Fa optstring -is a plus sign -.Pq Ql + , -it will be ignored. -This is for compatibility with -.Tn GNU -.Fn getopt . -.It -If the first character of -.Fa optstring -is a dash -.Pq Ql - , -non-options will be returned as arguments to the option character -.Ql \e1 . -This is for compatibility with -.Tn GNU -.Fn getopt . -.It -A single dash -.Pq Ql - -may be specified as a character in -.Fa optstring , -however it should -.Em never -have an argument associated with it. -This allows -.Fn getopt -to be used with programs that expect -.Ql - -as an option flag. -This practice is wrong, and should not be used in any current development. -It is provided for backward compatibility -.Em only . -Care should be taken not to use -.Ql - -as the first character in -.Fa optstring -to avoid a semantic conflict with -.Tn GNU -.Fn getopt -semantics (see above). -By default, a single dash causes -.Fn getopt -to return \-1. -.El -.Pp -Historic -.Bx -versions of -.Fn getopt -set -.Fa optopt -to the last option character processed. -However, this conflicts with -.St -p1003.1 -which stipulates that -.Fa optopt -be set to the last character that caused an error. -.Sh HISTORY -The -.Fn getopt -function first appeared in -.At III -and was reimplemented for -.Bx 4.3 . -.Sh BUGS -The -.Fn getopt -function was once specified to return -.Dv EOF -instead of \-1. -This was changed by -.St -p1003.2-92 -to decouple -.Fn getopt -from -.In stdio.h . -.Pp -It is possible to handle digits as option letters. -This allows -.Fn getopt -to be used with programs that expect a number -.Pq Dq Li \-3 -as an option. -This practice is wrong, and should not be used in any current development. -It is provided for backward compatibility -.Em only . -The following code fragment works in most cases and can handle mixed -number and letter arguments. -.Bd -literal -offset indent -int aflag = 0, bflag = 0, ch, lastch = '\e0'; -int length = -1, newarg = 1, prevoptind = 1; - -while ((ch = getopt(argc, argv, "0123456789ab")) != -1) { - switch (ch) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (newarg || !isdigit(lastch)) - length = 0; - else if (length > INT_MAX / 10) - usage(); - length = (length * 10) + (ch - '0'); - break; - case 'a': - aflag = 1; - break; - case 'b': - bflag = 1; - break; - default: - usage(); - } - lastch = ch; - newarg = optind != prevoptind; - prevoptind = optind; -} -.Ed diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3 deleted file mode 100644 index 88594cbf9c..0000000000 --- a/src/lib/libc/stdlib/getopt_long.3 +++ /dev/null @@ -1,460 +0,0 @@ -.\" $OpenBSD: getopt_long.3,v 1.25 2022/09/11 06:38:11 jmc Exp $ -.\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $ -.\" -.\" Copyright (c) 1988, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt GETOPT_LONG 3 -.Os -.Sh NAME -.Nm getopt_long , -.Nm getopt_long_only -.Nd get long options from command line argument list -.Sh SYNOPSIS -.In getopt.h -.Vt extern char *optarg; -.Vt extern int optind; -.Vt extern int optopt; -.Vt extern int opterr; -.Vt extern int optreset; -.Ft int -.Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" -.Ft int -.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" -.Sh DESCRIPTION -The -.Fn getopt_long -function is similar to -.Xr getopt 3 -but it accepts options in two forms: words and characters. -The -.Fn getopt_long -function provides a superset of the functionality of -.Xr getopt 3 . -.Fn getopt_long -can be used in two ways. -In the first way, every long option understood by the program has a -corresponding short option, and the option structure is only used to -translate from long options to short options. -When used in this fashion, -.Fn getopt_long -behaves identically to -.Xr getopt 3 . -This is a good way to add long option processing to an existing program -with the minimum of rewriting. -.Pp -In the second mechanism, a long option sets a flag in the -.Fa option -structure passed, or will store a pointer to the command line argument -in the -.Fa option -structure passed to it for options that take arguments. -Additionally, the long option's argument may be specified as a single -argument with an equal sign, e.g. -.Bd -literal -offset indent -$ myprogram --myoption=somevalue -.Ed -.Pp -When a long option is processed, the call to -.Fn getopt_long -will return 0. -For this reason, long option processing without -shortcuts is not backwards compatible with -.Xr getopt 3 . -.Pp -It is possible to combine these methods, providing for long options -processing with short option equivalents for some options. -Less frequently used options would be processed as long options only. -.Pp -Abbreviated long option names are accepted when -.Fn getopt_long -processes long options if the abbreviation is unique. -An exact match is always preferred for a defined long option. -.Pp -By default, -.Fn getopt_long -permutes -.Ar argv -such that all option arguments are evaluated before any non-options arguments. -If the first character of -.Fa optstring -is a plus sign -.Pq Ql + -or if the environment variable -.Ev POSIXLY_CORRECT -is set, then -.Ar argv -is processed in order and option processing stops as soon as the first -non-option argument is encountered. -.Pp -The -.Fn getopt_long -call requires an array to be initialized describing the long -options. -Each element of the array is a structure: -.Bd -literal -offset indent -struct option { - char *name; - int has_arg; - int *flag; - int val; -}; -.Ed -.Pp -The -.Fa name -field should contain the option name without the leading double dash. -.Pp -The -.Fa has_arg -field should be one of: -.Pp -.Bl -tag -width "optional_argument" -compact -offset indent -.It Dv no_argument -no argument to the option is expected. -.It Dv required_argument -an argument to the option is required. -.It Dv optional_argument -an argument to the option may be presented. -.El -.Pp -If -.Fa flag -is not -.Dv NULL , -then the integer pointed to by it will be set to the value in the -.Fa val -field. -If the -.Fa flag -field is -.Dv NULL , -then the -.Fa val -field will be returned. -Setting -.Fa flag -to -.Dv NULL -and setting -.Fa val -to the corresponding short option will make this function act just -like -.Xr getopt 3 . -.Pp -If the -.Fa longindex -argument is not -.Dv NULL , -then the integer pointed to by it will be set to the index of the long -option relative to -.Fa longopts . -.Pp -The last element of the -.Fa longopts -array has to be filled with zeroes. -.Pp -The -.Fn getopt_long_only -function behaves identically to -.Fn getopt_long -with the exception that long options may start with -.Sq - -in addition to -.Sq -- . -If an option starting with -.Sq - -does not match a long option but does match a single-character option, -the single-character option is returned. -.Sh RETURN VALUES -If the -.Fa flag -field in -.Vt struct option -is -.Dv NULL , -.Fn getopt_long -and -.Fn getopt_long_only -return the value specified in the -.Fa val -field, which is usually just the corresponding short option. -If -.Fa flag -is not -.Dv NULL , -these functions return 0 and store -.Fa val -in the location pointed to by -.Fa flag . -These functions return -.Sq \&: -if there was a missing option argument, -.Sq \&? -if the user specified an unknown or ambiguous option, and -\-1 when the argument list has been exhausted. -.Sh IMPLEMENTATION DIFFERENCES -This section describes differences to the GNU implementation -found in glibc-2.1.3: -.Bl -bullet -.It -handling of -.Ql - -within the option string (not the first character): -.Bl -tag -width "OpenBSD" -.It GNU -treats a -.Ql - -on the command line as a non-argument. -.It OpenBSD -a -.Ql - -within the option string matches a -.Ql - -(single dash) on the command line. -This functionality is provided for backward compatibility with -programs, such as -.Xr su 1 , -that use -.Ql - -as an option flag. -This practice is wrong, and should not be used in any current development. -.El -.It -handling of -.Ql :: -in the option string in the presence of -.Ev POSIXLY_CORRECT : -.Bl -tag -width "OpenBSD" -.It Both -GNU and -.Ox -ignore -.Ev POSIXLY_CORRECT -here and take -.Ql :: -to mean the preceding option takes an optional argument. -.El -.It -return value in case of missing argument if first character -(after -.Ql + -or -.Ql - ) -in the option string is not -.Ql \&: : -.Bl -tag -width "OpenBSD" -.It GNU -returns -.Ql \&? -.It OpenBSD -returns -.Ql \&: -(since -.Ox Ns 's -.Xr getopt 3 -does). -.El -.It -handling of -.Ql --a -in -.Xr getopt 3 : -.Bl -tag -width "OpenBSD" -.It GNU -parses this as option -.Ql - , -option -.Ql a . -.It OpenBSD -parses this as -.Ql -- , -and returns \-1 (ignoring the -.Ql a ) -(because the original -.Fn getopt -did.) -.El -.It -setting of -.Va optopt -for long options with -.Va flag -.No non- Ns Dv NULL : -.Bl -tag -width "OpenBSD" -.It GNU -sets -.Va optopt -to -.Va val . -.It OpenBSD -sets -.Va optopt -to 0 (since -.Va val -would never be returned). -.El -.It -handling of -.Ql -W -with -.Ql W; -in the option string in -.Xr getopt 3 -(not -.Fn getopt_long ) : -.Bl -tag -width "OpenBSD" -.It GNU -causes a segmentation fault. -.It OpenBSD -no special handling is done; -.Ql W; -is interpreted as two separate options, neither of which take an argument. -.El -.It -setting of -.Va optarg -for long options without an argument that are invoked via -.Ql -W -(with -.Ql W; -in the option string): -.Bl -tag -width "OpenBSD" -.It GNU -sets -.Va optarg -to the option name (the argument of -.Ql -W ) . -.It OpenBSD -sets -.Va optarg -to -.Dv NULL -(the argument of the long option). -.El -.It -handling of -.Ql -W -with an argument that is not (a prefix to) a known long option -(with -.Ql W; -in the option string): -.Bl -tag -width "OpenBSD" -.It GNU -returns -.Ql -W -with -.Va optarg -set to the unknown option. -.It OpenBSD -treats this as an error (unknown option) and returns -.Ql \&? -with -.Va optopt -set to 0 and -.Va optarg -set to -.Dv NULL -(as GNU's man page documents). -.El -.It -The error messages are different. -.It -.Ox -does not permute the argument vector at the same points in -the calling sequence as GNU does. -The aspects normally used by the caller -(ordering after \-1 is returned, value of -.Va optind -relative to current positions) are the same, though. -(We do fewer variable swaps.) -.El -.Sh ENVIRONMENT -.Bl -tag -width Ev -.It Ev POSIXLY_CORRECT -If set, option processing stops when the first non-option is found and -a leading -.Sq + -in the -.Ar optstring -is ignored. -.El -.Sh EXAMPLES -.Bd -literal -int bflag, ch, fd; -int daggerset; - -/* options descriptor */ -static struct option longopts[] = { - { "buffy", no_argument, NULL, 'b' }, - { "fluoride", required_argument, NULL, 'f' }, - { "daggerset", no_argument, &daggerset, 1 }, - { NULL, 0, NULL, 0 } -}; - -bflag = 0; -while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) - switch (ch) { - case 'b': - bflag = 1; - break; - case 'f': - if ((fd = open(optarg, O_RDONLY)) == -1) - err(1, "unable to open %s", optarg); - break; - case 0: - if (daggerset) - fprintf(stderr, "Buffy will use her dagger to " - "apply fluoride to dracula's teeth\en"); - break; - default: - usage(); - } -argc -= optind; -argv += optind; -.Ed -.Sh SEE ALSO -.Xr getopt 3 -.Sh HISTORY -The -.Fn getopt_long -and -.Fn getopt_long_only -functions first appeared in GNU libiberty. -This implementation first appeared in -.Ox 3.3 . -.Sh BUGS -The -.Ar argv -argument is not really -.Dv const -as its elements may be permuted (unless -.Ev POSIXLY_CORRECT -is set). diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c deleted file mode 100644 index 0de50457c2..0000000000 --- a/src/lib/libc/stdlib/getopt_long.c +++ /dev/null @@ -1,513 +0,0 @@ -/* $OpenBSD: getopt_long.c,v 1.32 2020/05/27 22:25:09 schwarze Exp $ */ -/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ - -/* - * Copyright (c) 2002 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#if 0 -/* DEF_* only work on initialized (non-COMMON) variables */ -DEF_WEAK(opterr); -DEF_WEAK(optind); -DEF_WEAK(optopt); -#endif - -#define PRINT_ERROR ((opterr) && (*options != ':')) - -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#define EMSG "" - -static int getopt_internal(int, char * const *, const char *, - const struct option *, int *, int); -static int parse_long_options(char * const *, const char *, - const struct option *, int *, int, int); -static int gcd(int, int); -static void permute_args(int, int, int, char * const *); - -static char *place = EMSG; /* option letter processing */ - -/* XXX: set optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c"; -static const char recargstring[] = "option requires an argument -- %s"; -static const char ambig[] = "ambiguous option -- %.*s"; -static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; -static const char illoptstring[] = "unknown option -- %s"; - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return (b); -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - ((char **)nargv)[pos] = nargv[cstart]; - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * parse_long_options -- - * Parse long options in argc/argv argument vector. - * Returns -1 if short_too is set and the option does not match long_options. - */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too, int flags) -{ - char *current_argv, *has_equal; - size_t current_argv_len; - int i, match, exact_match, second_partial_match; - - current_argv = place; - match = -1; - exact_match = 0; - second_partial_match = 0; - - optind++; - - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - exact_match = 1; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; - - if (match == -1) /* first partial match */ - match = i; - else if ((flags & FLAG_LONGONLY) || - long_options[i].has_arg != long_options[match].has_arg || - long_options[i].flag != long_options[match].flag || - long_options[i].val != long_options[match].val) - second_partial_match = 1; - } - if (!exact_match && second_partial_match) { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, current_argv); - optopt = 0; - return (BADCH); - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return (BADARG); - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - warnx(recargstring, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --optind; - return (-1); - } - if (PRINT_ERROR) - warnx(illoptstring, current_argv); - optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ - char *oli; /* option letter list index */ - int optchar, short_too; - static int posixly_correct = -1; - - if (options == NULL) - return (-1); - - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; - - /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - */ - if (posixly_correct == -1 || optreset) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (*options == '-') - flags |= FLAG_ALLARGS; - else if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - if (*options == '+' || *options == '-') - options++; - - optarg = NULL; - if (optreset) - nonopt_start = nonopt_end = -1; -start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[optind]) != '-' || - (place[1] == '\0' && strchr(options, '-') == NULL)) { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; - - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } - - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ - if (long_options != NULL && place != nargv[optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - if (*place == '-') - place++; /* --foo long option */ - else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ - - optchar = parse_long_options(nargv, options, long_options, - idx, short_too, flags); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } - - if ((optchar = (int)*place++) == (int)':' || - (oli = strchr(options, optchar)) == NULL) { - if (!*place) - ++optind; - if (PRINT_ERROR) - warnx(illoptchar, optchar); - optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[optind]; - optchar = parse_long_options(nargv, options, long_options, - idx, 0, flags); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else - optarg = nargv[optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return (optchar); -} - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ - - /* - * We don't pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ - return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); -} - -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE)); -} - -/* - * getopt_long_only -- - * Parse argc/argv argument vector. - */ -int -getopt_long_only(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY)); -} diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3 deleted file mode 100644 index fee3840bef..0000000000 --- a/src/lib/libc/stdlib/getsubopt.3 +++ /dev/null @@ -1,162 +0,0 @@ -.\" $OpenBSD: getsubopt.3,v 1.16 2022/08/04 06:20:24 jsg Exp $ -.\" -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93 -.\" -.Dd $Mdocdate: August 4 2022 $ -.Dt GETSUBOPT 3 -.Os -.Sh NAME -.Nm getsubopt -.Nd get sub options from an argument -.Sh SYNOPSIS -.In stdlib.h -.Vt extern char *suboptarg; -.Ft int -.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep" -.Sh DESCRIPTION -The -.Fn getsubopt -function parses a string containing tokens delimited by one or more -tab, space, or comma -.Pq Ql \&, -characters. -It is intended for use in parsing groups of option arguments provided -as part of a utility command line. -.Pp -The argument -.Fa optionp -is a pointer to a pointer to the string. -The argument -.Fa tokens -is a pointer to a -.Dv NULL Ns -terminated -array of pointers to strings. -.Pp -The -.Fn getsubopt -function returns the zero-based offset of the pointer in the -.Fa tokens -array referencing a string which matches the first token -in the string, or \-1 if the string contains no tokens or -.Fa tokens -does not contain a matching string. -.Pp -If the token is of the form -.Ar name Ns = Ns Ar value , -the location referenced by -.Fa valuep -will be set to point to the start of the -.Dq value -portion of the token. -.Pp -On return from -.Fn getsubopt , -.Fa optionp -will be set to point to the start of the next token in the string, -or the NUL at the end of the string if no more tokens are present. -The comma, space, or tab character ending the token just parsed, -and the equal sign separating name and value if any, are replaced -with NUL bytes in the original -.Pf * Fa optionp -input string. -The external variable -.Fa suboptarg -will be set to point to the start of the current token, or -.Dv NULL -if no tokens were present. -The argument -.Fa valuep -will be set to point to the value portion of the token, or -.Dv NULL -if no value portion was present. -.Sh EXAMPLES -.Bd -literal -char *tokens[] = { - #define ONE 0 - "one", - #define TWO 1 - "two", - NULL -}; - -\&... - -extern char *optarg, *suboptarg; -char *options, *value; - -while ((ch = getopt(argc, argv, "ab:")) != -1) { - switch (ch) { - case 'a': - /* process "a" option */ - break; - case 'b': - options = optarg; - while (*options) { - switch (getsubopt(&options, tokens, &value)) { - case ONE: - /* process "one" sub option */ - break; - case TWO: - /* process "two" sub option */ - if (!value) - error("no value for two"); - i = atoi(value); - break; - case -1: - if (suboptarg) - error("illegal sub option %s", - suboptarg); - else - error("missing sub option"); - break; - } - } - break; - } -} -.Ed -.Sh SEE ALSO -.Xr getopt 3 , -.Xr strsep 3 -.Sh STANDARDS -The -.Fn getsubopt -function conforms to -.St -p1003.1-2008 . -.Pp -Allowing space and tab characters to separate tokens -and the external variable -.Va suboptarg -are extensions to that standard. -.Sh HISTORY -The -.Fn getsubopt -function first appeared in -.Bx 4.3 Net/2 . diff --git a/src/lib/libc/stdlib/getsubopt.c b/src/lib/libc/stdlib/getsubopt.c deleted file mode 100644 index 735c85ba8a..0000000000 --- a/src/lib/libc/stdlib/getsubopt.c +++ /dev/null @@ -1,92 +0,0 @@ -/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -/* - * The SVID interface to getsubopt provides no way of figuring out which - * part of the suboptions list wasn't matched. This makes error messages - * tricky... The extern variable suboptarg is a pointer to the token - * which didn't match. - */ -char *suboptarg; - -int -getsubopt(char **optionp, char * const *tokens, char **valuep) -{ - int cnt; - char *p; - - suboptarg = *valuep = NULL; - - if (!optionp || !*optionp) - return(-1); - - /* skip leading white-space, commas */ - for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); - - if (!*p) { - *optionp = p; - return(-1); - } - - /* save the start of the token, and skip the rest of the token. */ - for (suboptarg = p; - *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';); - - if (*p) { - /* - * If there's an equals sign, set the value pointer, and - * skip over the value part of the token. Terminate the - * token. - */ - if (*p == '=') { - *p = '\0'; - for (*valuep = ++p; - *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); - if (*p) - *p++ = '\0'; - } else - *p++ = '\0'; - /* Skip any whitespace or commas after this token. */ - for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); - } - - /* set optionp for next round. */ - *optionp = p; - - for (cnt = 0; *tokens; ++tokens, ++cnt) - if (!strcmp(suboptarg, *tokens)) - return(cnt); - return(-1); -} diff --git a/src/lib/libc/stdlib/hcreate.3 b/src/lib/libc/stdlib/hcreate.3 deleted file mode 100644 index 90bde1995f..0000000000 --- a/src/lib/libc/stdlib/hcreate.3 +++ /dev/null @@ -1,234 +0,0 @@ -.\" $OpenBSD: hcreate.3,v 1.8 2018/01/30 11:37:58 jmc Exp $ -.\" $NetBSD: hcreate.3,v 1.8 2010/05/01 06:18:03 jruoho Exp $ -.\" -.\" Copyright (c) 1999 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by Klaus Klein. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd $Mdocdate: January 30 2018 $ -.Dt HCREATE 3 -.Os -.Sh NAME -.Nm hcreate , -.Nm hdestroy , -.Nm hsearch -.Nd manage hash search table -.Sh SYNOPSIS -.In search.h -.Ft int -.Fn hcreate "size_t nel" -.Ft void -.Fn hdestroy "void" -.Ft ENTRY * -.Fn hsearch "ENTRY item" "ACTION action" -.Sh DESCRIPTION -The -.Fn hcreate , -.Fn hdestroy , -and -.Fn hsearch -functions manage hash search tables. -.Pp -The -.Fn hcreate -function allocates and initializes the table. -The -.Fa nel -argument specifies an estimate of the maximum number of entries to be held -by the table. -Unless further memory allocation fails, supplying an insufficient -.Fa nel -value will not result in functional harm, although a performance degradation -may occur. -Initialization using the -.Fn hcreate -function is mandatory prior to any access operations using -.Fn hsearch . -.Pp -The -.Fn hdestroy -function destroys a table previously created using -.Fn hcreate . -After a call to -.Fn hdestroy , -the data can no longer be accessed. -.Pp -The -.Fn hsearch -function is used to search the hash table. -It returns a pointer into the -hash table indicating the address of an item. -The -.Fa item -argument is of type -.Vt ENTRY , -defined in the -.In search.h -header. -This is a structure type that contains two pointers: -.Pp -.Bl -tag -compact -offset indent -width "void *data " -.It Fa char *key -comparison key -.It Fa void *data -pointer to data associated with -.Fa key -.El -.Pp -The key comparison function used by -.Fn hsearch -is -.Xr strcmp 3 . -.Pp -The -.Fa action -argument is of type -.Vt ACTION , -an enumeration type which defines the following values: -.Bl -tag -offset indent -width ENTERXX -.It Dv ENTER -Insert -.Fa item -into the hash table. -If an existing item with the same key is found, it is not replaced. -Note that the -.Fa key -and -.Fa data -elements of -.Fa item -are used directly by the new table entry. -The storage for the -key must not be modified during the lifetime of the hash table. -.It Dv FIND -Search the hash table without inserting -.Fa item . -.El -.Pp -Note that the comparison -.Fa key -must be allocated using -.Xr malloc 3 -or -.Xr calloc 3 -if action is -.Dv ENTER -and -.Fn hdestroy -will be called. -This is because -.Fn hdestroy -will call -.Xr free 3 -for each comparison -.Fa key -(but not -.Fa data ) . -Typically the comparison -.Fa key -is allocated by using -.Xr strdup 3 . -.Sh RETURN VALUES -If successful, the -.Fn hcreate -function returns a non-zero value. -Otherwise, a value of 0 is returned and -.Va errno -is set to indicate the error. -.Pp -If successful, the -.Fn hsearch -function returns a pointer to a hash table entry matching -the provided key. -If the action is -.Dv FIND -and the item was not found, or if the action is -.Dv ENTER -and the insertion failed, -.Dv NULL -is returned and -.Va errno -is set to indicate the error. -If the action is -.Dv ENTER -and an entry already existed in the table matching the given -key, the existing entry is returned and is not replaced. -.Sh ERRORS -The -.Fn hcreate -and -.Fn hsearch -functions will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Insufficient memory is available. -.El -.Sh SEE ALSO -.Xr bsearch 3 , -.Xr lsearch 3 , -.Xr malloc 3 , -.Xr strcmp 3 -.Sh STANDARDS -The -.Fn hcreate , -.Fn hdestroy -and -.Fn hsearch -functions conform to -.St -xpg4.2 . -.Sh HISTORY -The -.Fn hcreate , -.Fn hdestroy -and -.Fn hsearch -functions first appeared in -.At V . -.Sh CAVEATS -At least the following limitations can be mentioned: -.Bl -bullet -.It -The interface permits the use of only one hash table at a time. -.It -Individual hash table entries can be added, but not deleted. -.It -The standard is indecipherable about the -internal memory usage of the functions, -mentioning only that -.Do -.Fn hcreate -and -.Fn hsearch -functions may use -.Fn malloc -to allocate space -.Dc . -This limits the portability of the functions, -given that other implementations may not -.Xr free 3 -the buffer pointed by -.Fa key . -.El diff --git a/src/lib/libc/stdlib/hcreate.c b/src/lib/libc/stdlib/hcreate.c deleted file mode 100644 index b31108a90e..0000000000 --- a/src/lib/libc/stdlib/hcreate.c +++ /dev/null @@ -1,189 +0,0 @@ -/* $OpenBSD: hcreate.c,v 1.7 2016/05/29 20:47:49 guenther Exp $ */ -/* $NetBSD: hcreate.c,v 1.5 2004/04/23 02:48:12 simonb Exp $ */ - -/* - * Copyright (c) 2001 Christopher G. Demetriou - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the - * NetBSD Project. See http://www.NetBSD.org/ for - * information about NetBSD. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * <> - */ - -/* - * hcreate() / hsearch() / hdestroy() - * - * SysV/XPG4 hash table functions. - * - * Implementation done based on NetBSD manual page and Solaris manual page, - * plus my own personal experience about how they're supposed to work. - * - * I tried to look at Knuth (as cited by the Solaris manual page), but - * nobody had a copy in the office, so... - */ - -#include -#include -#include -#include -#include -#include -#include - -#include /* for __default_hash */ - -#ifndef _DIAGASSERT -#define _DIAGASSERT(x) -#endif - -/* - * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit - * ptr machine) without adjusting MAX_BUCKETS_LG2 below. - */ -struct internal_entry { - SLIST_ENTRY(internal_entry) link; - ENTRY ent; -}; -SLIST_HEAD(internal_head, internal_entry); - -#define MIN_BUCKETS_LG2 4 -#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2) - -/* - * max * sizeof internal_entry must fit into size_t. - * assumes internal_entry is <= 32 (2^5) bytes. - */ -#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5) -#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2) - -static struct internal_head *htable; -static size_t htablesize; - -int -hcreate(size_t nel) -{ - size_t idx; - unsigned int p2; - - /* Make sure this isn't called when a table already exists. */ - _DIAGASSERT(htable == NULL); - if (htable != NULL) { - errno = EINVAL; - return 0; - } - - /* If nel is too small, make it min sized. */ - if (nel < MIN_BUCKETS) - nel = MIN_BUCKETS; - - /* If it's too large, cap it. */ - if (nel > MAX_BUCKETS) - nel = MAX_BUCKETS; - - /* If it's is not a power of two in size, round up. */ - if ((nel & (nel - 1)) != 0) { - for (p2 = 0; nel != 0; p2++) - nel >>= 1; - _DIAGASSERT(p2 <= MAX_BUCKETS_LG2); - nel = 1 << p2; - } - - /* Allocate the table. */ - htablesize = nel; - htable = calloc(htablesize, sizeof htable[0]); - if (htable == NULL) { - errno = ENOMEM; - return 0; - } - - /* Initialize it. */ - for (idx = 0; idx < htablesize; idx++) - SLIST_INIT(&htable[idx]); - - return 1; -} - -void -hdestroy(void) -{ - struct internal_entry *ie; - size_t idx; - - _DIAGASSERT(htable != NULL); - if (htable == NULL) - return; - - for (idx = 0; idx < htablesize; idx++) { - while (!SLIST_EMPTY(&htable[idx])) { - ie = SLIST_FIRST(&htable[idx]); - SLIST_REMOVE_HEAD(&htable[idx], link); - free(ie->ent.key); - free(ie); - } - } - free(htable); - htable = NULL; -} - -ENTRY * -hsearch(ENTRY item, ACTION action) -{ - struct internal_head *head; - struct internal_entry *ie; - uint32_t hashval; - size_t len; - - _DIAGASSERT(htable != NULL); - _DIAGASSERT(item.key != NULL); - _DIAGASSERT(action == ENTER || action == FIND); - - len = strlen(item.key); - hashval = __default_hash(item.key, len); - - head = &htable[hashval & (htablesize - 1)]; - ie = SLIST_FIRST(head); - while (ie != NULL) { - if (strcmp(ie->ent.key, item.key) == 0) - break; - ie = SLIST_NEXT(ie, link); - } - - if (ie != NULL) - return &ie->ent; - else if (action == FIND) - return NULL; - - ie = malloc(sizeof *ie); - if (ie == NULL) - return NULL; - ie->ent.key = item.key; - ie->ent.data = item.data; - - SLIST_INSERT_HEAD(head, ie, link); - return &ie->ent; -} diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c deleted file mode 100644 index f1db2205b0..0000000000 --- a/src/lib/libc/stdlib/heapsort.c +++ /dev/null @@ -1,175 +0,0 @@ -/* $OpenBSD: heapsort.c,v 1.11 2017/05/20 12:48:56 millert Exp $ */ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -/* - * Swap two areas of size number of bytes. Although qsort(3) permits random - * blocks of memory to be sorted, sorting pointers is almost certainly the - * common case (and, were it not, could easily be made so). Regardless, it - * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer - * arithmetic gets lost in the time required for comparison function calls. - */ -#define SWAP(a, b, count, size, tmp) { \ - count = size; \ - do { \ - tmp = *a; \ - *a++ = *b; \ - *b++ = tmp; \ - } while (--count); \ -} - -/* Copy one block of size size to another. */ -#define COPY(a, b, count, size, tmp1, tmp2) { \ - count = size; \ - tmp1 = a; \ - tmp2 = b; \ - do { \ - *tmp1++ = *tmp2++; \ - } while (--count); \ -} - -/* - * Build the list into a heap, where a heap is defined such that for - * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. - * - * There are two cases. If j == nmemb, select largest of Ki and Kj. If - * j < nmemb, select largest of Ki, Kj and Kj+1. - */ -#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ - for (par_i = initval; (child_i = par_i * 2) <= nmemb; \ - par_i = child_i) { \ - child = base + child_i * size; \ - if (child_i < nmemb && compar(child, child + size) < 0) { \ - child += size; \ - ++child_i; \ - } \ - par = base + par_i * size; \ - if (compar(child, par) <= 0) \ - break; \ - SWAP(par, child, count, size, tmp); \ - } \ -} - -/* - * Select the top of the heap and 'heapify'. Since by far the most expensive - * action is the call to the compar function, a considerable optimization - * in the average case can be achieved due to the fact that k, the displaced - * element, is usually quite small, so it would be preferable to first - * heapify, always maintaining the invariant that the larger child is copied - * over its parent's record. - * - * Then, starting from the *bottom* of the heap, finding k's correct place, - * again maintaining the invariant. As a result of the invariant no element - * is 'lost' when k is assigned its correct place in the heap. - * - * The time savings from this optimization are on the order of 15-20% for the - * average case. See Knuth, Vol. 3, page 158, problem 18. - * - * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset. - */ -#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \ - for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \ - child = base + child_i * size; \ - if (child_i < nmemb && compar(child, child + size) < 0) { \ - child += size; \ - ++child_i; \ - } \ - par = base + par_i * size; \ - COPY(par, child, count, size, tmp1, tmp2); \ - } \ - for (;;) { \ - child_i = par_i; \ - par_i = child_i / 2; \ - child = base + child_i * size; \ - par = base + par_i * size; \ - if (child_i == 1 || compar(k, par) < 0) { \ - COPY(child, k, count, size, tmp1, tmp2); \ - break; \ - } \ - COPY(child, par, count, size, tmp1, tmp2); \ - } \ -} - -/* - * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average - * and worst. While heapsort is faster than the worst case of quicksort, - * the BSD quicksort does median selection so that the chance of finding - * a data set that will trigger the worst case is nonexistent. Heapsort's - * only advantage over quicksort is that it requires little additional memory. - */ -int -heapsort(void *vbase, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)) -{ - size_t cnt, i, j, l; - char tmp, *tmp1, *tmp2; - char *base, *k, *p, *t; - - if (nmemb <= 1) - return (0); - - if (!size) { - errno = EINVAL; - return (-1); - } - - if ((k = malloc(size)) == NULL) - return (-1); - - /* - * Items are numbered from 1 to nmemb, so offset from size bytes - * below the starting address. - */ - base = (char *)vbase - size; - - for (l = nmemb / 2 + 1; --l;) - CREATE(l, nmemb, i, j, t, p, size, cnt, tmp); - - /* - * For each element of the heap, save the largest element into its - * final slot, save the displaced element (k), then recreate the - * heap. - */ - while (nmemb > 1) { - COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2); - COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2); - --nmemb; - SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2); - } - free(k); - return (0); -} -DEF_WEAK(heapsort); diff --git a/src/lib/libc/stdlib/icdb.c b/src/lib/libc/stdlib/icdb.c deleted file mode 100644 index 2ddd9db48c..0000000000 --- a/src/lib/libc/stdlib/icdb.c +++ /dev/null @@ -1,391 +0,0 @@ -/* $OpenBSD: icdb.c,v 1.8 2016/09/04 16:56:02 nicm Exp $ */ -/* - * Copyright (c) 2015 Ted Unangst - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* - * Creating a new icdb: icdb_new - * Opening existing icdb: icdb_open - * - * Adding new entries: icdb_add - * Adding entries does not update the disk or indices. - * - * Save to disk: icdb_save - * Update indices: icdb_rehash - * icdb_save will call rehash. - * - * Change an existing entry: icdb_update - * Changing entries does write to disk. - * - * Find an entry: icdb_lookup - * Looking up an entry is only defined when the indices are synced. - * - * Close and free resources: icdb_close - */ - -/* - * There are two major modes of operation. - * - * Existing databases use the mmap codepath. The entire database is mapped - * into the address space for quick access. Individual entries may be updated, - * but no new entries added. - * - * New databases use malloc backed memory instead. The database may be saved - * with icdb_save. It should be saved to a new file to avoid corrupting any - * open databases in other processes. - */ - -/* - * An icdb has the following format: - * struct icbinfo header - * indexes [ uint32_t * indexsize * nkeys ] - * entries [ entrysize * nentries ] - * - * To find an entry in the file, the user specifies which key to use. - * The key is hashed and looked up in the index. The index contains the - * position of the entry in the entries array. -1 identifies not found. - * Chaining is done by rehashing the hash. All keys are fixed size byte arrays. - */ - -/* - * Header info for icdb. This struct is stored on disk. - */ -struct icdbinfo { - uint32_t magic; /* magic */ - uint32_t version; /* user specified version */ - uint32_t nentries; /* number of entries stored */ - uint32_t entrysize; /* size of each entry */ - uint32_t indexsize; /* number of entries in hash index */ - uint32_t nkeys; /* number of keys defined */ - uint32_t keysize[8]; /* size of each key */ - uint32_t keyoffset[8]; /* offset of each key in entry */ - SIPHASH_KEY siphashkey; /* random hash key */ -}; - -/* - * In memory representation with auxiliary data. - * idxdata and entries will be written to disk after info. - */ -struct icdb { - struct icdbinfo *info; - void *idxdata[8]; - void *entries; - size_t maplen; - uint32_t allocated; - int fd; -}; - -static const uint32_t magic = 0x1ca9d0b7; - -static uint32_t -roundup(uint32_t num) -{ - uint32_t r = 2; - - while (r < num * 3 / 2) - r *= 2; - return r; -} - -struct icdb * -icdb_new(uint32_t version, uint32_t nentries, uint32_t entrysize, - uint32_t nkeys, const uint32_t *keysizes, const uint32_t *keyoffsets) -{ - struct icdb *db; - struct icdbinfo *info; - int i; - - if (entrysize == 0 || entrysize > 1048576 || nkeys > 8) { - errno = EINVAL; - return NULL; - } - - if (!(db = calloc(1, sizeof(*db)))) - return NULL; - if (!(info = calloc(1, sizeof(*info)))) { - free(db); - return NULL; - } - db->info = info; - db->fd = -1; - info->magic = magic; - info->version = version; - if (nentries) - if ((db->entries = reallocarray(NULL, nentries, entrysize))) - db->allocated = nentries; - info->entrysize = entrysize; - info->nkeys = nkeys; - for (i = 0; i < nkeys; i++) { - info->keysize[i] = keysizes[i]; - info->keyoffset[i] = keyoffsets[i]; - } - return db; -} -DEF_WEAK(icdb_new); - -struct icdb * -icdb_open(const char *name, int flags, uint32_t version) -{ - struct icdb *db = NULL; - struct icdbinfo *info; - struct stat sb; - uint8_t *ptr = MAP_FAILED; - uint32_t baseoff, indexsize, idxmask, idxlen; - int fd, i, saved_errno; - - if ((fd = open(name, flags | O_CLOEXEC)) == -1) - return NULL; - if (fstat(fd, &sb) != 0) - goto fail; - if (sb.st_size < sizeof(struct icdbinfo)) - goto fail; - ptr = mmap(NULL, sb.st_size, PROT_READ | - ((flags & O_RDWR) ? PROT_WRITE : 0), MAP_SHARED, fd, 0); - if (ptr == MAP_FAILED) - goto fail; - info = (struct icdbinfo *)ptr; - if (info->magic != magic || info->version != version) { - errno = ENOENT; - goto fail; - } - - if (!(db = calloc(1, sizeof(*db)))) - goto fail; - db->info = info; - - indexsize = info->indexsize; - idxmask = indexsize - 1; - idxlen = indexsize * sizeof(uint32_t); - baseoff = sizeof(*info) + idxlen * info->nkeys; - - for (i = 0; i < info->nkeys; i++) - db->idxdata[i] = ptr + sizeof(*info) + i * idxlen; - db->entries = ptr + baseoff; - db->maplen = sb.st_size; - db->fd = fd; - return db; - -fail: - saved_errno = errno; - if (ptr != MAP_FAILED) - munmap(ptr, sb.st_size); - if (fd != -1) - close(fd); - free(db); - errno = saved_errno; - return NULL; -} -DEF_WEAK(icdb_open); - -int -icdb_get(struct icdb *db, void *entry, uint32_t idx) -{ - uint32_t entrysize = db->info->entrysize; - - memcpy(entry, (uint8_t *)db->entries + idx * entrysize, entrysize); - return 0; -} -DEF_WEAK(icdb_get); - -int -icdb_lookup(struct icdb *db, int keynum, const void *key, void *entry, - uint32_t *idxp) -{ - struct icdbinfo *info = db->info; - uint32_t offset; - uint64_t hash; - uint32_t indexsize, idxmask, idxlen; - uint32_t *idxdata; - - indexsize = info->indexsize; - idxmask = indexsize - 1; - idxlen = indexsize * sizeof(uint32_t); - - idxdata = db->idxdata[keynum]; - - hash = SipHash24(&info->siphashkey, key, info->keysize[keynum]); - while ((offset = idxdata[hash & idxmask]) != -1) { - if (icdb_get(db, entry, offset) != 0) { - errno = ENOENT; - return -1; - } - if (memcmp((uint8_t *)entry + info->keyoffset[keynum], key, - info->keysize[keynum]) == 0) { - if (idxp) - *idxp = offset; - return 0; - } - hash = SipHash24(&info->siphashkey, &hash, sizeof(hash)); - } - return 1; -} -DEF_WEAK(icdb_lookup); - -int -icdb_nentries(struct icdb *db) -{ - return db->info->nentries; -} -DEF_WEAK(icdb_nentries); - -const void * -icdb_entries(struct icdb *db) -{ - return db->entries; -} -DEF_WEAK(icdb_entries); - -int -icdb_update(struct icdb *db, const void *entry, int offset) -{ - struct icdbinfo *info = db->info; - uint32_t entrysize = info->entrysize; - uint32_t baseoff; - uint32_t indexsize, idxmask, idxlen; - - indexsize = info->indexsize; - idxmask = indexsize - 1; - idxlen = indexsize * sizeof(uint32_t); - baseoff = sizeof(*info) + idxlen * info->nkeys; - - memcpy((uint8_t *)db->entries + offset * entrysize, entry, entrysize); - if (db->fd != -1) { - msync((uint8_t *)db->entries + offset * entrysize, entrysize, - MS_SYNC); - } - return 0; -} -DEF_WEAK(icdb_update); - -int -icdb_add(struct icdb *db, const void *entry) -{ - struct icdbinfo *info = db->info; - size_t entrysize = info->entrysize; - - if (db->allocated == info->nentries) { - void *p; - size_t amt = db->allocated ? db->allocated * 2 : 63; - if (!(p = reallocarray(db->entries, amt, entrysize))) - return -1; - db->allocated = amt; - db->entries = p; - } - memcpy((uint8_t *)db->entries + info->nentries * entrysize, - entry, entrysize); - info->nentries++; - return 0; -} -DEF_WEAK(icdb_add); - -int -icdb_rehash(struct icdb *db) -{ - struct icdbinfo *info = db->info; - uint32_t entrysize = info->entrysize; - uint32_t indexsize, idxmask, idxlen; - int i, j; - - indexsize = info->indexsize = roundup(info->nentries); - idxmask = indexsize - 1; - idxlen = sizeof(uint32_t) * indexsize; - - arc4random_buf(&info->siphashkey, sizeof(info->siphashkey)); - - for (i = 0; i < info->nkeys; i++) { - uint32_t *idxdata = reallocarray(db->idxdata[i], - indexsize, sizeof(uint32_t)); - if (!idxdata) - return -1; - memset(idxdata, 0xff, idxlen); - db->idxdata[i] = idxdata; - } - for (j = 0; j < info->nentries; j++) { - for (i = 0; i < info->nkeys; i++) { - uint32_t *idxdata = db->idxdata[i]; - uint64_t hash = SipHash24(&info->siphashkey, - (uint8_t *)db->entries + j * entrysize + - info->keyoffset[i], info->keysize[i]); - while (idxdata[hash & idxmask] != -1) - hash = SipHash24(&info->siphashkey, &hash, sizeof(hash)); - idxdata[hash & idxmask] = j; - } - } - return 0; -} -DEF_WEAK(icdb_rehash); - -int -icdb_save(struct icdb *db, int fd) -{ - struct icdbinfo *info = db->info; - uint32_t entrysize = info->entrysize; - uint32_t indexsize, idxlen; - int i; - - if (icdb_rehash(db) != 0) - return -1; - - indexsize = info->indexsize; - idxlen = sizeof(uint32_t) * indexsize; - - if (ftruncate(fd, 0) != 0) - return -1; - if (write(fd, info, sizeof(*info)) != sizeof(*info)) - return -1; - for (i = 0; i < info->nkeys; i++) { - if (write(fd, db->idxdata[i], idxlen) != idxlen) - return -1; - } - if (write(fd, db->entries, info->nentries * entrysize) != - info->nentries * entrysize) - return -1; - return 0; -} -DEF_WEAK(icdb_save); - -int -icdb_close(struct icdb *db) -{ - int i; - - if (db->fd == -1) { - for (i = 0; i < db->info->nkeys; i++) - free(db->idxdata[i]); - free(db->entries); - free(db->info); - } else { - munmap(db->info, db->maplen); - close(db->fd); - } - free(db); - return 0; -} -DEF_WEAK(icdb_close); diff --git a/src/lib/libc/stdlib/icdb_new.3 b/src/lib/libc/stdlib/icdb_new.3 deleted file mode 100644 index 9fc07bda80..0000000000 --- a/src/lib/libc/stdlib/icdb_new.3 +++ /dev/null @@ -1,68 +0,0 @@ -.\" $OpenBSD: icdb_new.3,v 1.2 2016/09/04 19:05:09 jmc Exp $ -.\" -.\" Copyright (c) Ted Unangst -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.\" -.Dd $Mdocdate: September 4 2016 $ -.Dt ICBB_NEW 3 -.Os -.Sh NAME -.Nm icdb_new , -.Nm icdb_open , -.Nm icdb_get , -.Nm icdb_lookup , -.Nm icdb_nentries , -.Nm icdb_entries , -.Nm icdb_update , -.Nm icdb_add , -.Nm icdb_rehash , -.Nm icdb_save , -.Nm icdb_close -.Nd simple database -.Sh SYNOPSIS -.In icbd.h -.Ft struct icdb * -.Fn icdb_new "uint32_t version" "uint32_t nentries" "uint32_t entrysize" -.Ft struct icdb * -.Fn icdb_open "const char *name" "int flags" "uint32_t version" -.Ft int -.Fn icdb_get "struct icdb *db" "void *entry" "uint32_t idx" -.Ft int -.Fn icdb_lookup "struct icdb *db" "int keynum" "const void *key" "void *entry" "uint32_t *idxp" -.Ft int -.Fn icdb_nentries "struct icdb *db" -.Ft const void * -.Fn icdb_entries "struct icdb *db" -.Ft int -.Fn icdb_update "struct icdb *db" "const void *entry" "int offset" -.Ft int -.Fn icdb_add "struct icdb *db" "const void *entry" -.Ft int -.Fn icdb_rehash "struct icdb *db" -.Ft int -.Fn icdb_save "struct icdb *db" "int fd" -.Ft int -.Fn icdb_close "struct icdb *db" -.Sh DESCRIPTION -These functions provide access to a simple memory mapped database format. -.Sh EXAMPLES -Look how easy it is to use. -.Sh STANDARDS -These functions are not standardized. -.Sh HISTORY -The icdb functions were introduced in -.Ox 6.0 . -.Sh AUTHORS -.An Ted Unangst Aq Mt tedu@openbsd.org diff --git a/src/lib/libc/stdlib/imaxabs.3 b/src/lib/libc/stdlib/imaxabs.3 deleted file mode 100644 index 340be61b6e..0000000000 --- a/src/lib/libc/stdlib/imaxabs.3 +++ /dev/null @@ -1,70 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: imaxabs.3,v 1.8 2019/01/18 07:32:17 schwarze Exp $ -.\" -.Dd $Mdocdate: January 18 2019 $ -.Dt IMAXABS 3 -.Os -.Sh NAME -.Nm imaxabs -.Nd integer absolute value function -.Sh SYNOPSIS -.In inttypes.h -.In stdint.h -.Ft intmax_t -.Fn imaxabs "intmax_t j" -.Sh DESCRIPTION -The -.Fn imaxabs -function computes the absolute value of the intmax_t variable -.Fa j . -.Sh RETURN VALUES -The -.Fn imaxabs -function returns the absolute value. -.Sh SEE ALSO -.Xr abs 3 , -.Xr cabs 3 , -.Xr floor 3 , -.Xr hypot 3 , -.Xr labs 3 -.Sh STANDARDS -The -.Fn imaxabs -function conforms to -.St -isoC-99 . -.Sh CAVEATS -The result of applying -.Fn imaxabs -to -.Dv INTMAX_MIN -is undefined. diff --git a/src/lib/libc/stdlib/imaxabs.c b/src/lib/libc/stdlib/imaxabs.c deleted file mode 100644 index b7e910eefd..0000000000 --- a/src/lib/libc/stdlib/imaxabs.c +++ /dev/null @@ -1,38 +0,0 @@ -/* $OpenBSD: imaxabs.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -intmax_t -imaxabs(intmax_t j) -{ - return (j < 0 ? -j : j); -} diff --git a/src/lib/libc/stdlib/imaxdiv.3 b/src/lib/libc/stdlib/imaxdiv.3 deleted file mode 100644 index 70168acb30..0000000000 --- a/src/lib/libc/stdlib/imaxdiv.3 +++ /dev/null @@ -1,65 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: imaxdiv.3,v 1.8 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt IMAXDIV 3 -.Os -.Sh NAME -.Nm imaxdiv -.Nd return quotient and remainder from division -.Sh SYNOPSIS -.In inttypes.h -.Ft imaxdiv_t -.Fn imaxdiv "intmax_t num" "intmax_t denom" -.Sh DESCRIPTION -The -.Fn imaxdiv -function computes the value -.Fa num Ns / Ns Fa denom -and returns the quotient and remainder in a structure named -.Vt imaxdiv_t -that contains two -.Vt intmax_t -members named -.Fa quot -and -.Fa rem . -.Sh SEE ALSO -.Xr div 3 , -.Xr ldiv 3 , -.Xr lldiv 3 -.Sh STANDARDS -The -.Fn imaxdiv -function conforms to -.St -isoC-99 . diff --git a/src/lib/libc/stdlib/imaxdiv.c b/src/lib/libc/stdlib/imaxdiv.c deleted file mode 100644 index 0515a94b96..0000000000 --- a/src/lib/libc/stdlib/imaxdiv.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $OpenBSD: imaxdiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include /* imaxdiv_t */ - -imaxdiv_t -imaxdiv(intmax_t num, intmax_t denom) -{ - imaxdiv_t r; - - /* see div.c for comments */ - - r.quot = num / denom; - r.rem = num % denom; - if (num >= 0 && r.rem < 0) { - r.quot++; - r.rem -= denom; - } - return (r); -} diff --git a/src/lib/libc/stdlib/insque.3 b/src/lib/libc/stdlib/insque.3 deleted file mode 100644 index 136c08bad8..0000000000 --- a/src/lib/libc/stdlib/insque.3 +++ /dev/null @@ -1,103 +0,0 @@ -.\" $OpenBSD: insque.3,v 1.12 2020/04/26 16:36:14 schwarze Exp $ -.\" Copyright (c) 1993 John Brezak -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" -.Dd $Mdocdate: April 26 2020 $ -.Dt INSQUE 3 -.Os -.Sh NAME -.Nm insque , -.Nm remque -.Nd legacy doubly linked lists -.Sh SYNOPSIS -.In search.h -.Ft void -.Fn insque "void *elem" "void *pred" -.Ft void -.Fn remque "void *elem" -.Sh DESCRIPTION -.Bf -symbolic -These interfaces have been superseded by the -.Xr queue 3 -macros and are provided for compatibility with legacy code. -.Ef -.Pp -.Fn insque -and -.Fn remque -manipulate a legacy variety of intrusive doubly linked lists. -A list can be either circular or linear. -Each element in the list must be of the following form: -.Bd -literal -offset indent -struct qelem { - struct qelem *q_forw; - struct qelem *q_back; - char q_data[]; -}; -.Ed -.Pp -The first two members of the struct must be pointers of the -same type that point to the next and previous elements in -the list, respectively. -Any subsequent data in the struct is application-dependent. -.Pp -The -.Fn insque -function inserts -.Fa elem -into a list immediately after -.Fa pred . -.Pp -The -.Fn remque -function removes -.Fa elem -from the list. -.Pp -These functions are not atomic. -.Sh SEE ALSO -.Xr queue 3 -.Sh STANDARDS -The -.Fn insque -and -.Fn remque -functions conform to the X/Open System Interfaces option of the -.St -p1003.1-2008 -specification. -.Sh HISTORY -The -.Fn insque -and -.Fn remque -functions are derived from the -.Li insque -and -.Li remque -instructions on the VAX. -They first appeared in -.Bx 4.2 . diff --git a/src/lib/libc/stdlib/insque.c b/src/lib/libc/stdlib/insque.c deleted file mode 100644 index 590ff837b8..0000000000 --- a/src/lib/libc/stdlib/insque.c +++ /dev/null @@ -1,54 +0,0 @@ -/* $OpenBSD: insque.c,v 1.3 2014/08/15 04:14:36 guenther Exp $ */ - -/* - * Copyright (c) 1993 John Brezak - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -struct qelem { - struct qelem *q_forw; - struct qelem *q_back; -}; - -void -insque(void *entry, void *pred) -{ - struct qelem *e = entry; - struct qelem *p = pred; - - if (p == NULL) - e->q_forw = e->q_back = NULL; - else { - e->q_forw = p->q_forw; - e->q_back = p; - if (p->q_forw != NULL) - p->q_forw->q_back = e; - p->q_forw = e; - } -} diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c deleted file mode 100644 index cb8c592750..0000000000 --- a/src/lib/libc/stdlib/jrand48.c +++ /dev/null @@ -1,22 +0,0 @@ -/* $OpenBSD: jrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -long -jrand48(unsigned short xseed[3]) -{ - __dorand48(xseed); - return ((long) xseed[2] << 16) + (long) xseed[1]; -} diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c deleted file mode 100644 index 4f33df37b2..0000000000 --- a/src/lib/libc/stdlib/l64a.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $OpenBSD: l64a.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -char * -l64a(long value) -{ - static char buf[8]; - char *s = buf; - int digit; - int i; - - if (value < 0) { - errno = EINVAL; - return(NULL); - } - - for (i = 0; value != 0 && i < 6; i++) { - digit = value & 0x3f; - - if (digit < 2) - *s = digit + '.'; - else if (digit < 12) - *s = digit + '0' - 2; - else if (digit < 38) - *s = digit + 'A' - 12; - else - *s = digit + 'a' - 38; - - value >>= 6; - s++; - } - - *s = '\0'; - - return(buf); -} diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3 deleted file mode 100644 index f3fd6fd528..0000000000 --- a/src/lib/libc/stdlib/labs.3 +++ /dev/null @@ -1,88 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: labs.3,v 1.17 2019/01/18 07:32:17 schwarze Exp $ -.\" -.Dd $Mdocdate: January 18 2019 $ -.Dt LABS 3 -.Os -.Sh NAME -.Nm labs , -.Nm llabs , -.Nm qabs -.Nd return the absolute value of a long integer -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft long -.Fn labs "long i" -.Ft long long -.Fn llabs "long long j" -.Ft quad_t -.Fn qabs "quad_t j" -.Sh DESCRIPTION -The -.Fn labs -function returns the absolute value of the long integer -.Fa i . -The -.Fn llabs -function returns the absolute value of the long long integer -.Fa j . -.Pp -The -.Fn qabs -function is a deprecated equivalent of -.Fn llabs . -.Sh SEE ALSO -.Xr abs 3 , -.Xr cabs 3 , -.Xr floor 3 , -.Xr imaxabs 3 -.Sh STANDARDS -The -.Fn labs -and -.Fn llabs -functions conform to -.St -isoC-99 . -.Sh CAVEATS -The results of applying -.Fn labs -to -.Dv LONG_MIN -and -.Fn llabs -to -.Dv LLONG_MIN -are undefined, and -.Fn qabs -is not portable in the first place. diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c deleted file mode 100644 index ca60b9aba2..0000000000 --- a/src/lib/libc/stdlib/labs.c +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: labs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -long -labs(long j) -{ - return(j < 0 ? -j : j); -} diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c deleted file mode 100644 index f03083e3c8..0000000000 --- a/src/lib/libc/stdlib/lcong48.c +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: lcong48.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -void -lcong48(unsigned short p[7]) -{ - lcong48_deterministic(p); - __rand48_deterministic = 0; -} - -void -lcong48_deterministic(unsigned short p[7]) -{ - __rand48_deterministic = 1; - __rand48_seed[0] = p[0]; - __rand48_seed[1] = p[1]; - __rand48_seed[2] = p[2]; - __rand48_mult[0] = p[3]; - __rand48_mult[1] = p[4]; - __rand48_mult[2] = p[5]; - __rand48_add = p[6]; -} -DEF_WEAK(lcong48_deterministic); diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3 deleted file mode 100644 index c7ddc85ac5..0000000000 --- a/src/lib/libc/stdlib/ldiv.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: ldiv.3,v 1.14 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt LDIV 3 -.Os -.Sh NAME -.Nm ldiv -.Nd return quotient and remainder from division -.Sh SYNOPSIS -.In stdlib.h -.Ft ldiv_t -.Fn ldiv "long num" "long denom" -.Sh DESCRIPTION -The -.Fn ldiv -function computes the value -.Fa num Ns / Ns Fa denom -and returns the quotient and remainder in a structure named -.Vt ldiv_t -that contains two -.Vt long integer -members named -.Fa quot -and -.Fa rem . -.Sh SEE ALSO -.Xr div 3 , -.Xr imaxdiv 3 , -.Xr lldiv 3 -.Sh STANDARDS -The -.Fn ldiv -function conforms to -.St -ansiC . -.Sh HISTORY -An -.Fn ldiv -function with similar functionality, but a different calling convention, -first appeared in -.At v4 . diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c deleted file mode 100644 index 775065f525..0000000000 --- a/src/lib/libc/stdlib/ldiv.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $OpenBSD: ldiv.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include /* ldiv_t */ - -ldiv_t -ldiv(long num, long denom) -{ - ldiv_t r; - - /* see div.c for comments */ - - r.quot = num / denom; - r.rem = num % denom; - if (num >= 0 && r.rem < 0) { - r.quot++; - r.rem -= denom; - } - return (r); -} diff --git a/src/lib/libc/stdlib/llabs.c b/src/lib/libc/stdlib/llabs.c deleted file mode 100644 index f4a260f4a8..0000000000 --- a/src/lib/libc/stdlib/llabs.c +++ /dev/null @@ -1,40 +0,0 @@ -/* $OpenBSD: llabs.c,v 1.4 2016/08/14 23:18:03 guenther Exp $ */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -long long -llabs(long long j) -{ - return (j < 0 ? -j : j); -} - -__weak_alias(qabs, llabs); diff --git a/src/lib/libc/stdlib/lldiv.3 b/src/lib/libc/stdlib/lldiv.3 deleted file mode 100644 index 539d7b5179..0000000000 --- a/src/lib/libc/stdlib/lldiv.3 +++ /dev/null @@ -1,73 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: lldiv.3,v 1.9 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt LLDIV 3 -.Os -.Sh NAME -.Nm lldiv , -.Nm qdiv -.Nd return quotient and remainder from division -.Sh SYNOPSIS -.In stdlib.h -.Ft lldiv_t -.Fn lldiv "long long num" "long long denom" -.Ft qdiv_t -.Fn qdiv "quad_t num" "quad_t denom" -.Sh DESCRIPTION -The -.Fn lldiv -function computes the value -.Fa num Ns / Ns Fa denom -and returns the quotient and remainder in a structure named -.Vt lldiv_t -that contains two -.Vt long long integer -members named -.Fa quot -and -.Fa rem . -.Pp -The -.Fn qdiv -function is a deprecated equivalent of -.Fn lldiv . -.Sh SEE ALSO -.Xr div 3 , -.Xr imaxdiv 3 , -.Xr ldiv 3 -.Sh STANDARDS -The -.Fn lldiv -function conforms to -.St -isoC-99 . diff --git a/src/lib/libc/stdlib/lldiv.c b/src/lib/libc/stdlib/lldiv.c deleted file mode 100644 index 59c37b878c..0000000000 --- a/src/lib/libc/stdlib/lldiv.c +++ /dev/null @@ -1,52 +0,0 @@ -/* $OpenBSD: lldiv.c,v 1.2 2016/08/14 23:18:03 guenther Exp $ */ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include /* lldiv_t */ - -lldiv_t -lldiv(long long num, long long denom) -{ - lldiv_t r; - - /* see div.c for comments */ - - r.quot = num / denom; - r.rem = num % denom; - if (num >= 0 && r.rem < 0) { - r.quot++; - r.rem -= denom; - } - return (r); -} - -__weak_alias(qdiv, lldiv); diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c deleted file mode 100644 index 142cca7f78..0000000000 --- a/src/lib/libc/stdlib/lrand48.c +++ /dev/null @@ -1,24 +0,0 @@ -/* $OpenBSD: lrand48.c,v 1.5 2015/08/27 04:33:31 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -long -lrand48(void) -{ - if (__rand48_deterministic == 0) - return arc4random() & 0x7fffffff; - __dorand48(__rand48_seed); - return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1); -} diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3 deleted file mode 100644 index d82c55c859..0000000000 --- a/src/lib/libc/stdlib/lsearch.3 +++ /dev/null @@ -1,106 +0,0 @@ -.\" $OpenBSD: lsearch.3,v 1.14 2015/11/30 17:03:05 jmc Exp $ -.\" -.\" Copyright (c) 1989, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93 -.\" -.Dd $Mdocdate: November 30 2015 $ -.Dt LSEARCH 3 -.Os -.Sh NAME -.Nm lsearch , -.Nm lfind -.Nd linear searching routines -.Sh SYNOPSIS -.In search.h -.Ft void * -.Fn lsearch "const void *key" "void *base" "size_t *nelp" \ - "size_t width" "int (*compar)(const void *, const void *)" -.Ft void * -.Fn lfind "const void *key" "const void *base" "size_t *nelp" \ - "size_t width" "int (*compar)(const void *, const void *)" -.Sh DESCRIPTION -The functions -.Fn lsearch -and -.Fn lfind -provide basic linear searching functionality. -.Pp -.Fa base -is the pointer to the beginning of an array. -The argument -.Fa nelp -is the current number of elements in the array, where each element -is -.Fa width -bytes long. -The -.Fa compar -function -is a comparison routine which is used to compare two elements. -It takes two arguments which point to the -.Fa key -object and to an array member, in that order, and must return an integer -less than, equivalent to, or greater than zero if the -.Fa key -object is considered, respectively, to be less than, equal to, or greater -than the array member. -.Pp -The -.Fn lsearch -and -.Fn lfind -functions -return a pointer into the array referenced by -.Fa base -where -.Fa key -is located. -If -.Fa key -does not exist, -.Fn lfind -will return a null pointer and -.Fn lsearch -will add it to the array. -When an element is added to the array by -.Fn lsearch , -the location referenced by the argument -.Fa nelp -is incremented by one. -.Sh SEE ALSO -.Xr bsearch 3 , -.Xr dbopen 3 -.Sh STANDARDS -The -.Fn lsearch -and -.Fn lfind -functions conform to the X/Open System Interfaces option of the -.St -p1003.1-2008 -specification. diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c deleted file mode 100644 index 95ebf49b81..0000000000 --- a/src/lib/libc/stdlib/lsearch.c +++ /dev/null @@ -1,70 +0,0 @@ -/* $OpenBSD: lsearch.c,v 1.7 2021/12/08 22:06:28 cheloha Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Roger L. Snyder. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -typedef int (*cmp_fn_t)(const void *, const void *); - -void * -lsearch(const void *key, void *base, size_t *nelp, size_t width, - cmp_fn_t compar) -{ - void *element = lfind(key, base, nelp, width, compar); - - /* - * Use memmove(3) to ensure the key is copied cleanly into the - * array, even if the key overlaps with the end of the array. - */ - if (element == NULL) { - element = memmove((char *)base + *nelp * width, key, width); - *nelp += 1; - } - return element; -} - -void * -lfind(const void *key, const void *base, size_t *nelp, size_t width, - cmp_fn_t compar) -{ - const char *element, *end; - - end = (const char *)base + *nelp * width; - for (element = base; element < end; element += width) - if (!compar(key, element)) /* key found */ - return((void *)element); - return NULL; -} -DEF_WEAK(lfind); diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 deleted file mode 100644 index bea5575bf8..0000000000 --- a/src/lib/libc/stdlib/malloc.3 +++ /dev/null @@ -1,860 +0,0 @@ -.\" -.\" Copyright (c) 1980, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: malloc.3,v 1.142 2024/08/03 20:09:24 guenther Exp $ -.\" -.Dd $Mdocdate: August 3 2024 $ -.Dt MALLOC 3 -.Os -.Sh NAME -.Nm malloc , -.Nm calloc , -.Nm realloc , -.Nm free , -.Nm reallocarray , -.Nm recallocarray , -.Nm freezero , -.Nm aligned_alloc , -.Nm malloc_conceal , -.Nm calloc_conceal -.Nd memory allocation and deallocation -.Sh SYNOPSIS -.In stdlib.h -.Ft void * -.Fn malloc "size_t size" -.Ft void * -.Fn calloc "size_t nmemb" "size_t size" -.Ft void * -.Fn realloc "void *ptr" "size_t size" -.Ft void -.Fn free "void *ptr" -.Ft void * -.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" -.Ft void * -.Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size" -.Ft void -.Fn freezero "void *ptr" "size_t size" -.Ft void * -.Fn aligned_alloc "size_t alignment" "size_t size" -.Ft void * -.Fn malloc_conceal "size_t size" -.Ft void * -.Fn calloc_conceal "size_t nmemb" "size_t size" -.Vt char *malloc_options ; -.Sh DESCRIPTION -The standard functions -.Fn malloc , -.Fn calloc , -and -.Fn realloc -allocate -.Em objects , -regions of memory to store values. -The -.Fn malloc -function allocates uninitialized space for an object of -the specified -.Fa size . -.Fn malloc -maintains multiple lists of free objects according to size, allocating -from the appropriate list or requesting memory from the kernel. -The allocated space is suitably aligned (after possible pointer coercion) for -storage of any type of object. -.Pp -The -.Fn calloc -function allocates space for an array of -.Fa nmemb -objects, each of the specified -.Fa size . -The space is initialized to zero. -.Pp -The -.Fn realloc -function changes the size of the object pointed to by -.Fa ptr -to -.Fa size -bytes and returns a pointer to the (possibly moved) object. -If -.Fa ptr -is not -.Dv NULL , -it must be a pointer returned by an earlier call to an allocation or -reallocation function that was not freed in between. -The contents of the object are unchanged up to the lesser -of the new and old sizes. -If the new size is larger, the value of the newly allocated portion -of the object is indeterminate and uninitialized. -If the space cannot be allocated, the object -pointed to by -.Fa ptr -is unchanged. -If -.Fa ptr -is -.Dv NULL , -.Fn realloc -behaves like -.Fn malloc -and allocates a new object. -.Pp -The -.Fn free -function causes the space pointed to by -.Fa ptr -to be either placed on a list of free blocks to make it available for future -allocation or, when appropriate, to be returned to the kernel using -.Xr munmap 2 . -If -.Fa ptr -is -.Dv NULL , -no action occurs. -If -.Fa ptr -was previously freed by -.Fn free -or a reallocation function, -the behavior is undefined and the double free is a security concern. -.Pp -Designed for safe allocation of arrays, -the -.Fn reallocarray -function is similar to -.Fn realloc -except it operates on -.Fa nmemb -members of size -.Fa size -and checks for integer overflow in the calculation -.Fa nmemb -* -.Fa size . -.Pp -Used for the allocation of memory holding sensitive data, -the -.Fn recallocarray -and -.Fn freezero -functions guarantee that memory becoming unallocated is explicitly -.Em discarded , -meaning pages of memory are disposed via -.Xr munmap 2 -and cached free objects are cleared with -.Xr explicit_bzero 3 . -.Pp -The -.Fn recallocarray -function is similar to -.Fn reallocarray -except it ensures newly allocated memory is cleared similar to -.Fn calloc . -If -.Fa ptr -is -.Dv NULL , -.Fa oldnmemb -is ignored and the call is equivalent to -.Fn calloc . -If -.Fa ptr -is not -.Dv NULL , -.Fa oldnmemb -must be a value such that -.Fa oldnmemb -* -.Fa size -is the size of the earlier allocation that returned -.Fa ptr , -otherwise the behavior is undefined. -.Pp -The -.Fn freezero -function is similar to the -.Fn free -function except it ensures memory is explicitly discarded. -If -.Fa ptr -is -.Dv NULL , -no action occurs. -If -.Fa ptr -is not -.Dv NULL , -the -.Fa size -argument must be equal to or smaller than the size of the earlier allocation -that returned -.Fa ptr . -.Fn freezero -guarantees the memory range starting at -.Fa ptr -with length -.Fa size -is discarded while deallocating the whole object originally allocated. -.Pp -The -.Fn aligned_alloc -function allocates -.Fa size -bytes of memory such that the allocation's base address is a multiple of -.Fa alignment . -The requested -.Fa alignment -must be a power of 2. -If -.Fa size -is not a multiple of -.Fa alignment , -behavior is undefined. -.Pp -The -.Fn malloc_conceal -and -.Fn calloc_conceal -functions behave the same as -.Fn malloc -and -.Fn calloc -respectively, -with the exception that the allocation returned is marked with the -.Dv MAP_CONCEAL -.Xr mmap 2 -flag and calling -.Fn free -on the allocation will discard the contents explicitly. -A reallocation of a concealed allocation will leave these properties intact. -.Sh MALLOC OPTIONS -Upon the first call to the -.Fn malloc -family of functions, an initialization sequence inspects the -value of the -.Va vm.malloc_conf -.Xr sysctl 2 , -next checks the environment for a variable called -.Ev MALLOC_OPTIONS , -and finally looks at the global variable -.Va malloc_options -in the program. -Each is scanned for the flags documented below. -Unless otherwise noted uppercase means on, lowercase means off. -During initialization, flags occurring later modify the behaviour -that was requested by flags processed earlier. -.Bl -tag -width indent -.It Cm C -.Dq Canaries . -Add canaries at the end of allocations in order to detect -heap overflows. -The canary's content is checked when -.Nm free -is called. -If it has been corrupted, the process is aborted. -.It Cm D -.Dq Dump . -.Fn malloc -will dump a leak report using -.Xr utrace 2 -at exit. -To record the dump: -.Pp -.Dl $ MALLOC_OPTIONS=D ktrace -tu program ... -.Pp -To view the leak report: -.Pp -.Dl $ kdump -u malloc ... -.Pp -By default, the immediate caller of a -.Nm -function will be recorded. -Use malloc option -.Cm 2 , -.Cm 3 -or -.Cm 4 -to record deeper call stacks. -These malloc options imply -.Cm D . -.It Cm F -.Dq Freecheck . -Enable more extensive double free and write after free detection. -All chunks in the delayed free list will be checked for double frees and -write after frees. -Unused pages on the freelist are read and write protected to -cause a segmentation fault upon access. -.It Cm G -.Dq Guard . -Enable guard pages. -Each page size or larger allocation is followed by a guard page that will -cause a segmentation fault upon any access. -.It Cm J -.Dq More junking . -Increase the junk level by one if it is smaller than 2. -.It Cm j -.Dq Less junking . -Decrease the junk level by one if it is larger than 0. -Junking writes some junk bytes into the area allocated. -Junk is bytes of 0xdb when allocating; -small allocations are initially junked with 0xdf as are freed allocations. -By default the junk level is 1: after free, -small chunks are completely junked; -for pages the first part is junked. -After a delay, -the filling pattern is validated and the process is aborted if the pattern -was modified. -For junk level 2, junking is done on allocation as well and without size -restrictions. -If the junk level is zero, no junking is performed. -.It Cm R -.Dq realloc . -Always reallocate when -.Fn realloc -is called, even if the initial allocation was big enough. -.\".Pp -.\".It Cm U -.\".Dq utrace . -.\"Generate entries for -.\".Xr ktrace 1 -.\"for all operations. -.\"Consult the source for this one. -.It Cm S -.\" Malloc option S is vaguely documented on purpose. -Enable all options suitable for security auditing. -.It Cm U -.Dq Free unmap . -Enable use after free protection for larger allocations. -Unused pages on the freelist are read and write protected to -cause a segmentation fault upon access. -.It Cm V -.Dq Verbose . -Use with -.Cm D -to get a verbose dump of malloc's internal state. -.It Cm X -.Dq xmalloc . -Rather than return failure, -.Xr abort 3 -the program with a diagnostic message on stderr. -It is the intention that this option be set at compile time by -including in the source: -.Bd -literal -offset indent -extern char *malloc_options; -malloc_options = "X"; -.Ed -.Pp -Note that this will cause code that is supposed to handle -out-of-memory conditions gracefully to abort instead. -.It Cm < -.Dq Halve the cache size . -Decrease the size of the free page cache by a factor of two. -.It Cm > -.Dq Double the cache size . -Increase the size of the free page cache by a factor of two. -.El -.Pp -If a program changes behavior if any of these options (except -.Cm X ) -are used, -it is buggy. -.Pp -The default size of the cache is 64 single page allocations. -It also caches a number of larger regions. -Multi-threaded programs use multiple pools. -.Sh RETURN VALUES -Upon successful completion, the allocation functions -return a pointer to the allocated space; otherwise, -.Dv NULL -is returned and -.Va errno -is set to -.Er ENOMEM . -The function -.Fn aligned_alloc -returns -.Dv NULL -and sets -.Va errno -to -.Er EINVAL -if -.Fa alignment -is not a power of 2. -.Pp -If -.Fa nmemb -or -.Fa size -is equal to 0, a unique pointer to an access protected, -zero sized object is returned. -Access via this pointer will generate a -.Dv SIGSEGV -exception. -.Pp -If multiplying -.Fa nmemb -and -.Fa size -results in integer overflow, -.Fn calloc , -.Fn reallocarray -and -.Fn recallocarray -return -.Dv NULL -and set -.Va errno -to -.Er ENOMEM . -.Pp -If -.Fa ptr -is not -.Dv NULL -and multiplying -.Fa oldnmemb -and -.Fa size -results in integer overflow, -.Fn recallocarray -returns -.Dv NULL -and sets -.Va errno -to -.Er EINVAL . -.Sh IDIOMS -Consider -.Fn calloc -or the extensions -.Fn reallocarray -and -.Fn recallocarray -when there is multiplication in the -.Fa size -argument of -.Fn malloc -or -.Fn realloc . -For example, avoid this common idiom as it may lead to integer overflow: -.Bd -literal -offset indent -if ((p = malloc(num * size)) == NULL) - err(1, NULL); -.Ed -.Pp -A drop-in replacement is the -.Ox -extension -.Fn reallocarray : -.Bd -literal -offset indent -if ((p = reallocarray(NULL, num, size)) == NULL) - err(1, NULL); -.Ed -.Pp -Alternatively, -.Fn calloc -may be used at the cost of initialization overhead. -.Pp -When using -.Fn realloc , -be careful to avoid the following idiom: -.Bd -literal -offset indent -size += 50; -if ((p = realloc(p, size)) == NULL) - return (NULL); -.Ed -.Pp -Do not adjust the variable describing how much memory has been allocated -until the allocation has been successful. -This can cause aberrant program behavior if the incorrect size value is used. -In most cases, the above sample will also result in a leak of memory. -As stated earlier, a return value of -.Dv NULL -indicates that the old object still remains allocated. -Better code looks like this: -.Bd -literal -offset indent -newsize = size + 50; -if ((newp = realloc(p, newsize)) == NULL) { - free(p); - p = NULL; - size = 0; - return (NULL); -} -p = newp; -size = newsize; -.Ed -.Pp -As with -.Fn malloc , -it is important to ensure the new size value will not overflow; -i.e. avoid allocations like the following: -.Bd -literal -offset indent -if ((newp = realloc(p, num * size)) == NULL) { - ... -.Ed -.Pp -Instead, use -.Fn reallocarray : -.Bd -literal -offset indent -if ((newp = reallocarray(p, num, size)) == NULL) { - ... -.Ed -.Pp -Calling -.Fn realloc -with a -.Dv NULL -.Fa ptr -is equivalent to calling -.Fn malloc . -Instead of this idiom: -.Bd -literal -offset indent -if (p == NULL) - newp = malloc(newsize); -else - newp = realloc(p, newsize); -.Ed -.Pp -Use the following: -.Bd -literal -offset indent -newp = realloc(p, newsize); -.Ed -.Pp -The -.Fn recallocarray -function should be used for resizing objects containing sensitive data like -keys. -To avoid leaking information, -it guarantees memory is cleared before placing it on the internal free list. -Deallocation of such an object should be done by calling -.Fn freezero . -.Sh ENVIRONMENT -.Bl -tag -width "MALLOC_OPTIONS" -.It Ev MALLOC_OPTIONS -String of option flags. -.El -.Sh EXAMPLES -If -.Fn malloc -must be used with multiplication, be sure to test for overflow: -.Bd -literal -offset indent -size_t num, size; -\&... - -/* Check for size_t overflow */ -if (size && num > SIZE_MAX / size) - errc(1, EOVERFLOW, "overflow"); - -if ((p = malloc(num * size)) == NULL) - err(1, NULL); -.Ed -.Pp -The above test is not sufficient in all cases. -For example, multiplying ints requires a different set of checks: -.Bd -literal -offset indent -int num, size; -\&... - -/* Avoid invalid requests */ -if (size < 0 || num < 0) - errc(1, EOVERFLOW, "overflow"); - -/* Check for signed int overflow */ -if (size && num > INT_MAX / size) - errc(1, EOVERFLOW, "overflow"); - -if ((p = malloc(num * size)) == NULL) - err(1, NULL); -.Ed -.Pp -Assuming the implementation checks for integer overflow as -.Ox -does, it is much easier to use -.Fn calloc , -.Fn reallocarray , -or -.Fn recallocarray . -.Pp -The above examples could be simplified to: -.Bd -literal -offset indent -if ((p = reallocarray(NULL, num, size)) == NULL) - err(1, NULL); -.Ed -.Pp -or at the cost of initialization: -.Bd -literal -offset indent -if ((p = calloc(num, size)) == NULL) - err(1, NULL); -.Ed -.Pp -Set a systemwide reduction of the cache to a quarter of the -default size and use guard pages: -.Pp -.Dl # sysctl vm.malloc_conf='G<<' -.Sh DIAGNOSTICS -If any of the functions detect an error condition, -a message will be printed to file descriptor -2 (not using stdio). -Errors will result in the process being aborted. -.Pp -Here is a brief description of the error messages and what they mean: -.Bl -tag -width Ds -.It Dq out of memory -If the -.Cm X -option is specified, it is an error for the allocation functions -to return -.Dv NULL . -.It Dq bogus pointer (double free?) -An attempt to -.Fn free -or -reallocate an unallocated pointer was made. -.It Dq double free -There was an attempt to free an allocation that had already been freed. -.It Dq write to free mem Va address Ns [ Va start Ns .. Ns Va end Ns ]@ Ns Va size -An allocation has been modified after it was freed, -or a chunk that was never allocated was written to. -The -.Va range -at which corruption was detected is printed between [ and ]. -.Pp -Enabling option -.Cm D -allows malloc to print information about where the allocation -was done. -.It Dq modified chunk-pointer -The pointer passed to -.Fn free -or a reallocation function has been modified. -.It Dq canary corrupted Va address Ns [ Va offset Ns ]@ Ns Va length Ns / Ns Va size -A byte after the requested -.Va length -has been overwritten, -indicating a heap overflow. -The -.Va offset -at which corruption was detected is printed between [ and ], -the requested -.Va length -of the allocation is printed before the / and the -.Va size -of the allocation after the /. -.It Dq recorded size Va oldsize No inconsistent with Va size -.Fn recallocarray -or -.Fn freezero -has detected that the given old size does not match the recorded size in its -meta data. -Enabling option -.Cm C -allows -.Fn recallocarray -to catch more of these cases. -.It Dq recursive call -An attempt was made to call recursively into these functions, i.e., from a -signal handler. -This behavior is not supported. -In particular, signal handlers should -.Em not -use any of the -.Fn malloc -functions nor utilize any other functions which may call -.Fn malloc -(e.g., -.Xr stdio 3 -routines). -.It Dq unknown char in Ev MALLOC_OPTIONS -We found something we didn't understand. -.It any other error -.Fn malloc -detected an internal error; -consult sources and/or wizards. -.El -.Sh SEE ALSO -.Xr brk 2 , -.Xr mmap 2 , -.Xr munmap 2 , -.Xr sysctl 2 , -.Xr alloca 3 , -.Xr getpagesize 3 , -.Xr posix_memalign 3 -.Sh STANDARDS -The -.Fn malloc , -.Fn calloc , -.Fn realloc , -and -.Fn free -functions conform to -.St -ansiC . -The -.Fn aligned_alloc -function conforms to -.St -isoC-2011 . -The -.Fn reallocarray -function conforms to -.St -p1003.1-2024 . -.Pp -If -.Fa nmemb -or -.Fa size -are 0, the return value is implementation defined; -other conforming implementations may return -.Dv NULL -in this case. -.Pp -The -.Ev MALLOC_OPTIONS -environment variable, the -.Va vm.malloc_conf -sysctl and the -.Sx DIAGNOSTICS -output are extensions to the standard. -.Sh HISTORY -A -.Fn free -internal kernel function and a predecessor to -.Fn malloc , -.Fn alloc , -first appeared in -.At v1 . -C library functions -.Fn alloc -and -.Fn free -appeared in -.At v6 . -The functions -.Fn malloc , -.Fn calloc , -and -.Fn realloc -first appeared in -.At v7 . -.Pp -A new implementation by Chris Kingsley was introduced in -.Bx 4.2 , -followed by a complete rewrite by Poul-Henning Kamp which appeared in -.Fx 2.2 -and was included in -.Ox 2.0 . -These implementations were all -.Xr sbrk 2 -based. -In -.Ox 3.8 , -Thierry Deval rewrote -.Nm -to use the -.Xr mmap 2 -system call, -making the page addresses returned by -.Nm -random. -A rewrite by Otto Moerbeek introducing a new central data structure and more -randomization appeared in -.Ox 4.4 . -.Pp -The -.Fn reallocarray -function appeared in -.Ox 5.6 . -The -.Fn recallocarray -function appeared in -.Ox 6.1 . -The -.Fn freezero -function appeared in -.Ox 6.2 . -The -.Fn aligned_alloc -function appeared in -.Ox 6.5 . -The -.Fn malloc_conceal -and -.Fn calloc_conceal -functions appeared in -.Ox 6.6 . -.Sh CAVEATS -When using -.Fn malloc , -be wary of signed integer and -.Vt size_t -overflow especially when there is multiplication in the -.Fa size -argument. -.Pp -Signed integer overflow will cause undefined behavior which compilers -typically handle by wrapping back around to negative numbers. -Depending on the input, this can result in allocating more or less -memory than intended. -.Pp -An unsigned overflow has defined behavior which will wrap back around and -return less memory than intended. -.Pp -A signed or unsigned integer overflow is a -.Em security -risk if less memory is returned than intended. -Subsequent code may corrupt the heap by writing beyond the memory that was -allocated. -An attacker may be able to leverage this heap corruption to execute arbitrary -code. -.Pp -Consider using -.Fn calloc , -.Fn reallocarray -or -.Fn recallocarray -instead of using multiplication in -.Fn malloc -and -.Fn realloc -to avoid these problems on -.Ox . -.Pp -The mechanism to record caller functions when using malloc options -.Cm 2 , -.Cm 3 , -or -.Cm 4 -is not guaranteed to work for all platforms, compilers or compilation -options, -and might even crash your program. -Use -.Em only -for debugging purposes. diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c deleted file mode 100644 index cad8e5d6a1..0000000000 --- a/src/lib/libc/stdlib/malloc.c +++ /dev/null @@ -1,2781 +0,0 @@ -/* $OpenBSD: malloc.c,v 1.297 2024/09/20 02:00:46 jsg Exp $ */ -/* - * Copyright (c) 2008, 2010, 2011, 2016, 2023 Otto Moerbeek - * Copyright (c) 2012 Matthew Dempsky - * Copyright (c) 2008 Damien Miller - * Copyright (c) 2000 Poul-Henning Kamp - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * If we meet some day, and you think this stuff is worth it, you - * can buy me a beer in return. Poul-Henning Kamp - */ - -#ifndef MALLOC_SMALL -#define MALLOC_STATS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MALLOC_STATS -#include -#include -#include -#endif - -#include "thread_private.h" -#include - -#define MALLOC_PAGESHIFT _MAX_PAGE_SHIFT - -#define MALLOC_MINSHIFT 4 -#define MALLOC_MAXSHIFT (MALLOC_PAGESHIFT - 1) -#define MALLOC_PAGESIZE (1UL << MALLOC_PAGESHIFT) -#define MALLOC_MINSIZE (1UL << MALLOC_MINSHIFT) -#define MALLOC_PAGEMASK (MALLOC_PAGESIZE - 1) -#define MASK_POINTER(p) ((void *)(((uintptr_t)(p)) & ~MALLOC_PAGEMASK)) - -#define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT) -#define MALLOC_MAXCACHE 256 -#define MALLOC_DELAYED_CHUNK_MASK 15 -#ifdef MALLOC_STATS -#define MALLOC_INITIAL_REGIONS 512 -#else -#define MALLOC_INITIAL_REGIONS (MALLOC_PAGESIZE / sizeof(struct region_info)) -#endif -#define MALLOC_DEFAULT_CACHE 64 -#define MALLOC_CHUNK_LISTS 4 -#define CHUNK_CHECK_LENGTH 32 - -#define B2SIZE(b) ((b) * MALLOC_MINSIZE) -#define B2ALLOC(b) ((b) == 0 ? MALLOC_MINSIZE : \ - (b) * MALLOC_MINSIZE) -#define BUCKETS (MALLOC_MAXCHUNK / MALLOC_MINSIZE) - -/* - * We move allocations between half a page and a whole page towards the end, - * subject to alignment constraints. This is the extra headroom we allow. - * Set to zero to be the most strict. - */ -#define MALLOC_LEEWAY 0 -#define MALLOC_MOVE_COND(sz) ((sz) - mopts.malloc_guard < \ - MALLOC_PAGESIZE - MALLOC_LEEWAY) -#define MALLOC_MOVE(p, sz) (((char *)(p)) + \ - ((MALLOC_PAGESIZE - MALLOC_LEEWAY - \ - ((sz) - mopts.malloc_guard)) & \ - ~(MALLOC_MINSIZE - 1))) - -#define PAGEROUND(x) (((x) + (MALLOC_PAGEMASK)) & ~MALLOC_PAGEMASK) - -/* - * What to use for Junk. This is the byte value we use to fill with - * when the 'J' option is enabled. Use SOME_JUNK right after alloc, - * and SOME_FREEJUNK right before free. - */ -#define SOME_JUNK 0xdb /* deadbeef */ -#define SOME_FREEJUNK 0xdf /* dead, free */ -#define SOME_FREEJUNK_ULL 0xdfdfdfdfdfdfdfdfULL - -#define MMAP(sz,f) mmap(NULL, (sz), PROT_READ | PROT_WRITE, \ - MAP_ANON | MAP_PRIVATE | (f), -1, 0) - -#define MMAPNONE(sz,f) mmap(NULL, (sz), PROT_NONE, \ - MAP_ANON | MAP_PRIVATE | (f), -1, 0) - -#define MMAPA(a,sz,f) mmap((a), (sz), PROT_READ | PROT_WRITE, \ - MAP_ANON | MAP_PRIVATE | (f), -1, 0) - -struct region_info { - void *p; /* page; low bits used to mark chunks */ - uintptr_t size; /* size for pages, or chunk_info pointer */ -#ifdef MALLOC_STATS - void **f; /* where allocated from */ -#endif -}; - -LIST_HEAD(chunk_head, chunk_info); - -/* - * Two caches, one for "small" regions, one for "big". - * Small cache is an array per size, big cache is one array with different - * sized regions - */ -#define MAX_SMALLCACHEABLE_SIZE 32 -#define MAX_BIGCACHEABLE_SIZE 512 -/* If the total # of pages is larger than this, evict before inserting */ -#define BIGCACHE_FILL(sz) (MAX_BIGCACHEABLE_SIZE * (sz) / 4) - -struct smallcache { - void **pages; - ushort length; - ushort max; -}; - -struct bigcache { - void *page; - size_t psize; -}; - -#ifdef MALLOC_STATS -#define NUM_FRAMES 4 -struct btnode { - RBT_ENTRY(btnode) entry; - void *caller[NUM_FRAMES]; -}; -RBT_HEAD(btshead, btnode); -RBT_PROTOTYPE(btshead, btnode, entry, btcmp); -#endif /* MALLOC_STATS */ - -struct dir_info { - u_int32_t canary1; - int active; /* status of malloc */ - struct region_info *r; /* region slots */ - size_t regions_total; /* number of region slots */ - size_t regions_free; /* number of free slots */ - size_t rbytesused; /* random bytes used */ - const char *func; /* current function */ - int malloc_junk; /* junk fill? */ - int mmap_flag; /* extra flag for mmap */ - int mutex; - int malloc_mt; /* multi-threaded mode? */ - /* lists of free chunk info structs */ - struct chunk_head chunk_info_list[BUCKETS + 1]; - /* lists of chunks with free slots */ - struct chunk_head chunk_dir[BUCKETS + 1][MALLOC_CHUNK_LISTS]; - /* delayed free chunk slots */ - void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1]; - u_char rbytes[32]; /* random bytes */ - /* free pages cache */ - struct smallcache smallcache[MAX_SMALLCACHEABLE_SIZE]; - size_t bigcache_used; - size_t bigcache_size; - struct bigcache *bigcache; - void *chunk_pages; - size_t chunk_pages_used; -#ifdef MALLOC_STATS - void *caller; - size_t inserts; - size_t insert_collisions; - size_t deletes; - size_t delete_moves; - size_t cheap_realloc_tries; - size_t cheap_reallocs; - size_t malloc_used; /* bytes allocated */ - size_t malloc_guarded; /* bytes used for guards */ - struct btshead btraces; /* backtraces seen */ - struct btnode *btnodes; /* store of backtrace nodes */ - size_t btnodesused; -#define STATS_ADD(x,y) ((x) += (y)) -#define STATS_SUB(x,y) ((x) -= (y)) -#define STATS_INC(x) ((x)++) -#define STATS_ZERO(x) ((x) = 0) -#define STATS_SETF(x,y) ((x)->f = (y)) -#define STATS_SETFN(x,k,y) ((x)->f[k] = (y)) -#define SET_CALLER(x,y) if (DO_STATS) ((x)->caller = (y)) -#else -#define STATS_ADD(x,y) /* nothing */ -#define STATS_SUB(x,y) /* nothing */ -#define STATS_INC(x) /* nothing */ -#define STATS_ZERO(x) /* nothing */ -#define STATS_SETF(x,y) /* nothing */ -#define STATS_SETFN(x,k,y) /* nothing */ -#define SET_CALLER(x,y) /* nothing */ -#endif /* MALLOC_STATS */ - u_int32_t canary2; -}; - -static void unmap(struct dir_info *d, void *p, size_t sz, size_t clear); - -/* - * This structure describes a page worth of chunks. - * - * How many bits per u_short in the bitmap - */ -#define MALLOC_BITS (NBBY * sizeof(u_short)) -struct chunk_info { - LIST_ENTRY(chunk_info) entries; - void *page; /* pointer to the page */ - /* number of shorts should add up to 8, check alloc_chunk_info() */ - u_short canary; - u_short bucket; - u_short free; /* how many free chunks */ - u_short total; /* how many chunks */ - u_short offset; /* requested size table offset */ -#define CHUNK_INFO_TAIL 3 - u_short bits[CHUNK_INFO_TAIL]; /* which chunks are free */ -}; - -#define CHUNK_FREE(i, n) ((i)->bits[(n) / MALLOC_BITS] & \ - (1U << ((n) % MALLOC_BITS))) - -struct malloc_readonly { - /* Main bookkeeping information */ - struct dir_info *malloc_pool[_MALLOC_MUTEXES]; - u_int malloc_mutexes; /* how much in actual use? */ - int malloc_freecheck; /* Extensive double free check */ - int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ - int def_malloc_junk; /* junk fill? */ - int malloc_realloc; /* always realloc? */ - int malloc_xmalloc; /* xmalloc behaviour? */ - u_int chunk_canaries; /* use canaries after chunks? */ - int internal_funcs; /* use better recallocarray/freezero? */ - u_int def_maxcache; /* free pages we cache */ - u_int junk_loc; /* variation in location of junk */ - size_t malloc_guard; /* use guard pages after allocations? */ -#ifdef MALLOC_STATS - int malloc_stats; /* save callers, dump leak report */ - int malloc_verbose; /* dump verbose statistics at end */ -#define DO_STATS mopts.malloc_stats -#else -#define DO_STATS 0 -#endif - u_int32_t malloc_canary; /* Matched against ones in pool */ -}; - - -/* This object is mapped PROT_READ after initialisation to prevent tampering */ -static union { - struct malloc_readonly mopts; - u_char _pad[MALLOC_PAGESIZE]; -} malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE))) - __attribute__((section(".openbsd.mutable"))); -#define mopts malloc_readonly.mopts - -char *malloc_options; /* compile-time options */ - -static __dead void wrterror(struct dir_info *d, char *msg, ...) - __attribute__((__format__ (printf, 2, 3))); - -#ifdef MALLOC_STATS -void malloc_dump(void); -PROTO_NORMAL(malloc_dump); -static void malloc_exit(void); -static void print_chunk_details(struct dir_info *, void *, size_t, size_t); -static void* store_caller(struct dir_info *, struct btnode *); - -/* below are the arches for which deeper caller info has been tested */ -#if defined(__aarch64__) || \ - defined(__amd64__) || \ - defined(__arm__) || \ - defined(__i386__) || \ - defined(__powerpc__) -__attribute__((always_inline)) -static inline void* -caller(struct dir_info *d) -{ - struct btnode p; - int level = DO_STATS; - - if (level == 0) - return NULL; - - memset(&p.caller, 0, sizeof(p.caller)); - if (level >= 1) - p.caller[0] = __builtin_extract_return_addr( - __builtin_return_address(0)); - if (p.caller[0] != NULL && level >= 2) - p.caller[1] = __builtin_extract_return_addr( - __builtin_return_address(1)); - if (p.caller[1] != NULL && level >= 3) - p.caller[2] = __builtin_extract_return_addr( - __builtin_return_address(2)); - if (p.caller[2] != NULL && level >= 4) - p.caller[3] = __builtin_extract_return_addr( - __builtin_return_address(3)); - return store_caller(d, &p); -} -#else -__attribute__((always_inline)) -static inline void* caller(struct dir_info *d) -{ - struct btnode p; - - if (DO_STATS == 0) - return NULL; - memset(&p.caller, 0, sizeof(p.caller)); - p.caller[0] = __builtin_extract_return_addr(__builtin_return_address(0)); - return store_caller(d, &p); -} -#endif -#endif /* MALLOC_STATS */ - -/* low bits of r->p determine size: 0 means >= page size and r->size holding - * real size, otherwise low bits is the bucket + 1 - */ -#define REALSIZE(sz, r) \ - (sz) = (uintptr_t)(r)->p & MALLOC_PAGEMASK, \ - (sz) = ((sz) == 0 ? (r)->size : B2SIZE((sz) - 1)) - -static inline size_t -hash(void *p) -{ - size_t sum; - uintptr_t u; - - u = (uintptr_t)p >> MALLOC_PAGESHIFT; - sum = u; - sum = (sum << 7) - sum + (u >> 16); -#ifdef __LP64__ - sum = (sum << 7) - sum + (u >> 32); - sum = (sum << 7) - sum + (u >> 48); -#endif - return sum; -} - -static inline struct dir_info * -getpool(void) -{ - if (mopts.malloc_pool[1] == NULL || !mopts.malloc_pool[1]->malloc_mt) - return mopts.malloc_pool[1]; - else /* first one reserved for special pool */ - return mopts.malloc_pool[1 + TIB_GET()->tib_tid % - (mopts.malloc_mutexes - 1)]; -} - -static __dead void -wrterror(struct dir_info *d, char *msg, ...) -{ - int saved_errno = errno; - va_list ap; - - dprintf(STDERR_FILENO, "%s(%d) in %s(): ", __progname, - getpid(), (d != NULL && d->func) ? d->func : "unknown"); - va_start(ap, msg); - vdprintf(STDERR_FILENO, msg, ap); - va_end(ap); - dprintf(STDERR_FILENO, "\n"); - -#ifdef MALLOC_STATS - if (DO_STATS && mopts.malloc_verbose) - malloc_dump(); -#endif - - errno = saved_errno; - - abort(); -} - -static void -rbytes_init(struct dir_info *d) -{ - arc4random_buf(d->rbytes, sizeof(d->rbytes)); - /* add 1 to account for using d->rbytes[0] */ - d->rbytesused = 1 + d->rbytes[0] % (sizeof(d->rbytes) / 2); -} - -static inline u_char -getrbyte(struct dir_info *d) -{ - u_char x; - - if (d->rbytesused >= sizeof(d->rbytes)) - rbytes_init(d); - x = d->rbytes[d->rbytesused++]; - return x; -} - -static void -omalloc_parseopt(char opt) -{ - switch (opt) { - case '+': - mopts.malloc_mutexes <<= 1; - if (mopts.malloc_mutexes > _MALLOC_MUTEXES) - mopts.malloc_mutexes = _MALLOC_MUTEXES; - break; - case '-': - mopts.malloc_mutexes >>= 1; - if (mopts.malloc_mutexes < 2) - mopts.malloc_mutexes = 2; - break; - case '>': - mopts.def_maxcache <<= 1; - if (mopts.def_maxcache > MALLOC_MAXCACHE) - mopts.def_maxcache = MALLOC_MAXCACHE; - break; - case '<': - mopts.def_maxcache >>= 1; - break; - case 'c': - mopts.chunk_canaries = 0; - break; - case 'C': - mopts.chunk_canaries = 1; - break; -#ifdef MALLOC_STATS - case 'd': - mopts.malloc_stats = 0; - break; - case 'D': - case '1': - mopts.malloc_stats = 1; - break; - case '2': - mopts.malloc_stats = 2; - break; - case '3': - mopts.malloc_stats = 3; - break; - case '4': - mopts.malloc_stats = 4; - break; -#endif /* MALLOC_STATS */ - case 'f': - mopts.malloc_freecheck = 0; - mopts.malloc_freeunmap = 0; - break; - case 'F': - mopts.malloc_freecheck = 1; - mopts.malloc_freeunmap = 1; - break; - case 'g': - mopts.malloc_guard = 0; - break; - case 'G': - mopts.malloc_guard = MALLOC_PAGESIZE; - break; - case 'j': - if (mopts.def_malloc_junk > 0) - mopts.def_malloc_junk--; - break; - case 'J': - if (mopts.def_malloc_junk < 2) - mopts.def_malloc_junk++; - break; - case 'r': - mopts.malloc_realloc = 0; - break; - case 'R': - mopts.malloc_realloc = 1; - break; - case 'u': - mopts.malloc_freeunmap = 0; - break; - case 'U': - mopts.malloc_freeunmap = 1; - break; -#ifdef MALLOC_STATS - case 'v': - mopts.malloc_verbose = 0; - break; - case 'V': - mopts.malloc_verbose = 1; - break; -#endif /* MALLOC_STATS */ - case 'x': - mopts.malloc_xmalloc = 0; - break; - case 'X': - mopts.malloc_xmalloc = 1; - break; - default: - dprintf(STDERR_FILENO, "malloc() warning: " - "unknown char in MALLOC_OPTIONS\n"); - break; - } -} - -static void -omalloc_init(void) -{ - char *p, *q, b[16]; - int i, j; - const int mib[2] = { CTL_VM, VM_MALLOC_CONF }; - size_t sb; - - /* - * Default options - */ - mopts.malloc_mutexes = 8; - mopts.def_malloc_junk = 1; - mopts.def_maxcache = MALLOC_DEFAULT_CACHE; - - for (i = 0; i < 3; i++) { - switch (i) { - case 0: - sb = sizeof(b); - j = sysctl(mib, 2, b, &sb, NULL, 0); - if (j != 0) - continue; - p = b; - break; - case 1: - if (issetugid() == 0) - p = getenv("MALLOC_OPTIONS"); - else - continue; - break; - case 2: - p = malloc_options; - break; - default: - p = NULL; - } - - for (; p != NULL && *p != '\0'; p++) { - switch (*p) { - case 'S': - for (q = "CFGJ"; *q != '\0'; q++) - omalloc_parseopt(*q); - mopts.def_maxcache = 0; - break; - case 's': - for (q = "cfgj"; *q != '\0'; q++) - omalloc_parseopt(*q); - mopts.def_maxcache = MALLOC_DEFAULT_CACHE; - break; - default: - omalloc_parseopt(*p); - break; - } - } - } - -#ifdef MALLOC_STATS - if (DO_STATS && (atexit(malloc_exit) == -1)) { - dprintf(STDERR_FILENO, "malloc() warning: atexit(3) failed." - " Will not be able to dump stats on exit\n"); - } -#endif - - while ((mopts.malloc_canary = arc4random()) == 0) - ; - mopts.junk_loc = arc4random(); - if (mopts.chunk_canaries) - do { - mopts.chunk_canaries = arc4random(); - } while ((u_char)mopts.chunk_canaries == 0 || - (u_char)mopts.chunk_canaries == SOME_FREEJUNK); -} - -static void -omalloc_poolinit(struct dir_info *d, int mmap_flag) -{ - u_int i, j; - - d->r = NULL; - d->rbytesused = sizeof(d->rbytes); - d->regions_free = d->regions_total = 0; - for (i = 0; i <= BUCKETS; i++) { - LIST_INIT(&d->chunk_info_list[i]); - for (j = 0; j < MALLOC_CHUNK_LISTS; j++) - LIST_INIT(&d->chunk_dir[i][j]); - } - d->mmap_flag = mmap_flag; - d->malloc_junk = mopts.def_malloc_junk; -#ifdef MALLOC_STATS - RBT_INIT(btshead, &d->btraces); -#endif - d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; - d->canary2 = ~d->canary1; -} - -static int -omalloc_grow(struct dir_info *d) -{ - size_t newtotal; - size_t newsize; - size_t mask; - size_t i, oldpsz; - struct region_info *p; - - if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2) - return 1; - - newtotal = d->regions_total == 0 ? MALLOC_INITIAL_REGIONS : - d->regions_total * 2; - newsize = PAGEROUND(newtotal * sizeof(struct region_info)); - mask = newtotal - 1; - - /* Don't use cache here, we don't want user uaf touch this */ - p = MMAP(newsize, d->mmap_flag); - if (p == MAP_FAILED) - return 1; - - STATS_ADD(d->malloc_used, newsize); - STATS_ZERO(d->inserts); - STATS_ZERO(d->insert_collisions); - for (i = 0; i < d->regions_total; i++) { - void *q = d->r[i].p; - if (q != NULL) { - size_t index = hash(q) & mask; - STATS_INC(d->inserts); - while (p[index].p != NULL) { - index = (index - 1) & mask; - STATS_INC(d->insert_collisions); - } - p[index] = d->r[i]; - } - } - - if (d->regions_total > 0) { - oldpsz = PAGEROUND(d->regions_total * - sizeof(struct region_info)); - /* clear to avoid meta info ending up in the cache */ - unmap(d, d->r, oldpsz, oldpsz); - } - d->regions_free += newtotal - d->regions_total; - d->regions_total = newtotal; - d->r = p; - return 0; -} - -/* - * The hashtable uses the assumption that p is never NULL. This holds since - * non-MAP_FIXED mappings with hint 0 start at BRKSIZ. - */ -static int -insert(struct dir_info *d, void *p, size_t sz, void *f) -{ - size_t index; - size_t mask; - void *q; - - if (d->regions_free * 4 < d->regions_total || d->regions_total == 0) { - if (omalloc_grow(d)) - return 1; - } - mask = d->regions_total - 1; - index = hash(p) & mask; - q = d->r[index].p; - STATS_INC(d->inserts); - while (q != NULL) { - index = (index - 1) & mask; - q = d->r[index].p; - STATS_INC(d->insert_collisions); - } - d->r[index].p = p; - d->r[index].size = sz; - STATS_SETF(&d->r[index], f); - d->regions_free--; - return 0; -} - -static struct region_info * -find(struct dir_info *d, void *p) -{ - size_t index; - size_t mask = d->regions_total - 1; - void *q, *r; - - if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || - d->canary1 != ~d->canary2) - wrterror(d, "internal struct corrupt"); - if (d->r == NULL) - return NULL; - p = MASK_POINTER(p); - index = hash(p) & mask; - r = d->r[index].p; - q = MASK_POINTER(r); - while (q != p && r != NULL) { - index = (index - 1) & mask; - r = d->r[index].p; - q = MASK_POINTER(r); - } - return (q == p && r != NULL) ? &d->r[index] : NULL; -} - -static void -delete(struct dir_info *d, struct region_info *ri) -{ - /* algorithm R, Knuth Vol III section 6.4 */ - size_t mask = d->regions_total - 1; - size_t i, j, r; - - if (d->regions_total & (d->regions_total - 1)) - wrterror(d, "regions_total not 2^x"); - d->regions_free++; - STATS_INC(d->deletes); - - i = ri - d->r; - for (;;) { - d->r[i].p = NULL; - d->r[i].size = 0; - j = i; - for (;;) { - i = (i - 1) & mask; - if (d->r[i].p == NULL) - return; - r = hash(d->r[i].p) & mask; - if ((i <= r && r < j) || (r < j && j < i) || - (j < i && i <= r)) - continue; - d->r[j] = d->r[i]; - STATS_INC(d->delete_moves); - break; - } - - } -} - -static inline void -junk_free(int junk, void *p, size_t sz) -{ - size_t i, step = 1; - uint64_t *lp = p; - - if (junk == 0 || sz == 0) - return; - sz /= sizeof(uint64_t); - if (junk == 1) { - if (sz > MALLOC_PAGESIZE / sizeof(uint64_t)) - sz = MALLOC_PAGESIZE / sizeof(uint64_t); - step = sz / 4; - if (step == 0) - step = 1; - } - /* Do not always put the free junk bytes in the same spot. - There is modulo bias here, but we ignore that. */ - for (i = mopts.junk_loc % step; i < sz; i += step) - lp[i] = SOME_FREEJUNK_ULL; -} - -static inline void -validate_junk(struct dir_info *pool, void *p, size_t argsz) -{ - size_t i, sz, step = 1; - uint64_t *lp = p; - - if (pool->malloc_junk == 0 || argsz == 0) - return; - sz = argsz / sizeof(uint64_t); - if (pool->malloc_junk == 1) { - if (sz > MALLOC_PAGESIZE / sizeof(uint64_t)) - sz = MALLOC_PAGESIZE / sizeof(uint64_t); - step = sz / 4; - if (step == 0) - step = 1; - } - /* see junk_free */ - for (i = mopts.junk_loc % step; i < sz; i += step) { - if (lp[i] != SOME_FREEJUNK_ULL) { -#ifdef MALLOC_STATS - if (DO_STATS && argsz <= MALLOC_MAXCHUNK) - print_chunk_details(pool, lp, argsz, i); - else -#endif - wrterror(pool, - "write to free mem %p[%zu..%zu]@%zu", - lp, i * sizeof(uint64_t), - (i + 1) * sizeof(uint64_t) - 1, argsz); - } - } -} - - -/* - * Cache maintenance. - * Opposed to the regular region data structure, the sizes in the - * cache are in MALLOC_PAGESIZE units. - */ -static void -unmap(struct dir_info *d, void *p, size_t sz, size_t clear) -{ - size_t psz = sz >> MALLOC_PAGESHIFT; - void *r; - u_short i; - struct smallcache *cache; - - if (sz != PAGEROUND(sz) || psz == 0) - wrterror(d, "munmap round"); - - if (d->bigcache_size > 0 && psz > MAX_SMALLCACHEABLE_SIZE && - psz <= MAX_BIGCACHEABLE_SIZE) { - u_short base = getrbyte(d); - u_short j; - - /* don't look through all slots */ - for (j = 0; j < d->bigcache_size / 4; j++) { - i = (base + j) & (d->bigcache_size - 1); - if (d->bigcache_used < - BIGCACHE_FILL(d->bigcache_size)) { - if (d->bigcache[i].psize == 0) - break; - } else { - if (d->bigcache[i].psize != 0) - break; - } - } - /* if we didn't find a preferred slot, use random one */ - if (d->bigcache[i].psize != 0) { - size_t tmp; - - r = d->bigcache[i].page; - d->bigcache_used -= d->bigcache[i].psize; - tmp = d->bigcache[i].psize << MALLOC_PAGESHIFT; - if (!mopts.malloc_freeunmap) - validate_junk(d, r, tmp); - if (munmap(r, tmp)) - wrterror(d, "munmap %p", r); - STATS_SUB(d->malloc_used, tmp); - } - - if (clear > 0) - explicit_bzero(p, clear); - if (mopts.malloc_freeunmap) { - if (mprotect(p, sz, PROT_NONE)) - wrterror(d, "mprotect %p", r); - } else - junk_free(d->malloc_junk, p, sz); - d->bigcache[i].page = p; - d->bigcache[i].psize = psz; - d->bigcache_used += psz; - return; - } - if (psz > MAX_SMALLCACHEABLE_SIZE || d->smallcache[psz - 1].max == 0) { - if (munmap(p, sz)) - wrterror(d, "munmap %p", p); - STATS_SUB(d->malloc_used, sz); - return; - } - cache = &d->smallcache[psz - 1]; - if (cache->length == cache->max) { - int fresh; - /* use a random slot */ - i = getrbyte(d) & (cache->max - 1); - r = cache->pages[i]; - fresh = (uintptr_t)r & 1; - *(uintptr_t*)&r &= ~1UL; - if (!fresh && !mopts.malloc_freeunmap) - validate_junk(d, r, sz); - if (munmap(r, sz)) - wrterror(d, "munmap %p", r); - STATS_SUB(d->malloc_used, sz); - cache->length--; - } else - i = cache->length; - - /* fill slot */ - if (clear > 0) - explicit_bzero(p, clear); - if (mopts.malloc_freeunmap) - mprotect(p, sz, PROT_NONE); - else - junk_free(d->malloc_junk, p, sz); - cache->pages[i] = p; - cache->length++; -} - -static void * -map(struct dir_info *d, size_t sz, int zero_fill) -{ - size_t psz = sz >> MALLOC_PAGESHIFT; - u_short i; - void *p; - struct smallcache *cache; - - if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || - d->canary1 != ~d->canary2) - wrterror(d, "internal struct corrupt"); - if (sz != PAGEROUND(sz) || psz == 0) - wrterror(d, "map round"); - - - if (d->bigcache_size > 0 && psz > MAX_SMALLCACHEABLE_SIZE && - psz <= MAX_BIGCACHEABLE_SIZE) { - size_t base = getrbyte(d); - size_t cached = d->bigcache_used; - ushort j; - - for (j = 0; j < d->bigcache_size && cached >= psz; j++) { - i = (j + base) & (d->bigcache_size - 1); - if (d->bigcache[i].psize == psz) { - p = d->bigcache[i].page; - d->bigcache_used -= psz; - d->bigcache[i].page = NULL; - d->bigcache[i].psize = 0; - - if (!mopts.malloc_freeunmap) - validate_junk(d, p, sz); - if (mopts.malloc_freeunmap) - mprotect(p, sz, PROT_READ | PROT_WRITE); - if (zero_fill) - memset(p, 0, sz); - else if (mopts.malloc_freeunmap) - junk_free(d->malloc_junk, p, sz); - return p; - } - cached -= d->bigcache[i].psize; - } - } - if (psz <= MAX_SMALLCACHEABLE_SIZE && d->smallcache[psz - 1].max > 0) { - cache = &d->smallcache[psz - 1]; - if (cache->length > 0) { - int fresh; - if (cache->length == 1) - p = cache->pages[--cache->length]; - else { - i = getrbyte(d) % cache->length; - p = cache->pages[i]; - cache->pages[i] = cache->pages[--cache->length]; - } - /* check if page was not junked, i.e. "fresh - we use the lsb of the pointer for that */ - fresh = (uintptr_t)p & 1UL; - *(uintptr_t*)&p &= ~1UL; - if (!fresh && !mopts.malloc_freeunmap) - validate_junk(d, p, sz); - if (mopts.malloc_freeunmap) - mprotect(p, sz, PROT_READ | PROT_WRITE); - if (zero_fill) - memset(p, 0, sz); - else if (mopts.malloc_freeunmap) - junk_free(d->malloc_junk, p, sz); - return p; - } - if (psz <= 1) { - p = MMAP(cache->max * sz, d->mmap_flag); - if (p != MAP_FAILED) { - STATS_ADD(d->malloc_used, cache->max * sz); - cache->length = cache->max - 1; - for (i = 0; i < cache->max - 1; i++) { - void *q = (char*)p + i * sz; - cache->pages[i] = q; - /* mark pointer in slot as not junked */ - *(uintptr_t*)&cache->pages[i] |= 1UL; - } - if (mopts.malloc_freeunmap) - mprotect(p, (cache->max - 1) * sz, - PROT_NONE); - p = (char*)p + (cache->max - 1) * sz; - /* zero fill not needed, freshly mmapped */ - return p; - } - } - - } - p = MMAP(sz, d->mmap_flag); - if (p != MAP_FAILED) - STATS_ADD(d->malloc_used, sz); - /* zero fill not needed */ - return p; -} - -static void -init_chunk_info(struct dir_info *d, struct chunk_info *p, u_int bucket) -{ - u_int i; - - p->bucket = bucket; - p->total = p->free = MALLOC_PAGESIZE / B2ALLOC(bucket); - p->offset = howmany(p->total, MALLOC_BITS); - p->canary = (u_short)d->canary1; - - /* set all valid bits in the bitmap */ - i = p->total - 1; - memset(p->bits, 0xff, sizeof(p->bits[0]) * (i / MALLOC_BITS)); - p->bits[i / MALLOC_BITS] = (2U << (i % MALLOC_BITS)) - 1; -} - -static struct chunk_info * -alloc_chunk_info(struct dir_info *d, u_int bucket) -{ - struct chunk_info *p; - - if (LIST_EMPTY(&d->chunk_info_list[bucket])) { - const size_t chunk_pages = 64; - size_t size, count, i; - char *q; - - count = MALLOC_PAGESIZE / B2ALLOC(bucket); - - size = howmany(count, MALLOC_BITS); - /* see declaration of struct chunk_info */ - if (size <= CHUNK_INFO_TAIL) - size = 0; - else - size -= CHUNK_INFO_TAIL; - size = sizeof(struct chunk_info) + size * sizeof(u_short); - if (mopts.chunk_canaries && bucket > 0) - size += count * sizeof(u_short); - size = _ALIGN(size); - count = MALLOC_PAGESIZE / size; - - /* Don't use cache here, we don't want user uaf touch this */ - if (d->chunk_pages_used == chunk_pages || - d->chunk_pages == NULL) { - q = MMAP(MALLOC_PAGESIZE * chunk_pages, d->mmap_flag); - if (q == MAP_FAILED) - return NULL; - d->chunk_pages = q; - d->chunk_pages_used = 0; - STATS_ADD(d->malloc_used, MALLOC_PAGESIZE * - chunk_pages); - } - q = (char *)d->chunk_pages + d->chunk_pages_used * - MALLOC_PAGESIZE; - d->chunk_pages_used++; - - for (i = 0; i < count; i++, q += size) { - p = (struct chunk_info *)q; - LIST_INSERT_HEAD(&d->chunk_info_list[bucket], p, - entries); - } - } - p = LIST_FIRST(&d->chunk_info_list[bucket]); - LIST_REMOVE(p, entries); - if (p->total == 0) - init_chunk_info(d, p, bucket); - return p; -} - -/* - * Allocate a page of chunks - */ -static struct chunk_info * -omalloc_make_chunks(struct dir_info *d, u_int bucket, u_int listnum) -{ - struct chunk_info *bp; - void *pp; - void *ff = NULL; - - /* Allocate a new bucket */ - pp = map(d, MALLOC_PAGESIZE, 0); - if (pp == MAP_FAILED) - return NULL; - if (DO_STATS) { - ff = map(d, MALLOC_PAGESIZE, 0); - if (ff == MAP_FAILED) - goto err; - memset(ff, 0, sizeof(void *) * MALLOC_PAGESIZE / - B2ALLOC(bucket)); - } - - /* memory protect the page allocated in the malloc(0) case */ - if (bucket == 0 && mprotect(pp, MALLOC_PAGESIZE, PROT_NONE) == -1) - goto err; - - bp = alloc_chunk_info(d, bucket); - if (bp == NULL) - goto err; - bp->page = pp; - - if (insert(d, (void *)((uintptr_t)pp | (bucket + 1)), (uintptr_t)bp, - ff)) - goto err; - LIST_INSERT_HEAD(&d->chunk_dir[bucket][listnum], bp, entries); - - if (bucket > 0 && d->malloc_junk != 0) - memset(pp, SOME_FREEJUNK, MALLOC_PAGESIZE); - - return bp; - -err: - unmap(d, pp, MALLOC_PAGESIZE, 0); - if (ff != NULL && ff != MAP_FAILED) - unmap(d, ff, MALLOC_PAGESIZE, 0); - return NULL; -} - -#if defined(__GNUC__) && __GNUC__ < 4 -static inline unsigned int -lb(u_int x) -{ -#if defined(__m88k__) - __asm__ __volatile__ ("ff1 %0, %0" : "=r" (x) : "0" (x)); - return x; -#else - /* portable version */ - unsigned int count = 0; - while ((x & (1U << (sizeof(int) * CHAR_BIT - 1))) == 0) { - count++; - x <<= 1; - } - return (sizeof(int) * CHAR_BIT - 1) - count; -#endif -} -#else -/* using built-in function version */ -static inline unsigned int -lb(u_int x) -{ - /* I need an extension just for integer-length (: */ - return (sizeof(int) * CHAR_BIT - 1) - __builtin_clz(x); -} -#endif - -/* https://pvk.ca/Blog/2015/06/27/linear-log-bucketing-fast-versatile-simple/ - via Tony Finch */ -static inline unsigned int -bin_of(unsigned int size) -{ - const unsigned int linear = 6; - const unsigned int subbin = 2; - - unsigned int mask, rounded, rounded_size; - unsigned int n_bits, shift; - - n_bits = lb(size | (1U << linear)); - shift = n_bits - subbin; - mask = (1ULL << shift) - 1; - rounded = size + mask; /* XXX: overflow. */ - - rounded_size = rounded & ~mask; - return rounded_size; -} - -static inline u_short -find_bucket(u_short size) -{ - /* malloc(0) is special */ - if (size == 0) - return 0; - if (size < MALLOC_MINSIZE) - size = MALLOC_MINSIZE; - if (mopts.def_maxcache != 0) - size = bin_of(size); - return howmany(size, MALLOC_MINSIZE); -} - -static void -fill_canary(char *ptr, size_t sz, size_t allocated) -{ - size_t check_sz = allocated - sz; - - if (check_sz > CHUNK_CHECK_LENGTH) - check_sz = CHUNK_CHECK_LENGTH; - memset(ptr + sz, mopts.chunk_canaries, check_sz); -} - -/* - * Allocate a chunk - */ -static void * -malloc_bytes(struct dir_info *d, size_t size) -{ - u_int i, j, k, r, bucket, listnum; - u_short *lp; - struct chunk_info *bp; - void *p; - - if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || - d->canary1 != ~d->canary2) - wrterror(d, "internal struct corrupt"); - - bucket = find_bucket(size); - - r = getrbyte(d); - listnum = r % MALLOC_CHUNK_LISTS; - - /* If it's empty, make a page more of that size chunks */ - if ((bp = LIST_FIRST(&d->chunk_dir[bucket][listnum])) == NULL) { - bp = omalloc_make_chunks(d, bucket, listnum); - if (bp == NULL) - return NULL; - } - - if (bp->canary != (u_short)d->canary1 || bucket != bp->bucket) - wrterror(d, "chunk info corrupted"); - - r /= MALLOC_CHUNK_LISTS; - /* do we need more random bits? */ - if (bp->total > 256 / MALLOC_CHUNK_LISTS) - r = r << 8 | getrbyte(d); - /* bias, as bp->total is not a power of 2 */ - i = r % bp->total; - - j = i % MALLOC_BITS; - i /= MALLOC_BITS; - lp = &bp->bits[i]; - /* potentially start somewhere in a short */ - if (j > 0 && *lp >> j) - k = ffs(*lp >> j) + j; - else { - /* no bit halfway, go to next full short */ - for (;;) { - if (*lp) { - k = ffs(*lp); - break; - } - if (++i >= bp->offset) - i = 0; - lp = &bp->bits[i]; - } - } - *lp ^= 1 << --k; - - /* If there are no more free, remove from free-list */ - if (--bp->free == 0) - LIST_REMOVE(bp, entries); - - /* Adjust to the real offset of that chunk */ - k += i * MALLOC_BITS; - - if (mopts.chunk_canaries && size > 0) - bp->bits[bp->offset + k] = size; - - if (DO_STATS) { - struct region_info *r = find(d, bp->page); - STATS_SETFN(r, k, d->caller); - } - - p = (char *)bp->page + k * B2ALLOC(bucket); - if (bucket > 0) { - validate_junk(d, p, B2SIZE(bucket)); - if (mopts.chunk_canaries) - fill_canary(p, size, B2SIZE(bucket)); - } - return p; -} - -static void -validate_canary(struct dir_info *d, u_char *ptr, size_t sz, size_t allocated) -{ - size_t check_sz = allocated - sz; - u_char *p, *q; - - if (check_sz > CHUNK_CHECK_LENGTH) - check_sz = CHUNK_CHECK_LENGTH; - p = ptr + sz; - q = p + check_sz; - - while (p < q) { - if (*p != (u_char)mopts.chunk_canaries && *p != SOME_JUNK) { - wrterror(d, "canary corrupted %p[%tu]@%zu/%zu%s", - ptr, p - ptr, sz, allocated, - *p == SOME_FREEJUNK ? " (double free?)" : ""); - } - p++; - } -} - -static inline uint32_t -find_chunknum(struct dir_info *d, struct chunk_info *info, void *ptr, int check) -{ - uint32_t chunknum; - - if (info->canary != (u_short)d->canary1) - wrterror(d, "chunk info corrupted"); - - /* Find the chunk number on the page */ - chunknum = ((uintptr_t)ptr & MALLOC_PAGEMASK) / B2ALLOC(info->bucket); - - if ((uintptr_t)ptr & (MALLOC_MINSIZE - 1)) - wrterror(d, "modified chunk-pointer %p", ptr); - if (CHUNK_FREE(info, chunknum)) - wrterror(d, "double free %p", ptr); - if (check && info->bucket > 0) { - validate_canary(d, ptr, info->bits[info->offset + chunknum], - B2SIZE(info->bucket)); - } - return chunknum; -} - -/* - * Free a chunk, and possibly the page it's on, if the page becomes empty. - */ -static void -free_bytes(struct dir_info *d, struct region_info *r, void *ptr) -{ - struct chunk_head *mp; - struct chunk_info *info; - uint32_t chunknum; - uint32_t listnum; - - info = (struct chunk_info *)r->size; - chunknum = find_chunknum(d, info, ptr, 0); - - info->bits[chunknum / MALLOC_BITS] |= 1U << (chunknum % MALLOC_BITS); - info->free++; - - if (info->free == 1) { - /* Page became non-full */ - listnum = getrbyte(d) % MALLOC_CHUNK_LISTS; - mp = &d->chunk_dir[info->bucket][listnum]; - LIST_INSERT_HEAD(mp, info, entries); - return; - } - - if (info->free != info->total) - return; - - LIST_REMOVE(info, entries); - - if (info->bucket == 0 && !mopts.malloc_freeunmap) - mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE); - unmap(d, info->page, MALLOC_PAGESIZE, 0); -#ifdef MALLOC_STATS - if (r->f != NULL) { - unmap(d, r->f, MALLOC_PAGESIZE, MALLOC_PAGESIZE); - r->f = NULL; - } -#endif - - delete(d, r); - mp = &d->chunk_info_list[info->bucket]; - LIST_INSERT_HEAD(mp, info, entries); -} - -static void * -omalloc(struct dir_info *pool, size_t sz, int zero_fill) -{ - void *p, *caller = NULL; - size_t psz; - - if (sz > MALLOC_MAXCHUNK) { - if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { - errno = ENOMEM; - return NULL; - } - sz += mopts.malloc_guard; - psz = PAGEROUND(sz); - p = map(pool, psz, zero_fill); - if (p == MAP_FAILED) { - errno = ENOMEM; - return NULL; - } -#ifdef MALLOC_STATS - if (DO_STATS) - caller = pool->caller; -#endif - if (insert(pool, p, sz, caller)) { - unmap(pool, p, psz, 0); - errno = ENOMEM; - return NULL; - } - if (mopts.malloc_guard) { - if (mprotect((char *)p + psz - mopts.malloc_guard, - mopts.malloc_guard, PROT_NONE)) - wrterror(pool, "mprotect"); - STATS_ADD(pool->malloc_guarded, mopts.malloc_guard); - } - - if (MALLOC_MOVE_COND(sz)) { - /* fill whole allocation */ - if (pool->malloc_junk == 2) - memset(p, SOME_JUNK, psz - mopts.malloc_guard); - /* shift towards the end */ - p = MALLOC_MOVE(p, sz); - /* fill zeros if needed and overwritten above */ - if (zero_fill && pool->malloc_junk == 2) - memset(p, 0, sz - mopts.malloc_guard); - } else { - if (pool->malloc_junk == 2) { - if (zero_fill) - memset((char *)p + sz - - mopts.malloc_guard, SOME_JUNK, - psz - sz); - else - memset(p, SOME_JUNK, - psz - mopts.malloc_guard); - } else if (mopts.chunk_canaries) - fill_canary(p, sz - mopts.malloc_guard, - psz - mopts.malloc_guard); - } - - } else { - /* takes care of SOME_JUNK */ - p = malloc_bytes(pool, sz); - if (zero_fill && p != NULL && sz > 0) - memset(p, 0, sz); - } - - return p; -} - -/* - * Common function for handling recursion. Only - * print the error message once, to avoid making the problem - * potentially worse. - */ -static void -malloc_recurse(struct dir_info *d) -{ - static int noprint; - - if (noprint == 0) { - noprint = 1; - wrterror(d, "recursive call"); - } - d->active--; - _MALLOC_UNLOCK(d->mutex); - errno = EDEADLK; -} - -void -_malloc_init(int from_rthreads) -{ - u_int i, j, nmutexes; - struct dir_info *d; - - _MALLOC_LOCK(1); - if (!from_rthreads && mopts.malloc_pool[1]) { - _MALLOC_UNLOCK(1); - return; - } - if (!mopts.malloc_canary) { - char *p; - size_t sz, roundup_sz, d_avail; - - omalloc_init(); - /* - * Allocate dir_infos with a guard page on either side. Also - * randomise offset inside the page at which the dir_infos - * lay (subject to alignment by 1 << MALLOC_MINSHIFT) - */ - sz = mopts.malloc_mutexes * sizeof(*d); - roundup_sz = (sz + MALLOC_PAGEMASK) & ~MALLOC_PAGEMASK; - if ((p = MMAPNONE(roundup_sz + 2 * MALLOC_PAGESIZE, 0)) == - MAP_FAILED) - wrterror(NULL, "malloc_init mmap1 failed"); - if (mprotect(p + MALLOC_PAGESIZE, roundup_sz, - PROT_READ | PROT_WRITE)) - wrterror(NULL, "malloc_init mprotect1 failed"); - if (mimmutable(p, roundup_sz + 2 * MALLOC_PAGESIZE)) - wrterror(NULL, "malloc_init mimmutable1 failed"); - d_avail = (roundup_sz - sz) >> MALLOC_MINSHIFT; - d = (struct dir_info *)(p + MALLOC_PAGESIZE + - (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); - STATS_ADD(d[1].malloc_used, roundup_sz + 2 * MALLOC_PAGESIZE); - for (i = 0; i < mopts.malloc_mutexes; i++) - mopts.malloc_pool[i] = &d[i]; - mopts.internal_funcs = 1; - if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) { - if (mprotect(&malloc_readonly, sizeof(malloc_readonly), - PROT_READ)) - wrterror(NULL, - "malloc_init mprotect r/o failed"); - if (mimmutable(&malloc_readonly, - sizeof(malloc_readonly))) - wrterror(NULL, - "malloc_init mimmutable r/o failed"); - } - } - - nmutexes = from_rthreads ? mopts.malloc_mutexes : 2; - for (i = 0; i < nmutexes; i++) { - d = mopts.malloc_pool[i]; - d->malloc_mt = from_rthreads; - if (d->canary1 == ~d->canary2) - continue; - if (i == 0) { - omalloc_poolinit(d, MAP_CONCEAL); - d->malloc_junk = 2; - d->bigcache_size = 0; - for (j = 0; j < MAX_SMALLCACHEABLE_SIZE; j++) - d->smallcache[j].max = 0; - } else { - size_t sz = 0; - - omalloc_poolinit(d, 0); - d->malloc_junk = mopts.def_malloc_junk; - d->bigcache_size = mopts.def_maxcache; - for (j = 0; j < MAX_SMALLCACHEABLE_SIZE; j++) { - d->smallcache[j].max = - mopts.def_maxcache >> (j / 8); - sz += d->smallcache[j].max * sizeof(void *); - } - sz += d->bigcache_size * sizeof(struct bigcache); - if (sz > 0) { - void *p = MMAP(sz, 0); - if (p == MAP_FAILED) - wrterror(NULL, - "malloc_init mmap2 failed"); - if (mimmutable(p, sz)) - wrterror(NULL, - "malloc_init mimmutable2 failed"); - for (j = 0; j < MAX_SMALLCACHEABLE_SIZE; j++) { - d->smallcache[j].pages = p; - p = (char *)p + d->smallcache[j].max * - sizeof(void *); - } - d->bigcache = p; - } - } - d->mutex = i; - } - - _MALLOC_UNLOCK(1); -} -DEF_STRONG(_malloc_init); - -#define PROLOGUE(p, fn) \ - d = (p); \ - if (d == NULL) { \ - _malloc_init(0); \ - d = (p); \ - } \ - _MALLOC_LOCK(d->mutex); \ - d->func = fn; \ - if (d->active++) { \ - malloc_recurse(d); \ - return NULL; \ - } \ - -#define EPILOGUE() \ - d->active--; \ - _MALLOC_UNLOCK(d->mutex); \ - if (r == NULL && mopts.malloc_xmalloc) \ - wrterror(d, "out of memory"); \ - if (r != NULL) \ - errno = saved_errno; \ - -void * -malloc(size_t size) -{ - void *r; - struct dir_info *d; - int saved_errno = errno; - - PROLOGUE(getpool(), "malloc") - SET_CALLER(d, caller(d)); - r = omalloc(d, size, 0); - EPILOGUE() - return r; -} -DEF_STRONG(malloc); - -void * -malloc_conceal(size_t size) -{ - void *r; - struct dir_info *d; - int saved_errno = errno; - - PROLOGUE(mopts.malloc_pool[0], "malloc_conceal") - SET_CALLER(d, caller(d)); - r = omalloc(d, size, 0); - EPILOGUE() - return r; -} -DEF_WEAK(malloc_conceal); - -static struct region_info * -findpool(void *p, struct dir_info *argpool, struct dir_info **foundpool, - const char ** saved_function) -{ - struct dir_info *pool = argpool; - struct region_info *r = find(pool, p); - - if (r == NULL) { - u_int i, nmutexes; - - nmutexes = mopts.malloc_pool[1]->malloc_mt ? - mopts.malloc_mutexes : 2; - for (i = 1; i < nmutexes; i++) { - u_int j = (argpool->mutex + i) & (nmutexes - 1); - - pool->active--; - _MALLOC_UNLOCK(pool->mutex); - pool = mopts.malloc_pool[j]; - _MALLOC_LOCK(pool->mutex); - pool->active++; - r = find(pool, p); - if (r != NULL) { - *saved_function = pool->func; - pool->func = argpool->func; - break; - } - } - if (r == NULL) - wrterror(argpool, "bogus pointer (double free?) %p", p); - } - *foundpool = pool; - return r; -} - -static void -ofree(struct dir_info **argpool, void *p, int clear, int check, size_t argsz) -{ - struct region_info *r; - struct dir_info *pool; - const char *saved_function; - size_t sz; - - r = findpool(p, *argpool, &pool, &saved_function); - - REALSIZE(sz, r); - if (pool->mmap_flag) { - clear = 1; - if (!check) { - argsz = sz; - if (sz > MALLOC_MAXCHUNK) - argsz -= mopts.malloc_guard; - } - } - if (check) { - if (sz <= MALLOC_MAXCHUNK) { - if (mopts.chunk_canaries && sz > 0) { - struct chunk_info *info = - (struct chunk_info *)r->size; - uint32_t chunknum = - find_chunknum(pool, info, p, 0); - - if (info->bits[info->offset + chunknum] < argsz) - wrterror(pool, "recorded size %hu" - " < %zu", - info->bits[info->offset + chunknum], - argsz); - } else { - if (sz < argsz) - wrterror(pool, "chunk size %zu < %zu", - sz, argsz); - } - } else if (sz - mopts.malloc_guard < argsz) { - wrterror(pool, "recorded size %zu < %zu", - sz - mopts.malloc_guard, argsz); - } - } - if (sz > MALLOC_MAXCHUNK) { - if (!MALLOC_MOVE_COND(sz)) { - if (r->p != p) - wrterror(pool, "bogus pointer %p", p); - if (mopts.chunk_canaries) - validate_canary(pool, p, - sz - mopts.malloc_guard, - PAGEROUND(sz - mopts.malloc_guard)); - } else { - /* shifted towards the end */ - if (p != MALLOC_MOVE(r->p, sz)) - wrterror(pool, "bogus moved pointer %p", p); - p = r->p; - } - if (mopts.malloc_guard) { - if (sz < mopts.malloc_guard) - wrterror(pool, "guard size"); - if (!mopts.malloc_freeunmap) { - if (mprotect((char *)p + PAGEROUND(sz) - - mopts.malloc_guard, mopts.malloc_guard, - PROT_READ | PROT_WRITE)) - wrterror(pool, "mprotect"); - } - STATS_SUB(pool->malloc_guarded, mopts.malloc_guard); - } - unmap(pool, p, PAGEROUND(sz), clear ? argsz : 0); - delete(pool, r); - } else { - void *tmp; - u_int i; - - /* Validate and optionally canary check */ - struct chunk_info *info = (struct chunk_info *)r->size; - if (B2SIZE(info->bucket) != sz) - wrterror(pool, "internal struct corrupt"); - find_chunknum(pool, info, p, mopts.chunk_canaries); - - if (mopts.malloc_freecheck) { - for (i = 0; i <= MALLOC_DELAYED_CHUNK_MASK; i++) { - tmp = pool->delayed_chunks[i]; - if (tmp == p) - wrterror(pool, - "double free %p", p); - if (tmp != NULL) { - size_t tmpsz; - - r = find(pool, tmp); - if (r == NULL) - wrterror(pool, - "bogus pointer (" - "double free?) %p", tmp); - REALSIZE(tmpsz, r); - validate_junk(pool, tmp, tmpsz); - } - } - } - - if (clear && argsz > 0) - explicit_bzero(p, argsz); - junk_free(pool->malloc_junk, p, sz); - - i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; - tmp = p; - p = pool->delayed_chunks[i]; - if (tmp == p) - wrterror(pool, "double free %p", p); - pool->delayed_chunks[i] = tmp; - if (p != NULL) { - r = find(pool, p); - if (r == NULL) - wrterror(pool, - "bogus pointer (double free?) %p", p); - if (!mopts.malloc_freecheck) { - REALSIZE(sz, r); - validate_junk(pool, p, sz); - } - free_bytes(pool, r, p); - } - } - - if (*argpool != pool) { - pool->func = saved_function; - *argpool = pool; - } -} - -void -free(void *ptr) -{ - struct dir_info *d; - int saved_errno = errno; - - /* This is legal. */ - if (ptr == NULL) - return; - - d = getpool(); - if (d == NULL) - wrterror(d, "free() called before allocation"); - _MALLOC_LOCK(d->mutex); - d->func = "free"; - if (d->active++) { - malloc_recurse(d); - return; - } - ofree(&d, ptr, 0, 0, 0); - d->active--; - _MALLOC_UNLOCK(d->mutex); - errno = saved_errno; -} -DEF_STRONG(free); - -static void -freezero_p(void *ptr, size_t sz) -{ - explicit_bzero(ptr, sz); - free(ptr); -} - -void -freezero(void *ptr, size_t sz) -{ - struct dir_info *d; - int saved_errno = errno; - - /* This is legal. */ - if (ptr == NULL) - return; - - if (!mopts.internal_funcs) { - freezero_p(ptr, sz); - return; - } - - d = getpool(); - if (d == NULL) - wrterror(d, "freezero() called before allocation"); - _MALLOC_LOCK(d->mutex); - d->func = "freezero"; - if (d->active++) { - malloc_recurse(d); - return; - } - ofree(&d, ptr, 1, 1, sz); - d->active--; - _MALLOC_UNLOCK(d->mutex); - errno = saved_errno; -} -DEF_WEAK(freezero); - -static void * -orealloc(struct dir_info **argpool, void *p, size_t newsz) -{ - struct region_info *r; - struct dir_info *pool; - const char *saved_function; - struct chunk_info *info; - size_t oldsz, goldsz, gnewsz; - void *q, *ret; - uint32_t chunknum; - int forced; - - if (p == NULL) - return omalloc(*argpool, newsz, 0); - - if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { - errno = ENOMEM; - return NULL; - } - - r = findpool(p, *argpool, &pool, &saved_function); - - REALSIZE(oldsz, r); - if (oldsz <= MALLOC_MAXCHUNK) { - if (DO_STATS || mopts.chunk_canaries) { - info = (struct chunk_info *)r->size; - chunknum = find_chunknum(pool, info, p, 0); - } - } - - goldsz = oldsz; - if (oldsz > MALLOC_MAXCHUNK) { - if (oldsz < mopts.malloc_guard) - wrterror(pool, "guard size"); - oldsz -= mopts.malloc_guard; - } - - gnewsz = newsz; - if (gnewsz > MALLOC_MAXCHUNK) - gnewsz += mopts.malloc_guard; - - forced = mopts.malloc_realloc || pool->mmap_flag; - if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && !forced) { - /* First case: from n pages sized allocation to m pages sized - allocation, m > n */ - size_t roldsz = PAGEROUND(goldsz); - size_t rnewsz = PAGEROUND(gnewsz); - - if (rnewsz < roldsz && rnewsz > roldsz / 2 && - roldsz - rnewsz < mopts.def_maxcache * MALLOC_PAGESIZE && - !mopts.malloc_guard) { - - ret = p; - goto done; - } - - if (rnewsz > roldsz) { - /* try to extend existing region */ - if (!mopts.malloc_guard) { - void *hint = (char *)r->p + roldsz; - size_t needed = rnewsz - roldsz; - - STATS_INC(pool->cheap_realloc_tries); - q = MMAPA(hint, needed, MAP_FIXED | - __MAP_NOREPLACE | pool->mmap_flag); - if (q == hint) { - STATS_ADD(pool->malloc_used, needed); - if (pool->malloc_junk == 2) - memset(q, SOME_JUNK, needed); - r->size = gnewsz; - if (r->p != p) { - /* old pointer is moved */ - memmove(r->p, p, oldsz); - p = r->p; - } - if (mopts.chunk_canaries) - fill_canary(p, newsz, - PAGEROUND(newsz)); - STATS_SETF(r, (*argpool)->caller); - STATS_INC(pool->cheap_reallocs); - ret = p; - goto done; - } - } - } else if (rnewsz < roldsz) { - /* shrink number of pages */ - if (mopts.malloc_guard) { - if (mprotect((char *)r->p + rnewsz - - mopts.malloc_guard, mopts.malloc_guard, - PROT_NONE)) - wrterror(pool, "mprotect"); - } - if (munmap((char *)r->p + rnewsz, roldsz - rnewsz)) - wrterror(pool, "munmap %p", (char *)r->p + - rnewsz); - STATS_SUB(pool->malloc_used, roldsz - rnewsz); - r->size = gnewsz; - if (MALLOC_MOVE_COND(gnewsz)) { - void *pp = MALLOC_MOVE(r->p, gnewsz); - memmove(pp, p, newsz); - p = pp; - } else if (mopts.chunk_canaries) - fill_canary(p, newsz, PAGEROUND(newsz)); - STATS_SETF(r, (*argpool)->caller); - ret = p; - goto done; - } else { - /* number of pages remains the same */ - void *pp = r->p; - - r->size = gnewsz; - if (MALLOC_MOVE_COND(gnewsz)) - pp = MALLOC_MOVE(r->p, gnewsz); - if (p != pp) { - memmove(pp, p, oldsz < newsz ? oldsz : newsz); - p = pp; - } - if (p == r->p) { - if (newsz > oldsz && pool->malloc_junk == 2) - memset((char *)p + newsz, SOME_JUNK, - rnewsz - mopts.malloc_guard - - newsz); - if (mopts.chunk_canaries) - fill_canary(p, newsz, PAGEROUND(newsz)); - } - STATS_SETF(r, (*argpool)->caller); - ret = p; - goto done; - } - } - if (oldsz <= MALLOC_MAXCHUNK && oldsz > 0 && - newsz <= MALLOC_MAXCHUNK && newsz > 0 && - !forced && find_bucket(newsz) == find_bucket(oldsz)) { - /* do not reallocate if new size fits good in existing chunk */ - if (pool->malloc_junk == 2) - memset((char *)p + newsz, SOME_JUNK, oldsz - newsz); - if (mopts.chunk_canaries) { - info->bits[info->offset + chunknum] = newsz; - fill_canary(p, newsz, B2SIZE(info->bucket)); - } - if (DO_STATS) - STATS_SETFN(r, chunknum, (*argpool)->caller); - ret = p; - } else if (newsz != oldsz || forced) { - /* create new allocation */ - q = omalloc(pool, newsz, 0); - if (q == NULL) { - ret = NULL; - goto done; - } - if (newsz != 0 && oldsz != 0) - memcpy(q, p, oldsz < newsz ? oldsz : newsz); - ofree(&pool, p, 0, 0, 0); - ret = q; - } else { - /* oldsz == newsz */ - if (newsz != 0) - wrterror(pool, "realloc internal inconsistency"); - if (DO_STATS) - STATS_SETFN(r, chunknum, (*argpool)->caller); - ret = p; - } -done: - if (*argpool != pool) { - pool->func = saved_function; - *argpool = pool; - } - return ret; -} - -void * -realloc(void *ptr, size_t size) -{ - struct dir_info *d; - void *r; - int saved_errno = errno; - - PROLOGUE(getpool(), "realloc") - SET_CALLER(d, caller(d)); - r = orealloc(&d, ptr, size); - EPILOGUE() - return r; -} -DEF_STRONG(realloc); - -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) - -void * -calloc(size_t nmemb, size_t size) -{ - struct dir_info *d; - void *r; - int saved_errno = errno; - - PROLOGUE(getpool(), "calloc") - SET_CALLER(d, caller(d)); - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { - d->active--; - _MALLOC_UNLOCK(d->mutex); - if (mopts.malloc_xmalloc) - wrterror(d, "out of memory"); - errno = ENOMEM; - return NULL; - } - - size *= nmemb; - r = omalloc(d, size, 1); - EPILOGUE() - return r; -} -DEF_STRONG(calloc); - -void * -calloc_conceal(size_t nmemb, size_t size) -{ - struct dir_info *d; - void *r; - int saved_errno = errno; - - PROLOGUE(mopts.malloc_pool[0], "calloc_conceal") - SET_CALLER(d, caller(d)); - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { - d->active--; - _MALLOC_UNLOCK(d->mutex); - if (mopts.malloc_xmalloc) - wrterror(d, "out of memory"); - errno = ENOMEM; - return NULL; - } - - size *= nmemb; - r = omalloc(d, size, 1); - EPILOGUE() - return r; -} -DEF_WEAK(calloc_conceal); - -static void * -orecallocarray(struct dir_info **argpool, void *p, size_t oldsize, - size_t newsize) -{ - struct region_info *r; - struct dir_info *pool; - const char *saved_function; - void *newptr; - size_t sz; - - if (p == NULL) - return omalloc(*argpool, newsize, 1); - - if (oldsize == newsize) - return p; - - r = findpool(p, *argpool, &pool, &saved_function); - - REALSIZE(sz, r); - if (sz <= MALLOC_MAXCHUNK) { - if (mopts.chunk_canaries && sz > 0) { - struct chunk_info *info = (struct chunk_info *)r->size; - uint32_t chunknum = find_chunknum(pool, info, p, 0); - - if (info->bits[info->offset + chunknum] != oldsize) - wrterror(pool, "recorded size %hu != %zu", - info->bits[info->offset + chunknum], - oldsize); - } else { - if (sz < oldsize) - wrterror(pool, "chunk size %zu < %zu", - sz, oldsize); - } - } else { - if (sz - mopts.malloc_guard < oldsize) - wrterror(pool, "recorded size %zu < %zu", - sz - mopts.malloc_guard, oldsize); - if (oldsize < (sz - mopts.malloc_guard) / 2) - wrterror(pool, - "recorded size %zu inconsistent with %zu", - sz - mopts.malloc_guard, oldsize); - } - - newptr = omalloc(pool, newsize, 0); - if (newptr == NULL) - goto done; - - if (newsize > oldsize) { - memcpy(newptr, p, oldsize); - memset((char *)newptr + oldsize, 0, newsize - oldsize); - } else - memcpy(newptr, p, newsize); - - ofree(&pool, p, 1, 0, oldsize); - -done: - if (*argpool != pool) { - pool->func = saved_function; - *argpool = pool; - } - - return newptr; -} - -static void * -recallocarray_p(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) -{ - size_t oldsize, newsize; - void *newptr; - - if (ptr == NULL) - return calloc(newnmemb, size); - - if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - newnmemb > 0 && SIZE_MAX / newnmemb < size) { - errno = ENOMEM; - return NULL; - } - newsize = newnmemb * size; - - if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { - errno = EINVAL; - return NULL; - } - oldsize = oldnmemb * size; - - /* - * Don't bother too much if we're shrinking just a bit, - * we do not shrink for series of small steps, oh well. - */ - if (newsize <= oldsize) { - size_t d = oldsize - newsize; - - if (d < oldsize / 2 && d < MALLOC_PAGESIZE) { - memset((char *)ptr + newsize, 0, d); - return ptr; - } - } - - newptr = malloc(newsize); - if (newptr == NULL) - return NULL; - - if (newsize > oldsize) { - memcpy(newptr, ptr, oldsize); - memset((char *)newptr + oldsize, 0, newsize - oldsize); - } else - memcpy(newptr, ptr, newsize); - - explicit_bzero(ptr, oldsize); - free(ptr); - - return newptr; -} - -void * -recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) -{ - struct dir_info *d; - size_t oldsize = 0, newsize; - void *r; - int saved_errno = errno; - - if (!mopts.internal_funcs) - return recallocarray_p(ptr, oldnmemb, newnmemb, size); - - PROLOGUE(getpool(), "recallocarray") - SET_CALLER(d, caller(d)); - - if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - newnmemb > 0 && SIZE_MAX / newnmemb < size) { - d->active--; - _MALLOC_UNLOCK(d->mutex); - if (mopts.malloc_xmalloc) - wrterror(d, "out of memory"); - errno = ENOMEM; - return NULL; - } - newsize = newnmemb * size; - - if (ptr != NULL) { - if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { - d->active--; - _MALLOC_UNLOCK(d->mutex); - errno = EINVAL; - return NULL; - } - oldsize = oldnmemb * size; - } - - r = orecallocarray(&d, ptr, oldsize, newsize); - EPILOGUE() - return r; -} -DEF_WEAK(recallocarray); - -static void * -mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) -{ - char *p, *q; - - if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0) - wrterror(d, "mapalign bad alignment"); - if (sz != PAGEROUND(sz)) - wrterror(d, "mapalign round"); - - /* Allocate sz + alignment bytes of memory, which must include a - * subrange of size bytes that is properly aligned. Unmap the - * other bytes, and then return that subrange. - */ - - /* We need sz + alignment to fit into a size_t. */ - if (alignment > SIZE_MAX - sz) - return MAP_FAILED; - - p = map(d, sz + alignment, zero_fill); - if (p == MAP_FAILED) - return MAP_FAILED; - q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1)); - if (q != p) { - if (munmap(p, q - p)) - wrterror(d, "munmap %p", p); - } - if (munmap(q + sz, alignment - (q - p))) - wrterror(d, "munmap %p", q + sz); - STATS_SUB(d->malloc_used, alignment); - - return q; -} - -static void * -omemalign(struct dir_info *pool, size_t alignment, size_t sz, int zero_fill) -{ - size_t psz; - void *p, *caller = NULL; - - /* If between half a page and a page, avoid MALLOC_MOVE. */ - if (sz > MALLOC_MAXCHUNK && sz < MALLOC_PAGESIZE) - sz = MALLOC_PAGESIZE; - if (alignment <= MALLOC_PAGESIZE) { - size_t pof2; - /* - * max(size, alignment) rounded up to power of 2 is enough - * to assure the requested alignment. Large regions are - * always page aligned. - */ - if (sz < alignment) - sz = alignment; - if (sz < MALLOC_PAGESIZE) { - pof2 = MALLOC_MINSIZE; - while (pof2 < sz) - pof2 <<= 1; - } else - pof2 = sz; - return omalloc(pool, pof2, zero_fill); - } - - if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { - errno = ENOMEM; - return NULL; - } - - if (sz < MALLOC_PAGESIZE) - sz = MALLOC_PAGESIZE; - sz += mopts.malloc_guard; - psz = PAGEROUND(sz); - - p = mapalign(pool, alignment, psz, zero_fill); - if (p == MAP_FAILED) { - errno = ENOMEM; - return NULL; - } - -#ifdef MALLOC_STATS - if (DO_STATS) - caller = pool->caller; -#endif - if (insert(pool, p, sz, caller)) { - unmap(pool, p, psz, 0); - errno = ENOMEM; - return NULL; - } - - if (mopts.malloc_guard) { - if (mprotect((char *)p + psz - mopts.malloc_guard, - mopts.malloc_guard, PROT_NONE)) - wrterror(pool, "mprotect"); - STATS_ADD(pool->malloc_guarded, mopts.malloc_guard); - } - - if (pool->malloc_junk == 2) { - if (zero_fill) - memset((char *)p + sz - mopts.malloc_guard, - SOME_JUNK, psz - sz); - else - memset(p, SOME_JUNK, psz - mopts.malloc_guard); - } else if (mopts.chunk_canaries) - fill_canary(p, sz - mopts.malloc_guard, - psz - mopts.malloc_guard); - - return p; -} - -int -posix_memalign(void **memptr, size_t alignment, size_t size) -{ - struct dir_info *d; - int res, saved_errno = errno; - void *r; - - /* Make sure that alignment is a large enough power of 2. */ - if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) - return EINVAL; - - d = getpool(); - if (d == NULL) { - _malloc_init(0); - d = getpool(); - } - _MALLOC_LOCK(d->mutex); - d->func = "posix_memalign"; - if (d->active++) { - malloc_recurse(d); - goto err; - } - SET_CALLER(d, caller(d)); - r = omemalign(d, alignment, size, 0); - d->active--; - _MALLOC_UNLOCK(d->mutex); - if (r == NULL) { - if (mopts.malloc_xmalloc) - wrterror(d, "out of memory"); - goto err; - } - errno = saved_errno; - *memptr = r; - return 0; - -err: - res = errno; - errno = saved_errno; - return res; -} -DEF_STRONG(posix_memalign); - -void * -aligned_alloc(size_t alignment, size_t size) -{ - struct dir_info *d; - int saved_errno = errno; - void *r; - - /* Make sure that alignment is a positive power of 2. */ - if (((alignment - 1) & alignment) != 0 || alignment == 0) { - errno = EINVAL; - return NULL; - } - /* Per spec, size should be a multiple of alignment */ - if ((size & (alignment - 1)) != 0) { - errno = EINVAL; - return NULL; - } - - PROLOGUE(getpool(), "aligned_alloc") - SET_CALLER(d, caller(d)); - r = omemalign(d, alignment, size, 0); - EPILOGUE() - return r; -} -DEF_STRONG(aligned_alloc); - -#ifdef MALLOC_STATS - -static int -btcmp(const struct btnode *e1, const struct btnode *e2) -{ - return memcmp(e1->caller, e2->caller, sizeof(e1->caller)); -} - -RBT_GENERATE(btshead, btnode, entry, btcmp); - -static void* -store_caller(struct dir_info *d, struct btnode *f) -{ - struct btnode *p; - - if (DO_STATS == 0 || d->btnodes == MAP_FAILED) - return NULL; - - p = RBT_FIND(btshead, &d->btraces, f); - if (p != NULL) - return p; - if (d->btnodes == NULL || - d->btnodesused >= MALLOC_PAGESIZE / sizeof(struct btnode)) { - d->btnodes = map(d, MALLOC_PAGESIZE, 0); - if (d->btnodes == MAP_FAILED) - return NULL; - d->btnodesused = 0; - } - p = &d->btnodes[d->btnodesused++]; - memcpy(p->caller, f->caller, sizeof(p->caller[0]) * DO_STATS); - RBT_INSERT(btshead, &d->btraces, p); - return p; -} - -static void fabstorel(const void *, char *, size_t); - -static void -print_chunk_details(struct dir_info *pool, void *p, size_t sz, size_t index) -{ - struct region_info *r; - struct chunk_info *chunkinfo; - struct btnode* btnode; - uint32_t chunknum; - int frame; - char buf1[128]; - char buf2[128]; - const char *msg = ""; - - r = find(pool, p); - chunkinfo = (struct chunk_info *)r->size; - chunknum = find_chunknum(pool, chunkinfo, p, 0); - btnode = (struct btnode *)r->f[chunknum]; - frame = DO_STATS - 1; - if (btnode != NULL) - fabstorel(btnode->caller[frame], buf1, sizeof(buf1)); - strlcpy(buf2, ". 0x0", sizeof(buf2)); - if (chunknum > 0) { - chunknum--; - btnode = (struct btnode *)r->f[chunknum]; - if (btnode != NULL) - fabstorel(btnode->caller[frame], buf2, sizeof(buf2)); - if (CHUNK_FREE(chunkinfo, chunknum)) - msg = " (now free)"; - } - - wrterror(pool, - "write to free chunk %p[%zu..%zu]@%zu allocated at %s " - "(preceding chunk %p allocated at %s%s)", - p, index * sizeof(uint64_t), (index + 1) * sizeof(uint64_t) - 1, - sz, buf1, p - sz, buf2, msg); -} - -static void -ulog(const char *format, ...) -{ - va_list ap; - static char* buf; - static size_t filled; - int len; - - if (buf == NULL) - buf = MMAP(KTR_USER_MAXLEN, 0); - if (buf == MAP_FAILED) - return; - - va_start(ap, format); - len = vsnprintf(buf + filled, KTR_USER_MAXLEN - filled, format, ap); - va_end(ap); - if (len < 0) - return; - if ((size_t)len > KTR_USER_MAXLEN - filled) - len = KTR_USER_MAXLEN - filled; - filled += len; - if (filled > 0) { - if (filled == KTR_USER_MAXLEN || buf[filled - 1] == '\n') { - utrace("malloc", buf, filled); - filled = 0; - } - } -} - -struct malloc_leak { - void *f; - size_t total_size; - int count; -}; - -struct leaknode { - RBT_ENTRY(leaknode) entry; - struct malloc_leak d; -}; - -static inline int -leakcmp(const struct leaknode *e1, const struct leaknode *e2) -{ - return e1->d.f < e2->d.f ? -1 : e1->d.f > e2->d.f; -} - -RBT_HEAD(leaktree, leaknode); -RBT_PROTOTYPE(leaktree, leaknode, entry, leakcmp); -RBT_GENERATE(leaktree, leaknode, entry, leakcmp); - -static void -wrtwarning(const char *func, char *msg, ...) -{ - int saved_errno = errno; - va_list ap; - - dprintf(STDERR_FILENO, "%s(%d) in %s(): ", __progname, - getpid(), func != NULL ? func : "unknown"); - va_start(ap, msg); - vdprintf(STDERR_FILENO, msg, ap); - va_end(ap); - dprintf(STDERR_FILENO, "\n"); - - errno = saved_errno; -} - -static void -putleakinfo(struct leaktree *leaks, void *f, size_t sz, int cnt) -{ - struct leaknode key, *p; - static struct leaknode *page; - static unsigned int used; - - if (cnt == 0 || page == MAP_FAILED) - return; - - key.d.f = f; - p = RBT_FIND(leaktree, leaks, &key); - if (p == NULL) { - if (page == NULL || - used >= MALLOC_PAGESIZE / sizeof(struct leaknode)) { - page = MMAP(MALLOC_PAGESIZE, 0); - if (page == MAP_FAILED) { - wrtwarning(__func__, strerror(errno)); - return; - } - used = 0; - } - p = &page[used++]; - p->d.f = f; - p->d.total_size = sz * cnt; - p->d.count = cnt; - RBT_INSERT(leaktree, leaks, p); - } else { - p->d.total_size += sz * cnt; - p->d.count += cnt; - } -} - -static void -fabstorel(const void *f, char *buf, size_t size) -{ - Dl_info info; - const char *object = "."; - const char *caller; - - caller = f; - if (caller != NULL && dladdr(f, &info) != 0) { - caller -= (uintptr_t)info.dli_fbase; - object = info.dli_fname; - } - snprintf(buf, size, "%s %p", object, caller); -} - -static void -dump_leak(struct leaknode *p) -{ - int i; - char buf[128]; - - if (p->d.f == NULL) { - fabstorel(NULL, buf, sizeof(buf)); - ulog("%18p %7zu %6u %6zu addr2line -e %s\n", - p->d.f, p->d.total_size, p->d.count, - p->d.total_size / p->d.count, buf); - return; - } - - for (i = 0; i < DO_STATS; i++) { - const char *abscaller; - - abscaller = ((struct btnode*)p->d.f)->caller[i]; - if (abscaller == NULL) - break; - fabstorel(abscaller, buf, sizeof(buf)); - if (i == 0) - ulog("%18p %7zu %6u %6zu addr2line -e %s\n", - abscaller, p->d.total_size, p->d.count, - p->d.total_size / p->d.count, buf); - else - ulog("%*p %*s %6s %6s addr2line -e %s\n", - i + 18, abscaller, 7 - i, "-", "-", "-", buf); - } -} - -static void -dump_leaks(struct leaktree *leaks) -{ - struct leaknode *p; - - ulog("Leak report:\n"); - ulog(" f sum # avg\n"); - - RBT_FOREACH(p, leaktree, leaks) - dump_leak(p); -} - -static void -dump_chunk(struct leaktree* leaks, struct chunk_info *p, void **f, - int fromfreelist) -{ - while (p != NULL) { - if (mopts.malloc_verbose) - ulog("chunk %18p %18p %4zu %d/%d\n", - p->page, NULL, - B2SIZE(p->bucket), p->free, p->total); - if (!fromfreelist) { - size_t i, sz = B2SIZE(p->bucket); - for (i = 0; i < p->total; i++) { - if (!CHUNK_FREE(p, i)) - putleakinfo(leaks, f[i], sz, 1); - } - break; - } - p = LIST_NEXT(p, entries); - if (mopts.malloc_verbose && p != NULL) - ulog(" ->"); - } -} - -static void -dump_free_chunk_info(struct dir_info *d, struct leaktree *leaks) -{ - u_int i, j, count; - struct chunk_info *p; - - ulog("Free chunk structs:\n"); - ulog("Bkt) #CI page" - " f size free/n\n"); - for (i = 0; i <= BUCKETS; i++) { - count = 0; - LIST_FOREACH(p, &d->chunk_info_list[i], entries) - count++; - for (j = 0; j < MALLOC_CHUNK_LISTS; j++) { - p = LIST_FIRST(&d->chunk_dir[i][j]); - if (p == NULL && count == 0) - continue; - if (j == 0) - ulog("%3d) %3d ", i, count); - else - ulog(" "); - if (p != NULL) - dump_chunk(leaks, p, NULL, 1); - else - ulog(".\n"); - } - } - -} - -static void -dump_free_page_info(struct dir_info *d) -{ - struct smallcache *cache; - size_t i, total = 0; - - ulog("Cached in small cache:\n"); - for (i = 0; i < MAX_SMALLCACHEABLE_SIZE; i++) { - cache = &d->smallcache[i]; - if (cache->length != 0) - ulog("%zu(%u): %u = %zu\n", i + 1, cache->max, - cache->length, cache->length * (i + 1)); - total += cache->length * (i + 1); - } - - ulog("Cached in big cache: %zu/%zu\n", d->bigcache_used, - d->bigcache_size); - for (i = 0; i < d->bigcache_size; i++) { - if (d->bigcache[i].psize != 0) - ulog("%zu: %zu\n", i, d->bigcache[i].psize); - total += d->bigcache[i].psize; - } - ulog("Free pages cached: %zu\n", total); -} - -static void -malloc_dump1(int poolno, struct dir_info *d, struct leaktree *leaks) -{ - size_t i, realsize; - - if (mopts.malloc_verbose) { - ulog("Malloc dir of %s pool %d at %p\n", __progname, poolno, d); - ulog("MT=%d J=%d Fl=%#x\n", d->malloc_mt, d->malloc_junk, - d->mmap_flag); - ulog("Region slots free %zu/%zu\n", - d->regions_free, d->regions_total); - ulog("Inserts %zu/%zu\n", d->inserts, d->insert_collisions); - ulog("Deletes %zu/%zu\n", d->deletes, d->delete_moves); - ulog("Cheap reallocs %zu/%zu\n", - d->cheap_reallocs, d->cheap_realloc_tries); - ulog("In use %zu\n", d->malloc_used); - ulog("Guarded %zu\n", d->malloc_guarded); - dump_free_chunk_info(d, leaks); - dump_free_page_info(d); - ulog("Hash table:\n"); - ulog("slot) hash d type page " - "f size [free/n]\n"); - } - for (i = 0; i < d->regions_total; i++) { - if (d->r[i].p != NULL) { - size_t h = hash(d->r[i].p) & - (d->regions_total - 1); - if (mopts.malloc_verbose) - ulog("%4zx) #%4zx %zd ", - i, h, h - i); - REALSIZE(realsize, &d->r[i]); - if (realsize > MALLOC_MAXCHUNK) { - putleakinfo(leaks, d->r[i].f, realsize, 1); - if (mopts.malloc_verbose) - ulog("pages %18p %18p %zu\n", d->r[i].p, - d->r[i].f, realsize); - } else - dump_chunk(leaks, - (struct chunk_info *)d->r[i].size, - d->r[i].f, 0); - } - } - if (mopts.malloc_verbose) - ulog("\n"); -} - -static void -malloc_dump0(int poolno, struct dir_info *pool, struct leaktree *leaks) -{ - int i; - void *p; - struct region_info *r; - - if (pool == NULL || pool->r == NULL) - return; - for (i = 0; i < MALLOC_DELAYED_CHUNK_MASK + 1; i++) { - p = pool->delayed_chunks[i]; - if (p == NULL) - continue; - r = find(pool, p); - if (r == NULL) - wrterror(pool, "bogus pointer in malloc_dump %p", p); - free_bytes(pool, r, p); - pool->delayed_chunks[i] = NULL; - } - malloc_dump1(poolno, pool, leaks); -} - -void -malloc_dump(void) -{ - u_int i; - int saved_errno = errno; - - /* XXX leak when run multiple times */ - struct leaktree leaks = RBT_INITIALIZER(&leaks); - - for (i = 0; i < mopts.malloc_mutexes; i++) - malloc_dump0(i, mopts.malloc_pool[i], &leaks); - - dump_leaks(&leaks); - ulog("\n"); - errno = saved_errno; -} -DEF_WEAK(malloc_dump); - -static void -malloc_exit(void) -{ - int save_errno = errno; - - ulog("******** Start dump %s *******\n", __progname); - ulog("M=%u I=%d F=%d U=%d J=%d R=%d X=%d C=%#x cache=%u " - "G=%zu\n", - mopts.malloc_mutexes, - mopts.internal_funcs, mopts.malloc_freecheck, - mopts.malloc_freeunmap, mopts.def_malloc_junk, - mopts.malloc_realloc, mopts.malloc_xmalloc, - mopts.chunk_canaries, mopts.def_maxcache, - mopts.malloc_guard); - - malloc_dump(); - ulog("******** End dump %s *******\n", __progname); - errno = save_errno; -} - -#endif /* MALLOC_STATS */ diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c deleted file mode 100644 index d60317ce08..0000000000 --- a/src/lib/libc/stdlib/merge.c +++ /dev/null @@ -1,336 +0,0 @@ -/* $OpenBSD: merge.c,v 1.10 2015/06/21 03:20:56 millert Exp $ */ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Hybrid exponential search/linear search merge sort with hybrid - * natural/pairwise first pass. Requires about .3% more comparisons - * for random data than LSMS with pairwise first pass alone. - * It works for objects as small as two bytes. - */ - -#define NATURAL -#define THRESHOLD 16 /* Best choice for natural merge cut-off. */ - -/* #define NATURAL to get hybrid natural merge. - * (The default is pairwise merging.) - */ - -#include - -#include -#include -#include - -static void setup(u_char *, u_char *, size_t, size_t, int (*)()); -static void insertionsort(u_char *, size_t, size_t, int (*)()); - -#define ISIZE sizeof(int) -#define PSIZE sizeof(u_char *) -#define ICOPY_LIST(src, dst, last) \ - do \ - *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \ - while(src < last) -#define ICOPY_ELT(src, dst, i) \ - do \ - *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \ - while (i -= ISIZE) - -#define CCOPY_LIST(src, dst, last) \ - do \ - *dst++ = *src++; \ - while (src < last) -#define CCOPY_ELT(src, dst, i) \ - do \ - *dst++ = *src++; \ - while (i -= 1) - -/* - * Find the next possible pointer head. (Trickery for forcing an array - * to do double duty as a linked list when objects do not align with word - * boundaries. - */ -/* Assumption: PSIZE is a power of 2. */ -#define EVAL(p) (u_char **) \ - ((u_char *)0 + \ - (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1))) - -/* - * Arguments are as for qsort. - */ -int -mergesort(void *base, size_t nmemb, size_t size, - int (*cmp)(const void *, const void *)) -{ - int i, sense; - int big, iflag; - u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; - u_char *list2, *list1, *p2, *p, *last, **p1; - - if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ - errno = EINVAL; - return (-1); - } - - if (nmemb == 0) - return (0); - - /* - * XXX - * Stupid subtraction for the Cray. - */ - iflag = 0; - if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE)) - iflag = 1; - - if ((list2 = malloc(nmemb * size + PSIZE)) == NULL) - return (-1); - - list1 = base; - setup(list1, list2, nmemb, size, cmp); - last = list2 + nmemb * size; - i = big = 0; - while (*EVAL(list2) != last) { - l2 = list1; - p1 = EVAL(list1); - for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) { - p2 = *EVAL(p2); - f1 = l2; - f2 = l1 = list1 + (p2 - list2); - if (p2 != last) - p2 = *EVAL(p2); - l2 = list1 + (p2 - list2); - while (f1 < l1 && f2 < l2) { - if ((*cmp)(f1, f2) <= 0) { - q = f2; - b = f1, t = l1; - sense = -1; - } else { - q = f1; - b = f2, t = l2; - sense = 0; - } - if (!big) { /* here i = 0 */ - while ((b += size) < t && cmp(q, b) >sense) - if (++i == 6) { - big = 1; - goto EXPONENTIAL; - } - } else { -EXPONENTIAL: for (i = size; ; i <<= 1) - if ((p = (b + i)) >= t) { - if ((p = t - size) > b && - (*cmp)(q, p) <= sense) - t = p; - else - b = p; - break; - } else if ((*cmp)(q, p) <= sense) { - t = p; - if (i == size) - big = 0; - goto FASTCASE; - } else - b = p; - while (t > b+size) { - i = (((t - b) / size) >> 1) * size; - if ((*cmp)(q, p = b + i) <= sense) - t = p; - else - b = p; - } - goto COPY; -FASTCASE: while (i > size) - if ((*cmp)(q, - p = b + (i >>= 1)) <= sense) - t = p; - else - b = p; -COPY: b = t; - } - i = size; - if (q == f1) { - if (iflag) { - ICOPY_LIST(f2, tp2, b); - ICOPY_ELT(f1, tp2, i); - } else { - CCOPY_LIST(f2, tp2, b); - CCOPY_ELT(f1, tp2, i); - } - } else { - if (iflag) { - ICOPY_LIST(f1, tp2, b); - ICOPY_ELT(f2, tp2, i); - } else { - CCOPY_LIST(f1, tp2, b); - CCOPY_ELT(f2, tp2, i); - } - } - } - if (f2 < l2) { - if (iflag) - ICOPY_LIST(f2, tp2, l2); - else - CCOPY_LIST(f2, tp2, l2); - } else if (f1 < l1) { - if (iflag) - ICOPY_LIST(f1, tp2, l1); - else - CCOPY_LIST(f1, tp2, l1); - } - *p1 = l2; - } - tp2 = list1; /* swap list1, list2 */ - list1 = list2; - list2 = tp2; - last = list2 + nmemb*size; - } - if (base == list2) { - memmove(list2, list1, nmemb*size); - list2 = list1; - } - free(list2); - return (0); -} - -#define swap(a, b) { \ - s = b; \ - i = size; \ - do { \ - tmp = *a; *a++ = *s; *s++ = tmp; \ - } while (--i); \ - a -= size; \ - } -#define reverse(bot, top) { \ - s = top; \ - do { \ - i = size; \ - do { \ - tmp = *bot; *bot++ = *s; *s++ = tmp; \ - } while (--i); \ - s -= size2; \ - } while(bot < s); \ -} - -/* - * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of - * increasing order, list2 in a corresponding linked list. Checks for runs - * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL - * is defined. Otherwise simple pairwise merging is used.) - */ -void -setup(u_char *list1, u_char *list2, size_t n, size_t size, - int (*cmp)(const void *, const void *)) -{ - int i, length, size2, sense; - u_char tmp, *f1, *f2, *s, *l2, *last, *p2; - - size2 = size*2; - if (n <= 5) { - insertionsort(list1, n, size, cmp); - *EVAL(list2) = (u_char*) list2 + n*size; - return; - } - /* - * Avoid running pointers out of bounds; limit n to evens - * for simplicity. - */ - i = 4 + (n & 1); - insertionsort(list1 + (n - i) * size, i, size, cmp); - last = list1 + size * (n - i); - *EVAL(list2 + (last - list1)) = list2 + n * size; - -#ifdef NATURAL - p2 = list2; - f1 = list1; - sense = (cmp(f1, f1 + size) > 0); - for (; f1 < last; sense = !sense) { - length = 2; - /* Find pairs with same sense. */ - for (f2 = f1 + size2; f2 < last; f2 += size2) { - if ((cmp(f2, f2+ size) > 0) != sense) - break; - length += 2; - } - if (length < THRESHOLD) { /* Pairwise merge */ - do { - p2 = *EVAL(p2) = f1 + size2 - list1 + list2; - if (sense > 0) - swap (f1, f1 + size); - } while ((f1 += size2) < f2); - } else { /* Natural merge */ - l2 = f2; - for (f2 = f1 + size2; f2 < l2; f2 += size2) { - if ((cmp(f2-size, f2) > 0) != sense) { - p2 = *EVAL(p2) = f2 - list1 + list2; - if (sense > 0) - reverse(f1, f2-size); - f1 = f2; - } - } - if (sense > 0) - reverse (f1, f2-size); - f1 = f2; - if (f2 < last || cmp(f2 - size, f2) > 0) - p2 = *EVAL(p2) = f2 - list1 + list2; - else - p2 = *EVAL(p2) = list2 + n*size; - } - } -#else /* pairwise merge only. */ - for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { - p2 = *EVAL(p2) = p2 + size2; - if (cmp (f1, f1 + size) > 0) - swap(f1, f1 + size); - } -#endif /* NATURAL */ -} - -/* - * This is to avoid out-of-bounds addresses in sorting the - * last 4 elements. - */ -static void -insertionsort(u_char *a, size_t n, size_t size, - int (*cmp)(const void *, const void *)) -{ - u_char *ai, *s, *t, *u, tmp; - int i; - - for (ai = a+size; --n >= 1; ai += size) - for (t = ai; t > a; t -= size) { - u = t - size; - if (cmp(u, t) <= 0) - break; - swap(u, t); - } -} diff --git a/src/lib/libc/stdlib/mkdtemp.c b/src/lib/libc/stdlib/mkdtemp.c deleted file mode 100644 index c11501f893..0000000000 --- a/src/lib/libc/stdlib/mkdtemp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* $OpenBSD: mkdtemp.c,v 1.2 2024/03/01 21:30:40 millert Exp $ */ -/* - * Copyright (c) 2024 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -static int -mkdtemp_cb(const char *path, int flags) -{ - return mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR); -} - -char * -mkdtemp(char *path) -{ - if (__mktemp4(path, 0, 0, mkdtemp_cb) == 0) - return path; - return NULL; -} - -char * -mkdtemps(char *path, int slen) -{ - if (__mktemp4(path, slen, 0, mkdtemp_cb) == 0) - return path; - return NULL; -} diff --git a/src/lib/libc/stdlib/mkstemp.c b/src/lib/libc/stdlib/mkstemp.c deleted file mode 100644 index 75a9d27d1a..0000000000 --- a/src/lib/libc/stdlib/mkstemp.c +++ /dev/null @@ -1,64 +0,0 @@ -/* $OpenBSD: mkstemp.c,v 1.1 2024/01/19 19:45:02 millert Exp $ */ -/* - * Copyright (c) 2024 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#define MKOSTEMP_FLAGS (O_APPEND | O_CLOEXEC | O_DSYNC | O_RSYNC | O_SYNC) - -static int -mkstemp_cb(const char *path, int flags) -{ - flags |= O_CREAT | O_EXCL | O_RDWR; - return open(path, flags, S_IRUSR|S_IWUSR); -} - -int -mkostemps(char *path, int slen, int flags) -{ - if (flags & ~MKOSTEMP_FLAGS) { - errno = EINVAL; - return -1; - } - return __mktemp4(path, slen, flags, mkstemp_cb); -} - -int -mkostemp(char *path, int flags) -{ - if (flags & ~MKOSTEMP_FLAGS) { - errno = EINVAL; - return -1; - } - return __mktemp4(path, 0, flags, mkstemp_cb); -} -DEF_WEAK(mkostemp); - -int -mkstemp(char *path) -{ - return __mktemp4(path, 0, 0, mkstemp_cb); -} -DEF_WEAK(mkstemp); - -int -mkstemps(char *path, int slen) -{ - return __mktemp4(path, slen, 0, mkstemp_cb); -} diff --git a/src/lib/libc/stdlib/mktemp.3 b/src/lib/libc/stdlib/mktemp.3 deleted file mode 100644 index 83b7c9eb30..0000000000 --- a/src/lib/libc/stdlib/mktemp.3 +++ /dev/null @@ -1,431 +0,0 @@ -.\" $OpenBSD: mktemp.3,v 1.2 2024/03/01 21:30:40 millert Exp $ -.\" -.\" Copyright (c) 1989, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd $Mdocdate: March 1 2024 $ -.Dt MKTEMP 3 -.Os -.Sh NAME -.Nm mktemp , -.Nm mkstemp , -.Nm mkostemp , -.Nm mkstemps , -.Nm mkostemps , -.Nm mkdtemp , -.Nm mkdtemps -.Nd make temporary file name (unique) -.Sh SYNOPSIS -.In stdlib.h -.Ft char * -.Fn mktemp "char *template" -.Ft int -.Fn mkstemp "char *template" -.Ft int -.Fn mkstemps "char *template" "int suffixlen" -.Ft char * -.Fn mkdtemp "char *template" -.Ft char * -.Fn mkdtemps "char *template" "int suffixlen" -.In stdlib.h -.In fcntl.h -.Ft int -.Fn mkostemp "char *template" "int flags" -.Ft int -.Fn mkostemps "char *template" "int suffixlen" "int flags" -.Sh DESCRIPTION -The -.Fn mktemp -family of functions take the given file name template and overwrite -a portion of it to create a new file name. -This file name is unique and suitable for use by the application. -The template may be any file name with at least six trailing -.Em X Ns s , -for example -.Pa /tmp/temp.XXXXXXXX . -The trailing -.Em X Ns s -are replaced with a unique digit and letter combination. -The number of unique file names that can be returned -depends on the number of -.Em X Ns s -provided; -.Fn mktemp -will try at least 2 ** 31 combinations before giving up. -At least six -.Em X Ns s -must be used, though 10 is much better. -.Pp -The -.Fn mktemp -function generates a temporary file name based on a template as -described above. -Because -.Fn mktemp -does not actually create the temporary file, there is a window of -opportunity during which another process can open the file instead. -Because of this race condition, -.Fn mktemp -should not be used where -.Fn mkstemp -can be used instead. -.Fn mktemp -was marked as a legacy interface in -.St -p1003.1-2001 . -.Pp -The -.Fn mkstemp -function makes the same replacement to the template and creates the template -file, mode 0600, returning a file descriptor opened for reading and writing. -This avoids the race between testing for a file's existence and opening it -for use. -.Pp -The -.Fn mkostemp -function acts the same as -.Fn mkstemp , -except that the -.Fa flags -argument may contain zero or more of the following flags for the underlying -.Xr open 2 -system call: -.Pp -.Bl -tag -width "O_CLOEXECXX" -offset indent -compact -.It Dv O_APPEND -Append on each write. -.It Dv O_CLOEXEC -Set the close-on-exec flag on the new file descriptor. -.It Dv O_SYNC -Perform synchronous I/O operations. -.El -.Pp -The -.Fn mkstemps -and -.Fn mkostemps -functions act the same as -.Fn mkstemp -and -.Fn mkostemp , -except they permit a suffix to exist in the template. -The template should be of the form -.Pa /tmp/tmpXXXXXXXXXXsuffix . -.Fn mkstemps -and -.Fn mkostemps -are told the length of the suffix string, i.e., -.Li strlen("suffix") . -.Pp -The -.Fn mkdtemp -function makes the same replacement to the template as in -.Fn mktemp -and creates the template directory, mode 0700. -The -.Fn mkdtemps -function acts the same as -.Fn mkdtemp , -except that it permits a suffix to exist in the template, -similar to -.Fn mkstemps . -.Sh RETURN VALUES -The -.Fn mktemp , -.Fn mkdtemp , -and -.Fn mkdtemps -functions return a pointer to the template on success and -.Dv NULL -on failure. -The -.Fn mkstemp , -.Fn mkostemp , -.Fn mkstemps , -and -.Fn mkostemps -functions return \-1 if no suitable file could be created. -If any call fails, an error code is placed in the global variable -.Va errno . -.Sh EXAMPLES -Quite often a programmer will want to replace a use of -.Fn mktemp -with -.Fn mkstemp , -usually to avoid the problems described above. -Doing this correctly requires a good understanding of the code in question. -.Pp -For instance, code of this form: -.Bd -literal -offset indent -char sfn[19]; -FILE *sfp; - -strlcpy(sfn, "/tmp/ed.XXXXXXXXXX", sizeof(sfn)); -if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) { - warn("%s", sfn); - return (NULL); -} -return (sfp); -.Ed -.Pp -should be rewritten like this: -.Bd -literal -offset indent -char sfn[19]; -FILE *sfp; -int fd; - -strlcpy(sfn, "/tmp/ed.XXXXXXXXXX", sizeof(sfn)); -if ((fd = mkstemp(sfn)) == -1 || - (sfp = fdopen(fd, "w+")) == NULL) { - if (fd != -1) { - unlink(sfn); - close(fd); - } - warn("%s", sfn); - return (NULL); -} -return (sfp); -.Ed -.Pp -Often one will find code which uses -.Fn mktemp -very early on, perhaps to globally initialize the template nicely, but the -code which calls -.Xr open 2 -or -.Xr fopen 3 -on that file name will occur much later. -(In almost all cases, the use of -.Xr fopen 3 -will mean that the flags -.Dv O_CREAT -| -.Dv O_EXCL -are not given to -.Xr open 2 , -and thus a symbolic link race becomes possible, hence making -necessary the use of -.Xr fdopen 3 -as seen above.) -Furthermore, one must be careful about code which opens, closes, and then -re-opens the file in question. -Finally, one must ensure that upon error the temporary file is -removed correctly. -.Pp -There are also cases where modifying the code to use -.Fn mktemp , -in concert with -.Xr open 2 -using the flags -.Dv O_CREAT -| -.Dv O_EXCL , -is better, as long as the code retries a new template if -.Xr open 2 -fails with an -.Va errno -of -.Er EEXIST . -.Sh ERRORS -The -.Fn mktemp , -.Fn mkstemp , -.Fn mkostemp , -and -.Fn mkdtemp -functions may set -.Va errno -to one of the following values: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Ar template -argument has fewer than six trailing -.Em X Ns s . -.It Bq Er EEXIST -All file names tried are already in use. -Consider appending more -.Em X Ns s to the -.Ar template . -.El -.Pp -The -.Fn mkstemps -and -.Fn mkostemps -functions may set -.Va errno -to -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Ar template -argument length is less than -.Ar suffixlen -or it has fewer than six -.Em X Ns s -before the suffix. -.It Bq Er EEXIST -All file names tried are already in use. -Consider appending more -.Em X Ns s to the -.Ar template . -.El -.Pp -In addition, the -.Fn mkostemp -and -.Fn mkostemps -functions may also set -.Va errno -to -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa flags -is invalid. -.El -.Pp -The -.Fn mktemp -function may also set -.Va errno -to any value specified by the -.Xr lstat 2 -function. -.Pp -The -.Fn mkstemp , -.Fn mkostemp , -.Fn mkstemps , -and -.Fn mkostemps -functions may also set -.Va errno -to any value specified by the -.Xr open 2 -function. -.Pp -The -.Fn mkdtemp -function may also set -.Va errno -to any value specified by the -.Xr mkdir 2 -function. -.Sh SEE ALSO -.Xr chmod 2 , -.Xr lstat 2 , -.Xr mkdir 2 , -.Xr open 2 , -.Xr tempnam 3 , -.Xr tmpfile 3 , -.Xr tmpnam 3 -.Sh STANDARDS -The -.Fn mkdtemp -and -.Fn mkstemp -functions conform to the -.St -p1003.1-2008 -specification. -The ability to specify more than six -.Em X Ns s -is an extension to that standard. -The -.Fn mkostemp -function is expected to conform to a future revision of that standard. -.Pp -The -.Fn mktemp -function conforms to -.St -p1003.1-2001 ; -as of -.St -p1003.1-2008 -it is no longer a part of the standard. -.Pp -The -.Fn mkstemps , -.Fn mkostemps , -and -.Fn mkdtemps -functions are non-standard and should not be used if portability is required. -.Sh HISTORY -A -.Fn mktemp -function appeared in -.At v7 . -The -.Fn mkdtemp -function appeared in -.Ox 2.2 . -The -.Fn mkstemp -function appeared in -.Bx 4.3 . -The -.Fn mkstemps -function appeared in -.Ox 2.3 . -The -.Fn mkostemp -and -.Fn mkostemps -functions appeared in -.Ox 5.7 . -The -.Fn mkdtemps -function appeared in -.Ox 7.5 . -.Sh BUGS -For -.Fn mktemp -there is an obvious race between file name selection and file -creation and deletion: the program is typically written to call -.Xr tmpnam 3 , -.Xr tempnam 3 , -or -.Fn mktemp . -Subsequently, the program calls -.Xr open 2 -or -.Xr fopen 3 -and erroneously opens a file (or symbolic link, FIFO or other -device) that the attacker has created in the expected file location. -Hence -.Fn mkstemp -is recommended, since it atomically creates the file. -An attacker can guess the file names produced by -.Fn mktemp . -Whenever it is possible, -.Fn mkstemp -or -.Fn mkdtemp -should be used instead. -.Pp -For this reason, -.Xr ld 1 -will output a warning message whenever it links code that uses -.Fn mktemp . diff --git a/src/lib/libc/stdlib/mktemp.c b/src/lib/libc/stdlib/mktemp.c deleted file mode 100644 index 4dc06f74d1..0000000000 --- a/src/lib/libc/stdlib/mktemp.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $OpenBSD: mktemp.c,v 1.2 2024/01/19 19:45:02 millert Exp $ */ -/* - * Copyright (c) 2024 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -static int -mktemp_cb(const char *path, int flags) -{ - struct stat sb; - - if (lstat(path, &sb) == 0) - errno = EEXIST; - return (errno == ENOENT ? 0 : -1); -} - -/* Also called via tmpnam(3) and tempnam(3). */ -char * -_mktemp(char *path) -{ - if (__mktemp4(path, 0, 0, mktemp_cb) == 0) - return path; - return NULL; -} - -__warn_references(mktemp, - "mktemp() possibly used unsafely; consider using mkstemp()"); - -char * -mktemp(char *path) -{ - return _mktemp(path); -} diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c deleted file mode 100644 index 3334e2ad2b..0000000000 --- a/src/lib/libc/stdlib/mrand48.c +++ /dev/null @@ -1,24 +0,0 @@ -/* $OpenBSD: mrand48.c,v 1.6 2015/08/27 04:33:31 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -long -mrand48(void) -{ - if (__rand48_deterministic == 0) - return (int)arc4random(); - __dorand48(__rand48_seed); - return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1]; -} diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c deleted file mode 100644 index f1f548c3af..0000000000 --- a/src/lib/libc/stdlib/nrand48.c +++ /dev/null @@ -1,22 +0,0 @@ -/* $OpenBSD: nrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -long -nrand48(unsigned short xseed[3]) -{ - __dorand48(xseed); - return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1); -} diff --git a/src/lib/libc/stdlib/posix_memalign.3 b/src/lib/libc/stdlib/posix_memalign.3 deleted file mode 100644 index fcd0a4cbdb..0000000000 --- a/src/lib/libc/stdlib/posix_memalign.3 +++ /dev/null @@ -1,97 +0,0 @@ -.\" $OpenBSD: posix_memalign.3,v 1.4 2017/05/13 07:11:29 otto Exp $ -.\" Copyright (C) 2006 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc/stdlib/posix_memalign.3,v 1.3 2007/03/28 04:32:51 jasone Exp $ -.\" -.Dd $Mdocdate: May 13 2017 $ -.Dt POSIX_MEMALIGN 3 -.Os -.Sh NAME -.Nm posix_memalign -.Nd aligned memory allocation -.Sh SYNOPSIS -.In stdlib.h -.Ft int -.Fn posix_memalign "void **ptr" "size_t alignment" "size_t size" -.Sh DESCRIPTION -The -.Fn posix_memalign -function allocates -.Fa size -bytes of memory such that the allocation's base address is a multiple of -.Fa alignment , -and returns the allocation in the value pointed to by -.Fa ptr . -.Pp -The requested -.Fa alignment -must be a power of 2 at least as large as -.Fn sizeof "void *" . -.Pp -Memory that is allocated via -.Fn posix_memalign -can be used as an argument in subsequent calls to -.Xr realloc 3 , -.Xr reallocarray 3 -and -.Xr free 3 , -but not -.Xr recallocarray 3 -and -.Xr freezero 3 . -.Sh RETURN VALUES -The -.Fn posix_memalign -function returns the value 0 if successful; otherwise it returns an error value. -.Sh ERRORS -The -.Fn posix_memalign -function will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fa alignment -parameter is not a power of 2 at least as large as -.Fn sizeof "void *" . -.It Bq Er ENOMEM -Memory allocation error. -.El -.Sh SEE ALSO -.Xr free 3 , -.Xr malloc 3 , -.Xr realloc 3 -.Sh STANDARDS -The -.Fn posix_memalign -function conforms to -.St -p1003.1-2001 . -.Sh HISTORY -The -.Fn posix_memalign -function first appeared in -.Ox 4.8 . diff --git a/src/lib/libc/stdlib/posix_openpt.3 b/src/lib/libc/stdlib/posix_openpt.3 deleted file mode 100644 index b55e1be750..0000000000 --- a/src/lib/libc/stdlib/posix_openpt.3 +++ /dev/null @@ -1,102 +0,0 @@ -.\" $OpenBSD: posix_openpt.3,v 1.4 2019/01/25 00:19:25 millert Exp $ -.\" -.\" Copyright (c) 2012 Todd C. Miller -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.Dd $Mdocdate: January 25 2019 $ -.Dt POSIX_OPENPT 3 -.Os -.Sh NAME -.Nm posix_openpt -.Nd open a pseudo-terminal device -.Sh SYNOPSIS -.In stdlib.h -.In fcntl.h -.Ft int -.Fn posix_openpt "int oflag" -.Sh DESCRIPTION -The -.Fn posix_openpt -function finds the next available pseudo-terminal and returns an open -file descriptor for its master device. -The path name of the slave device may be determined via the -.Fn ptsname -function. -Note that the -.Fn unlockpt -and -.Fn grantpt -functions should be called before opening the slave device. -.Pp -The -.Ar oflag -argument is formed by bitwise-inclusive -.Tn OR Ns 'ing -the following values defined in -.In fcntl.h : -.Bl -tag -width O_NOCTTY -offset indent -.It Dv O_RDWR -Open for reading and writing. -.It Dv O_NOCTTY -Prevent the device from being made the controlling terminal for the session. -This flag has no effect on -.Ox -and is included for compatibility with other systems. -.El -.Pp -The -.Dv O_RDWR -flag must be specified in -.Fa oflag . -If -.Fa oflag -contains values other than those listed above, -.Fn posix_openpt -will return an error. -.Sh RETURN VALUES -If successful, -.Fn posix_openpt -returns a non-negative integer, the file descriptor for the -pseudo-terminal master device. -Otherwise, a value of \-1 is returned and -.Va errno -is set to indicate the error. -.Sh ERRORS -The -.Fn posix_openpt -function will fail if: -.Bl -tag -width Er -.It Bq Er EMFILE -The per-process descriptor table is full. -.It Bq Er ENFILE -The system file table is full. -.It Bq Er EINVAL -The value of -.Fa oflag -is not valid. -.El -.Sh SEE ALSO -.Xr ptsname 3 , -.Xr pty 4 , -.Xr tty 4 -.Sh STANDARDS -The -.Fn posix_openpt -function conforms to -.St -p1003.1-2001 . -.Sh HISTORY -The -.Fn posix_openpt -function appeared in -.Ox 5.3 . diff --git a/src/lib/libc/stdlib/posix_pty.c b/src/lib/libc/stdlib/posix_pty.c deleted file mode 100644 index e45ab6ebd0..0000000000 --- a/src/lib/libc/stdlib/posix_pty.c +++ /dev/null @@ -1,120 +0,0 @@ -/* $OpenBSD: posix_pty.c,v 1.3 2019/01/25 00:19:25 millert Exp $ */ - -/* - * Copyright (c) 2012 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int -posix_openpt(int oflag) -{ - struct ptmget ptm; - int fd, mfd = -1; - - /* User must specify O_RDWR in oflag. */ - if ((oflag & O_ACCMODE) != O_RDWR || - (oflag & ~(O_ACCMODE | O_NOCTTY)) != 0) { - errno = EINVAL; - return -1; - } - - /* Get pty master and slave (this API only uses the master). */ - fd = open(PATH_PTMDEV, O_RDWR); - if (fd != -1) { - if (ioctl(fd, PTMGET, &ptm) != -1) { - close(ptm.sfd); - mfd = ptm.cfd; - } - close(fd); - } - - return mfd; -} - -/* - * Look up the name of the specified pty master fd. - * Note that the name returned does *not* include the /dev/ prefix. - * Returns the name on success and NULL on error, setting errno. - */ -static const char * -ptmname(int mfd) -{ - struct stat sb; - const char *name; - - /* Make sure it is a pty master. */ - if (fstat(mfd, &sb) != 0) - return NULL; - if (!S_ISCHR(sb.st_mode)) { - errno = EINVAL; - return NULL; - } - name = devname(sb.st_rdev, S_IFCHR); - if (strncmp(name, "pty", 3) != 0) { - errno = EINVAL; - return NULL; - } - return name; -} - -/* - * The PTMGET ioctl handles the mode and owner for us. - */ -int -grantpt(int mfd) -{ - return ptmname(mfd) ? 0 : -1; -} - -/* - * The PTMGET ioctl unlocks the pty master and slave for us. - */ -int -unlockpt(int mfd) -{ - return ptmname(mfd) ? 0 : -1; -} - -/* - * Look up the path of the slave pty that corresponds to the master fd. - * Returns the path if successful or NULL on error. - */ -char * -ptsname(int mfd) -{ - const char *master; - static char slave[sizeof(((struct ptmget *)NULL)->sn)]; - - if ((master = ptmname(mfd)) == NULL) - return NULL; - - /* Add /dev/ prefix and convert "pty" to "tty". */ - strlcpy(slave, _PATH_DEV, sizeof(slave)); - strlcat(slave, master, sizeof(slave)); - slave[sizeof(_PATH_DEV) - 1] = 't'; - - return slave; -} diff --git a/src/lib/libc/stdlib/ptsname.3 b/src/lib/libc/stdlib/ptsname.3 deleted file mode 100644 index 98705528f5..0000000000 --- a/src/lib/libc/stdlib/ptsname.3 +++ /dev/null @@ -1,160 +0,0 @@ -.\" $OpenBSD: ptsname.3,v 1.2 2012/12/04 18:42:16 millert Exp $ -.\" -.\" Copyright (c) 2002 The FreeBSD Project, Inc. -.\" All rights reserved. -.\" -.\" This software includes code contributed to the FreeBSD Project -.\" by Ryan Younce of North Carolina State University. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the FreeBSD Project nor the names of its -.\" contributors may be used to endorse or promote products derived from -.\" this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT -.\" OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: head/lib/libc/stdlib/ptsname.3 240412 2012-09-12 17:54:09Z emaste $ -.\" -.Dd $Mdocdate: December 4 2012 $ -.Dt PTSNAME 3 -.Os -.Sh NAME -.Nm grantpt , -.Nm ptsname , -.Nm unlockpt -.Nd pseudo-terminal access functions -.Sh SYNOPSIS -.In stdlib.h -.Ft int -.Fn grantpt "int fildes" -.Ft "char *" -.Fn ptsname "int fildes" -.Ft int -.Fn unlockpt "int fildes" -.Sh DESCRIPTION -The -.Fn grantpt , -.Fn ptsname , -and -.Fn unlockpt -functions allow access to pseudo-terminal devices. -These three functions accept a file descriptor that references the -master half of a pseudo-terminal pair. -This file descriptor is created with -.Xr posix_openpt 3 . -.Pp -The -.Fn grantpt -function is used to establish ownership and permissions -of the slave device counterpart to the master device -specified with -.Fa fildes . -The slave device's ownership is set to the real user ID -of the calling process, and the permissions are set to -user readable-writable and group writable. -The group owner of the slave device is also set to the -group -.Dq Li tty . -.Pp -The -.Fn ptsname -function returns the full path name of the slave device -counterpart to the master device specified with -.Fa fildes . -This value can be used -to subsequently open the appropriate slave after -.Xr posix_openpt 3 -and -.Fn grantpt -have been called. -.Pp -The -.Fn unlockpt -function clears the lock held on the pseudo-terminal pair -for the master device specified with -.Fa fildes . -.Sh RETURN VALUES -.Rv -std grantpt unlockpt -.Pp -The -.Fn ptsname -function returns a pointer to the name -of the slave device on success; otherwise a -.Dv NULL -pointer is returned. -.Sh ERRORS -The -.Fn grantpt , -.Fn ptsname -and -.Fn unlockpt -functions may fail and set -.Va errno -to: -.Bl -tag -width Er -.It Bq Er EBADF -.Fa fildes -is not a valid open file descriptor. -.It Bq Er EINVAL -.Fa fildes -is not a master pseudo-terminal device. -.El -.Pp -In addition, the -.Fn grantpt -function may set -.Va errno -to: -.Bl -tag -width Er -.It Bq Er EACCES -The slave pseudo-terminal device could not be accessed. -.El -.Sh SEE ALSO -.Xr posix_openpt 3 , -.Xr pty 4 , -.Xr tty 4 -.Sh STANDARDS -The -.Fn ptsname -function conforms to -.St -p1003.1-2008 . -.Pp -This implementation of -.Fn grantpt -and -.Fn unlockpt -does not conform to -.St -p1003.1-2008 , -because it depends on -.Xr posix_openpt 3 -to create the pseudo-terminal device with proper permissions in place. -It only validates whether -.Fa fildes -is a valid pseudo-terminal master device. -Future revisions of the specification will likely allow this behaviour, -as stated by the Austin Group. -.Sh HISTORY -The -.Fn grantpt , -.Fn ptsname -and -.Fn unlockpt -functions appeared in -.Ox 5.3 . diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3 deleted file mode 100644 index 4c0cddaccb..0000000000 --- a/src/lib/libc/stdlib/qsort.3 +++ /dev/null @@ -1,276 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: qsort.3,v 1.27 2020/02/08 01:09:57 jsg Exp $ -.\" -.Dd $Mdocdate: February 8 2020 $ -.Dt QSORT 3 -.Os -.Sh NAME -.Nm qsort , -.Nm heapsort , -.Nm mergesort -.Nd sort functions -.Sh SYNOPSIS -.In stdlib.h -.Ft void -.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" -.Ft int -.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" -.Ft int -.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" -.Sh DESCRIPTION -The -.Fn qsort -function is a modified partition-exchange sort, or quicksort. -The -.Fn heapsort -function is a modified selection sort. -The -.Fn mergesort -function is a modified merge sort with exponential search -intended for sorting data with pre-existing order. -.Pp -The -.Fn qsort -and -.Fn heapsort -functions sort an array of -.Fa nmemb -objects, the initial member of which is pointed to by -.Fa base . -The size of each object is specified by -.Fa size . -.Fn mergesort -behaves similarly, but -.Em requires -that -.Fa size -be greater than -.Dq "sizeof(void *) / 2" . -.Pp -The contents of the array -.Fa base -are sorted in ascending order according to -a comparison function pointed to by -.Fa compar , -which requires two arguments pointing to the objects being -compared. -.Pp -The comparison function must return an int less than, equal to, or -greater than zero if the first argument is considered to be respectively -less than, equal to, or greater than the second. -.Pp -The functions -.Fn qsort -and -.Fn heapsort -are -.Em not -stable, that is, if two members compare as equal, their order in -the sorted array is undefined. -The function -.Fn mergesort -is stable. -.Pp -The -.Fn qsort -function is an implementation of C.A.R. Hoare's -.Dq quicksort -algorithm, -a variant of partition-exchange sorting; in particular, see D.E. Knuth's -Algorithm Q. -.Fn qsort -takes O N lg N average time. -This implementation uses median selection to avoid its -O N**2 worst-case behavior and will fall back to -.Fn heapsort -if the recursion depth exceeds 2 lg N. -.Pp -The -.Fn heapsort -function is an implementation of J.W.J. William's -.Dq heapsort -algorithm, -a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. -.Fn heapsort -takes O N lg N worst-case time. -This implementation of -.Fn heapsort -is implemented without recursive function calls. -.Pp -The function -.Fn mergesort -requires additional memory of size -.Fa nmemb * -.Fa size -bytes; it should be used only when space is not at a premium. -.Fn mergesort -is optimized for data with pre-existing order; its worst case -time is O N lg N; its best case is O N. -.Pp -Normally, -.Fn qsort -is faster than -.Fn mergesort , -which is faster than -.Fn heapsort . -Memory availability and pre-existing order in the data can make this untrue. -.Sh RETURN VALUES -.Rv -std heapsort mergesort -.Sh EXAMPLES -.Bd -literal -#include -#include -#include - -char *array[] = { "XX", "YYY", "Z" }; -#define N (sizeof(array) / sizeof(array[0])) - -int -cmp(const void *a, const void *b) -{ - /* - * a and b point to elements of the array. - * Cast and dereference to obtain the actual elements, - * which are also pointers in this case. - */ - size_t lena = strlen(*(const char **)a); - size_t lenb = strlen(*(const char **)b); - /* - * Do not subtract the lengths. The difference between values - * cannot be represented by an int. - */ - return lena < lenb ? -1 : lena > lenb; -} - -int -main() -{ - size_t i; - - qsort(array, N, sizeof(array[0]), cmp); - for (i = 0; i < N; i++) - printf("%s\en", array[i]); -} -.Ed -.Pp -It is almost always an error to use subtraction to compute the return value -of the comparison function. -.Sh ERRORS -The -.Fn heapsort -and -.Fn mergesort -functions succeed unless: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fa size -argument is zero, or the -.Fa size -argument to -.Fn mergesort -is less than -.Dq "sizeof(void *) / 2" . -.It Bq Er ENOMEM -.Fn heapsort -or -.Fn mergesort -were unable to allocate memory. -.El -.Sh SEE ALSO -.Xr sort 1 , -.Xr radixsort 3 -.Rs -.%A Hoare, C.A.R. -.%D 1962 -.%T "Quicksort" -.%J "The Computer Journal" -.%V 5:1 -.%P pp. 10-15 -.Re -.Rs -.%A Williams, J.W.J -.%D 1964 -.%T "Heapsort" -.%J "Communications of the ACM" -.%V 7:1 -.%P pp. 347\-348 -.Re -.Rs -.%A Knuth, D.E. -.%D 1968 -.%B "The Art of Computer Programming" -.%V Vol. 3 -.%T "Sorting and Searching" -.%P pp. 114\-123, 145\-149 -.Re -.Rs -.%A McIlroy, P.M. -.%T "Optimistic Sorting and Information Theoretic Complexity" -.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" -.%P pp. 467\-464 -.%D January 1993 -.Re -.Rs -.%A Bentley, J.L. -.%A McIlroy, M.D. -.%T "Engineering a Sort Function" -.%J "Software \- Practice and Experience" -.%V Vol. 23(11) -.%P pp. 1249\-1265 -.%D November 1993 -.Re -.Rs -.%A Musser, D. -.%T "Introspective Sorting and Selection Algorithms" -.%J "Software \- Practice and Experience" -.%V Vol. 27(8) -.%P pp. 983\-993 -.%D August 1997 -.Re -.Sh STANDARDS -Previous versions of -.Fn qsort -did not permit the comparison routine itself to call -.Fn qsort . -This is no longer true. -.Pp -The -.Fn qsort -function conforms to -.St -ansiC . -.Sh HISTORY -A -.Fn qsort -function first appeared in -.At v2 . diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c deleted file mode 100644 index ca73e67f29..0000000000 --- a/src/lib/libc/stdlib/qsort.c +++ /dev/null @@ -1,238 +0,0 @@ -/* $OpenBSD: qsort.c,v 1.18 2017/05/30 14:54:09 millert Exp $ */ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -static __inline char *med3(char *, char *, char *, int (*)(const void *, const void *)); -static __inline void swapfunc(char *, char *, size_t, int); - -#define min(a, b) (a) < (b) ? a : b - -/* - * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". - * - * This version differs from Bentley & McIlroy in the following ways: - * 1. The partition value is swapped into a[0] instead of being - * stored out of line. - * - * 2. The swap function can swap 32-bit aligned elements on 64-bit - * platforms instead of swapping them as byte-aligned. - * - * 3. It uses David Musser's introsort algorithm to fall back to - * heapsort(3) when the recursion depth reaches 2*lg(n + 1). - * This avoids quicksort's quadratic behavior for pathological - * input without appreciably changing the average run time. - * - * 4. Tail recursion is eliminated when sorting the larger of two - * subpartitions to save stack space. - */ -#define SWAPTYPE_BYTEV 1 -#define SWAPTYPE_INTV 2 -#define SWAPTYPE_LONGV 3 -#define SWAPTYPE_INT 4 -#define SWAPTYPE_LONG 5 - -#define TYPE_ALIGNED(TYPE, a, es) \ - (((char *)a - (char *)0) % sizeof(TYPE) == 0 && es % sizeof(TYPE) == 0) - -#define swapcode(TYPE, parmi, parmj, n) { \ - size_t i = (n) / sizeof (TYPE); \ - TYPE *pi = (TYPE *) (parmi); \ - TYPE *pj = (TYPE *) (parmj); \ - do { \ - TYPE t = *pi; \ - *pi++ = *pj; \ - *pj++ = t; \ - } while (--i > 0); \ -} - -static __inline void -swapfunc(char *a, char *b, size_t n, int swaptype) -{ - switch (swaptype) { - case SWAPTYPE_INT: - case SWAPTYPE_INTV: - swapcode(int, a, b, n); - break; - case SWAPTYPE_LONG: - case SWAPTYPE_LONGV: - swapcode(long, a, b, n); - break; - default: - swapcode(char, a, b, n); - break; - } -} - -#define swap(a, b) do { \ - switch (swaptype) { \ - case SWAPTYPE_INT: { \ - int t = *(int *)(a); \ - *(int *)(a) = *(int *)(b); \ - *(int *)(b) = t; \ - break; \ - } \ - case SWAPTYPE_LONG: { \ - long t = *(long *)(a); \ - *(long *)(a) = *(long *)(b); \ - *(long *)(b) = t; \ - break; \ - } \ - default: \ - swapfunc(a, b, es, swaptype); \ - } \ -} while (0) - -#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) - -static __inline char * -med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) -{ - return cmp(a, b) < 0 ? - (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) - :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); -} - -static void -introsort(char *a, size_t n, size_t es, size_t maxdepth, int swaptype, - int (*cmp)(const void *, const void *)) -{ - char *pa, *pb, *pc, *pd, *pl, *pm, *pn; - int cmp_result; - size_t r, s; - -loop: if (n < 7) { - for (pm = a + es; pm < a + n * es; pm += es) - for (pl = pm; pl > a && cmp(pl - es, pl) > 0; - pl -= es) - swap(pl, pl - es); - return; - } - if (maxdepth == 0) { - if (heapsort(a, n, es, cmp) == 0) - return; - } - maxdepth--; - pm = a + (n / 2) * es; - if (n > 7) { - pl = a; - pn = a + (n - 1) * es; - if (n > 40) { - s = (n / 8) * es; - pl = med3(pl, pl + s, pl + 2 * s, cmp); - pm = med3(pm - s, pm, pm + s, cmp); - pn = med3(pn - 2 * s, pn - s, pn, cmp); - } - pm = med3(pl, pm, pn, cmp); - } - swap(a, pm); - pa = pb = a + es; - pc = pd = a + (n - 1) * es; - for (;;) { - while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { - if (cmp_result == 0) { - swap(pa, pb); - pa += es; - } - pb += es; - } - while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { - if (cmp_result == 0) { - swap(pc, pd); - pd -= es; - } - pc -= es; - } - if (pb > pc) - break; - swap(pb, pc); - pb += es; - pc -= es; - } - - pn = a + n * es; - r = min(pa - a, pb - pa); - vecswap(a, pb - r, r); - r = min(pd - pc, pn - pd - es); - vecswap(pb, pn - r, r); - /* - * To save stack space we sort the smaller side of the partition first - * using recursion and eliminate tail recursion for the larger side. - */ - r = pb - pa; - s = pd - pc; - if (r < s) { - /* Recurse for 1st side, iterate for 2nd side. */ - if (s > es) { - if (r > es) { - introsort(a, r / es, es, maxdepth, - swaptype, cmp); - } - a = pn - s; - n = s / es; - goto loop; - } - } else { - /* Recurse for 2nd side, iterate for 1st side. */ - if (r > es) { - if (s > es) { - introsort(pn - s, s / es, es, maxdepth, - swaptype, cmp); - } - n = r / es; - goto loop; - } - } -} - -void -qsort(void *a, size_t n, size_t es, int (*cmp)(const void *, const void *)) -{ - size_t i, maxdepth = 0; - int swaptype; - - /* Approximate 2*ceil(lg(n + 1)) */ - for (i = n; i > 0; i >>= 1) - maxdepth++; - maxdepth *= 2; - - if (TYPE_ALIGNED(long, a, es)) - swaptype = es == sizeof(long) ? SWAPTYPE_LONG : SWAPTYPE_LONGV; - else if (sizeof(int) != sizeof(long) && TYPE_ALIGNED(int, a, es)) - swaptype = es == sizeof(int) ? SWAPTYPE_INT : SWAPTYPE_INTV; - else - swaptype = SWAPTYPE_BYTEV; - - introsort(a, n, es, maxdepth, swaptype, cmp); - -} - -DEF_STRONG(qsort); diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3 deleted file mode 100644 index 7290142a9c..0000000000 --- a/src/lib/libc/stdlib/radixsort.3 +++ /dev/null @@ -1,151 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: radixsort.3,v 1.14 2022/08/04 06:20:24 jsg Exp $ -.\" -.Dd $Mdocdate: August 4 2022 $ -.Dt RADIXSORT 3 -.Os -.Sh NAME -.Nm radixsort , -.Nm sradixsort -.Nd radix sort -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft int -.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte" -.Ft int -.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte" -.Sh DESCRIPTION -The -.Fn radixsort -and -.Fn sradixsort -functions are implementations of radix sort. -.Pp -These functions sort an array of -.Fa nmemb -pointers to byte strings. -The initial member is referenced by -.Fa base . -The byte strings may contain any values; the end of each string -is denoted by the user-specified value -.Fa endbyte . -.Pp -Applications may specify a sort order by providing the -.Fa table -argument. -If non-null, -.Fa table -must reference an array of -.Dv UCHAR_MAX -+ 1 bytes which contains the sort weight of each possible byte value. -The end-of-string byte must have a sort weight of 0 or 255 -(for sorting in reverse order). -More than one byte may have the same sort weight. -The -.Fa table -argument is useful for applications which wish to sort different characters -equally; for example, providing a table with the same weights -for A\-Z as for a\-z will result in a case-insensitive sort. -If -.Fa table -is -.Dv NULL , -the contents of the array are sorted in ascending order according to the -ASCII order of the byte strings they reference and -.Fa endbyte -has a sorting weight of 0. -.Pp -The -.Fn sradixsort -function is stable; that is, if two elements compare as equal, their -order in the sorted array is unchanged. -The -.Fn sradixsort -function uses additional memory sufficient to hold -.Fa nmemb -pointers. -.Pp -The -.Fn radixsort -function is not stable, but uses no additional memory. -.Pp -These functions are variants of most-significant-byte radix sorting; in -particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10. -They take linear time relative to the number of bytes in the strings. -.Sh RETURN VALUES -.Rv -std -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EINVAL -The value of the -.Fa endbyte -element of -.Fa table -is not 0 or 255. -.El -.Pp -Additionally, the -.Fn sradixsort -function may fail and set -.Va errno -for any of the errors specified for the library routine -.Xr malloc 3 . -.Sh SEE ALSO -.Xr sort 1 , -.Xr qsort 3 -.Rs -.%A Knuth, D.E. -.%D 1968 -.%B "The Art of Computer Programming" -.%T "Sorting and Searching" -.%V Vol. 3 -.%P pp. 170-178 -.Re -.Rs -.%A Paige, R. -.%D 1987 -.%T "Three Partition Refinement Algorithms" -.%J "SIAM J. Comput." -.%V Vol. 16 -.%N No. 6 -.Re -.Rs -.%A McIlroy, P. -.%D 1993 -.%B "Engineering Radix Sort" -.%T "Computing Systems" -.%V Vol. 6:1 -.%P pp. 5-27 -.Re -.Sh HISTORY -The -.Fn radixsort -function first appeared in -.Bx 4.3 Net/2 . diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c deleted file mode 100644 index 49d03b52d5..0000000000 --- a/src/lib/libc/stdlib/radixsort.c +++ /dev/null @@ -1,294 +0,0 @@ -/* $OpenBSD: radixsort.c,v 1.9 2007/09/02 15:19:17 deraadt Exp $ */ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy and by Dan Bernstein at New York University, - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Radixsort routines. - * - * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack. - * Use radixsort(a, n, trace, endchar) for this case. - * - * For stable sorting (using N extra pointers) use sradixsort(), which calls - * r_sort_b(). - * - * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic, - * "Engineering Radix Sort". - */ - -#include -#include -#include - -typedef struct { - const u_char **sa; - int sn, si; -} stack; - -static __inline void simplesort -(const u_char **, int, int, const u_char *, u_int); -static void r_sort_a(const u_char **, int, int, const u_char *, u_int); -static void r_sort_b(const u_char **, - const u_char **, int, int, const u_char *, u_int); - -#define THRESHOLD 20 /* Divert to simplesort(). */ -#define SIZE 512 /* Default stack size. */ - -#define SETUP { \ - if (tab == NULL) { \ - tr = tr0; \ - for (c = 0; c < endch; c++) \ - tr0[c] = c + 1; \ - tr0[c] = 0; \ - for (c++; c < 256; c++) \ - tr0[c] = c; \ - endch = 0; \ - } else { \ - endch = tab[endch]; \ - tr = tab; \ - if (endch != 0 && endch != 255) { \ - errno = EINVAL; \ - return (-1); \ - } \ - } \ -} - -int -radixsort(const u_char **a, int n, const u_char *tab, u_int endch) -{ - const u_char *tr; - int c; - u_char tr0[256]; - - SETUP; - r_sort_a(a, n, 0, tr, endch); - return (0); -} - -int -sradixsort(const u_char **a, int n, const u_char *tab, u_int endch) -{ - const u_char *tr, **ta; - int c; - u_char tr0[256]; - - SETUP; - if (n < THRESHOLD) - simplesort(a, n, 0, tr, endch); - else { - if ((ta = calloc(n, sizeof(a))) == NULL) - return (-1); - r_sort_b(a, ta, n, 0, tr, endch); - free(ta); - } - return (0); -} - -#define empty(s) (s >= sp) -#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si -#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i -#define swap(a, b, t) t = a, a = b, b = t - -/* Unstable, in-place sort. */ -void -r_sort_a(const u_char **a, int n, int i, const u_char *tr, u_int endch) -{ - static int count[256], nc, bmin; - int c; - const u_char **ak, *r; - stack s[SIZE], *sp, *sp0, *sp1, temp; - int *cp, bigc; - const u_char **an, *t, **aj, **top[256]; - - /* Set up stack. */ - sp = s; - push(a, n, i); - while (!empty(s)) { - pop(a, n, i); - if (n < THRESHOLD) { - simplesort(a, n, i, tr, endch); - continue; - } - an = a + n; - - /* Make character histogram. */ - if (nc == 0) { - bmin = 255; /* First occupied bin, excluding eos. */ - for (ak = a; ak < an;) { - c = tr[(*ak++)[i]]; - if (++count[c] == 1 && c != endch) { - if (c < bmin) - bmin = c; - nc++; - } - } - if (sp + nc > s + SIZE) { /* Get more stack. */ - r_sort_a(a, n, i, tr, endch); - continue; - } - } - - /* - * Set top[]; push incompletely sorted bins onto stack. - * top[] = pointers to last out-of-place element in bins. - * count[] = counts of elements in bins. - * Before permuting: top[c-1] + count[c] = top[c]; - * during deal: top[c] counts down to top[c-1]. - */ - sp0 = sp1 = sp; /* Stack position of biggest bin. */ - bigc = 2; /* Size of biggest bin. */ - if (endch == 0) /* Special case: set top[eos]. */ - top[0] = ak = a + count[0]; - else { - ak = a; - top[255] = an; - } - for (cp = count + bmin; nc > 0; cp++) { - while (*cp == 0) /* Find next non-empty pile. */ - cp++; - if (*cp > 1) { - if (*cp > bigc) { - bigc = *cp; - sp1 = sp; - } - push(ak, *cp, i+1); - } - top[cp-count] = ak += *cp; - nc--; - } - swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */ - - /* - * Permute misplacements home. Already home: everything - * before aj, and in bin[c], items from top[c] on. - * Inner loop: - * r = next element to put in place; - * ak = top[r[i]] = location to put the next element. - * aj = bottom of 1st disordered bin. - * Outer loop: - * Once the 1st disordered bin is done, ie. aj >= ak, - * aj<-aj + count[c] connects the bins in a linked list; - * reset count[c]. - */ - for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0) - for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);) - swap(*ak, r, t); - } -} - -/* Stable sort, requiring additional memory. */ -void -r_sort_b(const u_char **a, const u_char **ta, int n, int i, const u_char *tr, - u_int endch) -{ - static int count[256], nc, bmin; - int c; - const u_char **ak, **ai; - stack s[512], *sp, *sp0, *sp1, temp; - const u_char **top[256]; - int *cp, bigc; - - sp = s; - push(a, n, i); - while (!empty(s)) { - pop(a, n, i); - if (n < THRESHOLD) { - simplesort(a, n, i, tr, endch); - continue; - } - - if (nc == 0) { - bmin = 255; - for (ak = a + n; --ak >= a;) { - c = tr[(*ak)[i]]; - if (++count[c] == 1 && c != endch) { - if (c < bmin) - bmin = c; - nc++; - } - } - if (sp + nc > s + SIZE) { - r_sort_b(a, ta, n, i, tr, endch); - continue; - } - } - - sp0 = sp1 = sp; - bigc = 2; - if (endch == 0) { - top[0] = ak = a + count[0]; - count[0] = 0; - } else { - ak = a; - top[255] = a + n; - count[255] = 0; - } - for (cp = count + bmin; nc > 0; cp++) { - while (*cp == 0) - cp++; - if ((c = *cp) > 1) { - if (c > bigc) { - bigc = c; - sp1 = sp; - } - push(ak, c, i+1); - } - top[cp-count] = ak += c; - *cp = 0; /* Reset count[]. */ - nc--; - } - swap(*sp0, *sp1, temp); - - for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */ - *--ak = *--ai; - for (ak = ta+n; --ak >= ta;) /* Deal to piles. */ - *--top[tr[(*ak)[i]]] = *ak; - } -} - -static __inline void -simplesort(const u_char **a, int n, int b, const u_char *tr, u_int endch) - /* insertion sort */ -{ - u_char ch; - const u_char **ak, **ai, *s, *t; - - for (ak = a+1; --n >= 1; ak++) - for (ai = ak; ai > a; ai--) { - for (s = ai[0] + b, t = ai[-1] + b; - (ch = tr[*s]) != endch; s++, t++) - if (ch != tr[*t]) - break; - if (ch >= tr[*t]) - break; - swap(ai[0], ai[-1], s); - } -} diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3 deleted file mode 100644 index cf7dde8536..0000000000 --- a/src/lib/libc/stdlib/rand.3 +++ /dev/null @@ -1,135 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: rand.3,v 1.21 2022/03/29 18:15:52 naddy Exp $ -.\" -.Dd $Mdocdate: March 29 2022 $ -.Dt RAND 3 -.Os -.Sh NAME -.Nm rand , -.Nm rand_r , -.Nm srand , -.Nm srand_deterministic -.Nd bad pseudo-random number generator -.Sh SYNOPSIS -.In stdlib.h -.Ft void -.Fn srand "unsigned int seed" -.Ft void -.Fn srand_deterministic "unsigned int seed" -.Ft int -.Fn rand void -.Ft int -.Fn rand_r "unsigned int *seed" -.Sh DESCRIPTION -.Bf -symbolic -Standards insist that this interface return deterministic results. -Unsafe usage is very common, so -.Ox -changed the subsystem to return non-deterministic results by default. -.Ef -.Pp -To satisfy portable code, -.Fn srand -may be called to initialize the subsystem. -In -.Ox -the -.Ar seed -variable is ignored, and strong random number results will be provided from -.Xr arc4random 3 . -In other systems, the -.Ar seed -variable primes a simplistic deterministic algorithm. -.Pp -If the standardized behavior is required -.Fn srand_deterministic -can be substituted for -.Fn srand , -then subsequent -.Fn rand -calls will return results using the deterministic algorithm. -The deterministic sequence algorithm changed a number of times since -original development, is underspecified, and should not be relied upon to -remain consistent between platforms and over time. -.Pp -The -.Fn rand -function returns a result in the range of 0 to -.Dv RAND_MAX . -By default, this result comes from -.Xr arc4random 3 . -If -.Fn srand_deterministic -was called, the result will be computed using the deterministic algorithm. -.Pp -The -.Fn rand_r -function is a thread-safe version of -.Fn rand . -Storage for the seed must be provided through the -.Fa seed -argument, and needs to have been initialized by the caller. -It always operates using the deterministic algorithm. -.Sh SEE ALSO -.Xr arc4random 3 , -.Xr rand48 3 , -.Xr random 3 -.Sh STANDARDS -The -.Fn rand -function conforms to -.St -ansiC . -.Pp -The -.Fn rand_r -function conforms to -.St -p1003.1-2008 . -.Pp -The -.Fn srand -function does not conform to -.St -ansiC , -intentionally. -.Pp -The -.Fn srand_deterministic -function is an -.Ox -extension. -.Sh HISTORY -The functions -.Fn rand -and -.Fn srand -first appeared in -.At v3 . diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c deleted file mode 100644 index 97964f6ef9..0000000000 --- a/src/lib/libc/stdlib/rand.c +++ /dev/null @@ -1,74 +0,0 @@ -/* $OpenBSD: rand.c,v 1.18 2017/11/28 06:55:49 tb Exp $ */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -static int rand_deterministic; -static u_int next = 1; - -int -rand_r(u_int *seed) -{ - *seed = *seed * 1103515245 + 12345; - return (*seed & RAND_MAX); -} -DEF_WEAK(rand_r); - -#if defined(APIWARN) -__warn_references(rand_r, - "rand_r() is not random, it is deterministic."); -#endif - -int -rand(void) -{ - if (rand_deterministic == 0) - return (arc4random() & RAND_MAX); - return (rand_r(&next)); -} - -#if defined(APIWARN) -__warn_references(rand, - "rand() may return deterministic values, is that what you want?"); -#endif - -void -srand(u_int seed) -{ - rand_deterministic = 0; -} - -void -srand_deterministic(u_int seed) -{ - rand_deterministic = 1; - next = seed; -} diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3 deleted file mode 100644 index fa7a7179bc..0000000000 --- a/src/lib/libc/stdlib/rand48.3 +++ /dev/null @@ -1,240 +0,0 @@ -.\" Copyright (c) 1993 Martin Birgmeier -.\" All rights reserved. -.\" -.\" You may redistribute unmodified or modified versions of this source -.\" code provided that the above copyright notice and this and the -.\" following conditions are retained. -.\" -.\" This software is provided ``as is'', and comes with no warranties -.\" of any kind. I shall in no event be liable for anything that happens -.\" to anyone/anything when using this software. -.\" -.\" $OpenBSD: rand48.3,v 1.21 2019/12/20 19:16:40 tb Exp $ -.\" -.Dd $Mdocdate: December 20 2019 $ -.Dt DRAND48 3 -.Os -.Sh NAME -.Nm drand48 , -.Nm erand48 , -.Nm lrand48 , -.Nm nrand48 , -.Nm mrand48 , -.Nm jrand48 , -.Nm srand48 , -.Nm srand48_deterministic , -.Nm seed48 , -.Nm seed48_deterministic , -.Nm lcong48 , -.Nm lcong48_deterministic -.Nd pseudo-random number generators and initialization routines -.Sh SYNOPSIS -.In stdlib.h -.Ft double -.Fn drand48 void -.Ft double -.Fn erand48 "unsigned short xseed[3]" -.Ft long -.Fn lrand48 void -.Ft long -.Fn nrand48 "unsigned short xseed[3]" -.Ft long -.Fn mrand48 void -.Ft long -.Fn jrand48 "unsigned short xseed[3]" -.Ft void -.Fn srand48 "long seed" -.Ft void -.Fn srand48_deterministic "long seed" -.Ft "unsigned short *" -.Fn seed48 "unsigned short xseed[3]" -.Ft "unsigned short *" -.Fn seed48_deterministic "unsigned short xseed[3]" -.Ft void -.Fn lcong48 "unsigned short p[7]" -.Ft void -.Fn lcong48_deterministic "unsigned short p[7]" -.Sh DESCRIPTION -.Bf -symbolic -Standards insist that this interface return deterministic results. -Unsafe usage is very common, so -.Ox -changed the subsystem to return non-deterministic results by default. -.Ef -.Pp -To satisfy portable code, -.Fn srand48 , -.Fn seed48 , -or -.Fn lcong48 -should be called to initialize the subsystem. -In -.Ox -the -seeding parameters are ignored, and strong random number results will be -provided from -.Xr arc4random 3 . -In other systems, the -parameters prime a simplistic deterministic algorithm. -.Pp -If the standardized behavior is required then -.Fn srand48_deterministic , -.Fn seed48_deterministic , -and -.Fn lcong48_deterministic -can be substituted for -.Fn srand48 , -.Fn seed48 , -and -.Fn lcong48 . -That will cause subsequent -calls to -.Fn drand48 , -.Fn lrand48 , -and -.Fn jrand48 -to return results using the deterministic algorithm. -.Pp -.Fn drand48 -and -.Fn erand48 -return values of type double. -The full 48 bits of r(n+1) are -loaded into the mantissa of the returned value, with the exponent set -such that the values produced lie in the interval [0.0, 1.0). -.Pp -.Fn lrand48 -and -.Fn nrand48 -return values of type long in the range -[0, 2**31-1]. -The high-order (31) bits of -r(n+1) are loaded into the lower bits of the returned value, with -the topmost (sign) bit set to zero. -.Pp -.Fn mrand48 -and -.Fn jrand48 -return values of type long in the range -[-2**31, 2**31-1]. -The high-order (32) bits of r(n+1) are loaded into the returned value. -.Pp -In the deterministic mode, the -.Fn rand48 -family of functions generates numbers using a linear congruential -algorithm working on integers 48 bits in size. -The particular formula employed is -r(n+1) = (a * r(n) + c) mod m -where the default values are -for the multiplicand a = 0xfdeece66d = 25214903917 and -the addend c = 0xb = 11. -The modulus is always fixed at m = 2 ** 48. -r(n) is called the seed of the random number generator. -.Pp -For all the six generator routines described next, the first -computational step is to perform a single iteration of the algorithm. -.Pp -.Fn drand48 , -.Fn lrand48 , -and -.Fn mrand48 -use an internal buffer to store r(n). -For these functions -the initial value of r(0) = 0x1234abcd330e = 20017429951246. -.Pp -On the other hand, -.Fn erand48 , -.Fn nrand48 , -and -.Fn jrand48 -use a user-supplied buffer to store the seed r(n), -which consists of an array of 3 shorts, where the zeroth member -holds the least significant bits. -.Pp -All functions share the same multiplicand and addend. -.Pp -.Fn srand48_deterministic -is used to initialize the internal buffer r(n) of -.Fn drand48 , -.Fn lrand48 , -and -.Fn mrand48 -such that the 32 bits of the seed value are copied into the upper 32 bits -of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e. -Additionally, the constant multiplicand and addend of the algorithm are -reset to the default values given above. -.Pp -.Fn seed48_deterministic -also initializes the internal buffer r(n) of -.Fn drand48 , -.Fn lrand48 , -and -.Fn mrand48 , -but here all 48 bits of the seed can be specified in an array of 3 shorts, -where the zeroth member specifies the lowest bits. -Again, the constant multiplicand and addend of the algorithm are -reset to the default values given above. -.Fn seed48_deterministic -returns a pointer to an array of 3 shorts which contains the old seed. -This array is statically allocated, so its contents are lost after -each new call to -.Fn seed48_deterministic . -.Pp -Finally, -.Fn lcong48_deterministic -allows full control over the multiplicand and addend used in -.Fn drand48 , -.Fn erand48 , -.Fn lrand48 , -.Fn nrand48 , -.Fn mrand48 , -and -.Fn jrand48 , -and the seed used in -.Fn drand48 , -.Fn lrand48 , -and -.Fn mrand48 . -An array of 7 shorts is passed as parameter; the first three shorts are -used to initialize the seed; the second three are used to initialize the -multiplicand; and the last short is used to initialize the addend. -It is thus not possible to use values greater than 0xffff as the addend. -.Pp -Note that all three methods of seeding the random number generator -always also set the multiplicand and addend for any of the six -generator calls. -.Sh SEE ALSO -.Xr arc4random 3 , -.Xr rand 3 , -.Xr random 3 -.Sh STANDARDS -The -.Fn drand48 , -.Fn erand48 , -.Fn jrand48 , -.Fn lrand48 , -.Fn mrand48 , -and -.Fn nrand48 , -functions conform to -.St -p1003.1-2008 . -.Pp -The -.Fn seed48 , -.Fn srand48 , -and -.Fn lcong48 -function do not conform to -.St -ansiC , -intentionally. -.Pp -The -.Fn seed48_deterministic , -.Fn srand48_deterministic , -and -.Fn lcong48_deterministic -functions are -.Ox -extensions. -.Sh AUTHORS -.An Martin Birgmeier diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h deleted file mode 100644 index 7a719beba6..0000000000 --- a/src/lib/libc/stdlib/rand48.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - * - * $OpenBSD: rand48.h,v 1.6 2015/09/14 13:30:17 guenther Exp $ - */ - -#ifndef _RAND48_H_ -#define _RAND48_H_ - -#include - -__BEGIN_HIDDEN_DECLS -extern unsigned short __rand48_seed[3]; -extern unsigned short __rand48_mult[3]; -extern unsigned short __rand48_add; - -void __dorand48(unsigned short[3]); -extern int __rand48_deterministic; -__END_HIDDEN_DECLS - -#define RAND48_SEED_0 (0x330e) -#define RAND48_SEED_1 (0xabcd) -#define RAND48_SEED_2 (0x1234) -#define RAND48_MULT_0 (0xe66d) -#define RAND48_MULT_1 (0xdeec) -#define RAND48_MULT_2 (0x0005) -#define RAND48_ADD (0x000b) - -#endif /* _RAND48_H_ */ diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3 deleted file mode 100644 index 0770d20f09..0000000000 --- a/src/lib/libc/stdlib/random.3 +++ /dev/null @@ -1,197 +0,0 @@ -.\" Copyright (c) 1983, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: random.3,v 1.29 2021/02/12 17:03:51 deraadt Exp $ -.\" -.Dd $Mdocdate: February 12 2021 $ -.Dt RANDOM 3 -.Os -.Sh NAME -.Nm random , -.Nm srandom , -.Nm srandom_deterministic , -.Nm srandomdev , -.Nm initstate , -.Nm setstate -.Nd pseudo-random number generator; routines for changing generators -.Sh SYNOPSIS -.In stdlib.h -.Ft long -.Fn random void -.Ft void -.Fn srandom "unsigned int seed" -.Ft void -.Fn srandom_deterministic "unsigned int seed" -.Ft void -.Fn srandomdev void -.Ft char * -.Fn initstate "unsigned int seed" "char *state" "size_t n" -.Ft char * -.Fn setstate "char *state" -.Sh DESCRIPTION -.Bf -symbolic -Standards insist that this interface return deterministic results. -Unsafe usage is very common, so -.Ox -changed the subsystem to return non-deterministic results by default. -.Ef -.Pp -To satisfy portable code, -.Fn srandom -or -.Fn srandomdev -may be called to initialize the subsystem. -In -.Ox -the -.Ar seed -variable is ignored, and strong random number results will be provided from -.Xr arc4random 3 . -In other systems, the -.Ar seed -variable primes a simplistic deterministic algorithm. -.Pp -If the standardized behavior is required -.Fn srandom_deterministic -can be substituted for -.Fn srandom , -then subsequent -.Fn random -calls will return results using the deterministic algorithm. -.Pp -In non-deterministic (default) mode, the -.Fn random -function returns results from -.Xr arc4random 3 -in the range from 0 to (2**31)\-1. -.Pp -In deterministic mode, the -.Fn random -function uses a non-linear additive feedback random number generator employing -a default table of size 31 long integers to return successive pseudo-random -numbers in the range from 0 to (2**31)\-1. -The period of this random number generator is very large, approximately -16*((2**31)\-1), but the results are a deterministic sequence from the seed. -The deterministic sequence algorithm changed a number of times since -original development, is underspecified, and should not be relied upon to -remain consistent between platforms and over time. -.Pp -The -.Fn initstate -routine allows a state array, passed in as an argument, to be initialized -for future use. -The size of the state array (in bytes) is used by -.Fn initstate -to decide how sophisticated a random number generator it should use \(em the -more state, the better the random numbers will be. -(Current "optimal" values for the amount of state information are -8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to -the nearest known amount. -Using less than 8 bytes will cause an error.) -The seed for the initialization (which specifies a starting point for -the random number sequence, and provides for restarting at the same -point) is also an argument. -The -.Fn initstate -function returns a pointer to the previous state information array. -.Pp -Once a state has been initialized, the -.Fn setstate -routine provides for rapid switching between states. -The -.Fn setstate -function returns a pointer to the previous state array; its -argument state array is used for further random number generation -until the next call to -.Fn initstate -or -.Fn setstate . -.Pp -Once a state array has been initialized, it may be restarted at a -different point either by calling -.Fn initstate -(with the desired seed, the state array, and its size) or by calling -both -.Fn setstate -(with the state array) and -.Fn srandom -(with the desired seed). -The advantage of calling both -.Fn setstate -and -.Fn srandom -is that the size of the state array does not have to be remembered after -it is initialized. -.Pp -Use of -.Fn srandom_deterministic , -.Fn initstate , -or -.Fn setstate -forces the subsystem into deterministic mode. -.Sh DIAGNOSTICS -If -.Fn initstate -is called with less than 8 bytes of state information, or if -.Fn setstate -detects that the state information has been garbled, error -messages are printed on the standard error output. -.Sh SEE ALSO -.Xr arc4random 3 , -.Xr drand48 3 , -.Xr rand 3 , -.Xr random 4 -.Sh STANDARDS -The -.Fn random , -.Fn initstate , -and -.Fn setstate -functions conform to -.St -xpg4.2 . -.Pp -The -.Fn srandom -function does not conform to -.St -xpg4.2 , -intentionally. -.Pp -The -.Fn srandomdev -function is an extension. -.Pp -The -.Fn srandom_deterministic -function is an -.Ox -extension. -.Sh HISTORY -These -functions appeared in -.Bx 4.2 . -.Sh AUTHORS -.An Earl T. Cohen diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c deleted file mode 100644 index 62a0c24bdb..0000000000 --- a/src/lib/libc/stdlib/random.c +++ /dev/null @@ -1,419 +0,0 @@ -/* $OpenBSD: random.c,v 1.31 2017/11/28 06:55:49 tb Exp $ */ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "thread_private.h" - -/* - * random.c: - * - * An improved random number generation package. In addition to the standard - * rand()/srand() like interface, this package also has a special state info - * interface. The initstate() routine is called with a seed, an array of - * bytes, and a count of how many bytes are being passed in; this array is - * then initialized to contain information for random number generation with - * that much state information. Good sizes for the amount of state - * information are 32, 64, 128, and 256 bytes. The state can be switched by - * calling the setstate() routine with the same array as was initiallized - * with initstate(). By default, the package runs with 128 bytes of state - * information and generates far better random numbers than a linear - * congruential generator. If the amount of state information is less than - * 32 bytes, a simple linear congruential R.N.G. is used. - * - * Internally, the state information is treated as an array of int32_t; the - * zeroeth element of the array is the type of R.N.G. being used (small - * integer); the remainder of the array is the state information for the - * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of - * state information, which will allow a degree seven polynomial. (Note: - * the zeroeth word of state information also has some other information - * stored in it -- see setstate() for details). - * - * The random number generation technique is a linear feedback shift register - * approach, employing trinomials (since there are fewer terms to sum up that - * way). In this approach, the least significant bit of all the numbers in - * the state table will act as a linear feedback shift register, and will - * have period 2^deg - 1 (where deg is the degree of the polynomial being - * used, assuming that the polynomial is irreducible and primitive). The - * higher order bits will have longer periods, since their values are also - * influenced by pseudo-random carries out of the lower bits. The total - * period of the generator is approximately deg*(2**deg - 1); thus doubling - * the amount of state information has a vast influence on the period of the - * generator. Note: the deg*(2**deg - 1) is an approximation only good for - * large deg, when the period of the shift register is the dominant factor. - * With deg equal to seven, the period is actually much longer than the - * 7*(2**7 - 1) predicted by this formula. - */ - -/* - * For each of the currently supported random number generators, we have a - * break value on the amount of state information (you need at least this - * many bytes of state info to support this random number generator), a degree - * for the polynomial (actually a trinomial) that the R.N.G. is based on, and - * the separation between the two lower order coefficients of the trinomial. - */ -#define TYPE_0 0 /* linear congruential */ -#define BREAK_0 8 -#define DEG_0 0 -#define SEP_0 0 - -#define TYPE_1 1 /* x**7 + x**3 + 1 */ -#define BREAK_1 32 -#define DEG_1 7 -#define SEP_1 3 - -#define TYPE_2 2 /* x**15 + x + 1 */ -#define BREAK_2 64 -#define DEG_2 15 -#define SEP_2 1 - -#define TYPE_3 3 /* x**31 + x**3 + 1 */ -#define BREAK_3 128 -#define DEG_3 31 -#define SEP_3 3 - -#define TYPE_4 4 /* x**63 + x + 1 */ -#define BREAK_4 256 -#define DEG_4 63 -#define SEP_4 1 - -/* - * Array versions of the above information to make code run faster -- - * relies on fact that TYPE_i == i. - */ -#define MAX_TYPES 5 /* max number of types above */ - -static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; -static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; - -/* - * Initially, everything is set up as if from: - * - * initstate(1, &randtbl, 128); - * - * Note that this initialization takes advantage of the fact that srandom() - * advances the front and rear pointers 10*rand_deg times, and hence the - * rear pointer which starts at 0 will also end up at zero; thus the zeroeth - * element of the state information, which contains info about the current - * position of the rear pointer is just - * - * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. - */ - -static int32_t randtbl[DEG_3 + 1] = { - TYPE_3, - 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05, - 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454, - 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471, - 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1, - 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41, - 0xf3bec5da, -}; - -/* - * fptr and rptr are two pointers into the state info, a front and a rear - * pointer. These two pointers are always rand_sep places aparts, as they - * cycle cyclically through the state information. (Yes, this does mean we - * could get away with just one pointer, but the code for random() is more - * efficient this way). The pointers are left positioned as they would be - * from the call - * - * initstate(1, randtbl, 128); - * - * (The position of the rear pointer, rptr, is really 0 (as explained above - * in the initialization of randtbl) because the state table pointer is set - * to point to randtbl[1] (as explained below). - */ -static int32_t *fptr = &randtbl[SEP_3 + 1]; -static int32_t *rptr = &randtbl[1]; - -/* - * The following things are the pointer to the state information table, the - * type of the current generator, the degree of the current polynomial being - * used, and the separation between the two pointers. Note that for efficiency - * of random(), we remember the first location of the state information, not - * the zeroeth. Hence it is valid to access state[-1], which is used to - * store the type of the R.N.G. Also, we remember the last location, since - * this is more efficient than indexing every time to find the address of - * the last element to see if the front and rear pointers have wrapped. - */ -static int32_t *state = &randtbl[1]; -static int32_t *end_ptr = &randtbl[DEG_3 + 1]; -static int rand_type = TYPE_3; -static int rand_deg = DEG_3; -static int rand_sep = SEP_3; - -static int random_deterministic; - -static void *random_mutex; -static long random_l(void); - -#define LOCK() _MUTEX_LOCK(&random_mutex) -#define UNLOCK() _MUTEX_UNLOCK(&random_mutex) - -/* - * srandom: - * - * Initialize the random number generator based on the given seed. If the - * type is the trivial no-state-information type, just remember the seed. - * Otherwise, initializes state[] based on the given "seed" via a linear - * congruential generator. Then, the pointers are set to known locations - * that are exactly rand_sep places apart. Lastly, it cycles the state - * information a given number of times to get rid of any initial dependencies - * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] - * for default usage relies on values produced by this routine. - */ -static void -srandom_l(unsigned int x) -{ - int i; - int32_t test; - div_t val; - - random_deterministic = 1; - if (rand_type == TYPE_0) - state[0] = x; - else { - /* A seed of 0 would result in state[] always being zero. */ - state[0] = x ? x : 1; - for (i = 1; i < rand_deg; i++) { - /* - * Implement the following, without overflowing 31 bits: - * - * state[i] = (16807 * state[i - 1]) % 2147483647; - * - * 2^31-1 (prime) = 2147483647 = 127773*16807+2836 - */ - val = div(state[i-1], 127773); - test = 16807 * val.rem - 2836 * val.quot; - state[i] = test + (test < 0 ? 2147483647 : 0); - } - fptr = &state[rand_sep]; - rptr = &state[0]; - for (i = 0; i < 10 * rand_deg; i++) - (void)random_l(); - } -} - -void -srandom(unsigned int x) -{ - random_deterministic = 0; -} - -void -srandomdev(void) -{ - random_deterministic = 0; /* back to the default */ -} - -void -srandom_deterministic(unsigned int x) -{ - LOCK(); - srandom_l(x); - UNLOCK(); -} - -/* - * initstate: - * - * Initialize the state information in the given array of n bytes for future - * random number generation. Based on the number of bytes we are given, and - * the break values for the different R.N.G.'s, we choose the best (largest) - * one we can and set things up for it. srandom() is then called to - * initialize the state information. - * - * Note that on return from srandom(), we set state[-1] to be the type - * multiplexed with the current value of the rear pointer; this is so - * successive calls to initstate() won't lose this information and will be - * able to restart with setstate(). - * - * Note: the first thing we do is save the current state, if any, just like - * setstate() so that it doesn't matter when initstate is called. - * - * Returns a pointer to the old state. - */ -char * -initstate(u_int seed, char *arg_state, size_t n) -{ - char *ostate = (char *)(&state[-1]); - - LOCK(); - random_deterministic = 1; - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = MAX_TYPES * (rptr - state) + rand_type; - if (n < BREAK_0) { - UNLOCK(); - return(NULL); - } - if (n < BREAK_1) { - rand_type = TYPE_0; - rand_deg = DEG_0; - rand_sep = SEP_0; - } else if (n < BREAK_2) { - rand_type = TYPE_1; - rand_deg = DEG_1; - rand_sep = SEP_1; - } else if (n < BREAK_3) { - rand_type = TYPE_2; - rand_deg = DEG_2; - rand_sep = SEP_2; - } else if (n < BREAK_4) { - rand_type = TYPE_3; - rand_deg = DEG_3; - rand_sep = SEP_3; - } else { - rand_type = TYPE_4; - rand_deg = DEG_4; - rand_sep = SEP_4; - } - state = &(((int32_t *)arg_state)[1]); /* first location */ - end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ - srandom_l(seed); - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = MAX_TYPES*(rptr - state) + rand_type; - UNLOCK(); - return(ostate); -} - -/* - * setstate: - * - * Restore the state from the given state array. - * - * Note: it is important that we also remember the locations of the pointers - * in the current state information, and restore the locations of the pointers - * from the old state information. This is done by multiplexing the pointer - * location into the zeroeth word of the state information. - * - * Note that due to the order in which things are done, it is OK to call - * setstate() with the same state as the current state. - * - * Returns a pointer to the old state information. - */ -char * -setstate(char *arg_state) -{ - int32_t *new_state = (int32_t *)arg_state; - int32_t type = new_state[0] % MAX_TYPES; - int32_t rear = new_state[0] / MAX_TYPES; - char *ostate = (char *)(&state[-1]); - - LOCK(); - random_deterministic = 1; - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = MAX_TYPES * (rptr - state) + rand_type; - switch(type) { - case TYPE_0: - case TYPE_1: - case TYPE_2: - case TYPE_3: - case TYPE_4: - rand_type = type; - rand_deg = degrees[type]; - rand_sep = seps[type]; - break; - default: - UNLOCK(); - return(NULL); - } - state = &new_state[1]; - if (rand_type != TYPE_0) { - rptr = &state[rear]; - fptr = &state[(rear + rand_sep) % rand_deg]; - } - end_ptr = &state[rand_deg]; /* set end_ptr too */ - UNLOCK(); - return(ostate); -} - -/* - * random: - * - * If we are using the trivial TYPE_0 R.N.G., just do the old linear - * congruential bit. Otherwise, we do our fancy trinomial stuff, which is - * the same in all the other cases due to all the global variables that have - * been set up. The basic operation is to add the number at the rear pointer - * into the one at the front pointer. Then both pointers are advanced to - * the next location cyclically in the table. The value returned is the sum - * generated, reduced to 31 bits by throwing away the "least random" low bit. - * - * Note: the code takes advantage of the fact that both the front and - * rear pointers can't wrap on the same call by not testing the rear - * pointer if the front one has wrapped. - * - * Returns a 31-bit random number. - */ -static long -random_l(void) -{ - int32_t i; - - if (random_deterministic == 0) - return arc4random() & 0x7fffffff; - - if (rand_type == TYPE_0) - i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; - else { - *fptr += *rptr; - i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */ - if (++fptr >= end_ptr) { - fptr = state; - ++rptr; - } else if (++rptr >= end_ptr) - rptr = state; - } - return((long)i); -} - -long -random(void) -{ - long r; - LOCK(); - r = random_l(); - UNLOCK(); - return r; -} - -#if defined(APIWARN) -__warn_references(random, - "random() may return deterministic values, is that what you want?"); -#endif diff --git a/src/lib/libc/stdlib/reallocarray.c b/src/lib/libc/stdlib/reallocarray.c deleted file mode 100644 index baea252a87..0000000000 --- a/src/lib/libc/stdlib/reallocarray.c +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */ -/* - * Copyright (c) 2008 Otto Moerbeek - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - -void * -reallocarray(void *optr, size_t nmemb, size_t size) -{ - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { - errno = ENOMEM; - return NULL; - } - return realloc(optr, size * nmemb); -} -DEF_WEAK(reallocarray); diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3 deleted file mode 100644 index 1dec10fef4..0000000000 --- a/src/lib/libc/stdlib/realpath.3 +++ /dev/null @@ -1,165 +0,0 @@ -.\" Copyright (c) 1994 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Jan-Simon Pendry. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: realpath.3,v 1.26 2021/10/13 15:04:53 kn Exp $ -.\" -.Dd $Mdocdate: October 13 2021 $ -.Dt REALPATH 3 -.Os -.Sh NAME -.Nm realpath -.Nd returns the canonicalized absolute pathname -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft "char *" -.Fn realpath "const char *pathname" "char *resolved" -.Sh DESCRIPTION -The -.Fn realpath -function resolves all symbolic links, extra -.Dq / -characters and references to -.Pa /./ -and -.Pa /../ -in -.Fa pathname , -and copies the resulting absolute pathname into the memory referenced by -.Fa resolved . -The -.Fa resolved -argument -.Em must -refer to a buffer capable of storing at least -.Dv PATH_MAX -characters, or be -.Dv NULL . -.Pp -The -.Fn realpath -function will resolve both absolute and relative paths -and return the absolute pathname corresponding to -.Fa pathname . -All components of -.Fa pathname -must exist when -.Fn realpath -is called. -.Sh RETURN VALUES -The -.Fn realpath -function returns -.Fa resolved -on success. -If -.Fa resolved -is -.Dv NULL -and no error occurred, then -.Fn realpath -returns a NUL-terminated string in a newly allocated buffer. -If an error occurs, -.Fn realpath -returns -.Dv NULL -and the contents of -.Fa resolved -are undefined. -.Sh ERRORS -The function -.Fn realpath -will fail if: -.Bl -tag -width Er -.It Bq Er EACCES -Read or search permission was denied for a component of -.Ar pathname . -.It Bq Er EINVAL -The -.Ar pathname -argument is a null pointer. -.It Bq Er EIO -An error occurred while reading from the file system. -.It Bq Er ELOOP -Too many symbolic links were encountered in translating -.Ar pathname . -.It Bq Er ENAMETOOLONG -A component of -.Ar pathname -exceeded -.Dv NAME_MAX -characters, or the entire -.Ar pathname -(including the terminating NUL) exceeded -.Dv PATH_MAX . -.It Bq Er ENAMETOOLONG -Pathname resolution of a symbolic link produced an intermediate -result whose length exceeds -.Dv PATH_MAX . -.It Bq Er ENOENT -A component of -.Ar pathname -does not name an existing file or -.Ar pathname -points to an empty string. -.It Bq Er ENOTDIR -A component of the path prefix is not a directory. -.It Bq Er ENOMEM -Sufficient storage space is unavailable for allocation. -.El -.Sh SEE ALSO -.Xr readlink 1 , -.Xr realpath 1 , -.Xr getcwd 3 -.Sh STANDARDS -The -.Fn realpath -function conforms to -.St -p1003.1-2008 . -.Sh HISTORY -The -.Fn realpath -function call first appeared in -.Bx 4.4 . -.Pp -In -.Ox 6.6 , -it was reimplemented on top of the -.Fn __realpath -system call. -Its calling convention differs from the standard -function by requiring -.Ar resolved -to not be -.Dv NULL -and by returning an integer, -zero on success, and -1 with corresponding errno on failure. -This is visible in the output of -.Xr kdump 1 . diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c deleted file mode 100644 index 6562e1311b..0000000000 --- a/src/lib/libc/stdlib/realpath.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $OpenBSD: realpath.c,v 1.28 2023/05/18 16:11:10 guenther Exp $ */ -/* - * Copyright (c) 2019 Bob Beck - * Copyright (c) 2019 Theo de Raadt - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * wrapper for kernel __realpath - */ - -char * -realpath(const char *path, char *resolved) -{ - char rbuf[PATH_MAX]; - - if (__realpath(path, rbuf) == -1) - return NULL; - if (resolved == NULL) - return (strdup(rbuf)); - strlcpy(resolved, rbuf, PATH_MAX); - return (resolved); -} diff --git a/src/lib/libc/stdlib/recallocarray.c b/src/lib/libc/stdlib/recallocarray.c deleted file mode 100644 index 81059e6ae1..0000000000 --- a/src/lib/libc/stdlib/recallocarray.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */ -/* - * Copyright (c) 2008, 2017 Otto Moerbeek - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include - -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - -void * -recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) -{ - size_t oldsize, newsize; - void *newptr; - - if (ptr == NULL) - return calloc(newnmemb, size); - - if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - newnmemb > 0 && SIZE_MAX / newnmemb < size) { - errno = ENOMEM; - return NULL; - } - newsize = newnmemb * size; - - if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { - errno = EINVAL; - return NULL; - } - oldsize = oldnmemb * size; - - /* - * Don't bother too much if we're shrinking just a bit, - * we do not shrink for series of small steps, oh well. - */ - if (newsize <= oldsize) { - size_t d = oldsize - newsize; - - if (d < oldsize / 2 && d < (size_t)getpagesize()) { - memset((char *)ptr + newsize, 0, d); - return ptr; - } - } - - newptr = malloc(newsize); - if (newptr == NULL) - return NULL; - - if (newsize > oldsize) { - memcpy(newptr, ptr, oldsize); - memset((char *)newptr + oldsize, 0, newsize - oldsize); - } else - memcpy(newptr, ptr, newsize); - - explicit_bzero(ptr, oldsize); - free(ptr); - - return newptr; -} -DEF_WEAK(recallocarray); diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c deleted file mode 100644 index 71b74b2dce..0000000000 --- a/src/lib/libc/stdlib/remque.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $OpenBSD: remque.c,v 1.3 2014/08/15 04:14:36 guenther Exp $ */ - -/* - * Copyright (c) 1993 John Brezak - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -struct qelem { - struct qelem *q_forw; - struct qelem *q_back; -}; - -void -remque(void *element) -{ - struct qelem *e = element; - - if (e->q_forw != NULL) - e->q_forw->q_back = e->q_back; - if (e->q_back != NULL) - e->q_back->q_forw = e->q_forw; -} diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c deleted file mode 100644 index b4b4424c73..0000000000 --- a/src/lib/libc/stdlib/seed48.c +++ /dev/null @@ -1,45 +0,0 @@ -/* $OpenBSD: seed48.c,v 1.6 2015/09/13 15:20:40 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -unsigned short * -seed48(unsigned short xseed[3]) -{ - unsigned short *res; - - res = seed48_deterministic(xseed); - __rand48_deterministic = 0; - return res; -} - -unsigned short * -seed48_deterministic(unsigned short xseed[3]) -{ - static unsigned short sseed[3]; - - __rand48_deterministic = 1; - sseed[0] = __rand48_seed[0]; - sseed[1] = __rand48_seed[1]; - sseed[2] = __rand48_seed[2]; - __rand48_seed[0] = xseed[0]; - __rand48_seed[1] = xseed[1]; - __rand48_seed[2] = xseed[2]; - __rand48_mult[0] = RAND48_MULT_0; - __rand48_mult[1] = RAND48_MULT_1; - __rand48_mult[2] = RAND48_MULT_2; - __rand48_add = RAND48_ADD; - return sseed; -} -DEF_WEAK(seed48_deterministic); diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c deleted file mode 100644 index fc8e5b677f..0000000000 --- a/src/lib/libc/stdlib/setenv.c +++ /dev/null @@ -1,185 +0,0 @@ -/* $OpenBSD: setenv.c,v 1.20 2022/08/08 22:40:03 millert Exp $ */ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -static char **lastenv; /* last value of environ */ - -/* - * putenv -- - * Add a name=value string directly to the environmental, replacing - * any current value. - */ -int -putenv(char *str) -{ - char **P, *cp; - size_t cnt = 0; - int offset = 0; - - for (cp = str; *cp && *cp != '='; ++cp) - ; - if (cp == str || *cp != '=') { - /* '=' is the first character of string or is missing. */ - errno = EINVAL; - return (-1); - } - - if (__findenv(str, (int)(cp - str), &offset) != NULL) { - environ[offset++] = str; - /* could be set multiple times */ - while (__findenv(str, (int)(cp - str), &offset)) { - for (P = &environ[offset];; ++P) - if (!(*P = *(P + 1))) - break; - } - return (0); - } - - /* create new slot for string */ - if (environ != NULL) { - for (P = environ; *P != NULL; P++) - ; - cnt = P - environ; - } - P = reallocarray(lastenv, cnt + 2, sizeof(char *)); - if (!P) - return (-1); - if (lastenv != environ && environ != NULL) - memcpy(P, environ, cnt * sizeof(char *)); - lastenv = environ = P; - environ[cnt] = str; - environ[cnt + 1] = NULL; - return (0); -} -DEF_WEAK(putenv); - -/* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. - */ -int -setenv(const char *name, const char *value, int rewrite) -{ - char *C, **P; - const char *np; - int l_value, offset = 0; - - if (!name || !*name) { - errno = EINVAL; - return (-1); - } - for (np = name; *np && *np != '='; ++np) - ; - if (*np) { - errno = EINVAL; - return (-1); /* has `=' in name */ - } - - l_value = strlen(value); - if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { - int tmpoff = offset + 1; - if (!rewrite) - return (0); -#if 0 /* XXX - existing entry may not be writable */ - if (strlen(C) >= l_value) { /* old larger; copy over */ - while ((*C++ = *value++)) - ; - return (0); - } -#endif - /* could be set multiple times */ - while (__findenv(name, (int)(np - name), &tmpoff)) { - for (P = &environ[tmpoff];; ++P) - if (!(*P = *(P + 1))) - break; - } - } else { /* create new slot */ - size_t cnt = 0; - - if (environ != NULL) { - for (P = environ; *P != NULL; P++) - ; - cnt = P - environ; - } - P = reallocarray(lastenv, cnt + 2, sizeof(char *)); - if (!P) - return (-1); - if (lastenv != environ && environ != NULL) - memcpy(P, environ, cnt * sizeof(char *)); - lastenv = environ = P; - offset = cnt; - environ[cnt + 1] = NULL; - } - if (!(environ[offset] = /* name + `=' + value */ - malloc((int)(np - name) + l_value + 2))) - return (-1); - for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) - ; - for (*C++ = '='; (*C++ = *value++); ) - ; - return (0); -} -DEF_WEAK(setenv); - -/* - * unsetenv(name) -- - * Delete environmental variable "name". - */ -int -unsetenv(const char *name) -{ - char **P; - const char *np; - int offset = 0; - - if (!name || !*name) { - errno = EINVAL; - return (-1); - } - for (np = name; *np && *np != '='; ++np) - ; - if (*np) { - errno = EINVAL; - return (-1); /* has `=' in name */ - } - - /* could be set multiple times */ - while (__findenv(name, (int)(np - name), &offset)) { - for (P = &environ[offset];; ++P) - if (!(*P = *(P + 1))) - break; - } - return (0); -} -DEF_WEAK(unsetenv); diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c deleted file mode 100644 index d41391d445..0000000000 --- a/src/lib/libc/stdlib/srand48.c +++ /dev/null @@ -1,38 +0,0 @@ -/* $OpenBSD: srand48.c,v 1.6 2015/09/13 08:31:48 guenther Exp $ */ -/* - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ - -#include "rand48.h" - -int __rand48_deterministic; - -void -srand48(long seed) -{ - srand48_deterministic(seed); - __rand48_deterministic = 0; -} - -void -srand48_deterministic(long seed) -{ - __rand48_deterministic = 1; - __rand48_seed[0] = RAND48_SEED_0; - __rand48_seed[1] = (unsigned short) seed; - __rand48_seed[2] = (unsigned short) (seed >> 16); - __rand48_mult[0] = RAND48_MULT_0; - __rand48_mult[1] = RAND48_MULT_1; - __rand48_mult[2] = RAND48_MULT_2; - __rand48_add = RAND48_ADD; -} -DEF_WEAK(srand48_deterministic); diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3 deleted file mode 100644 index ad8f28a02f..0000000000 --- a/src/lib/libc/stdlib/strtod.3 +++ /dev/null @@ -1,176 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: strtod.3,v 1.23 2022/09/11 06:38:11 jmc Exp $ -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt STRTOD 3 -.Os -.Sh NAME -.Nm strtod , -.Nm strtof , -.Nm strtold -.Nd convert ASCII string to double, float or long double -.Sh SYNOPSIS -.In stdlib.h -.Ft double -.Fn strtod "const char *nptr" "char **endptr" -.Pp -.Ft float -.Fn strtof "const char *nptr" "char **endptr" -.Pp -.Ft long double -.Fn strtold "const char *nptr" "char **endptr" -.Sh DESCRIPTION -The -.Fn strtod -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt double -representation. -The -.Fn strtof -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt float -representation. -The -.Fn strtold -function converts the initial portion of the string pointed to by -.Fa nptr -to -.Vt long double -representation. -.Pp -The expected form of the string is an optional plus -.Pq Ql + -or minus sign -.Pq Ql - -followed by a sequence of digits optionally containing -a decimal-point character, optionally followed by an exponent. -An exponent consists of an -.Sq E -or -.Sq e , -followed by an optional plus or minus sign, followed by a sequence of digits. -.Pp -Alternatively, if the portion of the string following the optional -plus or minus sign begins with -.Dq INF -or -.Dq NAN , -ignoring case, it is interpreted as an infinity or a quiet \*(Na, -respectively. -The syntax -.Dq NAN Ns Pq Ar s , -where -.Ar s -is an alphanumeric string, produces the same value as the call -.Fo nan -.Qq Ar s Ns -.Fc -(respectively, -.Fo nanf -.Qq Ar s Ns -.Fc -and -.Fo nanl -.Qq Ar s Ns -.Fc ) . -.Pp -In any of the above cases, leading whitespace characters in the -string (as defined by the -.Xr isspace 3 -function) are skipped. -.Sh RETURN VALUES -The -.Fn strtod , -.Fn strtof -and -.Fn strtold -functions return the converted value, if any. -.Pp -If -.Fa endptr -is not -.Dv NULL , -a pointer to the character after the last character used -in the conversion is stored in the location referenced by -.Fa endptr . -.Pp -If no conversion is performed, zero is returned and the value of -.Fa nptr -is stored in the location referenced by -.Fa endptr . -.Pp -If the correct value would cause overflow, plus or minus -.Dv HUGE_VAL -is returned (according to the sign of the value), and -.Er ERANGE -is stored in -.Va errno . -If the correct value would cause underflow, zero is returned and -.Er ERANGE -is stored in -.Va errno . -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er ERANGE -Overflow or underflow occurred. -.El -.Sh SEE ALSO -.Xr atof 3 , -.Xr atoi 3 , -.Xr atol 3 , -.Xr strtol 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn strtod -function conforms to -.St -ansiC-89 . -The -.Fn strtof -and -.Fn strtold -functions conform to -.St -isoC-99 . -.Sh CAVEATS -On systems other than -.Ox , -the -.Dv LC_NUMERIC -.Xr locale 1 -category can cause parsing failures; see CAVEATS in -.Xr setlocale 3 -for details. diff --git a/src/lib/libc/stdlib/strtoimax.c b/src/lib/libc/stdlib/strtoimax.c deleted file mode 100644 index 74e355626a..0000000000 --- a/src/lib/libc/stdlib/strtoimax.c +++ /dev/null @@ -1,151 +0,0 @@ -/* $OpenBSD: strtoimax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -/* - * Convert a string to an intmax_t - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -intmax_t -strtoimax(const char *nptr, char **endptr, int base) -{ - const char *s; - intmax_t acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * Ensure that base is between 2 and 36 inclusive, or the special - * value of 0. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for intmax_t is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? INTMAX_MIN : INTMAX_MAX; - cutlim = cutoff % base; - cutoff /= base; - if (neg) { - if (cutlim > 0) { - cutlim -= base; - cutoff += 1; - } - cutlim = -cutlim; - } - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (neg) { - if (acc < cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = INTMAX_MIN; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc -= c; - } - } else { - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = INTMAX_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc += c; - } - } - } - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtoimax); diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3 deleted file mode 100644 index 92774d082c..0000000000 --- a/src/lib/libc/stdlib/strtol.3 +++ /dev/null @@ -1,273 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: strtol.3,v 1.27 2015/04/14 22:16:03 nicm Exp $ -.\" -.Dd $Mdocdate: April 14 2015 $ -.Dt STRTOL 3 -.Os -.Sh NAME -.Nm strtol , -.Nm strtoll , -.Nm strtoimax , -.Nm strtoq -.Nd convert string value to a long, long long or intmax_t integer -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft long -.Fn strtol "const char *nptr" "char **endptr" "int base" -.Ft long long -.Fn strtoll "const char *nptr" "char **endptr" "int base" -.In inttypes.h -.Ft intmax_t -.Fn strtoimax "const char *nptr" "char **endptr" "int base" -.In sys/types.h -.In limits.h -.In stdlib.h -.Ft quad_t -.Fn strtoq "const char *nptr" "char **endptr" "int base" -.Sh DESCRIPTION -The -.Fn strtol -function converts the string in -.Fa nptr -to a -.Vt long -value. -The -.Fn strtoll -function converts the string in -.Fa nptr -to a -.Vt long long -value. -The -.Fn strtoimax -function converts the string in -.Fa nptr -to an -.Vt intmax_t -value. -The -.Fn strtoq -function is a deprecated equivalent of -.Fn strtoll -and is provided for backwards compatibility with legacy programs. -The conversion is done according to the given -.Fa base , -which must be a number between 2 and 36 inclusive or the special value 0. -.Pp -The string may begin with an arbitrary amount of whitespace -(as determined by -.Xr isspace 3 ) -followed by a single optional -.Ql + -or -.Ql - -sign. -If -.Fa base -is zero or 16, the string may then include a -.Ql 0x -prefix, and the number will be read in base 16; otherwise, a zero -.Fa base -is taken as 10 (decimal) unless the next character is -.Ql 0 , -in which case it is taken as 8 (octal). -.Pp -The remainder of the string is converted to a -.Vt long , -.Vt long long , -or -.Vt intmax_t -value in the obvious manner, -stopping at the first character which is not a valid digit -in the given base. -(In bases above 10, the letter -.Ql A -in either upper or lower case represents 10, -.Ql B -represents 11, and so forth, with -.Ql Z -representing 35.) -.Pp -If -.Fa endptr -is non-null, -.Fn strtol -stores the address of the first invalid character in -.Fa *endptr . -If there were no digits at all, however, -.Fn strtol -stores the original value of -.Fa nptr -in -.Fa *endptr . -(Thus, if -.Fa *nptr -is not -.Ql \e0 -but -.Fa **endptr -is -.Ql \e0 -on return, the entire string was valid.) -.Sh RETURN VALUES -The -.Fn strtol , -.Fn strtoll , -.Fn strtoimax , -and -.Fn strtoq -functions return the result of the conversion. -If overflow or underflow occurs, -.Va errno -is set to -.Er ERANGE -and the function return value is as follows: -.Bl -column "strtoimaxXX" "INTMAX_MIN" "INTMAX_MAX" -offset indent -.It Sy Function Ta Sy underflow Ta Sy overflow -.It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX -.It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX -.It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX -.It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX -.El -.Pp -If there is no valid digit, 0 is returned. -If -.Ar base -is invalid, 0 is returned and the global variable -.Va errno -is set to -.Er EINVAL . -.Sh EXAMPLES -Ensuring that a string is a valid number (i.e., in range and containing no -trailing characters) requires clearing -.Va errno -beforehand explicitly since -.Va errno -is not changed on a successful call to -.Fn strtol , -and the return value of -.Fn strtol -cannot be used unambiguously to signal an error: -.Bd -literal -offset indent -char *ep; -long lval; - -\&... - -errno = 0; -lval = strtol(buf, &ep, 10); -if (buf[0] == '\e0' || *ep != '\e0') - goto not_a_number; -if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) - goto out_of_range; -.Ed -.Pp -This example will accept -.Dq 12 -but not -.Dq 12foo -or -.Dq 12\en . -If trailing whitespace is acceptable, further checks must be done on -.Va *ep ; -alternately, use -.Xr sscanf 3 . -.Pp -If -.Fn strtol -is being used instead of -.Xr atoi 3 , -error checking is further complicated because the desired return value is an -.Vt int -rather than a -.Vt long ; -however, on some architectures integers and long integers are the same size. -Thus the following is necessary: -.Bd -literal -offset indent -char *ep; -int ival; -long lval; - -\&... - -errno = 0; -lval = strtol(buf, &ep, 10); -if (buf[0] == '\e0' || *ep != '\e0') - goto not_a_number; -if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || - (lval > INT_MAX || lval < INT_MIN)) - goto out_of_range; -ival = lval; -.Ed -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EINVAL -The value of -.Ar base -was neither between 2 and 36 inclusive nor the special value 0. -.It Bq Er ERANGE -The given string was out of range; the value converted has been clamped. -.El -.Sh SEE ALSO -.Xr atof 3 , -.Xr atoi 3 , -.Xr atol 3 , -.Xr atoll 3 , -.Xr sscanf 3 , -.Xr strtod 3 , -.Xr strtonum 3 , -.Xr strtoul 3 -.Sh STANDARDS -The -.Fn strtol , -.Fn strtoll , -and -.Fn strtoimax -functions conform to -.St -isoC-99 . -Setting -.Va errno -to -.Dv EINVAL -is an extension to that standard required by -.St -p1003.1-2008 . -.Pp -The -.Fn strtoq -function is a -.Bx -extension and is provided for backwards compatibility with legacy programs. -.Sh BUGS -Ignores the current locale. diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c deleted file mode 100644 index 599d2355a8..0000000000 --- a/src/lib/libc/stdlib/strtol.c +++ /dev/null @@ -1,151 +0,0 @@ -/* $OpenBSD: strtol.c,v 1.12 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -/* - * Convert a string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long -strtol(const char *nptr, char **endptr, int base) -{ - const char *s; - long acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * Ensure that base is between 2 and 36 inclusive, or the special - * value of 0. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? LONG_MIN : LONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - if (neg) { - if (cutlim > 0) { - cutlim -= base; - cutoff += 1; - } - cutlim = -cutlim; - } - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (neg) { - if (acc < cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = LONG_MIN; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc -= c; - } - } else { - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = LONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc += c; - } - } - } - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtol); diff --git a/src/lib/libc/stdlib/strtoll.c b/src/lib/libc/stdlib/strtoll.c deleted file mode 100644 index d21a249a0b..0000000000 --- a/src/lib/libc/stdlib/strtoll.c +++ /dev/null @@ -1,156 +0,0 @@ -/* $OpenBSD: strtoll.c,v 1.10 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -/* - * Convert a string to a long long. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long long -strtoll(const char *nptr, char **endptr, int base) -{ - const char *s; - long long acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * Ensure that base is between 2 and 36 inclusive, or the special - * value of 0. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for long longs is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? LLONG_MIN : LLONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - if (neg) { - if (cutlim > 0) { - cutlim -= base; - cutoff += 1; - } - cutlim = -cutlim; - } - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (neg) { - if (acc < cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = LLONG_MIN; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc -= c; - } - } else { - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = LLONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= base; - acc += c; - } - } - } - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtoll); - -__weak_alias(strtoq, strtoll); diff --git a/src/lib/libc/stdlib/strtonum.3 b/src/lib/libc/stdlib/strtonum.3 deleted file mode 100644 index 87a3ccd588..0000000000 --- a/src/lib/libc/stdlib/strtonum.3 +++ /dev/null @@ -1,152 +0,0 @@ -.\" $OpenBSD: strtonum.3,v 1.19 2022/09/11 06:38:11 jmc Exp $ -.\" -.\" Copyright (c) 2004 Ted Unangst -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.Dd $Mdocdate: September 11 2022 $ -.Dt STRTONUM 3 -.Os -.Sh NAME -.Nm strtonum -.Nd reliably convert string value to an integer -.Sh SYNOPSIS -.In stdlib.h -.Ft long long -.Fo strtonum -.Fa "const char *nptr" -.Fa "long long minval" -.Fa "long long maxval" -.Fa "const char **errstr" -.Fc -.Sh DESCRIPTION -The -.Fn strtonum -function converts the string in -.Fa nptr -to a -.Vt long long -value. -The -.Fn strtonum -function was designed to facilitate safe, robust programming -and overcome the shortcomings of the -.Xr atoi 3 -and -.Xr strtol 3 -family of interfaces. -.Pp -The string may begin with an arbitrary amount of whitespace -(as determined by -.Xr isspace 3 ) -followed by a single optional -.Ql + -or -.Ql - -sign. -.Pp -The remainder of the string is converted to a -.Vt long long -value according to base 10. -.Pp -The value obtained is then checked against the provided -.Fa minval -and -.Fa maxval -bounds. -If -.Fa errstr -is non-null, -.Fn strtonum -stores an error string in -.Fa *errstr -indicating the failure. -.Sh RETURN VALUES -The -.Fn strtonum -function returns the result of the conversion, -unless the value would exceed the provided bounds or is invalid. -On error, 0 is returned, -.Va errno -is set, and -.Fa errstr -will point to an error message. -.Fa *errstr -will be set to -.Dv NULL -on success; -this fact can be used to differentiate -a successful return of 0 from an error. -.Sh EXAMPLES -Using -.Fn strtonum -correctly is meant to be simpler than the alternative functions. -.Bd -literal -offset indent -int iterations; -const char *errstr; - -iterations = strtonum(optarg, 1, 64, &errstr); -if (errstr != NULL) - errx(1, "number of iterations is %s: %s", errstr, optarg); -.Ed -.Pp -The above example will guarantee that the value of iterations is between -1 and 64 (inclusive). -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er ERANGE -The given string was out of range. -.It Bq Er EINVAL -The given string did not consist solely of digit characters. -.It Bq Er EINVAL -.Ar minval -was larger than -.Ar maxval . -.El -.Pp -If an error occurs, -.Fa errstr -will be set to one of the following strings: -.Pp -.Bl -tag -width "too largeXX" -compact -.It Qq too large -The result was larger than the provided maximum value. -.It Qq too small -The result was smaller than the provided minimum value. -.It Qq invalid -The string did not consist solely of digit characters. -.El -.Sh SEE ALSO -.Xr atof 3 , -.Xr atoi 3 , -.Xr atol 3 , -.Xr atoll 3 , -.Xr sscanf 3 , -.Xr strtod 3 , -.Xr strtol 3 , -.Xr strtoul 3 -.Sh STANDARDS -.Fn strtonum -is an -.Ox -extension. -The existing alternatives, such as -.Xr atoi 3 -and -.Xr strtol 3 , -are either impossible or difficult to use safely. -.Sh HISTORY -The -.Fn strtonum -function first appeared in -.Ox 3.6 . diff --git a/src/lib/libc/stdlib/strtonum.c b/src/lib/libc/stdlib/strtonum.c deleted file mode 100644 index ad22d1c30c..0000000000 --- a/src/lib/libc/stdlib/strtonum.c +++ /dev/null @@ -1,66 +0,0 @@ -/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */ - -/* - * Copyright (c) 2004 Ted Unangst and Todd Miller - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#define INVALID 1 -#define TOOSMALL 2 -#define TOOLARGE 3 - -long long -strtonum(const char *numstr, long long minval, long long maxval, - const char **errstrp) -{ - long long ll = 0; - int error = 0; - char *ep; - struct errval { - const char *errstr; - int err; - } ev[4] = { - { NULL, 0 }, - { "invalid", EINVAL }, - { "too small", ERANGE }, - { "too large", ERANGE }, - }; - - ev[0].err = errno; - errno = 0; - if (minval > maxval) { - error = INVALID; - } else { - ll = strtoll(numstr, &ep, 10); - if (numstr == ep || *ep != '\0') - error = INVALID; - else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) - error = TOOSMALL; - else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) - error = TOOLARGE; - } - if (errstrp != NULL) - *errstrp = ev[error].errstr; - errno = ev[error].err; - if (error) - ll = 0; - - return (ll); -} -DEF_WEAK(strtonum); diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3 deleted file mode 100644 index dd5668d1d6..0000000000 --- a/src/lib/libc/stdlib/strtoul.3 +++ /dev/null @@ -1,260 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: strtoul.3,v 1.24 2014/11/30 21:21:59 schwarze Exp $ -.\" -.Dd $Mdocdate: November 30 2014 $ -.Dt STRTOUL 3 -.Os -.Sh NAME -.Nm strtoul , -.Nm strtoull , -.Nm strtoumax , -.Nm strtouq -.Nd convert a string to an unsigned long, unsigned long long or uintmax_t integer -.Sh SYNOPSIS -.In limits.h -.In stdlib.h -.Ft unsigned long -.Fn strtoul "const char *nptr" "char **endptr" "int base" -.Ft unsigned long long -.Fn strtoull "const char *nptr" "char **endptr" "int base" -.In inttypes.h -.Ft uintmax_t -.Fn strtoumax "const char *nptr" "char **endptr" "int base" -.In sys/types.h -.In limits.h -.In stdlib.h -.Ft u_quad_t -.Fn strtouq "const char *nptr" "char **endptr" "int base" -.Sh DESCRIPTION -The -.Fn strtoul -function converts the string in -.Fa nptr -to an -.Vt unsigned long -value. -The -.Fn strtoull -function converts the string in -.Fa nptr -to an -.Vt unsigned long long -value. -The -.Fn strtoumax -function converts the string in -.Fa nptr -to a -.Vt umaxint_t -value. -The -.Fn strtouq -function is a deprecated equivalent of -.Fn strtoull -and is provided for backwards compatibility with legacy programs. -The conversion is done according to the given -.Fa base , -which must be a number between 2 and 36 inclusive or the special value 0. -If the string in -.Fa nptr -represents a negative number, it will be converted to its unsigned equivalent. -This behavior is consistent with what happens when a signed integer type is -cast to its unsigned counterpart. -.Pp -The string may begin with an arbitrary amount of whitespace -(as determined by -.Xr isspace 3 ) -followed by a single optional -.Ql + -or -.Ql - -sign. -If -.Fa base -is zero or 16, the string may then include a -.Ql 0x -prefix, and the number will be read in base 16; otherwise, a zero -.Fa base -is taken as 10 (decimal) unless the next character is -.Ql 0 , -in which case it is taken as 8 (octal). -.Pp -The remainder of the string is converted to an -.Vt unsigned long , -.Vt unsigned long long , -or -.Vt uintmax_t -value in the obvious manner, -stopping at the first character which is not a valid digit -in the given base. -(In bases above 10, the letter -.Ql A -in either upper or lower case represents 10, -.Ql B -represents 11, and so forth, with -.Ql Z -representing 35.) -.Pp -If -.Fa endptr -is non-null, -.Fn strtoul -stores the address of the first invalid character in -.Fa *endptr . -If there were no digits at all, however, -.Fn strtoul -stores the original value of -.Fa nptr -in -.Fa *endptr . -(Thus, if -.Fa *nptr -is not -.Ql \e0 -but -.Fa **endptr -is -.Ql \e0 -on return, the entire string was valid.) -.Sh RETURN VALUES -The -.Fn strtoul , -.Fn strtoull , -.Fn strtoumax -and -.Fn strtouq -functions return either the result of the conversion or, -if there was a leading minus sign, -the negation of the result of the conversion, -unless the original (non-negated) value would overflow. -If overflow occurs, -.Fn strtoul -returns -.Dv ULONG_MAX , -.Fn strtoull -returns -.Dv ULLONG_MAX , -.Fn strtoumax -returns -.Dv UINTMAX_MAX , -.Fn strtouq -returns -.Dv ULLONG_MAX -and the global variable -.Va errno -is set to -.Er ERANGE . -.Pp -There is no way to determine if -.Fn strtoul -has processed a negative number (and returned an unsigned value) short of -examining the string in -.Fa nptr -directly. -.Pp -If there is no valid digit, 0 is returned. -If -.Ar base -is invalid, 0 is returned and the global variable -.Va errno -is set to -.Er EINVAL . -.Sh EXAMPLES -Ensuring that a string is a valid number (i.e., in range and containing no -trailing characters) requires clearing -.Va errno -beforehand explicitly since -.Va errno -is not changed on a successful call to -.Fn strtoul , -and the return value of -.Fn strtoul -cannot be used unambiguously to signal an error: -.Bd -literal -offset indent -char *ep; -unsigned long ulval; - -\&... - -errno = 0; -ulval = strtoul(buf, &ep, 10); -if (buf[0] == '\e0' || *ep != '\e0') - goto not_a_number; -if (errno == ERANGE && ulval == ULONG_MAX) - goto out_of_range; -.Ed -.Pp -This example will accept -.Dq 12 -but not -.Dq 12foo -or -.Dq 12\en . -If trailing whitespace is acceptable, further checks must be done on -.Va *ep ; -alternately, use -.Xr sscanf 3 . -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EINVAL -The value of -.Ar base -was neither between 2 and 36 inclusive nor the special value 0. -.It Bq Er ERANGE -The given string was out of range; the value converted has been clamped. -.El -.Sh SEE ALSO -.Xr sscanf 3 , -.Xr strtol 3 -.Sh STANDARDS -The -.Fn strtoul , -.Fn strtoull , -and -.Fn strtoumax -functions conform to -.St -isoC-99 . -Setting -.Va errno -to -.Dv EINVAL -is an extension to that standard required by -.St -p1003.1-2008 . -.Pp -The -.Fn strtouq -function is a -.Bx -extension and is provided for backwards compatibility with legacy programs. -.Sh BUGS -Ignores the current locale. diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c deleted file mode 100644 index 6667bea8fa..0000000000 --- a/src/lib/libc/stdlib/strtoul.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $OpenBSD: strtoul.c,v 1.11 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -/* - * Convert a string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long -strtoul(const char *nptr, char **endptr, int base) -{ - const char *s; - unsigned long acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * See strtol for comments as to the logic used. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - cutoff = ULONG_MAX / (unsigned long)base; - cutlim = ULONG_MAX % (unsigned long)base; - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = ULONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= (unsigned long)base; - acc += c; - } - } - if (neg && any > 0) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtoul); diff --git a/src/lib/libc/stdlib/strtoull.c b/src/lib/libc/stdlib/strtoull.c deleted file mode 100644 index d7733e4003..0000000000 --- a/src/lib/libc/stdlib/strtoull.c +++ /dev/null @@ -1,114 +0,0 @@ -/* $OpenBSD: strtoull.c,v 1.9 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -/* - * Convert a string to an unsigned long long. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long long -strtoull(const char *nptr, char **endptr, int base) -{ - const char *s; - unsigned long long acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * See strtoll for comments as to the logic used. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - cutoff = ULLONG_MAX / (unsigned long long)base; - cutlim = ULLONG_MAX % (unsigned long long)base; - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = ULLONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= (unsigned long long)base; - acc += c; - } - } - if (neg && any > 0) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtoull); - -__weak_alias(strtouq, strtoull); diff --git a/src/lib/libc/stdlib/strtoumax.c b/src/lib/libc/stdlib/strtoumax.c deleted file mode 100644 index 348184c1ac..0000000000 --- a/src/lib/libc/stdlib/strtoumax.c +++ /dev/null @@ -1,109 +0,0 @@ -/* $OpenBSD: strtoumax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */ -/* - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -/* - * Convert a string to a uintmax_t. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -uintmax_t -strtoumax(const char *nptr, char **endptr, int base) -{ - const char *s; - uintmax_t acc, cutoff; - int c; - int neg, any, cutlim; - - /* - * See strtoimax for comments as to the logic used. - */ - if (base < 0 || base == 1 || base > 36) { - if (endptr != 0) - *endptr = (char *)nptr; - errno = EINVAL; - return 0; - } - - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && c == '0' && - (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - cutoff = UINTMAX_MAX / (uintmax_t)base; - cutlim = UINTMAX_MAX % (uintmax_t)base; - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = UINTMAX_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= (uintmax_t)base; - acc += c; - } - } - if (neg && any > 0) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} -DEF_STRONG(strtoumax); diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3 deleted file mode 100644 index bdd94c0115..0000000000 --- a/src/lib/libc/stdlib/system.3 +++ /dev/null @@ -1,116 +0,0 @@ -.\" Copyright (c) 1990, 1991 The Regents of the University of California. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $OpenBSD: system.3,v 1.14 2016/02/05 18:09:19 espie Exp $ -.\" -.Dd $Mdocdate: February 5 2016 $ -.Dt SYSTEM 3 -.Os -.Sh NAME -.Nm system -.Nd pass a command to the shell -.Sh SYNOPSIS -.In stdlib.h -.Ft int -.Fn system "const char *string" -.Sh DESCRIPTION -The -.Fn system -function hands the argument -.Fa string -to the command interpreter -.Xr sh 1 . -The calling process waits for the shell to finish executing the command, -ignoring -.Dv SIGINT -and -.Dv SIGQUIT , -and blocking -.Dv SIGCHLD . -.Pp -If -.Fa string -is -.Dv NULL , -.Fn system -will return non-zero. -Otherwise, -.Fn system -returns the termination status of the shell in the format specified by -.Xr waitpid 2 . -.Pp -Note that fork handlers established using -.Xr pthread_atfork 3 -are not called when a multithreaded program calls -.Fn system . -.Sh RETURN VALUES -If a child process cannot be created, or the termination status of -the shell cannot be obtained, -.Fn system -returns \-1 and sets -.Va errno -to indicate the error. -If execution of the shell fails, -.Fn system -returns the termination status for a program that terminates with a call of -.Fn exit 127 . -.Sh SEE ALSO -.Xr sh 1 , -.Xr execve 2 , -.Xr waitpid 2 , -.Xr popen 3 -.Sh STANDARDS -The -.Fn system -function conforms to -.St -ansiC -and -.St -p1003.2-92 . -.Sh HISTORY -The -.Fn system -function first appeared in -.At v6 . -.Sh CAVEATS -Never supply the -.Fn system -function with a command containing any part of an unsanitized user-supplied -string. -Shell meta-characters present will be honored by the -.Xr sh 1 -command interpreter. -.Pp -It is often simpler to bypass the shell and run an external command using -.Xr fork 2 , -.Xr execlp 3 , -and -.Xr waitpid 2 -directly instead of having to sanitize a string for shell consumption. diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c deleted file mode 100644 index 28f01a9c5d..0000000000 --- a/src/lib/libc/stdlib/system.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $OpenBSD: system.c,v 1.13 2022/05/21 00:53:53 millert Exp $ */ -/* - * Copyright (c) 1988 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int -system(const char *command) -{ - pid_t pid, cpid; - struct sigaction intsave, quitsave, sa; - sigset_t mask, omask; - int pstat; - char *argp[] = {"sh", "-c", NULL, NULL}; - - if (!command) /* just checking... */ - return(1); - - argp[2] = (char *)command; - - sigemptyset(&mask); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGQUIT); - sigprocmask(SIG_BLOCK, &mask, &omask); - switch (cpid = vfork()) { - case -1: /* error */ - sigprocmask(SIG_SETMASK, &omask, NULL); - return(-1); - case 0: /* child */ - sigprocmask(SIG_SETMASK, &omask, NULL); - execve(_PATH_BSHELL, argp, environ); - _exit(127); - } - - /* Ignore SIGINT and SIGQUIT while waiting for command to complete. */ - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, &intsave); - sigaction(SIGQUIT, &sa, &quitsave); - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGQUIT); - sigprocmask(SIG_UNBLOCK, &mask, NULL); - - do { - pid = waitpid(cpid, &pstat, 0); - } while (pid == -1 && errno == EINTR); - - sigprocmask(SIG_SETMASK, &omask, NULL); - sigaction(SIGINT, &intsave, NULL); - sigaction(SIGQUIT, &quitsave, NULL); - return (pid == -1 ? -1 : pstat); -} -DEF_STRONG(system); diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c deleted file mode 100644 index 49f9dbc17a..0000000000 --- a/src/lib/libc/stdlib/tfind.c +++ /dev/null @@ -1,40 +0,0 @@ -/* $OpenBSD: tfind.c,v 1.7 2015/09/26 16:03:48 guenther Exp $ */ - -/* - * Tree search generalized from Knuth (6.2.2) Algorithm T just like - * the AT&T man page says. - * - * The node_t structure is for internal use only - * - * Written by reading the System V Interface Definition, not the code. - * - * Totally public domain. - */ -#include - -typedef struct node_t -{ - char *key; - struct node_t *llink, *rlink; -} node; - -/* find a node, or return 0 */ -void * -tfind(const void *vkey, void * const *vrootp, - int (*compar)(const void *, const void *)) -{ - char *key = (char *)vkey; - node **rootp = (node **)vrootp; - - if (rootp == (struct node_t **)0) - return ((struct node_t *)0); - while (*rootp != (struct node_t *)0) { /* T1: */ - int r; - if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */ - return (*rootp); /* key found */ - rootp = (r < 0) ? - &(*rootp)->llink : /* T3: follow left branch */ - &(*rootp)->rlink; /* T4: follow right branch */ - } - return (node *)0; -} diff --git a/src/lib/libc/stdlib/thread_atexit.c b/src/lib/libc/stdlib/thread_atexit.c deleted file mode 100644 index ef0423c428..0000000000 --- a/src/lib/libc/stdlib/thread_atexit.c +++ /dev/null @@ -1,44 +0,0 @@ -/* $OpenBSD: thread_atexit.c,v 1.2 2019/06/02 01:03:01 guenther Exp $ */ -/* - * Copyright (c) 2017 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include "atexit.h" - -__weak_alias(__cxa_thread_atexit, __cxa_thread_atexit_impl); - -int -__cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso) -{ - struct thread_atexit_fn *fnp; - struct tib *tib = TIB_GET(); - - fnp = calloc(1, sizeof(struct thread_atexit_fn)); - if (fnp == NULL) - return -1; - - dlctl(NULL, DL_REFERENCE, dso); - - fnp->func = func; - fnp->arg = arg; - fnp->next = tib->tib_atexit; - tib->tib_atexit = fnp; - - return 0; -} diff --git a/src/lib/libc/stdlib/tsearch.3 b/src/lib/libc/stdlib/tsearch.3 deleted file mode 100644 index a7ab985013..0000000000 --- a/src/lib/libc/stdlib/tsearch.3 +++ /dev/null @@ -1,126 +0,0 @@ -.\" $OpenBSD: tsearch.3,v 1.22 2022/03/31 17:27:16 naddy Exp $ -.\" -.\" Copyright (c) 1997 Todd C. Miller -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.Dd $Mdocdate: March 31 2022 $ -.Dt TSEARCH 3 -.Os -.Sh NAME -.Nm tsearch , -.Nm tfind , -.Nm tdelete , -.Nm twalk -.Nd manipulate binary search trees -.Sh SYNOPSIS -.In search.h -.Ft void * -.Fn tdelete "const void *key" "void **rootp" "int (*compar)(const void *, const void *)" -.Ft void * -.Fn tfind "const void *key" "void * const *rootp" "int (*compar)(const void *, const void *)" -.Ft void * -.Fn tsearch "const void *key" "void **rootp" "int (*compar)(const void *, const void *)" -.Ft void -.Fn twalk "const void *root" "void (*action)(const void *, VISIT, int)" -.Sh DESCRIPTION -The -.Fn tdelete , -.Fn tfind , -.Fn tsearch , -and -.Fn twalk -functions manage binary search trees based on algorithms T and D -from Knuth (6.2.2). -The comparison function passed in by -the user has the same style of return values as -.Xr strcmp 3 . -.Pp -.Fn tfind -searches for the datum matched by the argument -.Fa key -in the binary tree rooted at -.Fa rootp , -returning a pointer to the datum if it is found and -.Dv NULL -if it is not. -.Pp -.Fn tsearch -is identical to -.Fn tfind -except that if no match is found, -.Fa key -is inserted into the tree and a pointer to it is returned. -If -.Fa rootp -points to a null value, a new binary search tree is created. -.Pp -.Fn tdelete -deletes a node from the specified binary search tree and returns -a pointer to the parent of the node to be deleted. -If the node to be deleted is the root of the binary search tree, -.Fa rootp -will be adjusted and an unspecified non-null pointer will be returned. -It takes the same arguments as -.Fn tfind -and -.Fn tsearch . -.Pp -.Fn twalk -walks the binary search tree rooted in -.Fa root -and calls the function -.Fa action -on each node. -.Fa action -is called with three arguments: a pointer to the current node, -a value from the enum -.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;" -specifying the traversal type, and a node level (where level -zero is the root of the tree). -.Sh RETURN VALUES -The -.Fn tsearch -function returns -.Dv NULL -if allocation of a new node fails (usually -due to a lack of free memory). -.Pp -.Fn tdelete -returns a pointer to the parent of the deleted node or an unspecified -non-null pointer if the root node is deleted. -.Pp -.Fn tfind , -.Fn tsearch , -and -.Fn tdelete -return -.Dv NULL -if -.Fa rootp -is -.Dv NULL -or the datum cannot be found. -.Sh SEE ALSO -.Xr bsearch 3 , -.Xr lsearch 3 -.Sh STANDARDS -These functions conform to -.St -p1003.1-2008 . -.Sh CAVEATS -The value returned when deleting the root node was unspecified before -the -.St -p1003.1-2008 -standard, so users of the -.Fn tdelete -function should be wary of relying on a specific behaviour. diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c deleted file mode 100644 index 1dd31454eb..0000000000 --- a/src/lib/libc/stdlib/tsearch.c +++ /dev/null @@ -1,118 +0,0 @@ -/* $OpenBSD: tsearch.c,v 1.10 2015/09/26 16:03:48 guenther Exp $ */ - -/* - * Tree search generalized from Knuth (6.2.2) Algorithm T just like - * the AT&T man page says. - * - * The node_t structure is for internal use only - * - * Written by reading the System V Interface Definition, not the code. - * - * Totally public domain. - */ - -#include -#include - -typedef struct node_t { - char *key; - struct node_t *left, *right; -} node; - -/* find or insert datum into search tree */ -void * -tsearch(const void *vkey, void **vrootp, - int (*compar)(const void *, const void *)) -{ - node *q; - char *key = (char *)vkey; - node **rootp = (node **)vrootp; - - if (rootp == (struct node_t **)0) - return ((void *)0); - while (*rootp != (struct node_t *)0) { /* Knuth's T1: */ - int r; - - if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */ - return ((void *)*rootp); /* we found it! */ - rootp = (r < 0) ? - &(*rootp)->left : /* T3: follow left branch */ - &(*rootp)->right; /* T4: follow right branch */ - } - q = malloc(sizeof(node)); /* T5: key not found */ - if (q != (struct node_t *)0) { /* make new node */ - *rootp = q; /* link new node to old */ - q->key = key; /* initialize new node */ - q->left = q->right = (struct node_t *)0; - } - return ((void *)q); -} - -/* delete node with given key */ -void * -tdelete(const void *vkey, void **vrootp, - int (*compar)(const void *, const void *)) -{ - node **rootp = (node **)vrootp; - char *key = (char *)vkey; - node *p = (node *)1; - node *q; - node *r; - int cmp; - - if (rootp == (struct node_t **)0 || *rootp == (struct node_t *)0) - return ((struct node_t *)0); - while ((cmp = (*compar)(key, (*rootp)->key)) != 0) { - p = *rootp; - rootp = (cmp < 0) ? - &(*rootp)->left : /* follow left branch */ - &(*rootp)->right; /* follow right branch */ - if (*rootp == (struct node_t *)0) - return ((void *)0); /* key not found */ - } - r = (*rootp)->right; /* D1: */ - if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */ - q = r; - else if (r != (struct node_t *)0) { /* Right link is null? */ - if (r->left == (struct node_t *)0) { /* D2: Find successor */ - r->left = q; - q = r; - } else { /* D3: Find (struct node_t *)0 link */ - for (q = r->left; q->left != (struct node_t *)0; q = r->left) - r = q; - r->left = q->right; - q->left = (*rootp)->left; - q->right = (*rootp)->right; - } - } - free((struct node_t *) *rootp); /* D4: Free node */ - *rootp = q; /* link parent to new node */ - return(p); -} - -/* Walk the nodes of a tree */ -static void -trecurse(node *root, void (*action)(const void *, VISIT, int), int level) -{ - if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0) - (*action)(root, leaf, level); - else { - (*action)(root, preorder, level); - if (root->left != (struct node_t *)0) - trecurse(root->left, action, level + 1); - (*action)(root, postorder, level); - if (root->right != (struct node_t *)0) - trecurse(root->right, action, level + 1); - (*action)(root, endorder, level); - } -} - -/* Walk the nodes of a tree */ -void -twalk(const void *vroot, void (*action)(const void *, VISIT, int)) -{ - node *root = (node *)vroot; - - if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0) - trecurse(root, action, 0); -} -- cgit v1.2.3-55-g6feb