Compare commits

..

103 Commits

Author SHA1 Message Date
Guillem Jover
084911ce87 Release libbsd 0.11.7 2022-10-06 04:07:52 +02:00
Guillem Jover
3538d38fe7 man: Discourage using the library in non-overlay mode
This makes code using it non-portable, and requires the namespeced
headers from libbsd, instead of any generic system headers. It also
requires more code changes than the overlay mode.
2022-10-06 03:59:33 +02:00
Guillem Jover
03fccd1505 include: Adjust reallocarray() per glibc adoption
On glibc 2.29 reallocarray() was moved to _DEFAULT_SOURCE.

Closes: !20
Based-on-patch-by: Callum Farmer <gmbr3@opensuse.org>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-10-05 12:31:49 +02:00
Callum Farmer
6b6e686b23 include: Adjust arc4random() per glibc adoption
Some arc4random functions were added in glibc 2.36.

Signed-off-by: Callum Farmer <gmbr3@opensuse.org>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-10-05 12:31:49 +02:00
Callum Farmer
da1f45ac71 include: explicit_bzero() requires _DEFAULT_SOURCE
Signed-off-by: Callum Farmer <gmbr3@opensuse.org>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-10-05 12:15:36 +02:00
Guillem Jover
2f9eddc277 include: Simplify glibc version dependent macro handling
We test once whether __GLIBC__ is not defined, so we do not need to test
whether it is on the OR branch afterwards. We decouple the glibc version
restriction check from the _*_SOURCE variable, as that contains an
implicit opposite version check.
2022-10-05 12:12:34 +02:00
Guillem Jover
28298ac037 doc: Switch references from pkg-config to pkgconf
The former used to be the reference implementation, but it has been
stagnant to the point of not showing much signs of life. Switch to
the currently active and more complete implementation for references.
2022-10-05 01:36:28 +02:00
Guillem Jover
ef981f930b doc: Add missing empty line to separate README sections 2022-10-04 04:29:37 +02:00
Guillem Jover
6928d7895e doc: Refer to the main git repository as primary 2022-10-04 04:29:37 +02:00
Guillem Jover
d5865759f8 test: Fix explicit_bzero() test on the Hurd
On the Hurd a small read(3) might end up (indirectly) copying the data
on the stack, which we will end up finding even when we have cleared
the buffer.

To avoid these side effects, we add a new function, that we force not
to be inlined, so that we can reuse the same stack space, that will
blank any possible stack side effects. This should be portable
regardless of stack growing up or down.

Diagnosis-by: Samuel Thibault <sthibault@debian.org>
2022-10-04 04:29:37 +02:00
Guillem Jover
be327c6ebe fgetwln: Add comment about lack of getwline(3) for recommendation
Ideally we'd recommend getwline(3), but unfortunately even though it
was part of the ISO/IEC TR 24731-2:2010 draft, it did not make it into
C11 and is not widely implemented.
2022-10-04 04:29:07 +02:00
Guillem Jover
a14612d968 setmode: Dot not use saveset after free
While we are only doing a pointer difference and not dereferencing it,
it's easier and more correct to do the pointer difference before passing
it to reallocarray().

Warned-by: gcc
2022-08-23 23:51:05 +02:00
Guillem Jover
f4baceb82c man: Rewrite gerprogname(3bsd) from scratch
This gets rid of one of the last man pages with a BSD-4-clause license.
2022-08-03 11:39:31 +02:00
Guillem Jover
f35c545847 man: Lowercase man page title
While using fully uppercase man page titles has been the usual
convention for a very long time, it is rather ugly and something that
some other projects are switching away from.
2022-08-03 11:39:31 +02:00
Guillem Jover
b466b14afb man: Document that some arc4random(3) functions are now in glibc 2.36 2022-08-03 11:39:31 +02:00
Guillem Jover
1f6a48b209 Sync arc4random(3) implementation from OpenBSD
Closes: #12
2022-08-03 11:39:31 +02:00
Fabrice Fontaine
873639ebb5 Fix ELF support for big endian SH
Fix the following build failure with big endian SH (e.g. sh4aeb):

  ,---
  In file included from nlist.c:44:
  nlist.c: In function '__elf_is_okay__':
  local-elf.h:223:25: error: 'ELFDATA2LMSB' undeclared (first use in this function); did you mean 'ELFDATA2LSB'?
    223 | #define ELF_TARG_DATA   ELFDATA2LMSB
        |                         ^~~~~~~~~~~~
  `---

Fixes: http://autobuild.buildroot.org/results/2980fb79c208454195d77383f1ece9afbd7f981b
Closes: !19
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-06-08 11:51:55 +02:00
Guillem Jover
c9c78fdfd0 man: Use -compact also for alternative functions in libbsd(7)
The other function lists use the compact mode, let's be uniform about
this.
2022-06-08 11:50:47 +02:00
Guillem Jover
5f21307570 getentropy: Fix function cast for getauxval()
Fix also the Hurd implementation, missed in the original fix.

Extends: commit 72a82ee262
Warned-by: gcc
2022-06-08 11:49:16 +02:00
Guillem Jover
84acf21568 Release libbsd 0.11.6 2022-03-30 23:09:35 +02:00
WANG Xuerui
15200ec7ac Add LoongArch support to nlist()
Closes: !13
Signed-off-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-03-30 23:03:56 +02:00
Guillem Jover
f7465b93ec man: Document when functions were added to musl in libbsd(7)
The explicit_bzero(3) and reallocarray(3) functions are also present on
musl libc, mention it in the superseded section.
2022-03-30 22:58:47 +02:00
Guilherme Janczak
e5ed5fdd62 Remove arc4random() OpenBSD support
The arc4random() support for OpenBSD does not build. The intention was
to include any portability code so that the library could be easily
ported to such systems, but it makes little sense to build it on OpenBSD
where most of the functionality will be already present, or the software
would have been ported anyway.

[guillem@hadrons.org: Reword commit message to add rationale. ]

Closes: !15
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-03-30 22:55:56 +02:00
Duncan Overbruck
abb1a6b1a7 build: Add alpine to CI for tests with musl libc
Closes: !18
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-01-29 15:03:08 +01:00
Guillem Jover
c9ff83687c test: Import explicit_bzero and strtonum test cases from OpenBSD
- Remove trailing spaces.
- Declare file-scope functions and variables static.
- Declare functions with a proper prototype.
- Do not mix declarations and code for C90 conformance.
- Do not compare size_t and ssize_t variables.
2022-01-29 14:54:24 +01:00
Guillem Jover
62e67bb49e build: Sort test programs in .gitignore 2022-01-29 14:52:39 +01:00
Duncan Overbruck
87b1307040 test: Add fpurge() test case using open_memstream(3) FILE
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-01-29 14:10:55 +01:00
Duncan Overbruck
ba3c46b30f fpurge: Make it work with non fd based FILEs
Streams opened with for example open_memstream(3) will have no associated
file descriptor, and fileno(3) will fail.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-01-26 04:42:09 +01:00
Duncan Overbruck
091097e062 test: Remove static FILE declaration from fpurge test
This does not work with libcs that do not declare the structure
in a header file, like musl. And gets in the way of supporting
non-fd based streams.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-01-26 04:39:42 +01:00
Guillem Jover
5f9608c775 Release libbsd 0.11.5 2022-01-25 01:48:29 +01:00
Guillem Jover
eef07993c9 Revert "build: Add missing proctitle unit test program"
This reverts commit beafad2657.

This test was already handled later on as part of the BUILD_LIBBSD_CTOR
conditional. Adding it to the unconditional set made the build fail when
the system does not have GNU .init_array section support.

Closes: #9
Analysis-by: Duncan Overbruck <mail@duncano.de>
2022-01-25 01:41:14 +01:00
Guillem Jover
c6d589bc71 Document how to build from git and from a tarball release
Closes: #8
2022-01-23 21:09:05 +01:00
Guillem Jover
2975d809a0 build: Check for objdump explicitly
We should not assume that something will implicitly check for this tool,
as we need it ourselves, and this is an internal implementation detail
of right now libtool.

Fixes: commit f11ab67223
2022-01-23 20:52:26 +01:00
Sam James
f11ab67223 build: Respect $(OBJDUMP)
We already search for it in `./configure` so let's respect
the result of that search.

This helps with cross-compilation and any other cases
where one might want to choose a different toolchain.

Closes: !16
Bug: https://bugs.gentoo.org/831863
Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2022-01-23 18:42:01 +01:00
Guillem Jover
54796231c7 Release libbsd 0.11.4 2022-01-22 22:41:51 +01:00
Guillem Jover
7aed0edf73 man: Add missing comma in .Dd for tree(3)
Reported-by: Thorsten Glaser <tg@mirbsd.de>
2021-12-02 00:35:40 +01:00
Guillem Jover
fafcc397ac man: Update tree(3) man page from OpenBSD
This man page has a BSD-3-clause-author license instead of the old
BSD-4-clause license.
2021-12-01 04:17:11 +01:00
Guillem Jover
48107fc8c4 build: Clarify link-time warnings
Mention the involved function instead of stating an implicit "this
function". Mention libbsd when proposing using an alternative libmd
to make the context clear.
2021-12-01 04:17:11 +01:00
Guillem Jover
e7cf8c5785 Switch md5 compatibility logic back to direct linking
When using the recent dlsym() based wrapper, we are not requiring any
symbol from libmd, as we resolve those dynamically at run-time. We were
ending up linking against libmd because in another part of the code we
require (depending on the architecture) the SHA512 functions for the
getentropy() local implementation. But that function might be provided
by the system libc on some systems, which means we end up not linking
against libmd at all.

To solve this we go back to the previous simpler solution of linking
directly, which had the main drawback of then making programs fail to
link when not specifying -lmd (on platforms that need it). And then
switch the .so link point from a symlink to a linker script, so that we
can inject the -lmd library as-needed. This is similar to what glibc is
doing.

Fixes: commit 31f034e386
2021-12-01 04:14:35 +01:00
Guillem Jover
25d35625eb build: Split libmd dependency due to MD5 functions from SHA requirements
To be able to rework the md5 deprecation logic, we need to detangle when
we depend on libmd due to requiring MD5 functions, which might be
otherwise provided by libc, or when we require SHA functions for the
internal getentropy() implementation.
2021-11-28 22:40:58 +01:00
Guillem Jover
500b3080a2 build: Add new libbsd_symver_weak() macro
We will use it for the reworked md5 deprecation logic.
2021-11-28 22:34:59 +01:00
Guillem Jover
1eba406021 test: Check that strdup() does not fail
Warned-by: gcc
2021-11-27 23:42:37 +01:00
Guillem Jover
8ad7570c20 getentropy: Add missing prototype for BSD variant
Warned-by: gcc
2021-11-27 23:42:37 +01:00
Guillem Jover
43a8270317 nlist: Remove condition which is always true
The nlist() function is limited to handle ELF binaries of the same class
as size as the size_t of the architecture built.

In addition the SIZE_T_MAX macro is BSD specific, and was falling back
to the wrong constant on most 64-bit non-BSD systems.

Warned-by: gcc
2021-11-27 23:36:34 +01:00
Guillem Jover
6a71b24b63 build: Append __ after __attribute and __typeof keywords
Be consistent with other usages in the code base.
2021-11-27 22:53:32 +01:00
Guillem Jover
7389fe8d24 build: Ignore backup files 2021-11-27 06:54:49 +01:00
Victor Westerhuis
2716dfd0b7 test: Explicitly mark symbols as used
Because some of the symbols are not otherwise referenced, GCC would like
to remove them.

Closes: !14
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-11-27 06:52:17 +01:00
Victor Westerhuis
54f8745657 build: Enable .init_array support when building with LTO
Because these symbols are not otherwise referenced, GCC would like
to remove them.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-11-27 06:51:02 +01:00
Guillem Jover
428be9e030 man: Fix .Nx macro usage
Its arguments are used as version numbers, so we need continue the
content on the next line.
2021-11-27 05:06:14 +01:00
Alexander Miller
c7a5d780ae build: Allow building with -flto on gcc-10 and newer
Global asm statements (like .symver directives) do not work reliably
in gcc with link time optimization. Use the symver attribute introduced
with gcc-10 to set symbol versions instead, if available.

[guillem@hadrons.org:
 - Simplify by using __has_attribute fallback from <sys/cdefs.h>.
 - Coding style changes. ]

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-11-27 05:06:14 +01:00
Guillem Jover
1808d64b77 test: Fix pipe_feed() to allow checking fprintf format strings
Warned-by: gcc -W
2021-11-27 05:06:14 +01:00
Guillem Jover
beafad2657 build: Add missing proctitle unit test program 2021-11-27 05:06:14 +01:00
Guillem Jover
6145b56178 test: Do not pass NULL as the first funopen() argument
Warned-by: gcc -W
2021-11-27 05:06:14 +01:00
Guillem Jover
731b0a7739 build: Detect sed at configure time
Check whether sed is available and use the implementation matching the
requirements via the SED variable.
2021-11-27 05:06:14 +01:00
Guillem Jover
50b50a4330 vis: Add prototypes for strnvis() and strnunvis() variants
Warned-by: gcc
2021-11-27 05:06:14 +01:00
Guillem Jover
25e88f6479 test: Cast literal strings to (char *) on n_name assignment
The member is declared as n_name so we cannot directly assign a literal
string constant.

Warned-by: gcc
2021-11-27 05:06:14 +01:00
Guillem Jover
04a8fb2469 Add missing prototypes to functions
Warned-by: gcc
2021-11-27 05:06:14 +01:00
Guillem Jover
4f68a88f55 build: Add compiler warnings support
Detect as many warnings as possible during configure and enable them
if the user did not supply any, so that any such problem can be spotted
and fixed.
2021-11-27 05:06:14 +01:00
Guillem Jover
8f59221c4f nlist: Remove repeated shadowing variable declaration
Warned-by: gcc
2021-02-28 05:30:37 +01:00
Guillem Jover
72a82ee262 getentropy: Fix function cast for getauxval()
Warned-by: gcc
2021-02-28 05:30:37 +01:00
Guillem Jover
3c305f2873 test: Add proper prototypes for main() function
Warned-by: gcc
2021-02-28 05:30:31 +01:00
Guillem Jover
25278891d8 Mark local functions as static
Warned-by: gcc
2021-02-28 05:30:25 +01:00
Guillem Jover
e35d9141dc Add link-time warnings to MD5 wrapper functions
Let's get the word out that these functions are deprecated and should be
switched away from.
2021-02-28 05:28:57 +01:00
Guillem Jover
4feda87049 Require a semicolon for libbsd_link_warning() macro
Remove the semicolon in the macro definition to force adding one on the
call sites, to make the code look like an actual function.
2021-02-28 05:28:57 +01:00
Guillem Jover
d563a17430 man: Call the libbsd-ctor library by its name instead of bsd-ctor 2021-02-28 05:28:57 +01:00
Guillem Jover
785cf9d1e9 man: Fix pkg-config(1) references in libbsd(7) man page 2021-02-28 05:28:57 +01:00
Guillem Jover
15bd284b29 build: Add code coverage support in the GitLab CI 2021-02-28 05:28:49 +01:00
Guillem Jover
a9fc285988 build: Use apt-get instead of apt in the GitLab CI
The former is to be used programmatically, while the latter is intended
for interactive use.
2021-02-28 05:27:35 +01:00
Guillem Jover
c0d86a6412 build: Add a Libs.private field to overlay pkg-config file
We need to list all internal libraries there so that we can statically
link.

Fixes: commit 2374f409de
2021-02-09 08:36:01 +01:00
Guillem Jover
1fb25b7dca Release libbsd 0.11.3 2021-02-09 06:23:38 +01:00
Guillem Jover
31f034e386 Switch libmd wrapper to use dlsym()
Switch from the previous versioned symbol implementation which required
users to also link against the message digest provider explicitly, or
they would fail to find the symbols, to an implementation that loads
the symbols from the linked library providing the functions using
dlsym(), thus preserving backwards compatibility.
2021-02-09 06:23:38 +01:00
Guillem Jover
2374f409de build: Add a Libs.private field to pkg-config file
We need to list all internal libraries there so that we can statically
link.
2021-02-09 06:23:38 +01:00
Guillem Jover
a4e0db2b97 build: Use a single variable to track libraries to link against
Using various variables means we have to keep these in sync in various
places. Just use a single variable that we can use anywhere where this
is needed.
2021-02-09 06:23:38 +01:00
Guillem Jover
43d34c9d3b build: Fix message digest library checks
They were not failing when not finding the SHA-2 functions and
were hardcoding -lmd regardless of what library had been found.
2021-02-09 06:23:38 +01:00
Guillem Jover
1c3ff61699 Use uintptr_t and size_t instead of __-prefixed types in <sys/cdefs.h>
The __-prefixed types cannot be assumed to be defined. Use the standard
types instead.

Closes: #6
2021-02-09 06:23:27 +01:00
Guillem Jover
edea268ce9 Release libbsd 0.11.2 2021-02-08 04:02:46 +01:00
Guillem Jover
e832b7687e closefrom: Use close_range() on Linux when available
Closes: !11
Based-on-patch-by: cptpcrd <cptpcrd.git@gmail.com>
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-02-08 04:02:46 +01:00
cptpcrd
c4fca5bb4f closefrom: Handle lowfd < 0 properly
More important if close_range() is going to be used, since casting
negative values to 'unsigned int' might hide the errors.

[guillem@hadrons.org: Minor coding style fix. ]

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-02-08 04:02:46 +01:00
Guillem Jover
a1f79978e8 closefrom: Import some changes from sudo
Take most of the changes done in sudo, but preserve the existing local
changes and refactoring.

In addition, refactor pstat implementation into closefrom_pstat(), so
that the code is easier to read, and requires no conditional
declarations.
2021-02-08 04:02:46 +01:00
Faidon Liambotis
4676026286 Update <sys/queue.h> from FreeBSD
This brings <sys/queue.h> to the most up-to-date version from FreeBSD,
incorporating 18 commits from the past 5 years (2015-02-24 - 2021-01-25):

  $ git log --oneline 9090a24aed70..8d55837dc133 sys/sys/queue.h share/man/man3/queue.3

Only minimal changes compared to the FreeBSD version have been applied
(queue.3 -> queue.3bsd, _LIBBSD_ prefix).

[guillem@hadrons.org: Remove reference to kernel mode in man page. ]

Closes: !12
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-02-08 04:02:16 +01:00
Guillem Jover
25f9b30678 test: Improve code coverage for strnstr(3) unit tests 2021-02-07 23:24:51 +01:00
Guillem Jover
18ebabf223 man: Update libbsd(7) man page with updates in 0.11.0 2021-02-07 15:17:33 +01:00
Guillem Jover
4ab11c7f48 build: Install libmd-dev in the gitlab CI 2021-02-07 10:37:18 +01:00
Guillem Jover
766c883e30 build: Switch gitlab CI to use a Debian buster 2021-02-07 10:35:57 +01:00
Guillem Jover
a4de4d95a6 Release libbsd 0.11.1 2021-02-07 02:03:59 +01:00
Guillem Jover
233cab9d64 Add support for new LIBBSD_VIS_OPENBSD selection macro
This will make it possible to explicitly select the OpenBSD vis
implementation (the current default) for code of OpenBSD origins.
2021-02-07 02:03:22 +01:00
Guillem Jover
2462cd8888 Release libbsd 0.11.0 2021-02-07 01:28:27 +01:00
Guillem Jover
d54ceb37ce Update copyright claims 2021-02-07 01:28:27 +01:00
Guillem Jover
847e682f8d Use libmd hashing function implementations instead of embedding our own
This splits the implementation responsibilities, and reduces embedded
code copies, which was one of the driving points with this project to
start with, so it's nice to give a good example.
2021-02-07 01:28:27 +01:00
Aaron Dierking
68f980c90d Provide a default progname on Windows
[guillem@hadrons.org:
 - Remove .exe extension from default program name.
 - Call reallocarray() once by switching to a «do {} while» loop.
 - Minor coding style fixes. ]

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-02-07 01:28:27 +01:00
Guillem Jover
37a9b56c05 Import pwcache module from OpenBSD 2021-02-07 01:28:27 +01:00
Guillem Jover
45dd5229ea man: Remove empty line in reallocarray(3bsd)
Warned-by: lintian
Fixes: commit 01f0d1ea1e
2021-02-07 01:28:27 +01:00
Faidon Liambotis
01f0d1ea1e Add recallocarray() and freezero() from OpenBSD
Add recallocarray(), introduced in OpenBSD 6.1, and freezero(),
introduced in OpenBSD 6.2. The former is imported as-is from OpenBSD,
while the latter is the non-malloc-internal branch of the same code (and
also the OpenSSH portable variant).

Both of these originated in OpenBSD, but have also been implemented by
IllumOS, cf. https://www.illumos.org/issues/8546

Documentation for these functions is in malloc(3) upstream, the relevant
parts of which were previously imported in reallocarray(3bsd). Update
reallocarray(3bsd) with the changes that were introduced since, and add
the relevant bits for recallocarray() and freezero(), plus aliases.

[guillem@hadrons.org: Update copyright in COPYING. ]

Closes: !10
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-01-01 18:18:51 +01:00
Seth R Johnson
9c85d828a1 Fix ELF detection on Intel compilers
The Intel compiler does not define __amd64__ on x86_64 platforms;
instead, like other compilers, it defines __x86_64__ .

Closes: !8
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2021-01-01 18:12:12 +01:00
Guillem Jover
eac4ce0c67 man: Add a timespec(3bsd) alias to timeval(3bsd)
Even though man-pages project now includes man pages for system data
types, we still include these for any other system that does not have
them, to provide a self-contained project with code and documentation.
2020-12-21 17:48:46 +01:00
Guillem Jover
5ecff0c903 man: Add missing LIBRARY section 2020-12-21 17:44:26 +01:00
Guillem Jover
8c5a83d678 Fix coding style 2020-12-21 17:44:26 +01:00
Guillem Jover
d5b04ab19c test: Fix short lived memory leaks
These are non-issues, but having a clean ASAN test suite makes it
possible to detect actual problems in the tested code.

Warned-by: gcc ASAN
2020-12-21 17:44:26 +01:00
Guillem Jover
cfeafeabad funopen: Fix memory leak in funopen_close() when closefn is NULL
We need to free the cookiewrap even when the closefn method is NULL.

Warned-by: gcc ASAN
2020-12-21 17:44:26 +01:00
Guillem Jover
3d6b6ead64 build: Detect support for --version-script in ld 2020-12-21 17:43:11 +01:00
Guillem Jover
eb445425ff Do not define SIZE_T_MAX if already defined 2020-12-21 17:19:30 +01:00
Guillem Jover
59f6a95609 man: Add missing doc-operating-system-NetBSD string variable
Fixes: commit 99320b9168.
2020-12-21 17:19:23 +01:00
Guillem Jover
3548c5f6bf Add missing strnvisx() to the symbols script
Fixes: commit 2d7de186e9.
2020-12-21 17:19:12 +01:00
135 changed files with 2946 additions and 1460 deletions

5
.gitignore vendored
View File

@@ -1,4 +1,5 @@
ChangeLog ChangeLog
*~
*.pc *.pc
*.la *.la
*.lo *.lo
@@ -7,6 +8,8 @@ ChangeLog
*.a *.a
*.log *.log
*.trs *.trs
*.gcda
*.gcno
.dirstamp .dirstamp
.deps/ .deps/
.libs/ .libs/
@@ -17,6 +20,6 @@ autom4te.cache/
build-aux/ build-aux/
configure configure
config.* config.*
format.ld
libtool libtool
m4/
stamp-h1 stamp-h1

View File

@@ -1,9 +1,37 @@
image: debian:stretch .unit-tests:
test:
before_script:
- apt update -qq
- apt install -qq -y --no-install-recommends git gcc make autoconf automake libtool
script: script:
- ./autogen && ./configure - ./autogen && ./configure
- make check - make check
.coverage:
script:
- ./autogen && ./configure --disable-static
- make check CFLAGS="--coverage -O0 -ggdb" LDFLAGS="--coverage -O0 -ggdb"
- gcovr -s -e test/
.debian:
image: debian:buster
stage: test
before_script:
- apt-get update -qq
- apt-get install -qq -y --no-install-recommends
git gcc make autoconf automake libtool libmd-dev gcovr
.alpine:
image: alpine:latest
stage: test
before_script:
- apk add --no-cache git gcc make autoconf automake libtool
bsd-compat-headers linux-headers libmd-dev musl-dev gcovr
unit-tests:debian:
extends: [.debian, .unit-tests]
coverage:debian:
extends: [.debian, .coverage]
unit-tests:alpine:
extends: [.alpine, .unit-tests]
coverage:alpine:
extends: [.alpine, .coverage]

66
COPYING
View File

@@ -3,12 +3,11 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files: Files:
* *
Copyright: Copyright:
Copyright © 2004-2006, 2008-2018 Guillem Jover <guillem@hadrons.org> Copyright © 2004-2006, 2008-2022 Guillem Jover <guillem@hadrons.org>
License: BSD-3-clause License: BSD-3-clause
Files: Files:
man/arc4random.3bsd man/arc4random.3bsd
man/tree.3bsd
Copyright: Copyright:
Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
All rights reserved. All rights reserved.
@@ -38,39 +37,6 @@ License: BSD-4-clause-Niels-Provos
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Files:
man/getprogname.3bsd
Copyright:
Copyright © 2001 Christopher G. Demetriou
All rights reserved.
License: BSD-4-clause-Christopher-G-Demetriou
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.
Files: Files:
include/bsd/err.h include/bsd/err.h
include/bsd/stdlib.h include/bsd/stdlib.h
@@ -105,6 +71,7 @@ Files:
man/getbsize.3bsd man/getbsize.3bsd
man/heapsort.3bsd man/heapsort.3bsd
man/nlist.3bsd man/nlist.3bsd
man/pwcache.3bsd
man/queue.3bsd man/queue.3bsd
man/radixsort.3bsd man/radixsort.3bsd
man/reallocarray.3bsd man/reallocarray.3bsd
@@ -121,6 +88,7 @@ Files:
src/heapsort.c src/heapsort.c
src/merge.c src/merge.c
src/nlist.c src/nlist.c
src/pwcache.c
src/radixsort.c src/radixsort.c
src/setmode.c src/setmode.c
src/strmode.c src/strmode.c
@@ -131,6 +99,7 @@ Files:
Copyright: Copyright:
Copyright © 1980, 1982, 1986, 1989-1994 Copyright © 1980, 1982, 1986, 1989-1994
The Regents of the University of California. All rights reserved. The Regents of the University of California. All rights reserved.
Copyright © 1992 Keith Muller.
Copyright © 2001 Mike Barcroft <mike@FreeBSD.org> Copyright © 2001 Mike Barcroft <mike@FreeBSD.org>
. .
Some code is derived from software contributed to Berkeley by Some code is derived from software contributed to Berkeley by
@@ -275,8 +244,6 @@ Files:
man/getpeereid.3bsd man/getpeereid.3bsd
man/pidfile.3bsd man/pidfile.3bsd
src/expand_number.c src/expand_number.c
src/hash/sha512.h
src/hash/sha512c.c
src/pidfile.c src/pidfile.c
src/reallocf.c src/reallocf.c
src/timeconv.c src/timeconv.c
@@ -347,6 +314,7 @@ License: BSD-2-clause-verbatim
Files: Files:
include/bsd/sys/tree.h include/bsd/sys/tree.h
man/fparseln.3bsd man/fparseln.3bsd
man/tree.3bsd
src/fparseln.c src/fparseln.c
Copyright: Copyright:
Copyright © 1997 Christos Zoulas. Copyright © 1997 Christos Zoulas.
@@ -363,11 +331,11 @@ Files:
man/strtonum.3bsd man/strtonum.3bsd
src/arc4random.c src/arc4random.c
src/arc4random_linux.h src/arc4random_linux.h
src/arc4random_openbsd.h
src/arc4random_uniform.c src/arc4random_uniform.c
src/arc4random_unix.h src/arc4random_unix.h
src/arc4random_win.h src/arc4random_win.h
src/closefrom.c src/closefrom.c
src/freezero.c
src/getentropy_aix.c src/getentropy_aix.c
src/getentropy_bsd.c src/getentropy_bsd.c
src/getentropy_hpux.c src/getentropy_hpux.c
@@ -378,8 +346,11 @@ Files:
src/getentropy_win.c src/getentropy_win.c
src/readpassphrase.c src/readpassphrase.c
src/reallocarray.c src/reallocarray.c
src/recallocarray.c
src/strlcat.c src/strlcat.c
src/strlcpy.c src/strlcpy.c
test/explicit_bzero.c
test/strtonum.c
Copyright: Copyright:
Copyright © 2004 Ted Unangst and Todd Miller Copyright © 2004 Ted Unangst and Todd Miller
All rights reserved. All rights reserved.
@@ -388,15 +359,17 @@ Copyright:
Copyright © 1998, 2000-2002, 2004-2005, 2007, 2010, 2012-2015 Copyright © 1998, 2000-2002, 2004-2005, 2007, 2010, 2012-2015
Todd C. Miller <Todd.Miller@courtesan.com> Todd C. Miller <Todd.Miller@courtesan.com>
Copyright © 2004 Ted Unangst Copyright © 2004 Ted Unangst
Copyright © 2004 Otto Moerbeek <otto@drijf.net>
Copyright © 2008 Damien Miller <djm@openbsd.org> Copyright © 2008 Damien Miller <djm@openbsd.org>
Copyright © 2008 Otto Moerbeek <otto@drijf.net> Copyright © 2008, 2010-2011, 2016-2017 Otto Moerbeek <otto@drijf.net>
Copyright © 2013 Markus Friedl <markus@openbsd.org> Copyright © 2013 Markus Friedl <markus@openbsd.org>
Copyright © 2014 Bob Beck <beck@obtuse.com> Copyright © 2014 Bob Beck <beck@obtuse.com>
Copyright © 2014 Brent Cook <bcook@openbsd.org> Copyright © 2014 Brent Cook <bcook@openbsd.org>
Copyright © 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org> Copyright © 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
Copyright © 2014 Theo de Raadt <deraadt@openbsd.org> Copyright © 2014 Theo de Raadt <deraadt@openbsd.org>
Copyright © 2014 Google Inc.
Copyright © 2015 Michael Felt <aixtools@gmail.com> Copyright © 2015 Michael Felt <aixtools@gmail.com>
Copyright © 2015 Guillem Jover <guillem@hadrons.org> Copyright © 2015, 2022 Guillem Jover <guillem@hadrons.org>
License: ISC License: ISC
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@@ -453,17 +426,6 @@ License: Expat
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE. USE OR OTHER DEALINGS IN THE SOFTWARE.
Files:
include/bsd/md5.h
src/hash/md5.c
Copyright:
None
License: public-domain-Colin-Plumb
This code implements the MD5 message-digest algorithm.
The algorithm is due to Ron Rivest. This code was
written by Colin Plumb in 1993, no copyright is claimed.
This code is in the public domain; do with it what you wish.
Files: Files:
src/explicit_bzero.c src/explicit_bzero.c
src/chacha_private.h src/chacha_private.h
@@ -474,8 +436,6 @@ License: public-domain
Files: Files:
man/mdX.3bsd man/mdX.3bsd
src/hash/md5hl.c
src/hash/helper.c
Copyright: Copyright:
None None
License: Beerware License: Beerware

40
README
View File

@@ -5,6 +5,10 @@ and lacking on others like GNU systems, thus making it easier to port
projects with strong BSD origins, without needing to embed the same projects with strong BSD origins, without needing to embed the same
code over and over again on each project. code over and over again on each project.
A BSD compatible message-digest library is required, on systems where
this is not provided by its libc or libmd libraries, the canonical
implementation to use is <https://www.hadrons.org/software/libmd/>.
Releases Releases
-------- --------
@@ -27,10 +31,44 @@ The mail address is:
Source Repository Source Repository
----------------- -----------------
The master repository can be browsed at: The primary repository can be browsed at:
<https://cgit.freedesktop.org/libbsd> <https://cgit.freedesktop.org/libbsd>
and cloned from: and cloned from:
<https://anongit.freedesktop.org/git/libbsd> <https://anongit.freedesktop.org/git/libbsd>
Building from git source
------------------------
To prepare the libbsd source tree from git before starting the build process
some required software needs to be installed:
GNU autoconf >= 2.67
GNU automake >= 1.9
GNU libtool >= 2.0
After installing the needed software, and running the following command on
the git tree:
$ ./autogen
the source should be roughly equivalent to the distributed tar source.
Building from tar source
------------------------
The minimum software required to configure and build dpkg from a tarball is:
C89 compiler
make
The following software might be required depending on the system:
libmd (whenever the libc does not provide the needed digest functions)
The build process is done by running the usual «./configure; make». To
see all available configuration options please run «./configure --help».

View File

@@ -12,8 +12,8 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])],
[AC_SUBST([AM_DEFAULT_VERBOSITY], [1])]) [AC_SUBST([AM_DEFAULT_VERBOSITY], [1])])
LIBBSD_ABI_MAJOR=0 LIBBSD_ABI_MAJOR=0
LIBBSD_ABI_MINOR=10 LIBBSD_ABI_MINOR=11
LIBBSD_ABI_PATCH=0 LIBBSD_ABI_PATCH=7
LIBBSD_ABI="$LIBBSD_ABI_MAJOR:$LIBBSD_ABI_MINOR:$LIBBSD_ABI_PATCH" LIBBSD_ABI="$LIBBSD_ABI_MAJOR:$LIBBSD_ABI_MINOR:$LIBBSD_ABI_PATCH"
AC_SUBST([LIBBSD_ABI]) AC_SUBST([LIBBSD_ABI])
@@ -27,15 +27,72 @@ AC_SYS_LARGEFILE
LT_INIT LT_INIT
AC_CACHE_CHECK([if ld supports --version-script flag],
[libbsd_cv_version_script], [
echo "{ global: symbol; local: *; };" >conftest.map
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
AC_LINK_IFELSE([
AC_LANG_PROGRAM([], [])
], [
libbsd_cv_version_script=yes
], [
libbsd_cv_version_script=no
])
LDFLAGS="$save_LDFLAGS"
rm -f conftest.map
]
)
AM_CONDITIONAL([HAVE_LINKER_VERSION_SCRIPT],
[test "x$libbsd_cv_version_script" = "xyes"])
# Checks for programs. # Checks for programs.
AC_CHECK_TOOL([OBJDUMP], [objdump])
AC_PROG_CC AC_PROG_CC
AC_PROG_SED
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
# Set default compiler variables # Set default compiler variables
if test "$user_CFLAGS" = unset && test "$GCC" = yes; then AS_IF([test "$user_CFLAGS" = unset], [
CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter" LIBBSD_CHECK_COMPILER_FLAG([-Wall])
fi LIBBSD_CHECK_COMPILER_FLAG([-Wextra])
LIBBSD_CHECK_COMPILER_FLAG([-Wbad-function-cast])
LIBBSD_CHECK_COMPILER_FLAG([-Wc99-c11-compat])
LIBBSD_CHECK_COMPILER_FLAG([-Wcast-align])
LIBBSD_CHECK_COMPILER_FLAG([-Wdeclaration-after-statement])
LIBBSD_CHECK_COMPILER_FLAG([-Wdocumentation])
LIBBSD_CHECK_COMPILER_FLAG([-Wduplicated-branches])
LIBBSD_CHECK_COMPILER_FLAG([-Wduplicated-cond])
LIBBSD_CHECK_COMPILER_FLAG([-Wformat -Wformat-security])
LIBBSD_CHECK_COMPILER_FLAG([-Wformat=2])
LIBBSD_CHECK_COMPILER_FLAG([-Winit-self])
LIBBSD_CHECK_COMPILER_FLAG([-Wlogical-not-parentheses])
LIBBSD_CHECK_COMPILER_FLAG([-Wlogical-op])
LIBBSD_CHECK_COMPILER_FLAG([-Wmissing-declarations])
LIBBSD_CHECK_COMPILER_FLAG([-Wmissing-format-attribute])
LIBBSD_CHECK_COMPILER_FLAG([-Wmissing-prototypes])
LIBBSD_CHECK_COMPILER_FLAG([-Wnested-externs])
LIBBSD_CHECK_COMPILER_FLAG([-Wno-missing-field-initializers])
LIBBSD_CHECK_COMPILER_FLAG([-Wno-nonnull-compare])
LIBBSD_CHECK_COMPILER_FLAG([-Wno-tautological-constant-out-of-range-compare])
LIBBSD_CHECK_COMPILER_FLAG([-Wno-unused-parameter])
LIBBSD_CHECK_COMPILER_FLAG([-Wnull-dereference])
LIBBSD_CHECK_COMPILER_FLAG([-Wold-style-definition])
LIBBSD_CHECK_COMPILER_FLAG([-Wpointer-arith])
LIBBSD_CHECK_COMPILER_FLAG([-Wregister])
LIBBSD_CHECK_COMPILER_FLAG([-Wrestrict])
LIBBSD_CHECK_COMPILER_FLAG([-Wshadow])
LIBBSD_CHECK_COMPILER_FLAG([-Wshift-negative-value])
LIBBSD_CHECK_COMPILER_FLAG([-Wsizeof-array-argument])
LIBBSD_CHECK_COMPILER_FLAG([-Wstrict-prototypes])
LIBBSD_CHECK_COMPILER_FLAG([-Wswitch-bool])
LIBBSD_CHECK_COMPILER_FLAG([-Wvla])
LIBBSD_CHECK_COMPILER_FLAG([-Wwrite-strings])
CFLAGS="$CFLAGS $LIBBSD_COMPILER_FLAGS"
])
# Checks for libraries. # Checks for libraries.
AC_CHECK_LIB([testu01], [unif01_CreateExternGenBits], AC_CHECK_LIB([testu01], [unif01_CreateExternGenBits],
@@ -44,6 +101,27 @@ AC_SUBST([TESTU01_LIBS])
AM_CONDITIONAL([HAVE_LIBTESTU01], AM_CONDITIONAL([HAVE_LIBTESTU01],
[test "x$ac_cv_lib_testu01_unif01_CreateExternGenBits" = "xyes"]) [test "x$ac_cv_lib_testu01_unif01_CreateExternGenBits" = "xyes"])
saved_LIBS="$LIBS"
AC_SEARCH_LIBS([MD5Update], [md], [
AS_IF([test "x$ac_cv_search_MD5Update" != "xnone required"], [
MD5_LIBS="$MD5_LIBS $ac_cv_search_MD5Update"
need_transparent_libmd=yes
])
], [
AC_MSG_ERROR([cannot find required MD5 functions in libc or libmd])
])
AC_SEARCH_LIBS([SHA512Update], [md], [
AS_IF([test "x$ac_cv_search_SHA512Update" != "xnone required"], [
LIBBSD_LIBS="$LIBBSD_LIBS $ac_cv_search_SHA512Update"
])
], [
AC_MSG_ERROR([cannot find required SHA-2 functions in libc or libmd])
])
LIBS="$saved_LIBS"
AM_CONDITIONAL([NEED_TRANSPARENT_LIBMD],
[test "x$need_transparent_libmd" = "xyes"])
is_windows=no is_windows=no
AS_CASE([$host_os], AS_CASE([$host_os],
[*-gnu*], [ [*-gnu*], [
@@ -51,10 +129,9 @@ AS_CASE([$host_os],
saved_LIBS="$LIBS" saved_LIBS="$LIBS"
AC_SEARCH_LIBS([clock_gettime], [rt], [ AC_SEARCH_LIBS([clock_gettime], [rt], [
AS_IF([test "x$ac_cv_search_clock_gettime" != "xnone required"], [ AS_IF([test "x$ac_cv_search_clock_gettime" != "xnone required"], [
CLOCK_GETTIME_LIBS="$ac_cv_search_clock_gettime" LIBBSD_LIBS="$LIBBSD_LIBS $ac_cv_search_clock_gettime"
]) ])
]) ])
AC_SUBST([CLOCK_GETTIME_LIBS])
LIBS="$saved_LIBS" LIBS="$saved_LIBS"
], ],
[*-musl*], [ [*-musl*], [
@@ -68,7 +145,7 @@ AS_CASE([$host_os],
AM_CONDITIONAL([OS_WINDOWS], [test "x$is_windows" = "xyes"]) AM_CONDITIONAL([OS_WINDOWS], [test "x$is_windows" = "xyes"])
# Checks for header files. # Checks for header files.
AC_CHECK_HEADERS([sys/ndir.h sys/dir.h ndir.h dirent.h grp.h]) AC_CHECK_HEADERS([sys/ndir.h sys/dir.h ndir.h dirent.h pwd.h grp.h])
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE AC_C_INLINE
@@ -96,7 +173,7 @@ AC_CACHE_CHECK(
[[ [[
static int rc = 1; static int rc = 1;
static void init(int argc) { if (argc == 1) rc = 0; } static void init(int argc) { if (argc == 1) rc = 0; }
void (*init_func)(int argc) __attribute__((__section__(".init_array"))) = init; void (*init_func)(int argc) __attribute__((__section__(".init_array"), __used__)) = init;
int main() { return rc; } int main() { return rc; }
]] ]]
)], )],
@@ -162,8 +239,7 @@ AC_LINK_IFELSE(
[AC_DEFINE([HAVE___REGISTER_ATFORK], [1], [AC_DEFINE([HAVE___REGISTER_ATFORK], [1],
[Define to 1 if you have __register_atfork]) [Define to 1 if you have __register_atfork])
AC_MSG_RESULT([yes])], AC_MSG_RESULT([yes])],
[ARC4RANDOM_ATFORK_LIBS="-pthread" [LIBBSD_LIBS="$LIBBSD_LIBS -pthread"
AC_SUBST([ARC4RANDOM_ATFORK_LIBS])
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
]) ])
@@ -172,6 +248,9 @@ AC_CHECK_FUNCS([clearenv dirfd fopencookie __fpurge \
pstat_getproc sysconf]) pstat_getproc sysconf])
AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = "xtrue"]) AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = "xtrue"])
AC_SUBST([MD5_LIBS])
AC_SUBST([LIBBSD_LIBS])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
include/Makefile include/Makefile

View File

@@ -14,10 +14,12 @@ nobase_include_HEADERS = \
bsd/bsd.h \ bsd/bsd.h \
bsd/err.h \ bsd/err.h \
bsd/getopt.h \ bsd/getopt.h \
bsd/grp.h \
bsd/inttypes.h \ bsd/inttypes.h \
bsd/libutil.h \ bsd/libutil.h \
bsd/md5.h \ bsd/md5.h \
bsd/nlist.h \ bsd/nlist.h \
bsd/pwd.h \
bsd/readpassphrase.h \ bsd/readpassphrase.h \
bsd/stdio.h \ bsd/stdio.h \
bsd/stdlib.h \ bsd/stdlib.h \

51
include/bsd/grp.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* Copyright © 2021 Guillem Jover <guillem@hadrons.org>
*
* 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 not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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.
*/
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#if __has_include_next(<grp.h>)
#include_next <grp.h>
#endif
#else
#include <bsd/sys/cdefs.h>
#if __has_include(<grp.h>)
#include <grp.h>
#endif
#endif
#ifndef LIBBSD_GRP_H
#define LIBBSD_GRP_H
#define _GR_BUF_LEN (1024 + 200 * sizeof(char *))
__BEGIN_DECLS
int
gid_from_group(const char *, gid_t *);
const char *
group_from_gid(gid_t, int);
__END_DECLS
#endif

View File

@@ -1,58 +1,31 @@
/* $OpenBSD: md5.h,v 1.16 2004/06/22 01:57:30 jfb Exp $ */
/* /*
* This code implements the MD5 message-digest algorithm. * Copyright © 2021 Guillem Jover <guillem@hadrons.org>
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
* *
* Equivalent code is available from RSA Data Security, Inc. * Redistribution and use in source and binary forms, with or without
* This code has been tested against that, and is equivalent, * modification, are permitted provided that the following conditions
* except that you don't need to include two pages of legalese * are met:
* with every copy. * 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 not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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.
*/ */
#ifndef LIBBSD_MD5_H
#define LIBBSD_MD5_H
#include <stdint.h>
#define MD5_BLOCK_LENGTH 64
#define MD5_DIGEST_LENGTH 16
#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
typedef struct MD5Context {
uint32_t state[4]; /* state */
uint64_t count; /* number of bits, mod 2^64 */
uint8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */
} MD5_CTX;
#ifdef LIBBSD_OVERLAY #ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h> #include_next <md5.h>
#else #else
#include <bsd/sys/cdefs.h> #include <md5.h>
#endif #endif
#include <sys/types.h>
__BEGIN_DECLS
void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, const uint8_t *, size_t)
__attribute__((__bounded__(__string__,2,3)));
void MD5Pad(MD5_CTX *);
void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
__attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)));
void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH])
__attribute__((__bounded__(__minbytes__,1,4)))
__attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)));
char *MD5End(MD5_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
char *MD5File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
char *MD5FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
char *MD5Data(const uint8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,MD5_DIGEST_STRING_LENGTH)));
__END_DECLS
#endif /* LIBBSD_MD5_H */

51
include/bsd/pwd.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* Copyright © 2021 Guillem Jover <guillem@hadrons.org>
*
* 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 not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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.
*/
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#if __has_include_next(<pwd.h>)
#include_next <pwd.h>
#endif
#else
#include <bsd/sys/cdefs.h>
#if __has_include(<pwd.h>)
#include <pwd.h>
#endif
#endif
#ifndef LIBBSD_PWD_H
#define LIBBSD_PWD_H
#define _PW_BUF_LEN 1024 /* length of getpw*_r buffer */
__BEGIN_DECLS
int
uid_from_user(const char *, uid_t *);
const char *
user_from_uid(uid_t, int);
__END_DECLS
#endif

View File

@@ -51,11 +51,15 @@
#include <stdint.h> #include <stdint.h>
__BEGIN_DECLS __BEGIN_DECLS
#if !defined(__GLIBC__) || \
!__GLIBC_PREREQ(2, 36) || \
!defined(_DEFAULT_SOURCE)
uint32_t arc4random(void); uint32_t arc4random(void);
void arc4random_stir(void);
void arc4random_addrandom(unsigned char *dat, int datlen);
void arc4random_buf(void *_buf, size_t n); void arc4random_buf(void *_buf, size_t n);
uint32_t arc4random_uniform(uint32_t upper_bound); uint32_t arc4random_uniform(uint32_t upper_bound);
#endif
void arc4random_stir(void);
void arc4random_addrandom(unsigned char *dat, int datlen);
int dehumanize_number(const char *str, int64_t *size); int dehumanize_number(const char *str, int64_t *size);
@@ -72,9 +76,13 @@ int sradixsort(const unsigned char **base, int nmemb,
void *reallocf(void *ptr, size_t size); void *reallocf(void *ptr, size_t size);
#if !defined(__GLIBC__) || \ #if !defined(__GLIBC__) || \
(defined(__GLIBC__) && (!__GLIBC_PREREQ(2, 26) || !defined(_GNU_SOURCE))) !__GLIBC_PREREQ(2, 26) || \
(__GLIBC_PREREQ(2, 26) && !__GLIBC_PREREQ(2, 29) && !defined(_GNU_SOURCE)) || \
(__GLIBC_PREREQ(2, 29) && !defined(_DEFAULT_SOURCE))
void *reallocarray(void *ptr, size_t nmemb, size_t size); void *reallocarray(void *ptr, size_t nmemb, size_t size);
#endif #endif
void *recallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size);
void freezero(void *ptr, size_t size);
long long strtonum(const char *nptr, long long minval, long long maxval, long long strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr); const char **errstr);

View File

@@ -47,7 +47,8 @@ char *strnstr(const char *str, const char *find, size_t str_len);
void strmode(mode_t mode, char *str); void strmode(mode_t mode, char *str);
#if !defined(__GLIBC__) || \ #if !defined(__GLIBC__) || \
(defined(__GLIBC__) && (!__GLIBC_PREREQ(2, 25) || !defined(_GNU_SOURCE))) !__GLIBC_PREREQ(2, 25) || \
!defined(_DEFAULT_SOURCE)
void explicit_bzero(void *buf, size_t len); void explicit_bzero(void *buf, size_t len);
#endif #endif
__END_DECLS __END_DECLS

View File

@@ -187,10 +187,10 @@
# else # else
# ifndef __cplusplus # ifndef __cplusplus
# define __offsetof(type, field) \ # define __offsetof(type, field) \
((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field)) ((size_t)(uintptr_t)((const volatile void *)&((type *)0)->field))
# else # else
# define __offsetof(type, field) \ # define __offsetof(type, field) \
(__offsetof__ (reinterpret_cast <__size_t> \ (__offsetof__ (reinterpret_cast <size_t> \
(&reinterpret_cast <const volatile char &> \ (&reinterpret_cast <const volatile char &> \
(static_cast<type *> (0)->field)))) (static_cast<type *> (0)->field))))
# endif # endif
@@ -243,15 +243,15 @@
#endif #endif
#ifndef __DECONST #ifndef __DECONST
#define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var)) #define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
#endif #endif
#ifndef __DEVOLATILE #ifndef __DEVOLATILE
#define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var)) #define __DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var))
#endif #endif
#ifndef __DEQUALIFY #ifndef __DEQUALIFY
#define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var)) #define __DEQUALIFY(type, var) ((type)(uintptr_t)(const volatile void *)(var))
#endif #endif
#endif #endif

View File

@@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1991, 1993 * Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@@ -10,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@@ -80,17 +82,25 @@
* *
* For details on the use of these macros, see the queue(3) manual page. * For details on the use of these macros, see the queue(3) manual page.
* *
* Below is a summary of implemented functions where:
* + means the macro is available
* - means the macro is not available
* s means the macro is available but is slow (runs in O(n) time)
* *
* SLIST LIST STAILQ TAILQ * SLIST LIST STAILQ TAILQ
* _HEAD + + + + * _HEAD + + + +
* _CLASS_HEAD + + + +
* _HEAD_INITIALIZER + + + + * _HEAD_INITIALIZER + + + +
* _ENTRY + + + + * _ENTRY + + + +
* _CLASS_ENTRY + + + +
* _INIT + + + + * _INIT + + + +
* _EMPTY + + + + * _EMPTY + + + +
* _END + + + +
* _FIRST + + + + * _FIRST + + + +
* _NEXT + + + + * _NEXT + + + +
* _PREV - + - + * _PREV - + - +
* _LAST - - + + * _LAST - - + +
* _LAST_FAST - - - +
* _FOREACH + + + + * _FOREACH + + + +
* _FOREACH_FROM + + + + * _FOREACH_FROM + + + +
* _FOREACH_SAFE + + + + * _FOREACH_SAFE + + + +
@@ -103,14 +113,20 @@
* _INSERT_BEFORE - + - + * _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + + * _INSERT_AFTER + + + +
* _INSERT_TAIL - - + + * _INSERT_TAIL - - + +
* _CONCAT - - + + * _CONCAT s s + +
* _REMOVE_AFTER + - + - * _REMOVE_AFTER + - + -
* _REMOVE_HEAD + - + - * _REMOVE_HEAD + - + -
* _REMOVE + + + + * _REMOVE s + s +
* _SWAP + + + + * _SWAP + + + +
* *
*/ */
#ifdef QUEUE_MACRO_DEBUG #ifdef QUEUE_MACRO_DEBUG
#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
#define QUEUE_MACRO_DEBUG_TRACE
#define QUEUE_MACRO_DEBUG_TRASH
#endif
#ifdef QUEUE_MACRO_DEBUG_TRACE
/* Store the last 2 places the queue element or head was altered */ /* Store the last 2 places the queue element or head was altered */
struct qm_trace { struct qm_trace {
unsigned long lastline; unsigned long lastline;
@@ -120,9 +136,7 @@ struct qm_trace {
}; };
#define TRACEBUF struct qm_trace trace; #define TRACEBUF struct qm_trace trace;
#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } , #define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
#define QMD_TRACE_HEAD(head) do { \ #define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \ (head)->trace.prevline = (head)->trace.lastline; \
@@ -138,14 +152,31 @@ struct qm_trace {
(elem)->trace.lastfile = __FILE__; \ (elem)->trace.lastfile = __FILE__; \
} while (0) } while (0)
#else #else /* !QUEUE_MACRO_DEBUG_TRACE */
#define QMD_TRACE_ELEM(elem) #define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head) #define QMD_TRACE_HEAD(head)
#define QMD_SAVELINK(name, link)
#define TRACEBUF #define TRACEBUF
#define TRACEBUF_INITIALIZER #define TRACEBUF_INITIALIZER
#endif /* QUEUE_MACRO_DEBUG_TRACE */
#ifdef QUEUE_MACRO_DEBUG_TRASH
#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1)
#else /* !QUEUE_MACRO_DEBUG_TRASH */
#define QMD_SAVELINK(name, link)
#define TRASHIT(x) #define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */ #define QMD_IS_TRASHED(x) 0
#endif /* QUEUE_MACRO_DEBUG_TRASH */
#ifdef __cplusplus
/*
* In C++ there can be structure lists and class lists:
*/
#define QUEUE_TYPEOF(type) type
#else
#define QUEUE_TYPEOF(type) struct type
#endif
/* /*
* Singly-linked List declarations. * Singly-linked List declarations.
@@ -155,6 +186,11 @@ struct name { \
struct type *slh_first; /* first element */ \ struct type *slh_first; /* first element */ \
} }
#define SLIST_CLASS_HEAD(name, type) \
struct name { \
class type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \ #define SLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
@@ -163,9 +199,37 @@ struct { \
struct type *sle_next; /* next element */ \ struct type *sle_next; /* next element */ \
} }
#define SLIST_CLASS_ENTRY(type) \
struct { \
class type *sle_next; /* next element */ \
}
/* /*
* Singly-linked List functions. * Singly-linked List functions.
*/ */
#if (defined(_KERNEL) && defined(INVARIANTS))
#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \
if (*(prevp) != (elm)) \
panic("Bad prevptr *(%p) == %p != %p", \
(prevp), *(prevp), (elm)); \
} while (0)
#else
#define QMD_SLIST_CHECK_PREVPTR(prevp, elm)
#endif
#define SLIST_CONCAT(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
if (curelm == NULL) { \
if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \
SLIST_INIT(head2); \
} else if (SLIST_FIRST(head2) != NULL) { \
while (SLIST_NEXT(curelm, field) != NULL) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \
SLIST_INIT(head2); \
} \
} while (0)
#define SLIST_EMPTY(head) ((head)->slh_first == NULL) #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_FIRST(head) ((head)->slh_first)
@@ -217,7 +281,7 @@ struct { \
SLIST_REMOVE_HEAD((head), field); \ SLIST_REMOVE_HEAD((head), field); \
} \ } \
else { \ else { \
struct type *curelm = SLIST_FIRST((head)); \ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
while (SLIST_NEXT(curelm, field) != (elm)) \ while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \ curelm = SLIST_NEXT(curelm, field); \
SLIST_REMOVE_AFTER(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \
@@ -234,12 +298,20 @@ struct { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0) } while (0)
#define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \
QMD_SLIST_CHECK_PREVPTR(prevp, elm); \
*(prevp) = SLIST_NEXT(elm, field); \
TRASHIT((elm)->field.sle_next); \
} while (0)
#define SLIST_SWAP(head1, head2, type) do { \ #define SLIST_SWAP(head1, head2, type) do { \
struct type *swap_first = SLIST_FIRST(head1); \ QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \ SLIST_FIRST(head1) = SLIST_FIRST(head2); \
SLIST_FIRST(head2) = swap_first; \ SLIST_FIRST(head2) = swap_first; \
} while (0) } while (0)
#define SLIST_END(head) NULL
/* /*
* Singly-linked Tail queue declarations. * Singly-linked Tail queue declarations.
*/ */
@@ -249,6 +321,12 @@ struct name { \
struct type **stqh_last;/* addr of last next element */ \ struct type **stqh_last;/* addr of last next element */ \
} }
#define STAILQ_CLASS_HEAD(name, type) \
struct name { \
class type *stqh_first; /* first element */ \
class type **stqh_last; /* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \ #define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first } { NULL, &(head).stqh_first }
@@ -257,6 +335,11 @@ struct { \
struct type *stqe_next; /* next element */ \ struct type *stqe_next; /* next element */ \
} }
#define STAILQ_CLASS_ENTRY(type) \
struct { \
class type *stqe_next; /* next element */ \
}
/* /*
* Singly-linked Tail queue functions. * Singly-linked Tail queue functions.
*/ */
@@ -317,7 +400,8 @@ struct { \
#define STAILQ_LAST(head, type, field) \ #define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? NULL : \ (STAILQ_EMPTY((head)) ? NULL : \
__containerof((head)->stqh_last, struct type, field.stqe_next)) __containerof((head)->stqh_last, \
QUEUE_TYPEOF(type), field.stqe_next))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
@@ -327,7 +411,7 @@ struct { \
STAILQ_REMOVE_HEAD((head), field); \ STAILQ_REMOVE_HEAD((head), field); \
} \ } \
else { \ else { \
struct type *curelm = STAILQ_FIRST((head)); \ QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
while (STAILQ_NEXT(curelm, field) != (elm)) \ while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \ curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_AFTER(head, curelm, field); \ STAILQ_REMOVE_AFTER(head, curelm, field); \
@@ -348,8 +432,8 @@ struct { \
} while (0) } while (0)
#define STAILQ_SWAP(head1, head2, type) do { \ #define STAILQ_SWAP(head1, head2, type) do { \
struct type *swap_first = STAILQ_FIRST(head1); \ QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
struct type **swap_last = (head1)->stqh_last; \ QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
(head1)->stqh_last = (head2)->stqh_last; \ (head1)->stqh_last = (head2)->stqh_last; \
STAILQ_FIRST(head2) = swap_first; \ STAILQ_FIRST(head2) = swap_first; \
@@ -360,6 +444,8 @@ struct { \
(head2)->stqh_last = &STAILQ_FIRST(head2); \ (head2)->stqh_last = &STAILQ_FIRST(head2); \
} while (0) } while (0)
#define STAILQ_END(head) NULL
/* /*
* List declarations. * List declarations.
@@ -369,6 +455,11 @@ struct name { \
struct type *lh_first; /* first element */ \ struct type *lh_first; /* first element */ \
} }
#define LIST_CLASS_HEAD(name, type) \
struct name { \
class type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \ #define LIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
@@ -378,11 +469,23 @@ struct { \
struct type **le_prev; /* address of previous next element */ \ struct type **le_prev; /* address of previous next element */ \
} }
#define LIST_CLASS_ENTRY(type) \
struct { \
class type *le_next; /* next element */ \
class type **le_prev; /* address of previous next element */ \
}
/* /*
* List functions. * List functions.
*/ */
#if (defined(_KERNEL) && defined(INVARIANTS)) #if (defined(_KERNEL) && defined(INVARIANTS))
/*
* QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME)
*
* If the list is non-empty, validates that the first element of the list
* points back at 'head.'
*/
#define QMD_LIST_CHECK_HEAD(head, field) do { \ #define QMD_LIST_CHECK_HEAD(head, field) do { \
if (LIST_FIRST((head)) != NULL && \ if (LIST_FIRST((head)) != NULL && \
LIST_FIRST((head))->field.le_prev != \ LIST_FIRST((head))->field.le_prev != \
@@ -390,6 +493,12 @@ struct { \
panic("Bad list head %p first->prev != head", (head)); \ panic("Bad list head %p first->prev != head", (head)); \
} while (0) } while (0)
/*
* QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME)
*
* If an element follows 'elm' in the list, validates that the next element
* points back at 'elm.'
*/
#define QMD_LIST_CHECK_NEXT(elm, field) do { \ #define QMD_LIST_CHECK_NEXT(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL && \ if (LIST_NEXT((elm), field) != NULL && \
LIST_NEXT((elm), field)->field.le_prev != \ LIST_NEXT((elm), field)->field.le_prev != \
@@ -397,6 +506,11 @@ struct { \
panic("Bad link elm %p next->prev != elm", (elm)); \ panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0) } while (0)
/*
* QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME)
*
* Validates that the previous element (or head of the list) points to 'elm.'
*/
#define QMD_LIST_CHECK_PREV(elm, field) do { \ #define QMD_LIST_CHECK_PREV(elm, field) do { \
if (*(elm)->field.le_prev != (elm)) \ if (*(elm)->field.le_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \ panic("Bad link elm %p prev->next != elm", (elm)); \
@@ -407,6 +521,23 @@ struct { \
#define QMD_LIST_CHECK_PREV(elm, field) #define QMD_LIST_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */ #endif /* (_KERNEL && INVARIANTS) */
#define LIST_CONCAT(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \
if (curelm == NULL) { \
if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \
LIST_FIRST(head2)->field.le_prev = \
&LIST_FIRST((head1)); \
LIST_INIT(head2); \
} \
} else if (LIST_FIRST(head2) != NULL) { \
while (LIST_NEXT(curelm, field) != NULL) \
curelm = LIST_NEXT(curelm, field); \
LIST_NEXT(curelm, field) = LIST_FIRST(head2); \
LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \
LIST_INIT(head2); \
} \
} while (0)
#define LIST_EMPTY(head) ((head)->lh_first == NULL) #define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first) #define LIST_FIRST(head) ((head)->lh_first)
@@ -464,7 +595,8 @@ struct { \
#define LIST_PREV(elm, head, type, field) \ #define LIST_PREV(elm, head, type, field) \
((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
__containerof((elm)->field.le_prev, struct type, field.le_next)) __containerof((elm)->field.le_prev, \
QUEUE_TYPEOF(type), field.le_next))
#define LIST_REMOVE(elm, field) do { \ #define LIST_REMOVE(elm, field) do { \
QMD_SAVELINK(oldnext, (elm)->field.le_next); \ QMD_SAVELINK(oldnext, (elm)->field.le_next); \
@@ -480,7 +612,7 @@ struct { \
} while (0) } while (0)
#define LIST_SWAP(head1, head2, type, field) do { \ #define LIST_SWAP(head1, head2, type, field) do { \
struct type *swap_tmp = LIST_FIRST((head1)); \ QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
LIST_FIRST((head1)) = LIST_FIRST((head2)); \ LIST_FIRST((head1)) = LIST_FIRST((head2)); \
LIST_FIRST((head2)) = swap_tmp; \ LIST_FIRST((head2)) = swap_tmp; \
if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
@@ -489,6 +621,8 @@ struct { \
swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
} while (0) } while (0)
#define LIST_END(head) NULL
/* /*
* Tail queue declarations. * Tail queue declarations.
*/ */
@@ -499,6 +633,13 @@ struct name { \
TRACEBUF \ TRACEBUF \
} }
#define TAILQ_CLASS_HEAD(name, type) \
struct name { \
class type *tqh_first; /* first element */ \
class type **tqh_last; /* addr of last next element */ \
TRACEBUF \
}
#define TAILQ_HEAD_INITIALIZER(head) \ #define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
@@ -509,10 +650,23 @@ struct { \
TRACEBUF \ TRACEBUF \
} }
#define TAILQ_CLASS_ENTRY(type) \
struct { \
class type *tqe_next; /* next element */ \
class type **tqe_prev; /* address of previous next element */ \
TRACEBUF \
}
/* /*
* Tail queue functions. * Tail queue functions.
*/ */
#if (defined(_KERNEL) && defined(INVARIANTS)) #if (defined(_KERNEL) && defined(INVARIANTS))
/*
* QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
*
* If the tailq is non-empty, validates that the first element of the tailq
* points back at 'head.'
*/
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ #define QMD_TAILQ_CHECK_HEAD(head, field) do { \
if (!TAILQ_EMPTY(head) && \ if (!TAILQ_EMPTY(head) && \
TAILQ_FIRST((head))->field.tqe_prev != \ TAILQ_FIRST((head))->field.tqe_prev != \
@@ -520,11 +674,22 @@ struct { \
panic("Bad tailq head %p first->prev != head", (head)); \ panic("Bad tailq head %p first->prev != head", (head)); \
} while (0) } while (0)
/*
* QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
*
* Validates that the tail of the tailq is a pointer to pointer to NULL.
*/
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ #define QMD_TAILQ_CHECK_TAIL(head, field) do { \
if (*(head)->tqh_last != NULL) \ if (*(head)->tqh_last != NULL) \
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
} while (0) } while (0)
/*
* QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME)
*
* If an element follows 'elm' in the tailq, validates that the next element
* points back at 'elm.'
*/
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ #define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
if (TAILQ_NEXT((elm), field) != NULL && \ if (TAILQ_NEXT((elm), field) != NULL && \
TAILQ_NEXT((elm), field)->field.tqe_prev != \ TAILQ_NEXT((elm), field)->field.tqe_prev != \
@@ -532,6 +697,11 @@ struct { \
panic("Bad link elm %p next->prev != elm", (elm)); \ panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0) } while (0)
/*
* QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME)
*
* Validates that the previous element (or head of the tailq) points to 'elm.'
*/
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ #define QMD_TAILQ_CHECK_PREV(elm, field) do { \
if (*(elm)->field.tqe_prev != (elm)) \ if (*(elm)->field.tqe_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \ panic("Bad link elm %p prev->next != elm", (elm)); \
@@ -616,7 +786,7 @@ struct { \
TAILQ_NEXT((listelm), field) = (elm); \ TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
QMD_TRACE_ELEM(&(elm)->field); \ QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \ QMD_TRACE_ELEM(&(listelm)->field); \
} while (0) } while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
@@ -626,7 +796,7 @@ struct { \
*(listelm)->field.tqe_prev = (elm); \ *(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
QMD_TRACE_ELEM(&(elm)->field); \ QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \ QMD_TRACE_ELEM(&(listelm)->field); \
} while (0) } while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \ #define TAILQ_INSERT_HEAD(head, elm, field) do { \
@@ -655,11 +825,25 @@ struct { \
#define TAILQ_LAST(head, headname) \ #define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last)) (*(((struct headname *)((head)->tqh_last))->tqh_last))
/*
* The FAST function is fast in that it causes no data access other
* then the access to the head. The standard LAST function above
* will cause a data access of both the element you want and
* the previous element. FAST is very useful for instances when
* you may want to prefetch the last data element.
*/
#define TAILQ_LAST_FAST(head, type, field) \
(TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \ #define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_PREV_FAST(elm, head, type, field) \
((elm)->field.tqe_prev == &(head)->tqh_first ? NULL : \
__containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next))
#define TAILQ_REMOVE(head, elm, field) do { \ #define TAILQ_REMOVE(head, elm, field) do { \
QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
@@ -679,8 +863,8 @@ struct { \
} while (0) } while (0)
#define TAILQ_SWAP(head1, head2, type, field) do { \ #define TAILQ_SWAP(head1, head2, type, field) do { \
struct type *swap_first = (head1)->tqh_first; \ QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
struct type **swap_last = (head1)->tqh_last; \ QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
(head1)->tqh_first = (head2)->tqh_first; \ (head1)->tqh_first = (head2)->tqh_first; \
(head1)->tqh_last = (head2)->tqh_last; \ (head1)->tqh_last = (head2)->tqh_last; \
(head2)->tqh_first = swap_first; \ (head2)->tqh_first = swap_first; \
@@ -695,4 +879,6 @@ struct { \
(head2)->tqh_last = &(head2)->tqh_first; \ (head2)->tqh_last = &(head2)->tqh_first; \
} while (0) } while (0)
#define TAILQ_END(head) NULL
#endif /* !LIBBSD_SYS_QUEUE_H */ #endif /* !LIBBSD_SYS_QUEUE_H */

View File

@@ -99,8 +99,11 @@
* Provide both implementations and default for now on the historical one to * Provide both implementations and default for now on the historical one to
* avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so. * avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
* Define LIBBSD_NETBSD_VIS to switch to the NetBSD one now. * Define LIBBSD_NETBSD_VIS to switch to the NetBSD one now.
* Define LIBBSD_OPENBSD_VIS to keep using the OpenBSD one.
*/ */
#ifndef LIBBSD_NETBSD_VIS #if defined(LIBBSD_OPENBSD_VIS)
#undef LIBBSD_NETBSD_VIS
#elif !defined(LIBBSD_NETBSD_VIS)
#warning "NetBSD added incompatible strnvis() and strnunvis(), please see <bsd/vis.h> for more detils." #warning "NetBSD added incompatible strnvis() and strnunvis(), please see <bsd/vis.h> for more detils."
#endif #endif

2
m4/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.m4
!libbsd*.m4

24
m4/libbsd-compiler.m4 Normal file
View File

@@ -0,0 +1,24 @@
# Copyright © 2021 Guillem Jover <guillem@hadrons.org>
# LIBBSD_CHECK_COMPILER_FLAG
# -------------------------
AC_DEFUN([LIBBSD_CHECK_COMPILER_FLAG], [
AS_VAR_PUSHDEF([libbsd_varname_cache], [libbsd_cv_cflags_$1])
AC_CACHE_CHECK([whether $CC accepts $1], [libbsd_varname_cache], [
m4_define([libbsd_check_flag], m4_bpatsubst([$1], [^-Wno-], [-W]))
AS_VAR_COPY([libbsd_save_CFLAGS], [CFLAGS])
AS_VAR_SET([CFLAGS], ["-Werror libbsd_check_flag"])
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([[]])
], [
AS_VAR_SET([libbsd_varname_cache], [yes])
], [
AS_VAR_SET([libbsd_varname_cache], [no])
])
AS_VAR_COPY([CFLAGS], [libbsd_save_CFLAGS])
])
AS_VAR_IF([libbsd_varname_cache], [yes], [
AS_VAR_APPEND([LIBBSD_COMPILER_FLAGS], [" $1"])
])
AS_VAR_POPDEF([libbsd_varname_cache])
])

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

1
man/LIST_CLASS_HEAD.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -11,9 +11,11 @@ CLEANFILES = \
SED_MD5_SUBST = -e 's/mdX/md5/g' -e 's/mdY/md4/g' -e 's/MDX/MD5/g' SED_MD5_SUBST = -e 's/mdX/md5/g' -e 's/mdY/md4/g' -e 's/MDX/MD5/g'
md5.3bsd: $(srcdir)/mdX.3bsd md5.3bsd: $(srcdir)/mdX.3bsd
$(AM_V_GEN) sed $(SED_MD5_SUBST) $< > $@ $(AM_V_GEN) $(SED) $(SED_MD5_SUBST) $< > $@
dist_man_MANS = \ dist_man_MANS = \
LIST_CLASS_ENTRY.3bsd \
LIST_CLASS_HEAD.3bsd \
LIST_EMPTY.3bsd \ LIST_EMPTY.3bsd \
LIST_ENTRY.3bsd \ LIST_ENTRY.3bsd \
LIST_FIRST.3bsd \ LIST_FIRST.3bsd \
@@ -54,6 +56,8 @@ dist_man_MANS = \
RB_REMOVE.3bsd \ RB_REMOVE.3bsd \
RB_RIGHT.3bsd \ RB_RIGHT.3bsd \
RB_ROOT.3bsd \ RB_ROOT.3bsd \
SLIST_CLASS_ENTRY.3bsd \
SLIST_CLASS_HEAD.3bsd \
SLIST_EMPTY.3bsd \ SLIST_EMPTY.3bsd \
SLIST_ENTRY.3bsd \ SLIST_ENTRY.3bsd \
SLIST_FIRST.3bsd \ SLIST_FIRST.3bsd \
@@ -70,6 +74,7 @@ dist_man_MANS = \
SLIST_REMOVE.3bsd \ SLIST_REMOVE.3bsd \
SLIST_REMOVE_AFTER.3bsd \ SLIST_REMOVE_AFTER.3bsd \
SLIST_REMOVE_HEAD.3bsd \ SLIST_REMOVE_HEAD.3bsd \
SLIST_REMOVE_PREVPTR.3bsd \
SLIST_SWAP.3bsd \ SLIST_SWAP.3bsd \
SPLAY_EMPTY.3bsd \ SPLAY_EMPTY.3bsd \
SPLAY_ENTRY.3bsd \ SPLAY_ENTRY.3bsd \
@@ -88,6 +93,8 @@ dist_man_MANS = \
SPLAY_REMOVE.3bsd \ SPLAY_REMOVE.3bsd \
SPLAY_RIGHT.3bsd \ SPLAY_RIGHT.3bsd \
SPLAY_ROOT.3bsd \ SPLAY_ROOT.3bsd \
STAILQ_CLASS_ENTRY.3bsd \
STAILQ_CLASS_HEAD.3bsd \
STAILQ_CONCAT.3bsd \ STAILQ_CONCAT.3bsd \
STAILQ_EMPTY.3bsd \ STAILQ_EMPTY.3bsd \
STAILQ_ENTRY.3bsd \ STAILQ_ENTRY.3bsd \
@@ -108,6 +115,8 @@ dist_man_MANS = \
STAILQ_REMOVE_AFTER.3bsd \ STAILQ_REMOVE_AFTER.3bsd \
STAILQ_REMOVE_HEAD.3bsd \ STAILQ_REMOVE_HEAD.3bsd \
STAILQ_SWAP.3bsd \ STAILQ_SWAP.3bsd \
TAILQ_CLASS_ENTRY.3bsd \
TAILQ_CLASS_HEAD.3bsd \
TAILQ_CONCAT.3bsd \ TAILQ_CONCAT.3bsd \
TAILQ_EMPTY.3bsd \ TAILQ_EMPTY.3bsd \
TAILQ_ENTRY.3bsd \ TAILQ_ENTRY.3bsd \
@@ -165,6 +174,7 @@ dist_man_MANS = \
fgetln.3bsd \ fgetln.3bsd \
fgetwln.3bsd \ fgetwln.3bsd \
flopen.3bsd \ flopen.3bsd \
freezero.3bsd \
fmtcheck.3bsd \ fmtcheck.3bsd \
fparseln.3bsd \ fparseln.3bsd \
fpurge.3bsd \ fpurge.3bsd \
@@ -173,6 +183,8 @@ dist_man_MANS = \
getmode.3bsd \ getmode.3bsd \
getpeereid.3bsd \ getpeereid.3bsd \
getprogname.3bsd \ getprogname.3bsd \
gid_from_group.3bsd \
group_from_gid.3bsd \
heapsort.3bsd \ heapsort.3bsd \
humanize_number.3bsd \ humanize_number.3bsd \
le16dec.3bsd \ le16dec.3bsd \
@@ -190,11 +202,13 @@ dist_man_MANS = \
pidfile_open.3bsd \ pidfile_open.3bsd \
pidfile_remove.3bsd \ pidfile_remove.3bsd \
pidfile_write.3bsd \ pidfile_write.3bsd \
pwcache.3bsd \
queue.3bsd \ queue.3bsd \
radixsort.3bsd \ radixsort.3bsd \
readpassphrase.3bsd \ readpassphrase.3bsd \
reallocarray.3bsd \ reallocarray.3bsd \
reallocf.3bsd \ reallocf.3bsd \
recallocarray.3bsd \
setmode.3bsd \ setmode.3bsd \
setproctitle.3bsd \ setproctitle.3bsd \
setproctitle_init.3bsd \ setproctitle_init.3bsd \
@@ -223,6 +237,7 @@ dist_man_MANS = \
timercmp.3bsd \ timercmp.3bsd \
timerisset.3bsd \ timerisset.3bsd \
timersub.3bsd \ timersub.3bsd \
timespec.3bsd \
timespecadd.3bsd \ timespecadd.3bsd \
timespecclear.3bsd \ timespecclear.3bsd \
timespeccmp.3bsd \ timespeccmp.3bsd \
@@ -230,7 +245,9 @@ dist_man_MANS = \
timespecsub.3bsd \ timespecsub.3bsd \
timeval.3bsd \ timeval.3bsd \
tree.3bsd \ tree.3bsd \
uid_from_user.3bsd \
unvis.3bsd \ unvis.3bsd \
user_from_uid.3bsd \
vis.3bsd \ vis.3bsd \
wcslcat.3bsd \ wcslcat.3bsd \
wcslcpy.3bsd \ wcslcpy.3bsd \

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -0,0 +1 @@
.so man3/queue.3bsd

View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: arc4random.3,v 1.34 2014/07/19 16:11:16 naddy Exp $ .\" $OpenBSD: arc4random.3,v 1.37 2019/09/29 16:30:35 jmc Exp $
.\" .\"
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> .\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
.\" All rights reserved. .\" All rights reserved.
@@ -30,8 +30,8 @@
.\" .\"
.\" Manual page, using -mandoc macros .\" Manual page, using -mandoc macros
.\" .\"
.Dd $Mdocdate: July 19 2014 $ .Dd $Mdocdate: September 29 2019 $
.Dt ARC4RANDOM 3bsd .Dt arc4random 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm arc4random , .Nm arc4random ,
@@ -39,7 +39,7 @@
.Nm arc4random_uniform , .Nm arc4random_uniform ,
.Nm arc4random_stir , .Nm arc4random_stir ,
.Nm arc4random_addrandom .Nm arc4random_addrandom
.Nd arc4 random number generator .Nd random number generator
.Sh LIBRARY .Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) .ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd] .ds doc-str-Lb-libbsd \*[str-Lb-libbsd]

View File

@@ -31,7 +31,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 19, 1993 .Dd July 19, 1993
.Dt BITSTRING 3bsd .Dt bitstring 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm bit_alloc , .Nm bit_alloc ,
@@ -44,6 +44,10 @@
.Nm bitstr_size , .Nm bitstr_size ,
.Nm bit_test .Nm bit_test
.Nd bit-string manipulation macros .Nd bit-string manipulation macros
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
.Lb libbsd
.Sh SYNOPSIS .Sh SYNOPSIS
.In bitstring.h .In bitstring.h
(See (See

View File

@@ -25,12 +25,16 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 29, 2002 .Dd April 29, 2002
.Dt BYTEORDER 3bsd .Dt byteorder 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm be16enc , be16dec , be32enc , be32dec , be64enc , be64dec , .Nm be16enc , be16dec , be32enc , be32dec , be64enc , be64dec ,
.Nm le16enc , le16dec , le32enc , le32dec , le64enc , le64dec .Nm le16enc , le16dec , le32enc , le32dec , le64enc , le64dec
.Nd byte order operations .Nd byte order operations
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
.Lb libbsd
.Sh SYNOPSIS .Sh SYNOPSIS
.In sys/endian.h .In sys/endian.h
(See (See

View File

@@ -26,7 +26,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 12, 2009 .Dd June 12, 2009
.Dt CLOSEFROM 3bsd .Dt closefrom 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm closefrom .Nm closefrom

View File

@@ -28,7 +28,7 @@
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: April 23 2014 $ .Dd $Mdocdate: April 23 2014 $
.Dt ERRC 3bsd .Dt errc 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm errc , .Nm errc ,

View File

@@ -26,7 +26,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 15, 2010 .Dd August 15, 2010
.Dt EXPAND_NUMBER 3bsd .Dt expand_number 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm expand_number .Nm expand_number

View File

@@ -30,7 +30,7 @@
.\" $OpenBSD: bzero.3,v 1.10 2014/01/22 21:06:45 tedu Exp $ .\" $OpenBSD: bzero.3,v 1.10 2014/01/22 21:06:45 tedu Exp $
.\" .\"
.Dd $Mdocdate: January 22 2014 $ .Dd $Mdocdate: January 22 2014 $
.Dt EXPLICIT_BZERO 3bsd .Dt explicit_bzero 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm explicit_bzero .Nm explicit_bzero

View File

@@ -29,7 +29,7 @@
.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdio/fgetln.3,v 1.8 2004/07/16 06:07:12 tjr Exp $ .\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdio/fgetln.3,v 1.8 2004/07/16 06:07:12 tjr Exp $
.\" .\"
.Dd April 19, 1994 .Dd April 19, 1994
.Dt FGETLN 3bsd .Dt fgetln 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm fgetln .Nm fgetln

View File

@@ -29,7 +29,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 16, 2004 .Dd July 16, 2004
.Dt FGETWLN 3bsd .Dt fgetwln 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm fgetwln .Nm fgetwln

View File

@@ -26,7 +26,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 28, 2017 .Dd July 28, 2017
.Dt FLOPEN 3bsd .Dt flopen 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm flopen , .Nm flopen ,

View File

@@ -27,7 +27,7 @@
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd June 14, 2014 .Dd June 14, 2014
.Dt FMTCHECK 3bsd .Dt fmtcheck 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm fmtcheck .Nm fmtcheck

View File

@@ -23,7 +23,7 @@
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd November 30, 2002 .Dd November 30, 2002
.Dt FPARSELN 3bsd .Dt fparseln 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm fparseln .Nm fparseln

View File

@@ -32,7 +32,7 @@
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: November 4 2015 $ .Dd $Mdocdate: November 4 2015 $
.Dt FPURGE 3bsd .Dt fpurge 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm fpurge .Nm fpurge

1
man/freezero.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/reallocarray.3bsd

View File

@@ -31,7 +31,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 19, 2004 .Dd March 19, 2004
.Dt FUNOPEN 3bsd .Dt funopen 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm funopen , .Nm funopen ,

View File

@@ -29,7 +29,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd November 16, 2012 .Dd November 16, 2012
.Dt GETBSIZE 3bsd .Dt getbsize 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm getbsize .Nm getbsize

View File

@@ -26,7 +26,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 15, 2001 .Dd July 15, 2001
.Dt GETPEEREID 3bsd .Dt getpeereid 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm getpeereid .Nm getpeereid

View File

@@ -1,6 +1,4 @@
.\" .\" Copyright (c) 2022 Guillem Jover <guillem@hadrons.org>
.\" Copyright (c) 2001 Christopher G. Demetriou
.\" All rights reserved.
.\" .\"
.\" Redistribution and use in source and binary forms, with or without .\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions .\" modification, are permitted provided that the following conditions
@@ -10,34 +8,27 @@
.\" 2. Redistributions in binary form must reproduce the above copyright .\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the .\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution. .\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software .\" 3. The name of the author may not be used to endorse or promote products
.\" 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. .\" derived from this software without specific prior written permission.
.\" .
.\" THIS SOFTWARE IS PROVIDED ``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.
.\" .\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .Dd August 03, 2022
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .Dt getprogname 3bsd
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd May 1, 2001
.Dt GETPROGNAME 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm getprogname , .Nm getprogname ,
.Nm setprogname .Nm setprogname
.Nd get or set the program name .Nd get and set program name
.Sh LIBRARY .Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) .ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd] .ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
@@ -54,46 +45,39 @@ for include usage.)
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Fn getprogname .Fn getprogname
and returns a string with the current program name,
.Fn setprogname excluding any directory component.
functions manipulate the name of the current program. The function will return
They are used by error-reporting routines to produce .Dv NULL
consistent output. if it was unable to get the program name from any known source.
.Pp
The
.Fn getprogname
function returns the name of the program.
If the name has not been set yet, it will return
.Dv NULL .
.Pp .Pp
The The
.Fn setprogname .Fn setprogname
function sets the name of the program to be the last component of the function sets the current program name,
.Fa progname stripping any directory component prefix.
argument. The function will keep a reference to the passed string pointer,
Since a pointer to the given string is kept as the program name, so it must not be freed or modified while these functions might
it should not be modified for the rest of the program's lifetime. be called.
.Pp .Pp
In The implementations on most BSDs will try to initialize the program name
.Fx , at program startup time, and
the name of the program is set by the start-up code that is run before .Nm libbsd
.Fn main ; will try to infer it from various known sources depending on the
thus, target system.
running But it is not a portable assumption that the program name will be set
.Fn setprogname without calling
is not necessary. .Fn setprogname ,
Programs that desire maximum portability should still call it; so portable programs should always call it after starting up.
on another operating system,
these functions may be implemented in a portability library.
Calling
.Fn setprogname
allows the aforementioned library to learn the program name without
modifications to the start-up code.
.Sh SEE ALSO .Sh SEE ALSO
.Xr err 3 , .Xr setproctitle 3bsd .
.Xr setproctitle 3bsd
.Sh HISTORY .Sh HISTORY
These functions first appeared in The
.Fn setprogname
and
.Fn getprogname
functions first appeared in
.Nx 1.6 , .Nx 1.6 ,
and made their way into .Fx 4.4 ,
.Fx 4.4 . .Dx 2.1
and
.Ox 5.4 .

1
man/gid_from_group.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/pwcache.3bsd

1
man/group_from_gid.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/pwcache.3bsd

View File

@@ -33,7 +33,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 30, 2003 .Dd September 30, 2003
.Dt HEAPSORT 3bsd .Dt heapsort 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm heapsort , mergesort .Nm heapsort , mergesort

View File

@@ -28,7 +28,7 @@
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd February 9, 2008 .Dd February 9, 2008
.Dt HUMANIZE_NUMBER 3bsd .Dt humanize_number 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm dehumanize_number , .Nm dehumanize_number ,

View File

@@ -1,6 +1,6 @@
.\" libbsd man page .\" libbsd man page
.\" .\"
.\" Copyright © 2017-2018 Guillem Jover <guillem@hadrons.org> .\" Copyright © 2017-2022 Guillem Jover <guillem@hadrons.org>
.\" .\"
.\" Redistribution and use in source and binary forms, with or without .\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions .\" modification, are permitted provided that the following conditions
@@ -24,8 +24,8 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd May 21, 2018 .Dd August 3, 2022
.Dt LIBBSD 7 .Dt libbsd 7
.Os .Os
.Sh NAME .Sh NAME
.Nm libbsd .Nm libbsd
@@ -42,7 +42,7 @@ The library can be used in an overlay mode, which is the preferred way, so
that the code is portable and requires no modification to the original BSD that the code is portable and requires no modification to the original BSD
code. code.
This can be done easily with the This can be done easily with the
.Xr pkg-config 3 .Xr pkgconf 1
library named library named
.Pa libbsd-overlay . .Pa libbsd-overlay .
Or by adding the system-specific include directory with the Or by adding the system-specific include directory with the
@@ -59,12 +59,12 @@ The includes in this case should be the usual system ones, such as
.In unistd.h . .In unistd.h .
.Pp .Pp
The other way to use the library is to use the namespaced headers, The other way to use the library is to use the namespaced headers,
this is less portable as it makes using which is a discouraged way, being less portable as it makes using
.Nm libbsd .Nm libbsd
mandatory and it will not work on BSD-based systems, and requires mandatory and it will not work on BSD-based systems, and requires
modifying original BSD code. modifying original BSD code.
This can be done with the This can be done with the
.Xr pkg-config 3 .Xr pkgconf 1
library named library named
.Pa libbsd . .Pa libbsd .
The includes in this case should be namespaced with The includes in this case should be namespaced with
@@ -73,13 +73,13 @@ such as
.In bsd/unistd.h . .In bsd/unistd.h .
.Pp .Pp
The package also provides a The package also provides a
.Pa bsd-ctor .Nm libbsd-ctor
static library that can be used to inject automatic constructors into a static library that can be used to inject automatic constructors into a
program so that the program so that the
.Fn setproctitle_init 3 .Fn setproctitle_init 3
function gets invoked automatically at startup time. function gets invoked automatically at startup time.
This can be done with the This can be done with the
.Xr pkg-config 3 .Xr pkgconf 1
library named library named
.Pa libbsd-ctor . .Pa libbsd-ctor .
.Sh HEADERS .Sh HEADERS
@@ -94,11 +94,13 @@ be prefixed with
.It In bitstring.h .It In bitstring.h
.It In err.h .It In err.h
.It In getopt.h .It In getopt.h
.It In grp.h
.It In inttypes.h .It In inttypes.h
.It In libutil.h .It In libutil.h
.It In md5.h .It In md5.h
.It In netinet/ip_icmp.h .It In netinet/ip_icmp.h
.It In nlist.h .It In nlist.h
.It In pwd.h
.It In readpassphrase.h .It In readpassphrase.h
.It In stdio.h .It In stdio.h
.It In stdlib.h .It In stdlib.h
@@ -107,6 +109,7 @@ be prefixed with
.It In sys/bitstring.h .It In sys/bitstring.h
.It In sys/cdefs.h .It In sys/cdefs.h
.It In sys/endian.h .It In sys/endian.h
.It In sys/param.h
.It In sys/poll.h .It In sys/poll.h
.It In sys/queue.h .It In sys/queue.h
.It In sys/time.h .It In sys/time.h
@@ -125,6 +128,47 @@ It only works in non-overlay mode.
.Bl -tag -width 4m -compact .Bl -tag -width 4m -compact
.It In bsd/bsd.h .It In bsd/bsd.h
.El .El
.Sh ALTERNATIVES
Some functions have different prototypes depending on the BSD where they
originated from, and these various implementations provided are selectable
at build-time.
.Pp
This is the list of functions that provide multiple implementations:
.Pp
.Bl -tag -width 4m -compact
.It Fn strnvis 3
.It Fn strnunvis 3
.Nx
added
.Fn strnvis 3
and
.Fn strnunvis 3
but unfortunately made it incompatible with the existing one in
.Ox
and Freedesktop's libbsd (the former having existed for over ten years).
Despite this incompatibility being reported during development (see
http://gnats.netbsd.org/44977) they still shipped it.
Even more unfortunately
.Fx
and later MacOS picked up this incompatible implementation.
.Pp
Provide both implementations and default for now to the historical one to
avoid breakage, but we will switch to the
.Nx
one in a later release, which is internally consistent with the other
.Xr vis 3
functions and is now more widespread.
Define
.Dv LIBBSD_NETBSD_VIS
to switch to the
.Nx
one now.
Define
.Dv LIBBSD_OPENBSD_VIS
to keep using the
.Ox
one.
.El
.Sh DEPRECATED .Sh DEPRECATED
Some functions have been deprecated, they will emit warnings at compile time Some functions have been deprecated, they will emit warnings at compile time
and possibly while being linked at run-time. and possibly while being linked at run-time.
@@ -180,17 +224,33 @@ for example.
.It Fn MD5File 3 .It Fn MD5File 3
.It Fn MD5FileChunk 3 .It Fn MD5FileChunk 3
.It Fn MD5Data 3 .It Fn MD5Data 3
The set of MD5 digest functions are now provided by the The set of MD5 digest functions are now proxies for the implementations
provided by the
.Nm libmd .Nm libmd
companion library, so it is advised to use that instead. companion library, so it is advised to switch to use that directly instead.
.It Fn explicit_bzero 3 .It Fn explicit_bzero 3
This function is provided by This function is provided by
.Nm glibc .Nm glibc
2.25. 2.25, and
.Nm musl
1.1.20.
.It Fn reallocarray 3 .It Fn reallocarray 3
This function is provided by This function is provided by
.Nm glibc .Nm glibc
2.26. 2.26, and
.Nm musl
1.2.2.
.It Fn arc4random 3
.It Fn arc4random_buf 3
.It Fn arc4random_uniform 3
These functions are provided by
.Nm glibc
2.36.
Note that it does not provide the
.Fn arc4random_stir 3
and
.Fn arc4random_addrandom 3
functions.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr arc4random 3bsd , .Xr arc4random 3bsd ,
@@ -215,6 +275,7 @@ This function is provided by
.Xr md5 3bsd , .Xr md5 3bsd ,
.Xr nlist 3bsd , .Xr nlist 3bsd ,
.Xr pidfile 3bsd , .Xr pidfile 3bsd ,
.Xr pwcache 3bsd ,
.Xr queue 3bsd , .Xr queue 3bsd ,
.Xr radixsort 3bsd , .Xr radixsort 3bsd ,
.Xr readpassphrase 3bsd , .Xr readpassphrase 3bsd ,

View File

@@ -29,7 +29,7 @@
.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/nlist.3,v 1.7 2001/10/01 16:08:51 ru Exp $ .\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/nlist.3,v 1.7 2001/10/01 16:08:51 ru Exp $
.\" .\"
.Dd April 19, 1994 .Dd April 19, 1994
.Dt NLIST 3bsd .Dt nlist 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm nlist .Nm nlist

View File

@@ -25,7 +25,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd February 8, 2012 .Dd February 8, 2012
.Dt PIDFILE 3bsd .Dt pidfile 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm pidfile_open , .Nm pidfile_open ,

143
man/pwcache.3bsd Normal file
View File

@@ -0,0 +1,143 @@
.\" $OpenBSD: pwcache.3,v 1.15 2018/09/13 16:50:54 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.
.\"
.Dd $Mdocdate: September 13 2018 $
.Dt user_from_uid 3
.Os
.Sh NAME
.Nm user_from_uid ,
.Nm uid_from_user ,
.Nm group_from_gid ,
.Nm gid_from_group
.Nd cache password and group entries
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
.Lb libbsd
.Sh SYNOPSIS
.In pwd.h
(See
.Xr libbsd 7
for include usage.)
.Ft int
.Fn uid_from_user "const char *name" "uid_t *uid"
.Ft const char *
.Fn user_from_uid "uid_t uid" "int nouser"
.In grp.h
.Ft int
.Fn gid_from_group "const char *name" "gid_t *gid"
.Ft const char *
.Fn group_from_gid "gid_t gid" "int nogroup"
.Sh DESCRIPTION
The
.Fn user_from_uid
function returns the user name associated with the argument
.Fa uid .
The user name is cached so that multiple calls with the same
.Fa uid
do not require additional calls to
.Xr getpwuid 3 .
If there is no user associated with the
.Fa uid ,
a pointer is returned
to a string representation of the
.Fa uid ,
unless the argument
.Fa nouser
is non-zero, in which case a null pointer is returned.
.Pp
The
.Fn uid_from_user
function returns the user ID associated with the argument
.Fa name .
The user ID is cached so that multiple calls with the same
.Fa name
do not require additional calls to
.Xr getpwnam 3 .
If there is no user ID associated with the
.Fa name ,
the
.Fn uid_from_user
function returns -1;
otherwise it stores the user ID at the location pointed to by
.Fa uid
and returns 0.
.Pp
The
.Fn group_from_gid
function returns the group name associated with the argument
.Fa gid .
The group name is cached so that multiple calls with the same
.Fa gid
do not require additional calls to
.Xr getgrgid 3 .
If there is no group associated with the
.Fa gid ,
a pointer is returned
to a string representation of the
.Fa gid ,
unless the argument
.Fa nogroup
is non-zero, in which case a null pointer is returned.
.Pp
The
.Fn gid_from_group
function returns the group ID associated with the argument
.Fa name .
The group ID is cached so that multiple calls with the same
.Fa name
do not require additional calls to
.Xr getgrnam 3 .
If there is no group ID associated with the
.Fa name ,
the
.Fn gid_from_group
function returns -1;
otherwise it stores the group ID at the location pointed to by
.Fa gid
and returns 0.
.Sh SEE ALSO
.Xr getgrgid 3 ,
.Xr getpwuid 3
.Sh HISTORY
The
.Fn user_from_uid
and
.Fn group_from_gid
functions first appeared in
.Bx 4.4 .
.Pp
The
.Fn uid_from_user
and
.Fn gid_from_group
functions were ported from
.Nx
and first appeared in
.Ox 6.4 .

View File

@@ -28,35 +28,40 @@
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94 .\" @(#)queue.3 8.2 (Berkeley) 1/24/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 17, 2013 .Dd September 8, 2016
.Dt QUEUE 3bsd .Dt queue 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm SLIST_CLASS_ENTRY ,
.Nm SLIST_CLASS_HEAD ,
.Nm SLIST_CONCAT ,
.Nm SLIST_EMPTY , .Nm SLIST_EMPTY ,
.Nm SLIST_ENTRY , .Nm SLIST_ENTRY ,
.Nm SLIST_FIRST , .Nm SLIST_FIRST ,
.Nm SLIST_FOREACH , .Nm SLIST_FOREACH ,
.Nm SLIST_FOREACH_FROM , .Nm SLIST_FOREACH_FROM ,
.Nm SLIST_FOREACH_SAFE ,
.Nm SLIST_FOREACH_FROM_SAFE , .Nm SLIST_FOREACH_FROM_SAFE ,
.Nm SLIST_FOREACH_SAFE ,
.Nm SLIST_HEAD , .Nm SLIST_HEAD ,
.Nm SLIST_HEAD_INITIALIZER , .Nm SLIST_HEAD_INITIALIZER ,
.Nm SLIST_INIT , .Nm SLIST_INIT ,
.Nm SLIST_INSERT_AFTER , .Nm SLIST_INSERT_AFTER ,
.Nm SLIST_INSERT_HEAD , .Nm SLIST_INSERT_HEAD ,
.Nm SLIST_NEXT , .Nm SLIST_NEXT ,
.Nm SLIST_REMOVE ,
.Nm SLIST_REMOVE_AFTER , .Nm SLIST_REMOVE_AFTER ,
.Nm SLIST_REMOVE_HEAD , .Nm SLIST_REMOVE_HEAD ,
.Nm SLIST_REMOVE ,
.Nm SLIST_SWAP , .Nm SLIST_SWAP ,
.Nm STAILQ_CLASS_ENTRY ,
.Nm STAILQ_CLASS_HEAD ,
.Nm STAILQ_CONCAT , .Nm STAILQ_CONCAT ,
.Nm STAILQ_EMPTY , .Nm STAILQ_EMPTY ,
.Nm STAILQ_ENTRY , .Nm STAILQ_ENTRY ,
.Nm STAILQ_FIRST , .Nm STAILQ_FIRST ,
.Nm STAILQ_FOREACH , .Nm STAILQ_FOREACH ,
.Nm STAILQ_FOREACH_FROM , .Nm STAILQ_FOREACH_FROM ,
.Nm STAILQ_FOREACH_SAFE ,
.Nm STAILQ_FOREACH_FROM_SAFE , .Nm STAILQ_FOREACH_FROM_SAFE ,
.Nm STAILQ_FOREACH_SAFE ,
.Nm STAILQ_HEAD , .Nm STAILQ_HEAD ,
.Nm STAILQ_HEAD_INITIALIZER , .Nm STAILQ_HEAD_INITIALIZER ,
.Nm STAILQ_INIT , .Nm STAILQ_INIT ,
@@ -65,17 +70,20 @@
.Nm STAILQ_INSERT_TAIL , .Nm STAILQ_INSERT_TAIL ,
.Nm STAILQ_LAST , .Nm STAILQ_LAST ,
.Nm STAILQ_NEXT , .Nm STAILQ_NEXT ,
.Nm STAILQ_REMOVE ,
.Nm STAILQ_REMOVE_AFTER , .Nm STAILQ_REMOVE_AFTER ,
.Nm STAILQ_REMOVE_HEAD , .Nm STAILQ_REMOVE_HEAD ,
.Nm STAILQ_REMOVE ,
.Nm STAILQ_SWAP , .Nm STAILQ_SWAP ,
.Nm LIST_CLASS_ENTRY ,
.Nm LIST_CLASS_HEAD ,
.Nm LIST_CONCAT ,
.Nm LIST_EMPTY , .Nm LIST_EMPTY ,
.Nm LIST_ENTRY , .Nm LIST_ENTRY ,
.Nm LIST_FIRST , .Nm LIST_FIRST ,
.Nm LIST_FOREACH , .Nm LIST_FOREACH ,
.Nm LIST_FOREACH_FROM , .Nm LIST_FOREACH_FROM ,
.Nm LIST_FOREACH_SAFE ,
.Nm LIST_FOREACH_FROM_SAFE , .Nm LIST_FOREACH_FROM_SAFE ,
.Nm LIST_FOREACH_SAFE ,
.Nm LIST_HEAD , .Nm LIST_HEAD ,
.Nm LIST_HEAD_INITIALIZER , .Nm LIST_HEAD_INITIALIZER ,
.Nm LIST_INIT , .Nm LIST_INIT ,
@@ -86,18 +94,20 @@
.Nm LIST_PREV , .Nm LIST_PREV ,
.Nm LIST_REMOVE , .Nm LIST_REMOVE ,
.Nm LIST_SWAP , .Nm LIST_SWAP ,
.Nm TAILQ_CLASS_ENTRY ,
.Nm TAILQ_CLASS_HEAD ,
.Nm TAILQ_CONCAT , .Nm TAILQ_CONCAT ,
.Nm TAILQ_EMPTY , .Nm TAILQ_EMPTY ,
.Nm TAILQ_ENTRY , .Nm TAILQ_ENTRY ,
.Nm TAILQ_FIRST , .Nm TAILQ_FIRST ,
.Nm TAILQ_FOREACH , .Nm TAILQ_FOREACH ,
.Nm TAILQ_FOREACH_FROM , .Nm TAILQ_FOREACH_FROM ,
.Nm TAILQ_FOREACH_SAFE ,
.Nm TAILQ_FOREACH_FROM_SAFE , .Nm TAILQ_FOREACH_FROM_SAFE ,
.Nm TAILQ_FOREACH_REVERSE , .Nm TAILQ_FOREACH_REVERSE ,
.Nm TAILQ_FOREACH_REVERSE_FROM , .Nm TAILQ_FOREACH_REVERSE_FROM ,
.Nm TAILQ_FOREACH_REVERSE_SAFE ,
.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE , .Nm TAILQ_FOREACH_REVERSE_FROM_SAFE ,
.Nm TAILQ_FOREACH_REVERSE_SAFE ,
.Nm TAILQ_FOREACH_SAFE ,
.Nm TAILQ_HEAD , .Nm TAILQ_HEAD ,
.Nm TAILQ_HEAD_INITIALIZER , .Nm TAILQ_HEAD_INITIALIZER ,
.Nm TAILQ_INIT , .Nm TAILQ_INIT ,
@@ -112,58 +122,70 @@
.Nm TAILQ_SWAP .Nm TAILQ_SWAP
.Nd implementations of singly-linked lists, singly-linked tail queues, .Nd implementations of singly-linked lists, singly-linked tail queues,
lists and tail queues lists and tail queues
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
.Lb libbsd
.Sh SYNOPSIS .Sh SYNOPSIS
.In sys/queue.h .In sys/queue.h
(See (See
.Xr libbsd 7 .Xr libbsd 7
for include usage.) for include usage.)
.\" .\"
.Fn SLIST_CLASS_ENTRY "CLASSTYPE"
.Fn SLIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn SLIST_CONCAT "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" "SLIST_ENTRY NAME"
.Fn SLIST_EMPTY "SLIST_HEAD *head" .Fn SLIST_EMPTY "SLIST_HEAD *head"
.Fn SLIST_ENTRY "TYPE" .Fn SLIST_ENTRY "TYPE"
.Fn SLIST_FIRST "SLIST_HEAD *head" .Fn SLIST_FIRST "SLIST_HEAD *head"
.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" .Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
.Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" .Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
.Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var" .Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
.Fn SLIST_HEAD "HEADNAME" "TYPE" .Fn SLIST_HEAD "HEADNAME" "TYPE"
.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head" .Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
.Fn SLIST_INIT "SLIST_HEAD *head" .Fn SLIST_INIT "SLIST_HEAD *head"
.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME" .Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME" .Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME" .Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME" .Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME" .Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME" .Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE"
.Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "SLIST_ENTRY NAME"
.\" .\"
.Fn STAILQ_CLASS_ENTRY "CLASSTYPE"
.Fn STAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" .Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
.Fn STAILQ_EMPTY "STAILQ_HEAD *head" .Fn STAILQ_EMPTY "STAILQ_HEAD *head"
.Fn STAILQ_ENTRY "TYPE" .Fn STAILQ_ENTRY "TYPE"
.Fn STAILQ_FIRST "STAILQ_HEAD *head" .Fn STAILQ_FIRST "STAILQ_HEAD *head"
.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" .Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
.Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" .Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var" .Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn STAILQ_HEAD "HEADNAME" "TYPE" .Fn STAILQ_HEAD "HEADNAME" "TYPE"
.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head" .Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
.Fn STAILQ_INIT "STAILQ_HEAD *head" .Fn STAILQ_INIT "STAILQ_HEAD *head"
.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME" .Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" .Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" .Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE" "STAILQ_ENTRY NAME" .Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME" .Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" .Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" .Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME" .Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "TYPE"
.Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "STAILQ_ENTRY NAME"
.\" .\"
.Fn LIST_CLASS_ENTRY "CLASSTYPE"
.Fn LIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn LIST_CONCAT "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
.Fn LIST_EMPTY "LIST_HEAD *head" .Fn LIST_EMPTY "LIST_HEAD *head"
.Fn LIST_ENTRY "TYPE" .Fn LIST_ENTRY "TYPE"
.Fn LIST_FIRST "LIST_HEAD *head" .Fn LIST_FIRST "LIST_HEAD *head"
.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" .Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
.Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" .Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
.Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var" .Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
.Fn LIST_HEAD "HEADNAME" "TYPE" .Fn LIST_HEAD "HEADNAME" "TYPE"
.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head" .Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
.Fn LIST_INIT "LIST_HEAD *head" .Fn LIST_INIT "LIST_HEAD *head"
@@ -175,18 +197,20 @@ for include usage.)
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" .Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME" .Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
.\" .\"
.Fn TAILQ_CLASS_ENTRY "CLASSTYPE"
.Fn TAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME" .Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
.Fn TAILQ_EMPTY "TAILQ_HEAD *head" .Fn TAILQ_EMPTY "TAILQ_HEAD *head"
.Fn TAILQ_ENTRY "TYPE" .Fn TAILQ_ENTRY "TYPE"
.Fn TAILQ_FIRST "TAILQ_HEAD *head" .Fn TAILQ_FIRST "TAILQ_HEAD *head"
.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" .Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
.Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" .Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var" .Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" .Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
.Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" .Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var" .Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
.Fn TAILQ_HEAD "HEADNAME" "TYPE" .Fn TAILQ_HEAD "HEADNAME" "TYPE"
.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head" .Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
.Fn TAILQ_INIT "TAILQ_HEAD *head" .Fn TAILQ_INIT "TAILQ_HEAD *head"
@@ -201,8 +225,18 @@ for include usage.)
.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME" .Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
.\" .\"
.Sh DESCRIPTION .Sh DESCRIPTION
These macros define and operate on four types of data structures: These macros define and operate on four types of data structures which
singly-linked lists, singly-linked tail queues, lists, and tail queues. can be used in both C and C++ source code:
.Bl -enum -compact -offset indent
.It
Lists
.It
Singly-linked lists
.It
Singly-linked tail queues
.It
Tail queues
.El
All four structures support the following functionality: All four structures support the following functionality:
.Bl -enum -compact -offset indent .Bl -enum -compact -offset indent
.It .It
@@ -226,6 +260,8 @@ Singly-linked lists add the following functionality:
.Bl -enum -compact -offset indent .Bl -enum -compact -offset indent
.It .It
O(n) removal of any entry in the list. O(n) removal of any entry in the list.
.It
O(n) concatenation of two lists.
.El .El
.Pp .Pp
Singly-linked tail queues add the following functionality: Singly-linked tail queues add the following functionality:
@@ -273,6 +309,8 @@ Linked lists are the simplest of the doubly linked data structures.
They add the following functionality over the above: They add the following functionality over the above:
.Bl -enum -compact -offset indent .Bl -enum -compact -offset indent
.It .It
O(n) concatenation of two lists.
.It
They may be traversed backwards. They may be traversed backwards.
.El .El
However: However:
@@ -304,24 +342,39 @@ than singly-linked lists.
.Pp .Pp
In the macro definitions, In the macro definitions,
.Fa TYPE .Fa TYPE
is the name of a user defined structure, is the name of a user defined structure.
that must contain a field of type The structure must contain a field called
.Fa NAME
which is of type
.Li SLIST_ENTRY , .Li SLIST_ENTRY ,
.Li STAILQ_ENTRY , .Li STAILQ_ENTRY ,
.Li LIST_ENTRY , .Li LIST_ENTRY ,
or or
.Li TAILQ_ENTRY , .Li TAILQ_ENTRY .
named In the macro definitions,
.Fa NAME . .Fa CLASSTYPE
is the name of a user defined class.
The class must contain a field called
.Fa NAME
which is of type
.Li SLIST_CLASS_ENTRY ,
.Li STAILQ_CLASS_ENTRY ,
.Li LIST_CLASS_ENTRY ,
or
.Li TAILQ_CLASS_ENTRY .
The argument The argument
.Fa HEADNAME .Fa HEADNAME
is the name of a user defined structure that must be declared is the name of a user defined structure that must be declared
using the macros using the macros
.Li SLIST_HEAD , .Li SLIST_HEAD ,
.Li SLIST_CLASS_HEAD ,
.Li STAILQ_HEAD , .Li STAILQ_HEAD ,
.Li STAILQ_CLASS_HEAD ,
.Li LIST_HEAD , .Li LIST_HEAD ,
.Li LIST_CLASS_HEAD ,
.Li TAILQ_HEAD ,
or or
.Li TAILQ_HEAD . .Li TAILQ_CLASS_HEAD .
See the examples below for further explanation of how these See the examples below for further explanation of how these
macros are used. macros are used.
.Sh SINGLY-LINKED LISTS .Sh SINGLY-LINKED LISTS
@@ -363,6 +416,19 @@ evaluates to an initializer for the list
.Fa head . .Fa head .
.Pp .Pp
The macro The macro
.Nm SLIST_CONCAT
concatenates the list headed by
.Fa head2
onto the end of the one headed by
.Fa head1
removing all entries from the former.
Use of this macro should be avoided as it traverses the entirety of the
.Fa head1
list.
A singly-linked tail queue should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp
The macro
.Nm SLIST_EMPTY .Nm SLIST_EMPTY
evaluates to true if there are no elements in the list. evaluates to true if there are no elements in the list.
.Pp .Pp
@@ -470,6 +536,9 @@ The macro
removes the element removes the element
.Fa elm .Fa elm
from the list. from the list.
Use of this macro should be avoided as it traverses the entire list.
A doubly-linked list should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp .Pp
The macro The macro
.Nm SLIST_SWAP .Nm SLIST_SWAP
@@ -686,6 +755,9 @@ The macro
removes the element removes the element
.Fa elm .Fa elm
from the tail queue. from the tail queue.
Use of this macro should be avoided as it traverses the entire list.
A doubly-linked tail queue should be used if this macro is needed in
high-usage code paths or to operate on long tail queues.
.Pp .Pp
The macro The macro
.Nm STAILQ_SWAP .Nm STAILQ_SWAP
@@ -785,6 +857,19 @@ evaluates to an initializer for the list
.Fa head . .Fa head .
.Pp .Pp
The macro The macro
.Nm LIST_CONCAT
concatenates the list headed by
.Fa head2
onto the end of the one headed by
.Fa head1
removing all entries from the former.
Use of this macro should be avoided as it traverses the entirety of the
.Fa head1
list.
A tail queue should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp
The macro
.Nm LIST_EMPTY .Nm LIST_EMPTY
evaluates to true if there are no elements in the list. evaluates to true if there are no elements in the list.
.Pp .Pp
@@ -1206,6 +1291,26 @@ while (n1 != NULL) {
} }
TAILQ_INIT(&head); TAILQ_INIT(&head);
.Ed .Ed
.Sh DIAGNOSTICS
When debugging
.Nm queue(3) ,
it can be useful to trace queue changes.
To enable tracing, define the macro
.Va QUEUE_MACRO_DEBUG_TRACE
at compile time.
.Pp
It can also be useful to trash pointers that have been unlinked from a queue,
to detect use after removal.
To enable pointer trashing, define the macro
.Va QUEUE_MACRO_DEBUG_TRASH
at compile time.
The macro
.Fn QMD_IS_TRASHED "void *ptr"
returns true if
.Fa ptr
has been trashed by the
.Va QUEUE_MACRO_DEBUG_TRASH
option.
.Sh SEE ALSO .Sh SEE ALSO
.Xr tree 3bsd .Xr tree 3bsd
.Sh HISTORY .Sh HISTORY

View File

@@ -30,7 +30,7 @@
.\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94 .\" from: @(#)radixsort.3 8.2 (Berkeley) 1/27/94
.\" .\"
.Dd January 27, 1994 .Dd January 27, 1994
.Dt RADIXSORT 3bsd .Dt radixsort 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm radixsort , .Nm radixsort ,

View File

@@ -19,7 +19,7 @@
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\" .\"
.Dd $Mdocdate: March 6 2014 $ .Dd $Mdocdate: March 6 2014 $
.Dt READPASSPHRASE 3bsd .Dt readpassphrase 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm readpassphrase .Nm readpassphrase

View File

@@ -30,13 +30,15 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: malloc.3,v 1.78 2014/05/01 18:41:59 jmc Exp $ .\" $OpenBSD: malloc.3,v 1.126 2019/09/14 13:16:50 otto Exp $
.\" .\"
.Dd $Mdocdate: May 1 2014 $ .Dd $Mdocdate: September 14 2019 $
.Dt REALLOCARRAY 3bsd .Dt reallocarray 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm reallocarray .Nm reallocarray ,
.Nm recallocarray ,
.Nm freezero
.Nd memory allocation and deallocation .Nd memory allocation and deallocation
.Sh LIBRARY .Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) .ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
@@ -49,59 +51,244 @@
for include usage.) for include usage.)
.Ft void * .Ft void *
.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" .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"
.Sh DESCRIPTION .Sh DESCRIPTION
.Pp .Pp
When using Designed for safe allocation of arrays,
.Fn malloc the
be careful to avoid the following idiom:
.Bd -literal -offset indent
if ((p = malloc(num * size)) == NULL)
err(1, "malloc");
.Ed
.Pp
The multiplication may lead to an integer overflow, which can
be avoided using the extension
.Fn reallocarray ,
as follows:
.Bd -literal -offset indent
if ((p = reallocarray(NULL, num, size)) == NULL)
err(1, "malloc");
.Ed
.Pp
Alternatively
.Fn calloc
is a more portable solution which comes with the cost of clearing memory.
.Pp
If
.Fn malloc
must be used, be sure to test for overflow:
.Bd -literal -offset indent
if (size && num > SIZE_MAX / size) {
errno = ENOMEM;
err(1, "overflow");
}
.Ed
.Pp
The use of
.Fn reallocarray .Fn reallocarray
or function is similar to
.Fn calloc .Fn realloc
is strongly encouraged when allocating multiple sized objects except it operates on
in order to avoid possible integer overflows. .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
function guarantees that memory becoming unallocated is explicitly
.Em discarded ,
meaning 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.
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.
.Sh RETURN VALUES .Sh RETURN VALUES
The The
.Fn reallocarray .Fn reallocarray
function returns a pointer to the allocated space if successful; otherwise, and
.Fn recallocarray
functions return a pointer to the allocated space if successful; otherwise,
a null pointer is returned and a null pointer is returned and
.Va errno .Va errno
is set to is set to
.Er ENOMEM . .Er ENOMEM .
.Pp
If multiplying
.Fa nmemb
and
.Fa size
results in integer overflow,
.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
.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 SEE ALSO .Sh SEE ALSO
.Xr malloc 3 , .Xr malloc 3 ,
.Xr calloc 3 , .Xr calloc 3 ,
.Xr alloca 3 .Xr alloca 3
.Sh HISTORY .Sh HISTORY
The
.Fn reallocarray .Fn reallocarray
appeared in function appeared in
.Ox 5.6 , .Ox 5.6 ,
glibc 2.26. and glibc 2.26.
The
.Fn recallocarray
function appeared in
.Ox 6.1 .
The
.Fn freezero
function appeared in
.Ox 6.2 .

View File

@@ -33,7 +33,7 @@
.\" $FreeBSD: src/lib/libc/stdlib/malloc.3,v 1.80.2.2.2.1 2010/06/14 02:09:06 kensmith Exp $ .\" $FreeBSD: src/lib/libc/stdlib/malloc.3,v 1.80.2.2.2.1 2010/06/14 02:09:06 kensmith Exp $
.\" .\"
.Dd September 26, 2009 .Dd September 26, 2009
.Dt REALLOCF 3bsd .Dt reallocf 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm reallocf .Nm reallocf

1
man/recallocarray.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/reallocarray.3bsd

View File

@@ -31,7 +31,7 @@
.\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.12 2007/01/09 00:27:55 imp Exp $ .\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.12 2007/01/09 00:27:55 imp Exp $
.\" .\"
.Dd January 4, 2009 .Dd January 4, 2009
.Dt SETMODE 3bsd .Dt setmode 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm getmode , .Nm getmode ,

View File

@@ -21,7 +21,7 @@
.\" .\"
.\" The following requests are required for all man pages. .\" The following requests are required for all man pages.
.Dd December 16, 1995 .Dd December 16, 1995
.Dt SETPROCTITLE 3bsd .Dt setproctitle 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm setproctitle .Nm setproctitle
@@ -54,7 +54,7 @@ library routine only needs to be called (before any call to
and with and with
.Fn main .Fn main
arguments), if the automatic constructor support has not arguments), if the automatic constructor support has not
been linked in through the libbsd-ctor pkg-config file. been linked in through the libbsd-ctor pkgconf file.
.Pp .Pp
The title is set from the executable's name, followed by the The title is set from the executable's name, followed by the
result of a result of a

View File

@@ -27,7 +27,7 @@
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd May 6, 2010 .Dd May 6, 2010
.Dt STRINGLIST 3bsd .Dt stringlist 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm stringlist , .Nm stringlist ,

View File

@@ -15,7 +15,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: May 31 2007 $ .Dd $Mdocdate: May 31 2007 $
.Dt STRLCPY 3bsd .Dt strlcpy 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strlcpy , .Nm strlcpy ,

View File

@@ -29,7 +29,7 @@
.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.9 2003/07/01 15:28:05 maxim Exp $ .\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.9 2003/07/01 15:28:05 maxim Exp $
.\" .\"
.Dd July 28, 1994 .Dd July 28, 1994
.Dt STRMODE 3bsd .Dt strmode 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strmode .Nm strmode

View File

@@ -34,7 +34,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd October 11, 2001 .Dd October 11, 2001
.Dt STRSTR 3bsd .Dt strstr 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strnstr .Nm strnstr

View File

@@ -37,7 +37,7 @@
.\" NetBSD: strtol.3,v 1.31 2015/03/11 09:57:35 wiz Exp .\" NetBSD: strtol.3,v 1.31 2015/03/11 09:57:35 wiz Exp
.\" .\"
.Dd November 13, 2015 .Dd November 13, 2015
.Dt STRTOI 3bsd .Dt strtoi 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strtoi .Nm strtoi

View File

@@ -16,7 +16,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd January 18, 2015 .Dd January 18, 2015
.Dt STRTONUM 3bsd .Dt strtonum 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strtonum .Nm strtonum

View File

@@ -37,7 +37,7 @@
.\" NetBSD: strtoul.3,v 1.29 2015/03/10 13:00:58 christos Exp .\" NetBSD: strtoul.3,v 1.29 2015/03/10 13:00:58 christos Exp
.\" .\"
.Dd November 13, 2015 .Dd November 13, 2015
.Dt STRTOU 3bsd .Dt strtou 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm strtou .Nm strtou

View File

@@ -31,7 +31,7 @@
.\" $FreeBSD: src/share/man/man3/timeradd.3,v 1.3 2003/09/08 19:57:19 ru Exp $ .\" $FreeBSD: src/share/man/man3/timeradd.3,v 1.3 2003/09/08 19:57:19 ru Exp $
.\" .\"
.Dd June 7, 2010 .Dd June 7, 2010
.Dt TIMERADD 3bsd .Dt timeradd 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm timeradd , .Nm timeradd ,

1
man/timespec.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/timeval.3bsd

View File

@@ -28,7 +28,7 @@
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd April 12, 2011 .Dd April 12, 2011
.Dt TIMEVAL 3bsd .Dt timeval 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm timeval , .Nm timeval ,

View File

@@ -1,37 +1,30 @@
.\" $OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $ .\" $OpenBSD: tree.3,v 1.30 2019/05/10 13:13:14 florian Exp $
.\" .\"/*
.\" Copyright 2002 Niels Provos <provos@citi.umich.edu> .\" * Copyright 2002 Niels Provos <provos@citi.umich.edu>
.\" All rights reserved. .\" * All rights reserved.
.\" .\" *
.\" Redistribution and use in source and binary forms, with or without .\" * Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions .\" * modification, are permitted provided that the following conditions
.\" are met: .\" * are met:
.\" 1. Redistributions of source code must retain the above copyright .\" * 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer. .\" * notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright .\" * 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the .\" * notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution. .\" * 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 SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" This product includes software developed by Niels Provos. .\" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" 4. The name of the author may not be used to endorse or promote products .\" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" derived from this software without specific prior written permission. .\" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" .\" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" */
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .Dd May 10, 2019
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .Dt tree 3bsd
.\" (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$
.\"
.Dd December 27, 2007
.Dt TREE 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm SPLAY_PROTOTYPE , .Nm SPLAY_PROTOTYPE ,
@@ -70,98 +63,108 @@
.Nm RB_RIGHT , .Nm RB_RIGHT ,
.Nm RB_PARENT , .Nm RB_PARENT ,
.Nm RB_FOREACH , .Nm RB_FOREACH ,
.Nm RB_FOREACH_SAFE ,
.Nm RB_FOREACH_REVERSE , .Nm RB_FOREACH_REVERSE ,
.Nm RB_FOREACH_REVERSE_SAFE ,
.Nm RB_INIT , .Nm RB_INIT ,
.Nm RB_INSERT , .Nm RB_INSERT ,
.Nm RB_REMOVE .Nm RB_REMOVE
.Nd implementations of splay and red-black trees .Nd implementations of splay and red-black trees
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.ds doc-str-Lb-libbsd \*[str-Lb-libbsd]
.Lb libbsd
.Sh SYNOPSIS .Sh SYNOPSIS
.In sys/tree.h .In sys/tree.h
(See (See
.Xr libbsd 7 .Xr libbsd 7
for include usage.) for include usage.)
.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP .Pp
.Fn SPLAY_GENERATE NAME TYPE FIELD CMP .Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
.Fn SPLAY_ENTRY TYPE .Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP"
.Fn SPLAY_HEAD HEADNAME TYPE .Fn SPLAY_ENTRY "TYPE"
.Fn SPLAY_HEAD "HEADNAME" "TYPE"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head" .Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
.Fn SPLAY_ROOT "SPLAY_HEAD *head" .Fn SPLAY_ROOT "SPLAY_HEAD *head"
.Ft bool .Ft "int"
.Fn SPLAY_EMPTY "SPLAY_HEAD *head" .Fn SPLAY_EMPTY "SPLAY_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm" .Fn SPLAY_NEXT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_MIN NAME "SPLAY_HEAD *head" .Fn SPLAY_MIN "NAME" "SPLAY_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_MAX NAME "SPLAY_HEAD *head" .Fn SPLAY_MAX "NAME" "SPLAY_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm" .Fn SPLAY_FIND "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME" .Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME" .Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head" .Fn SPLAY_FOREACH "VARNAME" "NAME" "SPLAY_HEAD *head"
.Ft void .Ft void
.Fn SPLAY_INIT "SPLAY_HEAD *head" .Fn SPLAY_INIT "SPLAY_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm" .Fn SPLAY_INSERT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm" .Fn SPLAY_REMOVE "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
.Fn RB_PROTOTYPE NAME TYPE FIELD CMP .Pp
.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP .Fn RB_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
.Fn RB_GENERATE NAME TYPE FIELD CMP .Fn RB_PROTOTYPE_STATIC "NAME" "TYPE" "FIELD" "CMP"
.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP .Fn RB_GENERATE "NAME" "TYPE" "FIELD" "CMP"
.Fn RB_ENTRY TYPE .Fn RB_GENERATE_STATIC "NAME" "TYPE" "FIELD" "CMP"
.Fn RB_HEAD HEADNAME TYPE .Fn RB_ENTRY "TYPE"
.Fn RB_HEAD "HEADNAME" "TYPE"
.Fn RB_INITIALIZER "RB_HEAD *head" .Fn RB_INITIALIZER "RB_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_ROOT "RB_HEAD *head" .Fn RB_ROOT "RB_HEAD *head"
.Ft "bool" .Ft "int"
.Fn RB_EMPTY "RB_HEAD *head" .Fn RB_EMPTY "RB_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_NEXT "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_PREV NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_PREV "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_MIN NAME "RB_HEAD *head" .Fn RB_MIN "NAME" "RB_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_MAX NAME "RB_HEAD *head" .Fn RB_MAX "NAME" "RB_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_FIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_NFIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME" .Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME" .Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME" .Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
.Fn RB_FOREACH VARNAME NAME "RB_HEAD *head" .Fn RB_FOREACH "VARNAME" "NAME" "RB_HEAD *head"
.Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head" .Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
.Fn RB_FOREACH_REVERSE "VARNAME" "NAME" "RB_HEAD *head"
.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
.Ft void .Ft void
.Fn RB_INIT "RB_HEAD *head" .Fn RB_INIT "RB_HEAD *head"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_INSERT "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *" .Ft "struct TYPE *"
.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm" .Fn RB_REMOVE "NAME" "RB_HEAD *head" "struct TYPE *elm"
.Sh DESCRIPTION .Sh DESCRIPTION
These macros define data structures for different types of trees: These macros define data structures for different types of trees:
splay trees and red-black trees. splay trees and red-black trees.
.Pp .Pp
In the macro definitions, In the macro definitions,
.Fa TYPE .Fa TYPE
is the name tag of a user defined structure that must contain a field of type is the name tag of a user defined structure that must contain a field named
.Vt SPLAY_ENTRY , .Fa FIELD ,
of type
.Li SPLAY_ENTRY
or or
.Vt RB_ENTRY , .Li RB_ENTRY .
named
.Fa ENTRYNAME .
The argument The argument
.Fa HEADNAME .Fa HEADNAME
is the name tag of a user defined structure that must be declared is the name tag of a user defined structure that must be declared
using the macros using the macros
.Fn SPLAY_HEAD , .Fn SPLAY_HEAD
or or
.Fn RB_HEAD . .Fn RB_HEAD .
The argument The argument
@@ -169,46 +172,38 @@ The argument
has to be a unique name prefix for every tree that is defined. has to be a unique name prefix for every tree that is defined.
.Pp .Pp
The function prototypes are declared with The function prototypes are declared with
.Fn SPLAY_PROTOTYPE , .Li SPLAY_PROTOTYPE ,
.Fn RB_PROTOTYPE , .Li RB_PROTOTYPE ,
or or
.Fn RB_PROTOTYPE_STATIC . .Li RB_PROTOTYPE_STATIC .
The function bodies are generated with The function bodies are generated with
.Fn SPLAY_GENERATE , .Li SPLAY_GENERATE ,
.Fn RB_GENERATE , .Li RB_GENERATE ,
or or
.Fn RB_GENERATE_STATIC . .Li RB_GENERATE_STATIC .
See the examples below for further explanation of how these macros are used. See the examples below for further explanation of how these macros are used.
.Sh SPLAY TREES .Sh SPLAY TREES
A splay tree is a self-organizing data structure. A splay tree is a self-organizing data structure.
Every operation on the tree causes a splay to happen. Every operation on the tree causes a splay to happen.
The splay moves the requested The splay moves the requested node to the root of the tree and partly
node to the root of the tree and partly rebalances it. rebalances it.
.Pp .Pp
This has the benefit that request locality causes faster lookups as This has the benefit that request locality causes faster lookups as
the requested nodes move to the top of the tree. the requested nodes move to the top of the tree.
On the other hand, every lookup causes memory writes. On the other hand, every lookup causes memory writes.
.Pp .Pp
The Balance Theorem bounds the total access time for The Balance Theorem bounds the total access time for m operations
.Ar m and n inserts on an initially empty tree as O((m + n)lg n).
operations and The amortized cost for a sequence of m accesses to a splay tree is O(lg n).
.Ar n
inserts on an initially empty tree as
.Fn O "\*[lp]m + n\*[rp]lg n" .
The
amortized cost for a sequence of
.Ar m
accesses to a splay tree is
.Fn O "lg n" .
.Pp .Pp
A splay tree is headed by a structure defined by the A splay tree is headed by a structure defined by the
.Fn SPLAY_HEAD .Fn SPLAY_HEAD
macro. macro.
A A
.Fa SPLAY_HEAD
structure is declared as follows: structure is declared as follows:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn SPLAY_HEAD HEADNAME TYPE SPLAY_HEAD(HEADNAME, TYPE) head;
.Va head ;
.Ed .Ed
.Pp .Pp
where where
@@ -247,16 +242,15 @@ macro, but should be used only once.
Finally, Finally,
the the
.Fa CMP .Fa CMP
argument is the name of a function used to compare tree nodes argument is the name of a function used to compare trees' nodes
with each other. with each other.
The function takes two arguments of type The function takes two arguments of type
.Vt "struct TYPE *" . .Fa "struct TYPE *" .
If the first argument is smaller than the second, the function returns a If the first argument is smaller than the second, the function returns a
value smaller than zero. value smaller than zero.
If they are equal, the function returns zero. If they are equal, the function returns zero.
Otherwise, it should return a value greater than zero. Otherwise, it should return a value greater than zero.
The compare The compare function defines the order of the tree elements.
function defines the order of the tree elements.
.Pp .Pp
The The
.Fn SPLAY_INIT .Fn SPLAY_INIT
@@ -266,11 +260,8 @@ macro initializes the tree referenced by
The splay tree can also be initialized statically by using the The splay tree can also be initialized statically by using the
.Fn SPLAY_INITIALIZER .Fn SPLAY_INITIALIZER
macro like this: macro like this:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn SPLAY_HEAD HEADNAME TYPE SPLAY_HEAD(HEADNAME, TYPE) head = SPLAY_INITIALIZER(&head);
.Va head
=
.Fn SPLAY_INITIALIZER &head ;
.Ed .Ed
.Pp .Pp
The The
@@ -278,6 +269,11 @@ The
macro inserts the new element macro inserts the new element
.Fa elm .Fa elm
into the tree. into the tree.
Upon success,
.Va NULL
is returned.
If a matching element already exists in the tree, the insertion is
aborted, and a pointer to the existing element is returned.
.Pp .Pp
The The
.Fn SPLAY_REMOVE .Fn SPLAY_REMOVE
@@ -285,6 +281,11 @@ macro removes the element
.Fa elm .Fa elm
from the tree pointed by from the tree pointed by
.Fa head . .Fa head .
Upon success, a pointer to the removed element is returned.
.Va NULL
is returned if
.Fa elm
is not present in the tree.
.Pp .Pp
The The
.Fn SPLAY_FIND .Fn SPLAY_FIND
@@ -292,7 +293,7 @@ macro can be used to find a particular element in the tree.
.Bd -literal -offset indent .Bd -literal -offset indent
struct TYPE find, *res; struct TYPE find, *res;
find.key = 30; find.key = 30;
res = SPLAY_FIND(NAME, head, &find); res = SPLAY_FIND(NAME, &head, &find);
.Ed .Ed
.Pp .Pp
The The
@@ -309,8 +310,8 @@ for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
Or, for simplicity, one can use the Or, for simplicity, one can use the
.Fn SPLAY_FOREACH .Fn SPLAY_FOREACH
macro: macro:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn SPLAY_FOREACH np NAME head SPLAY_FOREACH(np, NAME, &head)
.Ed .Ed
.Pp .Pp
The The
@@ -320,29 +321,28 @@ macro should be used to check whether a splay tree is empty.
A red-black tree is a binary search tree with the node color as an A red-black tree is a binary search tree with the node color as an
extra attribute. extra attribute.
It fulfills a set of conditions: It fulfills a set of conditions:
.Bl -enum -offset indent .Pp
.Bl -enum -compact -offset indent
.It .It
Every search path from the root to a leaf consists of the same number of every search path from the root to a leaf consists of the same number of
black nodes. black nodes,
.It .It
Each red node (except for the root) has a black parent. each red node (except for the root) has a black parent,
.It .It
Each leaf node is black. each leaf node is black.
.El .El
.Pp .Pp
Every operation on a red-black tree is bounded as Every operation on a red-black tree is bounded as O(lg n).
.Fn O "lg n" . The maximum height of a red-black tree is 2lg (n+1).
The maximum height of a red-black tree is
.Fn 2lg "n + 1" .
.Pp .Pp
A red-black tree is headed by a structure defined by the A red-black tree is headed by a structure defined by the
.Fn RB_HEAD .Fn RB_HEAD
macro. macro.
A A
.Fa RB_HEAD
structure is declared as follows: structure is declared as follows:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn RB_HEAD HEADNAME TYPE RB_HEAD(HEADNAME, TYPE) head;
.Va head ;
.Ed .Ed
.Pp .Pp
where where
@@ -360,7 +360,7 @@ their prototypes need to be declared with the
.Fn RB_PROTOTYPE .Fn RB_PROTOTYPE
or or
.Fn RB_PROTOTYPE_STATIC .Fn RB_PROTOTYPE_STATIC
macro, macros,
where where
.Fa NAME .Fa NAME
is a unique identifier for this particular tree. is a unique identifier for this particular tree.
@@ -377,7 +377,7 @@ The function bodies are generated with the
.Fn RB_GENERATE .Fn RB_GENERATE
or or
.Fn RB_GENERATE_STATIC .Fn RB_GENERATE_STATIC
macro. macros.
These macros take the same arguments as the These macros take the same arguments as the
.Fn RB_PROTOTYPE .Fn RB_PROTOTYPE
and and
@@ -387,16 +387,15 @@ macros, but should be used only once.
Finally, Finally,
the the
.Fa CMP .Fa CMP
argument is the name of a function used to compare tree nodes argument is the name of a function used to compare trees' nodes
with each other. with each other.
The function takes two arguments of type The function takes two arguments of type
.Vt "struct TYPE *" . .Fa "struct TYPE *" .
If the first argument is smaller than the second, the function returns a If the first argument is smaller than the second, the function returns a
value smaller than zero. value smaller than zero.
If they are equal, the function returns zero. If they are equal, the function returns zero.
Otherwise, it should return a value greater than zero. Otherwise, it should return a value greater than zero.
The compare The compare function defines the order of the tree elements.
function defines the order of the tree elements.
.Pp .Pp
The The
.Fn RB_INIT .Fn RB_INIT
@@ -406,11 +405,8 @@ macro initializes the tree referenced by
The red-black tree can also be initialized statically by using the The red-black tree can also be initialized statically by using the
.Fn RB_INITIALIZER .Fn RB_INITIALIZER
macro like this: macro like this:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn RB_HEAD HEADNAME TYPE RB_HEAD(HEADNAME, TYPE) head = RB_INITIALIZER(&head);
.Va head
=
.Fn RB_INITIALIZER &head ;
.Ed .Ed
.Pp .Pp
The The
@@ -418,6 +414,11 @@ The
macro inserts the new element macro inserts the new element
.Fa elm .Fa elm
into the tree. into the tree.
Upon success,
.Va NULL
is returned.
If a matching element already exists in the tree, the insertion is
aborted, and a pointer to the existing element is returned.
.Pp .Pp
The The
.Fn RB_REMOVE .Fn RB_REMOVE
@@ -425,16 +426,24 @@ macro removes the element
.Fa elm .Fa elm
from the tree pointed by from the tree pointed by
.Fa head . .Fa head .
.Fn RB_REMOVE
returns
.Fa elm .
.Pp .Pp
The The
.Fn RB_FIND .Fn RB_FIND
and and
.Fn RB_NFIND .Fn RB_NFIND
macros can be used to find a particular element in the tree. macros can be used to find a particular element in the tree.
.Fn RB_FIND
finds the node with the same key as
.Fa elm .
.Fn RB_NFIND
finds the first node greater than or equal to the search key.
.Bd -literal -offset indent .Bd -literal -offset indent
struct TYPE find, *res; struct TYPE find, *res;
find.key = 30; find.key = 30;
res = RB_FIND(NAME, head, &find); res = RB_FIND(NAME, &head, &find);
.Ed .Ed
.Pp .Pp
The The
@@ -445,26 +454,119 @@ The
and and
.Fn RB_PREV .Fn RB_PREV
macros can be used to traverse the tree: macros can be used to traverse the tree:
.Pp .Bd -literal -offset indent
.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))" for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))
.Ed
.Pp .Pp
Or, for simplicity, one can use the Or, for simplicity, one can use the
.Fn RB_FOREACH .Fn RB_FOREACH
or or
.Fn RB_FOREACH_REVERSE .Fn RB_FOREACH_REVERSE
macro: macros:
.Bd -ragged -offset indent .Bd -literal -offset indent
.Fn RB_FOREACH np NAME head RB_FOREACH(np, NAME, &head)
.Ed .Ed
.Pp .Pp
The macros
.Fn RB_FOREACH_SAFE
and
.Fn RB_FOREACH_REVERSE_SAFE
traverse the tree referenced by head
in a forward or reverse direction respectively,
assigning each element in turn to np.
However, unlike their unsafe counterparts,
they permit both the removal of np
as well as freeing it from within the loop safely
without interfering with the traversal.
.Pp
The The
.Fn RB_EMPTY .Fn RB_EMPTY
macro should be used to check whether a red-black tree is empty. macro should be used to check whether a red-black tree is empty.
.Sh EXAMPLES
The following example demonstrates how to declare a red-black tree
holding integers.
Values are inserted into it and the contents of the tree are printed
in order.
Lastly, the internal structure of the tree is printed.
.Bd -literal -offset 3n
#include <sys/tree.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
struct node {
RB_ENTRY(node) entry;
int i;
};
int intcmp(struct node *, struct node *);
void print_tree(struct node *);
int
intcmp(struct node *e1, struct node *e2)
{
return (e1->i < e2->i ? -1 : e1->i > e2->i);
}
RB_HEAD(inttree, node) head = RB_INITIALIZER(&head);
RB_PROTOTYPE(inttree, node, entry, intcmp)
RB_GENERATE(inttree, node, entry, intcmp)
int testdata[] = {
20, 16, 17, 13, 3, 6, 1, 8, 2, 4, 10, 19, 5, 9, 12, 15, 18,
7, 11, 14
};
void
print_tree(struct node *n)
{
struct node *left, *right;
if (n == NULL) {
printf("nil");
return;
}
left = RB_LEFT(n, entry);
right = RB_RIGHT(n, entry);
if (left == NULL && right == NULL)
printf("%d", n->i);
else {
printf("%d(", n->i);
print_tree(left);
printf(",");
print_tree(right);
printf(")");
}
}
int
main(void)
{
int i;
struct node *n;
for (i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) {
if ((n = malloc(sizeof(struct node))) == NULL)
err(1, NULL);
n->i = testdata[i];
RB_INSERT(inttree, &head, n);
}
RB_FOREACH(n, inttree, &head) {
printf("%d\en", n->i);
}
print_tree(RB_ROOT(&head));
printf("\en");
return (0);
}
.Ed
.Sh SEE ALSO
.Xr queue 3bsd
.Sh NOTES .Sh NOTES
Trying to free a tree in the following way is a common error: Trying to free a tree in the following way is a common error:
.Bd -literal -offset indent .Bd -literal -offset indent
SPLAY_FOREACH(var, NAME, head) { SPLAY_FOREACH(var, NAME, &head) {
SPLAY_REMOVE(NAME, head, var); SPLAY_REMOVE(NAME, &head, var);
free(var); free(var);
} }
free(head); free(head);
@@ -472,36 +574,17 @@ free(head);
.Pp .Pp
Since Since
.Va var .Va var
is freed, the is free'd, the
.Fn FOREACH .Fn FOREACH
macro refers to a pointer that may have been reallocated already. macro refers to a pointer that may have been reallocated already.
Proper code needs a second variable. Proper code needs a second variable.
.Bd -literal -offset indent .Bd -literal -offset indent
for (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) { for (var = SPLAY_MIN(NAME, &head); var != NULL; var = nxt) {
nxt = SPLAY_NEXT(NAME, head, var); nxt = SPLAY_NEXT(NAME, &head, var);
SPLAY_REMOVE(NAME, head, var); SPLAY_REMOVE(NAME, &head, var);
free(var); free(var);
} }
.Ed .Ed
.Pp
Both
.Fn RB_INSERT
and
.Fn SPLAY_INSERT
return
.Dv NULL
if the element was inserted in the tree successfully, otherwise they
return a pointer to the element with the colliding key.
.Pp
Accordingly,
.Fn RB_REMOVE
and
.Fn SPLAY_REMOVE
return the pointer to the removed element otherwise they return
.Dv NULL
to indicate an error.
.Sh SEE ALSO
.Xr queue 3bsd
.Sh AUTHORS .Sh AUTHORS
The author of the tree macros is The author of the tree macros is
.An Niels Provos . .An Niels Provos .

1
man/uid_from_user.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/pwcache.3bsd

View File

@@ -30,7 +30,7 @@
.\" @(#)unvis.3 8.2 (Berkeley) 12/11/93 .\" @(#)unvis.3 8.2 (Berkeley) 12/11/93
.\" .\"
.Dd March 12, 2011 .Dd March 12, 2011
.Dt UNVIS 3bsd .Dt unvis 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm unvis , .Nm unvis ,

1
man/user_from_uid.3bsd Normal file
View File

@@ -0,0 +1 @@
.so man3/pwcache.3bsd

View File

@@ -30,7 +30,7 @@
.\" @(#)vis.3 8.1 (Berkeley) 6/9/93 .\" @(#)vis.3 8.1 (Berkeley) 6/9/93
.\" .\"
.Dd April 22, 2017 .Dd April 22, 2017
.Dt VIS 3bsd .Dt vis 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm vis , .Nm vis ,
@@ -529,6 +529,7 @@ The destination buffer size is not large enough to perform the conversion.
.%O "RFC 2045" .%O "RFC 2045"
.Re .Re
.Sh HISTORY .Sh HISTORY
.ds doc-operating-system-NetBSD-7.0 7.0
The The
.Fn vis , .Fn vis ,
.Fn strvis , .Fn strvis ,

View File

@@ -36,7 +36,7 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 4, 2009 .Dd March 4, 2009
.Dt WCSLCPY 3bsd .Dt wcslcpy 3bsd
.Os .Os
.Sh NAME .Sh NAME
.Nm wcslcat , .Nm wcslcat ,

View File

@@ -15,7 +15,6 @@ AM_CPPFLAGS += \
endif endif
libbsd_la_included_sources = \ libbsd_la_included_sources = \
hash/helper.c \
getentropy_aix.c \ getentropy_aix.c \
getentropy_bsd.c \ getentropy_bsd.c \
getentropy_hpux.c \ getentropy_hpux.c \
@@ -26,6 +25,7 @@ libbsd_la_included_sources = \
getentropy_win.c \ getentropy_win.c \
$(nil) $(nil)
CLEANFILES =
EXTRA_DIST = \ EXTRA_DIST = \
libbsd.map \ libbsd.map \
libbsd.pc.in \ libbsd.pc.in \
@@ -34,10 +34,6 @@ EXTRA_DIST = \
$(libbsd_la_included_sources) \ $(libbsd_la_included_sources) \
$(nil) $(nil)
CLEANFILES = \
hash/md5hl.c \
$(nil)
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = \ pkgconfig_DATA = \
libbsd.pc \ libbsd.pc \
@@ -53,25 +49,23 @@ pkgconfig_DATA += libbsd-ctor.pc
lib_LIBRARIES += libbsd-ctor.a lib_LIBRARIES += libbsd-ctor.a
endif endif
hash/md5hl.c: $(srcdir)/hash/helper.c
$(AM_V_at) $(MKDIR_P) hash
$(AM_V_GEN) sed -e 's:hashinc:md5.h:g' -e 's:HASH:MD5:g' $< > $@
libbsd_la_DEPENDENCIES = \ libbsd_la_DEPENDENCIES = \
$(libbsd_la_included_sources) \ $(libbsd_la_included_sources) \
libbsd.map libbsd.map
libbsd_la_LIBADD = \ libbsd_la_LIBADD = \
$(CLOCK_GETTIME_LIBS) \ $(MD5_LIBS) \
$(ARC4RANDOM_ATFORK_LIBS) \ $(LIBBSD_LIBS) \
$(nil) $(nil)
libbsd_la_LDFLAGS = \ libbsd_la_LDFLAGS = \
-Wl,--version-script=$(srcdir)/libbsd.map \
-version-number $(LIBBSD_ABI) -version-number $(LIBBSD_ABI)
if HAVE_LINKER_VERSION_SCRIPT
libbsd_la_LDFLAGS += \
-Wl,--version-script=$(srcdir)/libbsd.map
endif
libbsd_la_SOURCES = \ libbsd_la_SOURCES = \
arc4random.c \ arc4random.c \
arc4random.h \ arc4random.h \
arc4random_linux.h \ arc4random_linux.h \
arc4random_openbsd.h \
arc4random_uniform.c \ arc4random_uniform.c \
arc4random_unix.h \ arc4random_unix.h \
arc4random_win.h \ arc4random_win.h \
@@ -83,6 +77,7 @@ libbsd_la_SOURCES = \
expand_number.c \ expand_number.c \
explicit_bzero.c \ explicit_bzero.c \
fgetln.c \ fgetln.c \
freezero.c \
fgetwln.c \ fgetwln.c \
flopen.c \ flopen.c \
fmtcheck.c \ fmtcheck.c \
@@ -91,23 +86,22 @@ libbsd_la_SOURCES = \
funopen.c \ funopen.c \
getbsize.c \ getbsize.c \
getpeereid.c \ getpeereid.c \
hash/md5.c \
hash/md5hl.c \
hash/sha512.h \
hash/sha512c.c \
heapsort.c \ heapsort.c \
humanize_number.c \ humanize_number.c \
inet_net_pton.c \ inet_net_pton.c \
local-elf.h \ local-elf.h \
local-link.h \ local-link.h \
md5.c \
merge.c \ merge.c \
nlist.c \ nlist.c \
pidfile.c \ pidfile.c \
progname.c \ progname.c \
pwcache.c \
radixsort.c \ radixsort.c \
readpassphrase.c \ readpassphrase.c \
reallocarray.c \ reallocarray.c \
reallocf.c \ reallocf.c \
recallocarray.c \
setmode.c \ setmode.c \
setproctitle.c \ setproctitle.c \
strlcat.c \ strlcat.c \
@@ -131,22 +125,51 @@ libbsd_la_SOURCES += \
$(nil) $(nil)
endif endif
if NEED_TRANSPARENT_LIBMD
CLEANFILES += \
format.ld \
# EOL
endif
libbsd_ctor_a_SOURCES = \ libbsd_ctor_a_SOURCES = \
setproctitle_ctor.c \ setproctitle_ctor.c \
$(nil) $(nil)
if NEED_TRANSPARENT_LIBMD
TRANSPARENT_LIBMD_DEPENDS = format.ld
format.ld:
$(CC) -shared -nostdlib -nostartfiles -x assembler /dev/null -o $@.so
$(OBJDUMP) -f $@.so | sed -n 's/.*file format \(.*\)/OUTPUT_FORMAT(\1)/;T;p' > $@
rm -f $@.so
endif
runtimelibdir = $(libdir) runtimelibdir = $(libdir)
install-exec-hook: install-exec-hook: $(TRANSPARENT_LIBMD_DEPENDS)
if [ "$(libdir)" != "$(runtimelibdir)" ]; then \ if [ "$(libdir)" != "$(runtimelibdir)" ]; then \
$(MKDIR_P) $(DESTDIR)$(runtimelibdir); \ $(MKDIR_P) $(DESTDIR)$(runtimelibdir); \
mv $(DESTDIR)$(libdir)/libbsd*.so.* \ mv $(DESTDIR)$(libdir)/libbsd*.so.* \
$(DESTDIR)$(runtimelibdir)/; \ $(DESTDIR)$(runtimelibdir)/; \
fi
if NEED_TRANSPARENT_LIBMD
# The "GNU ld script" magic is required so that GNU ldconfig does not complain
# about an unknown format file.
soname=`readlink $(DESTDIR)$(libdir)/libbsd.so`; \ soname=`readlink $(DESTDIR)$(libdir)/libbsd.so`; \
sorelprefix=`echo $(libdir) | sed -r -e 's:(^/)?[^/]+:..:g'`; \ $(RM) $(DESTDIR)$(libdir)/libbsd.so; \
(echo '/* GNU ld script'; \
echo ' * The MD5 functions are provided by the libmd library. */'; \
cat format.ld; \
echo "GROUP($(runtimelibdir)/$$soname AS_NEEDED($(MD5_LIBS)))"; \
)>$(DESTDIR)$(libdir)/libbsd.so
else
if [ "$(libdir)" != "$(runtimelibdir)" ]; then \
soname=`readlink $(DESTDIR)$(libdir)/libbsd.so`; \
sorelprefix=`echo $(libdir) | $(SED) -r -e 's:(^/)?[^/]+:..:g'`; \
ln -sf $$sorelprefix$(runtimelibdir)/$$soname \ ln -sf $$sorelprefix$(runtimelibdir)/$$soname \
$(DESTDIR)$(libdir)/libbsd.so; \ $(DESTDIR)$(libdir)/libbsd.so; \
fi fi
endif
uninstall-hook: uninstall-hook:
rm -f $(DESTDIR)$(runtimelibdir)/libbsd*.so* rm -f $(DESTDIR)$(runtimelibdir)/libbsd*.so*

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: arc4random.c,v 1.53 2015/09/10 18:53:50 bcook Exp $ */ /* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $ */
/* /*
* Copyright (c) 1996, David Mazieres <dm@uun.org> * Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -50,6 +50,8 @@
#define BLOCKSZ 64 #define BLOCKSZ 64
#define RSBUFSZ (16*BLOCKSZ) #define RSBUFSZ (16*BLOCKSZ)
#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ /* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
static struct _rs { static struct _rs {
size_t rs_have; /* valid bytes at end of rs_buf */ size_t rs_have; /* valid bytes at end of rs_buf */
@@ -74,10 +76,10 @@ _rs_init(unsigned char *buf, size_t n)
if (rs == NULL) { if (rs == NULL) {
if (_rs_allocate(&rs, &rsx) == -1) if (_rs_allocate(&rs, &rsx) == -1)
abort(); _exit(1);
} }
chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0); chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
} }
@@ -108,6 +110,7 @@ static void
_rs_stir(void) _rs_stir(void)
{ {
unsigned char rnd[KEYSZ + IVSZ]; unsigned char rnd[KEYSZ + IVSZ];
uint32_t rekey_fuzz = 0;
if (getentropy(rnd, sizeof rnd) == -1) if (getentropy(rnd, sizeof rnd) == -1)
_getentropy_fail(); _getentropy_fail();
@@ -122,7 +125,10 @@ _rs_stir(void)
rs->rs_have = 0; rs->rs_have = 0;
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
rs->rs_count = 1600000; /* rekey interval should not be predictable */
chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
(uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
} }
static inline void static inline void

View File

@@ -32,9 +32,7 @@
int int
getentropy(void *buf, size_t len); getentropy(void *buf, size_t len);
#if defined(__OpenBSD__) #if defined(__linux__)
#include "arc4random_openbsd.h"
#elif defined(__linux__)
#include "arc4random_linux.h" #include "arc4random_linux.h"
#elif defined(_WIN32) #elif defined(_WIN32)
#include "arc4random_win.h" #include "arc4random_win.h"

View File

@@ -1,61 +0,0 @@
/* $OpenBSD: arc4random.h,v 1.3 2014/07/20 20:51:13 bcook Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
*
* 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.
*/
/*
* Stub functions for portability.
*/
#include <sys/mman.h>
#include <signal.h>
#include "thread_private.h"
static inline void
_getentropy_fail(void)
{
raise(SIGKILL);
}
static inline int
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
struct {
struct _rs rs;
struct _rsx rsx;
} *p;
if ((p = mmap(NULL, sizeof(*p), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
return (-1);
if (minherit(p, sizeof(*p), MAP_INHERIT_ZERO) == -1) {
munmap(p, sizeof(*p));
return (-1);
}
*rsp = &p->rs;
*rsxp = &p->rsx;
return (0);
}
static inline void
_rs_forkdetect(void)
{
}

View File

@@ -4,7 +4,7 @@ D. J. Bernstein
Public domain. Public domain.
*/ */
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ /* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
typedef unsigned char u8; typedef unsigned char u8;
typedef unsigned int u32; typedef unsigned int u32;
@@ -52,7 +52,7 @@ static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k"; static const char tau[16] = "expand 16-byte k";
static void static void
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
{ {
const char *constants; const char *constants;

View File

@@ -1,6 +1,8 @@
/* /*
* Copyright (c) 2004-2005, 2007, 2010, 2012-2014 * SPDX-License-Identifier: ISC
* Todd C. Miller <Todd.Miller@courtesan.com> *
* Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018
* Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -17,19 +19,17 @@
#include <config.h> #include <config.h>
#include <sys/types.h> #ifdef __linux__
#include <unistd.h> # include <sys/syscall.h>
#include <stdio.h> # if defined(__NR_close_range) && !defined(SYS_close_range)
#ifdef STDC_HEADERS # define SYS_close_range __NR_close_range
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif # endif
#endif /* STDC_HEADERS */ #endif
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_PSTAT_GETPROC #ifdef HAVE_PSTAT_GETPROC
# include <sys/param.h> # include <sys/param.h>
# include <sys/pstat.h> # include <sys/pstat.h>
@@ -56,10 +56,6 @@
# define OPEN_MAX 256 # define OPEN_MAX 256
#endif #endif
#if defined(HAVE_FCNTL_CLOSEM) && !defined(HAVE_DIRFD)
# define closefrom closefrom_fallback
#endif
static inline void static inline void
closefrom_close(int fd) closefrom_close(int fd)
{ {
@@ -71,56 +67,64 @@ closefrom_close(int fd)
#endif #endif
} }
#if defined(__linux__) && defined(SYS_close_range)
static inline int
sys_close_range(unsigned int fd, unsigned int max_fd, unsigned int flags)
{
return syscall(SYS_close_range, fd, max_fd, flags);
}
#endif
/* /*
* Close all file descriptors greater than or equal to lowfd. * Close all file descriptors greater than or equal to lowfd.
* This is the expensive (fallback) method. * This is the expensive (fallback) method.
*/ */
void static void
closefrom_fallback(int lowfd) closefrom_fallback(int lowfd)
{ {
long fd, maxfd; long fd, maxfd;
/* /*
* Fall back on sysconf() or getdtablesize(). We avoid checking * Fall back on sysconf(_SC_OPEN_MAX) or getdtablesize(). This is
* resource limits since it is possible to open a file descriptor * equivalent to checking the RLIMIT_NOFILE soft limit. It is
* and then drop the rlimit such that it is below the open fd. * possible for there to be open file descriptors past this limit
* but there is not much we can do about that since the hard limit
* may be RLIM_INFINITY (LLONG_MAX or ULLONG_MAX on modern systems).
*/ */
#ifdef HAVE_SYSCONF #ifdef HAVE_SYSCONF
maxfd = sysconf(_SC_OPEN_MAX); maxfd = sysconf(_SC_OPEN_MAX);
#else #else
maxfd = getdtablesize(); maxfd = getdtablesize();
#endif /* HAVE_SYSCONF */ #endif /* HAVE_SYSCONF */
if (maxfd < 0) if (maxfd < OPEN_MAX)
maxfd = OPEN_MAX; maxfd = OPEN_MAX;
/* Make sure we did not get RLIM_INFINITY as the upper limit. */
if (maxfd > INT_MAX)
maxfd = INT_MAX;
for (fd = lowfd; fd < maxfd; fd++) for (fd = lowfd; fd < maxfd; fd++)
closefrom_close(fd); closefrom_close(fd);
} }
/* #if defined(HAVE_PSTAT_GETPROC)
* Close all file descriptors greater than or equal to lowfd. static int
* We try the fast way first, falling back on the slow method. closefrom_pstat(int lowfd)
*/
#if defined(HAVE_FCNTL_CLOSEM)
void
closefrom(int lowfd)
{ {
if (fcntl(lowfd, F_CLOSEM, 0) == -1) struct pst_status pst;
closefrom_fallback(lowfd);
}
#elif defined(HAVE_PSTAT_GETPROC)
void
closefrom(int lowfd)
{
struct pst_status pstat;
int fd; int fd;
if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) { /*
for (fd = lowfd; fd <= pstat.pst_highestfd; fd++) * EOVERFLOW is not a fatal error for the fields we use.
* See the "EOVERFLOW Error" section of pstat_getvminfo(3).
*/
if (pstat_getproc(&pst, sizeof(pst), 0, getpid()) != -1 ||
errno == EOVERFLOW) {
for (fd = lowfd; fd <= pst.pst_highestfd; fd++)
(void)close(fd); (void)close(fd);
} else { return 0;
closefrom_fallback(lowfd);
} }
return -1;
} }
#elif defined(HAVE_DIRFD) #elif defined(HAVE_DIRFD)
static int static int
@@ -135,8 +139,8 @@ closefrom_procfs(int lowfd)
int ret = 0; int ret = 0;
int i; int i;
/* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */ /* Use /proc/self/fd (or /dev/fd on macOS) if it exists. */
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) # ifdef __APPLE__
path = "/dev/fd"; path = "/dev/fd";
# else # else
path = "/proc/self/fd"; path = "/proc/self/fd";
@@ -180,13 +184,36 @@ closefrom_procfs(int lowfd)
return ret; return ret;
} }
#endif
/*
* Close all file descriptors greater than or equal to lowfd.
* We try the fast way first, falling back on the slow method.
*/
void void
closefrom(int lowfd) closefrom(int lowfd)
{ {
if (closefrom_procfs(lowfd) == 0) if (lowfd < 0)
return; lowfd = 0;
/* Try the fast methods first, if possible. */
#if defined(HAVE_FCNTL_CLOSEM)
if (fcntl(lowfd, F_CLOSEM, 0) != -1)
return;
#endif /* HAVE_FCNTL_CLOSEM */
#if defined(__linux__) && defined(SYS_close_range)
if (sys_close_range(lowfd, UINT_MAX, 0) == 0)
return;
#endif
#if defined(HAVE_PSTAT_GETPROC)
if (closefrom_pstat(lowfd) != -1)
return;
#elif defined(HAVE_DIRFD)
if (closefrom_procfs(lowfd) != -1)
return;
#endif /* HAVE_DIRFD */
/* Do things the slow way. */
closefrom_fallback(lowfd); closefrom_fallback(lowfd);
} }
#endif /* HAVE_FCNTL_CLOSEM */

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */ /* $OpenBSD: explicit_bzero.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */
/* /*
* Public domain. * Public domain.
* Written by Matthew Dempsky. * Written by Matthew Dempsky.
@@ -6,6 +6,9 @@
#include <string.h> #include <string.h>
__attribute__((__weak__)) void
__explicit_bzero_hook(void *, size_t);
__attribute__((__weak__)) void __attribute__((__weak__)) void
__explicit_bzero_hook(void *buf, size_t len) __explicit_bzero_hook(void *buf, size_t len)
{ {

View File

@@ -76,8 +76,8 @@ fgetln(FILE *stream, size_t *len)
} }
} }
libbsd_link_warning(fgetln, libbsd_link_warning(fgetln,
"This function cannot be safely ported, use getline(3) " "The fgetln() function cannot be safely ported, use getline(3) "
"instead, as it is supported by GNU and POSIX.1-2008.") "instead, as it is supported by GNU and POSIX.1-2008.");
#else #else
#error "Function fgetln() needs to be ported." #error "Function fgetln() needs to be ported."
#endif #endif

View File

@@ -87,6 +87,9 @@ fgetwln(FILE *stream, size_t *lenp)
*lenp = wused; *lenp = wused;
return wused ? fb->wbuf : NULL; return wused ? fb->wbuf : NULL;
} }
/* XXX: Ideally we'd recommend getwline(3), but unfortunately even though it
* was part of the ISO/IEC TR 24731-2:2010 draft, it did not make it into C11
* and is not widely implemented. */
libbsd_link_warning(fgetwln, libbsd_link_warning(fgetwln,
"This function cannot be safely ported, use fgetwc(3) " "The fgetwln() function cannot be safely ported, use fgetwc(3) "
"instead, as it is supported by C99 and POSIX.1-2001.") "instead, as it is supported by C99 and POSIX.1-2001.");

View File

@@ -32,7 +32,7 @@
int int
fpurge(FILE *fp) fpurge(FILE *fp)
{ {
if (fp == NULL || fileno(fp) < 0) { if (fp == NULL) {
errno = EBADF; errno = EBADF;
return EOF; return EOF;
} }

30
src/freezero.c Normal file
View File

@@ -0,0 +1,30 @@
/* $OpenBSD: malloc.c,v 1.267 2020/11/23 15:42:11 otto Exp $ */
/*
* Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
*
* 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 <stdlib.h>
#include <string.h>
void
freezero(void *ptr, size_t sz)
{
/* This is legal. */
if (ptr == NULL)
return;
explicit_bzero(ptr, sz);
free(ptr);
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright © 2011, 2013, 2017 Guillem Jover * Copyright © 2011, 2013, 2017, 2020 Guillem Jover
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -87,10 +87,10 @@ funopen_close(void *cookie)
struct funopen_cookie *cookiewrap = cookie; struct funopen_cookie *cookiewrap = cookie;
int rc; int rc;
if (cookiewrap->closefn == NULL) if (cookiewrap->closefn)
return 0;
rc = cookiewrap->closefn(cookiewrap->orig_cookie); rc = cookiewrap->closefn(cookiewrap->orig_cookie);
else
rc = 0;
free(cookiewrap); free(cookiewrap);

View File

@@ -39,7 +39,7 @@
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
#include "hash/sha512.h" #include <sha512.h>
#include <libperfstat.h> #include <libperfstat.h>
@@ -54,9 +54,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);

View File

@@ -26,6 +26,8 @@
#include <errno.h> #include <errno.h>
#include <stddef.h> #include <stddef.h>
int getentropy(void *buf, size_t len);
/* /*
* Derived from lib/libc/gen/arc4random.c from FreeBSD. * Derived from lib/libc/gen/arc4random.c from FreeBSD.
*/ */

View File

@@ -42,7 +42,7 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include "hash/sha512.h" #include <sha512.h>
#include <sys/vfs.h> #include <sys/vfs.h>
@@ -59,9 +59,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);

View File

@@ -44,7 +44,7 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include "hash/sha512.h" #include <sha512.h>
#ifdef HAVE_GETAUXVAL #ifdef HAVE_GETAUXVAL
#include <sys/auxv.h> #include <sys/auxv.h>
@@ -62,9 +62,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);
@@ -228,7 +228,7 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
{ {
SHA512_CTX *ctx = data; SHA512_CTX *ctx = data;
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); SHA512_Update(ctx, (uint8_t *)&info->dlpi_addr, sizeof (info->dlpi_addr));
return (0); return (0);
} }
@@ -415,17 +415,17 @@ getentropy_fallback(void *buf, size_t len)
#ifdef HAVE_GETAUXVAL #ifdef HAVE_GETAUXVAL
#ifdef AT_RANDOM #ifdef AT_RANDOM
/* Not as random as you think but we take what we are given */ /* Not as random as you think but we take what we are given */
p = (char *) getauxval(AT_RANDOM); p = (char *) ((intptr_t) getauxval(AT_RANDOM));
if (p) if (p)
HR(p, 16); HR(p, 16);
#endif #endif
#ifdef AT_SYSINFO_EHDR #ifdef AT_SYSINFO_EHDR
p = (char *) getauxval(AT_SYSINFO_EHDR); p = (char *) ((intptr_t) getauxval(AT_SYSINFO_EHDR));
if (p) if (p)
HR(p, pgs); HR(p, pgs);
#endif #endif
#ifdef AT_BASE #ifdef AT_BASE
p = (char *) getauxval(AT_BASE); p = (char *) ((intptr_t) getauxval(AT_BASE));
if (p) if (p)
HD(p); HD(p);
#endif #endif

View File

@@ -48,7 +48,7 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include "hash/sha512.h" #include <sha512.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/random.h> #include <linux/random.h>
@@ -68,9 +68,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);
@@ -333,7 +333,7 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
{ {
SHA512_CTX *ctx = data; SHA512_CTX *ctx = data;
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); SHA512_Update(ctx, (uint8_t *)&info->dlpi_addr, sizeof (info->dlpi_addr));
return (0); return (0);
} }
@@ -520,17 +520,17 @@ getentropy_fallback(void *buf, size_t len)
#ifdef HAVE_GETAUXVAL #ifdef HAVE_GETAUXVAL
#ifdef AT_RANDOM #ifdef AT_RANDOM
/* Not as random as you think but we take what we are given */ /* Not as random as you think but we take what we are given */
p = (char *) getauxval(AT_RANDOM); p = (char *) ((intptr_t) getauxval(AT_RANDOM));
if (p) if (p)
HR(p, 16); HR(p, 16);
#endif #endif
#ifdef AT_SYSINFO_EHDR #ifdef AT_SYSINFO_EHDR
p = (char *) getauxval(AT_SYSINFO_EHDR); p = (char *) ((intptr_t) getauxval(AT_SYSINFO_EHDR));
if (p) if (p)
HR(p, pgs); HR(p, pgs);
#endif #endif
#ifdef AT_BASE #ifdef AT_BASE
p = (char *) getauxval(AT_BASE); p = (char *) ((intptr_t) getauxval(AT_BASE));
if (p) if (p)
HD(p); HD(p);
#endif #endif

View File

@@ -76,9 +76,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);

View File

@@ -62,9 +62,9 @@
HD(b); \ HD(b); \
} while (0) } while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HR(x, l) (SHA512_Update(&ctx, (uint8_t *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HD(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) #define HF(x) (SHA512_Update(&ctx, (uint8_t *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len); int getentropy(void *buf, size_t len);
@@ -249,7 +249,7 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
{ {
SHA512_CTX *ctx = data; SHA512_CTX *ctx = data;
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); SHA512_Update(ctx, (uint8_t *)&info->dlpi_addr, sizeof (info->dlpi_addr));
return (0); return (0);
} }

1
src/hash/.gitignore vendored
View File

@@ -1 +0,0 @@
md5hl.c

View File

@@ -1,105 +0,0 @@
/** $MirOS: src/lib/libc/hash/helper.c,v 1.5 2007/05/07 15:21:18 tg Exp $ */
/* $OpenBSD: helper.c,v 1.8 2005/08/08 08:05:35 espie Exp $ */
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <hashinc>
/* ARGSUSED */
char *
HASHEnd(HASH_CTX *ctx, char *buf)
{
int i;
uint8_t digest[HASH_DIGEST_LENGTH];
#ifdef HASH_DIGEST_UPPERCASE
static const char hex[] = "0123456789ABCDEF";
#else
static const char hex[] = "0123456789abcdef";
#endif
if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL)
return (NULL);
HASHFinal(digest, ctx);
for (i = 0; i < HASH_DIGEST_LENGTH; i++) {
buf[i + i] = hex[digest[i] >> 4];
buf[i + i + 1] = hex[digest[i] & 0x0f];
}
buf[i + i] = '\0';
memset(digest, 0, sizeof(digest));
return (buf);
}
char *
HASHFileChunk(const char *filename, char *buf, off_t off, off_t len)
{
struct stat sb;
unsigned char buffer[BUFSIZ];
HASH_CTX ctx;
int fd, save_errno;
ssize_t nr;
HASHInit(&ctx);
if ((fd = open(filename, O_RDONLY)) < 0)
return (NULL);
if (len == 0) {
if (fstat(fd, &sb) == -1) {
close(fd);
return (NULL);
}
len = sb.st_size;
}
if ((len < 0) || (off > 0 && lseek(fd, off, SEEK_SET) < 0)) {
close(fd);
return (NULL);
}
while ((nr = read(fd, buffer,
(size_t)(len ? MIN(BUFSIZ, len) : BUFSIZ))) > 0) {
HASHUpdate(&ctx, buffer, (size_t)nr);
if (len > 0 && (len -= nr) == 0)
break;
}
save_errno = errno;
close(fd);
errno = save_errno;
return (nr < 0 ? NULL : HASHEnd(&ctx, buf));
}
char *
HASHFile(const char *filename, char *buf)
{
return (HASHFileChunk(filename, buf, (off_t)0, (off_t)0));
}
char *
HASHData(const unsigned char *data, size_t len, char *buf)
{
HASH_CTX ctx;
HASHInit(&ctx);
HASHUpdate(&ctx, data, len);
return (HASHEnd(&ctx, buf));
}

View File

@@ -1,248 +0,0 @@
/* $OpenBSD: md5.c,v 1.8 2005/08/08 08:05:35 espie Exp $ */
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
#include <sys/types.h>
#include <string.h>
#include <md5.h>
#define PUT_64BIT_LE(cp, value) do { \
(cp)[7] = (value) >> 56; \
(cp)[6] = (value) >> 48; \
(cp)[5] = (value) >> 40; \
(cp)[4] = (value) >> 32; \
(cp)[3] = (value) >> 24; \
(cp)[2] = (value) >> 16; \
(cp)[1] = (value) >> 8; \
(cp)[0] = (value); } while (0)
#define PUT_32BIT_LE(cp, value) do { \
(cp)[3] = (value) >> 24; \
(cp)[2] = (value) >> 16; \
(cp)[1] = (value) >> 8; \
(cp)[0] = (value); } while (0)
static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
MD5Init(MD5_CTX *ctx)
{
ctx->count = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
ctx->state[3] = 0x10325476;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
{
size_t have, need;
/* Check how many bytes we already have and how many more we need. */
have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
need = MD5_BLOCK_LENGTH - have;
/* Update bitcount */
ctx->count += (uint64_t)len << 3;
if (len >= need) {
if (have != 0) {
memcpy(ctx->buffer + have, input, need);
MD5Transform(ctx->state, ctx->buffer);
input += need;
len -= need;
have = 0;
}
/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
while (len >= MD5_BLOCK_LENGTH) {
MD5Transform(ctx->state, input);
input += MD5_BLOCK_LENGTH;
len -= MD5_BLOCK_LENGTH;
}
}
/* Handle any remaining bytes of data. */
if (len != 0)
memcpy(ctx->buffer + have, input, len);
}
/*
* Pad pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Pad(MD5_CTX *ctx)
{
uint8_t count[8];
size_t padlen;
/* Convert count to 8 bytes in little endian order. */
PUT_64BIT_LE(count, ctx->count);
/* Pad out to 56 mod 64. */
padlen = MD5_BLOCK_LENGTH -
((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
if (padlen < 1 + 8)
padlen += MD5_BLOCK_LENGTH;
MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
MD5Update(ctx, count, 8);
}
/*
* Final wrapup--call MD5Pad, fill in digest and zero out ctx.
*/
void
MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
{
int i;
MD5Pad(ctx);
if (digest != NULL) {
for (i = 0; i < 4; i++)
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
memset(ctx, 0, sizeof(*ctx));
}
}
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_LENGTH])
{
uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
#if BYTE_ORDER == LITTLE_ENDIAN
memcpy(in, block, sizeof(in));
#else
for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
in[a] = (uint32_t)(
(uint32_t)(block[a * 4 + 0]) |
(uint32_t)(block[a * 4 + 1]) << 8 |
(uint32_t)(block[a * 4 + 2]) << 16 |
(uint32_t)(block[a * 4 + 3]) << 24);
}
#endif
a = state[0];
b = state[1];
c = state[2];
d = state[3];
MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}

View File

@@ -1,53 +0,0 @@
/*-
* Copyright 2005 Colin Percival
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#ifndef _SHA512_H_
#define _SHA512_H_
#include <sys/types.h>
#define SHA512_DIGEST_LENGTH 64
typedef struct SHA512Context {
uint64_t state[8];
uint64_t count[2];
unsigned char buf[128];
} SHA512_CTX;
__BEGIN_DECLS
void SHA512_Init(SHA512_CTX *);
void SHA512_Update(SHA512_CTX *, const void *, size_t);
void SHA512_Final(unsigned char [64], SHA512_CTX *);
char *SHA512_End(SHA512_CTX *, char *);
char *SHA512_File(const char *, char *);
char *SHA512_FileChunk(const char *, char *, off_t, off_t);
char *SHA512_Data(const void *, unsigned int, char *);
__END_DECLS
#endif /* !_SHA512_H_ */

View File

@@ -1,318 +0,0 @@
/*-
* Copyright 2005 Colin Percival
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#include <sys/endian.h>
#include <sys/types.h>
#include <string.h>
#include "sha512.h"
#if BYTE_ORDER == BIG_ENDIAN
/* Copy a vector of big-endian uint64_t into a vector of bytes */
#define be64enc_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
/* Copy a vector of bytes into a vector of big-endian uint64_t */
#define be64dec_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
#else /* BYTE_ORDER != BIG_ENDIAN */
/*
* Encode a length len/4 vector of (uint64_t) into a length len vector of
* (unsigned char) in big-endian form. Assumes len is a multiple of 8.
*/
static void
be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
{
size_t i;
for (i = 0; i < len / 8; i++)
be64enc(dst + i * 8, src[i]);
}
/*
* Decode a big-endian length len vector of (unsigned char) into a length
* len/4 vector of (uint64_t). Assumes len is a multiple of 8.
*/
static void
be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
{
size_t i;
for (i = 0; i < len / 8; i++)
dst[i] = be64dec(src + i * 8);
}
#endif /* BYTE_ORDER != BIG_ENDIAN */
/* Elementary functions used by SHA512 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (64 - n)))
#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
/* SHA512 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, k) \
RND(S[(80 - i) % 8], S[(81 - i) % 8], \
S[(82 - i) % 8], S[(83 - i) % 8], \
S[(84 - i) % 8], S[(85 - i) % 8], \
S[(86 - i) % 8], S[(87 - i) % 8], \
W[i] + k)
/*
* SHA512 block compression function. The 512-bit state is transformed via
* the 512-bit input block to produce a new state.
*/
static void
SHA512_Transform(uint64_t * state, const unsigned char block[128])
{
uint64_t W[80];
uint64_t S[8];
uint64_t t0, t1;
int i;
/* 1. Prepare message schedule W. */
be64dec_vect(W, block, 128);
for (i = 16; i < 80; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
/* 2. Initialize working variables. */
memcpy(S, state, 64);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
RNDr(S, W, 1, 0x7137449123ef65cdULL);
RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);
RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);
RNDr(S, W, 4, 0x3956c25bf348b538ULL);
RNDr(S, W, 5, 0x59f111f1b605d019ULL);
RNDr(S, W, 6, 0x923f82a4af194f9bULL);
RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);
RNDr(S, W, 8, 0xd807aa98a3030242ULL);
RNDr(S, W, 9, 0x12835b0145706fbeULL);
RNDr(S, W, 10, 0x243185be4ee4b28cULL);
RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);
RNDr(S, W, 12, 0x72be5d74f27b896fULL);
RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);
RNDr(S, W, 14, 0x9bdc06a725c71235ULL);
RNDr(S, W, 15, 0xc19bf174cf692694ULL);
RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);
RNDr(S, W, 17, 0xefbe4786384f25e3ULL);
RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);
RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);
RNDr(S, W, 20, 0x2de92c6f592b0275ULL);
RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);
RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);
RNDr(S, W, 23, 0x76f988da831153b5ULL);
RNDr(S, W, 24, 0x983e5152ee66dfabULL);
RNDr(S, W, 25, 0xa831c66d2db43210ULL);
RNDr(S, W, 26, 0xb00327c898fb213fULL);
RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);
RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);
RNDr(S, W, 29, 0xd5a79147930aa725ULL);
RNDr(S, W, 30, 0x06ca6351e003826fULL);
RNDr(S, W, 31, 0x142929670a0e6e70ULL);
RNDr(S, W, 32, 0x27b70a8546d22ffcULL);
RNDr(S, W, 33, 0x2e1b21385c26c926ULL);
RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);
RNDr(S, W, 35, 0x53380d139d95b3dfULL);
RNDr(S, W, 36, 0x650a73548baf63deULL);
RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);
RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);
RNDr(S, W, 39, 0x92722c851482353bULL);
RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);
RNDr(S, W, 41, 0xa81a664bbc423001ULL);
RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);
RNDr(S, W, 43, 0xc76c51a30654be30ULL);
RNDr(S, W, 44, 0xd192e819d6ef5218ULL);
RNDr(S, W, 45, 0xd69906245565a910ULL);
RNDr(S, W, 46, 0xf40e35855771202aULL);
RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);
RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);
RNDr(S, W, 49, 0x1e376c085141ab53ULL);
RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);
RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);
RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);
RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);
RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);
RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);
RNDr(S, W, 56, 0x748f82ee5defb2fcULL);
RNDr(S, W, 57, 0x78a5636f43172f60ULL);
RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);
RNDr(S, W, 59, 0x8cc702081a6439ecULL);
RNDr(S, W, 60, 0x90befffa23631e28ULL);
RNDr(S, W, 61, 0xa4506cebde82bde9ULL);
RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);
RNDr(S, W, 63, 0xc67178f2e372532bULL);
RNDr(S, W, 64, 0xca273eceea26619cULL);
RNDr(S, W, 65, 0xd186b8c721c0c207ULL);
RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);
RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);
RNDr(S, W, 68, 0x06f067aa72176fbaULL);
RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);
RNDr(S, W, 70, 0x113f9804bef90daeULL);
RNDr(S, W, 71, 0x1b710b35131c471bULL);
RNDr(S, W, 72, 0x28db77f523047d84ULL);
RNDr(S, W, 73, 0x32caab7b40c72493ULL);
RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);
RNDr(S, W, 75, 0x431d67c49c100d4cULL);
RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);
RNDr(S, W, 77, 0x597f299cfc657e2aULL);
RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);
RNDr(S, W, 79, 0x6c44198c4a475817ULL);
/* 4. Mix local working variables into global state */
for (i = 0; i < 8; i++)
state[i] += S[i];
}
static unsigned char PAD[128] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Add padding and terminating bit-count. */
static void
SHA512_Pad(SHA512_CTX * ctx)
{
unsigned char len[16];
uint64_t r, plen;
/*
* Convert length to a vector of bytes -- we do this now rather
* than later because the length will change after we pad.
*/
be64enc_vect(len, ctx->count, 16);
/* Add 1--128 bytes so that the resulting length is 112 mod 128 */
r = (ctx->count[1] >> 3) & 0x7f;
plen = (r < 112) ? (112 - r) : (240 - r);
SHA512_Update(ctx, PAD, (size_t)plen);
/* Add the terminating bit-count */
SHA512_Update(ctx, len, 16);
}
/* SHA-512 initialization. Begins a SHA-512 operation. */
void
SHA512_Init(SHA512_CTX * ctx)
{
/* Zero bits processed so far */
ctx->count[0] = ctx->count[1] = 0;
/* Magic initialization constants */
ctx->state[0] = 0x6a09e667f3bcc908ULL;
ctx->state[1] = 0xbb67ae8584caa73bULL;
ctx->state[2] = 0x3c6ef372fe94f82bULL;
ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
ctx->state[4] = 0x510e527fade682d1ULL;
ctx->state[5] = 0x9b05688c2b3e6c1fULL;
ctx->state[6] = 0x1f83d9abfb41bd6bULL;
ctx->state[7] = 0x5be0cd19137e2179ULL;
}
/* Add bytes into the hash */
void
SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
{
uint64_t bitlen[2];
uint64_t r;
const unsigned char *src = in;
/* Number of bytes left in the buffer from previous updates */
r = (ctx->count[1] >> 3) & 0x7f;
/* Convert the length into a number of bits */
bitlen[1] = ((uint64_t)len) << 3;
bitlen[0] = ((uint64_t)len) >> 61;
/* Update number of bits */
if ((ctx->count[1] += bitlen[1]) < bitlen[1])
ctx->count[0]++;
ctx->count[0] += bitlen[0];
/* Handle the case where we don't need to perform any transforms */
if (len < 128 - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block */
memcpy(&ctx->buf[r], src, 128 - r);
SHA512_Transform(ctx->state, ctx->buf);
src += 128 - r;
len -= 128 - r;
/* Perform complete blocks */
while (len >= 128) {
SHA512_Transform(ctx->state, src);
src += 128;
len -= 128;
}
/* Copy left over data into buffer */
memcpy(ctx->buf, src, len);
}
/*
* SHA-512 finalization. Pads the input data, exports the hash value,
* and clears the context state.
*/
void
SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx)
{
/* Add padding */
SHA512_Pad(ctx);
/* Write the hash */
be64enc_vect(digest, ctx->state, 64);
/* Clear the context state */
memset((void *)ctx, 0, sizeof(*ctx));
}

Some files were not shown because too many files have changed in this diff Show More