summaryrefslogtreecommitdiff
path: root/static/openbsd/man3
diff options
context:
space:
mode:
Diffstat (limited to 'static/openbsd/man3')
-rw-r--r--static/openbsd/man3/CMSG_DATA.3158
-rw-r--r--static/openbsd/man3/Makefile16
-rw-r--r--static/openbsd/man3/assert.388
-rw-r--r--static/openbsd/man3/bit_alloc.3175
-rw-r--r--static/openbsd/man3/dl_iterate_phdr.383
-rw-r--r--static/openbsd/man3/dlfcn.3323
-rw-r--r--static/openbsd/man3/end.361
-rw-r--r--static/openbsd/man3/intro.3527
-rw-r--r--static/openbsd/man3/makedev.394
-rw-r--r--static/openbsd/man3/offsetof.346
-rw-r--r--static/openbsd/man3/queue.31196
-rw-r--r--static/openbsd/man3/sysexits.3137
-rw-r--r--static/openbsd/man3/timeradd.3202
-rw-r--r--static/openbsd/man3/tree.3583
-rw-r--r--static/openbsd/man3/va_start.3268
15 files changed, 3957 insertions, 0 deletions
diff --git a/static/openbsd/man3/CMSG_DATA.3 b/static/openbsd/man3/CMSG_DATA.3
new file mode 100644
index 00000000..309be7ff
--- /dev/null
+++ b/static/openbsd/man3/CMSG_DATA.3
@@ -0,0 +1,158 @@
+.\" $OpenBSD: CMSG_DATA.3,v 1.6 2017/04/03 19:40:43 otto Exp $
+.\" Written by Jared Yanovich <jaredy@openbsd.org>
+.\" Public domain, July 3, 2005
+.Dd $Mdocdate: April 3 2017 $
+.Dt CMSG_DATA 3
+.Os
+.Sh NAME
+.Nm CMSG_DATA ,
+.Nm CMSG_FIRSTHDR ,
+.Nm CMSG_LEN ,
+.Nm CMSG_NXTHDR ,
+.Nm CMSG_SPACE
+.Nd socket control message routines
+.Sh SYNOPSIS
+.In sys/socket.h
+.Ft void *
+.Fn CMSG_DATA "struct cmsghdr *"
+.Ft struct cmsghdr *
+.Fn CMSG_FIRSTHDR "struct msghdr *"
+.Ft size_t
+.Fn CMSG_LEN "size_t"
+.Ft struct cmsghdr *
+.Fn CMSG_NXTHDR "struct msghdr *" "struct cmsghdr *"
+.Ft size_t
+.Fn CMSG_SPACE "size_t"
+.Sh DESCRIPTION
+The control message API is used to construct ancillary data objects for
+use in control messages sent and received across sockets.
+.Pp
+Control messages are passed around by the
+.Xr recvmsg 2
+and
+.Xr sendmsg 2
+system calls.
+The
+.Vt cmsghdr
+structure, described in
+.Xr recvmsg 2 ,
+is used to specify a chain of control messages.
+.Pp
+These routines should be used instead of directly accessing the control
+message header members and data buffers as they ensure that necessary
+alignment constraints are met.
+.Pp
+The following routines are provided:
+.Bl -tag -width Ds
+.It Fn CMSG_DATA cmsg
+This routine accesses the data portion of the control message header
+.Fa cmsg .
+It ensures proper alignment constraints on the beginning of ancillary
+data are met.
+.It Fn CMSG_FIRSTHDR mhdr
+This routine accesses the first control message attached to the
+message
+.Fa msg .
+If no control messages are attached to the message, this routine
+returns
+.Dv NULL .
+.It Fn CMSG_LEN len
+This routine determines the size in bytes of a control message,
+which includes the control message header.
+.Fa len
+specifies the length of the data held by the control message.
+This value is what is normally stored in the
+.Fa cmsg_len
+of each control message.
+This routine accounts for any alignment constraints on the beginning of
+ancillary data.
+.It Fn CMSG_NXTHDR mhdr cmsg
+This routine returns the location of the control message following
+.Fa cmsg
+in the message
+.Fa mhdr .
+If
+.Fa cmsg
+is the last control message in the chain, this routine returns
+.Dv NULL .
+.It Fn CMSG_SPACE len
+This routine determines the size in bytes needed to hold a control
+message and its contents of length
+.Fa len ,
+which includes the control message header.
+This value is what is normally stored in
+.Fa msg_msgcontrollen .
+This routine accounts for any alignment constraints on the beginning of
+ancillary data as well as any needed to pad the next control message.
+.El
+.Sh EXAMPLES
+The following example constructs a control message containing a file
+descriptor and passes it over a socket:
+.Bd -literal -offset indent
+struct msghdr msg;
+struct cmsghdr *cmsg;
+union {
+ struct cmsghdr hdr;
+ unsigned char buf[CMSG_SPACE(sizeof(int))];
+} cmsgbuf;
+struct iovec io_vector[1];
+
+io_vector[0].iov_base = &ch;
+io_vector[0].iov_len = 1;
+
+memset(&msg, 0, sizeof(msg));
+msg.msg_control = &cmsgbuf.buf;
+msg.msg_controllen = sizeof(cmsgbuf.buf);
+msg.msg_iov = io_vector;
+msg.msg_iovlen = 1;
+
+cmsg = CMSG_FIRSTHDR(&msg);
+cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+cmsg->cmsg_level = SOL_SOCKET;
+cmsg->cmsg_type = SCM_RIGHTS;
+*(int *)CMSG_DATA(cmsg) = fd;
+
+if (sendmsg(s, &msg, 0) == -1)
+ err(1, "sendmsg");
+.Ed
+.Pp
+And an example that receives and decomposes the control message:
+.Bd -literal -offset indent
+struct msghdr msg;
+struct cmsghdr *cmsg;
+union {
+ struct cmsghdr hdr;
+ unsigned char buf[CMSG_SPACE(sizeof(int))];
+} cmsgbuf;
+struct iovec io_vector[1];
+
+io_vector[0].iov_base = &ch;
+io_vector[0].iov_len = 1;
+
+memset(&msg, 0, sizeof(msg));
+msg.msg_control = &cmsgbuf.buf;
+msg.msg_controllen = sizeof(cmsgbuf.buf);
+msg.msg_iov = io_vector;
+msg.msg_iovlen = 1;
+
+if (recvmsg(s, &msg, 0) == -1)
+ err(1, "recvmsg");
+if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
+ errx(1, "control message truncated");
+for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
+ cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS) {
+ fd = *(int *)CMSG_DATA(cmsg);
+ /* Do something with the descriptor. */
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr recvmsg 2 ,
+.Xr sendmsg 2 ,
+.Xr socket 2
+.Sh HISTORY
+The control message API first appeared in
+.Bx 4.2 .
diff --git a/static/openbsd/man3/Makefile b/static/openbsd/man3/Makefile
new file mode 100644
index 00000000..6870e97f
--- /dev/null
+++ b/static/openbsd/man3/Makefile
@@ -0,0 +1,16 @@
+MAN = assert.3 \
+ bit_alloc.3 \
+ CMSG_DATA.3 \
+ dl_iterate_phdr.3 \
+ dlfcn.3 \
+ end.3 \
+ intro.3 \
+ makedev.3 \
+ offsetof.3 \
+ queue.3 \
+ sysexits.3 \
+ timeradd.3 \
+ tree.3 \
+ va_start.3
+
+include ../../mandoc.mk
diff --git a/static/openbsd/man3/assert.3 b/static/openbsd/man3/assert.3
new file mode 100644
index 00000000..c47a25ec
--- /dev/null
+++ b/static/openbsd/man3/assert.3
@@ -0,0 +1,88 @@
+.\" $OpenBSD: assert.3,v 1.10 2014/12/10 21:15:30 schwarze Exp $
+.\" $NetBSD: assert.3,v 1.5 1994/11/30 15:24:30 jtc Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.\" @(#)assert.3 8.1 (Berkeley) 6/9/93
+.\"
+.Dd $Mdocdate: December 10 2014 $
+.Dt ASSERT 3
+.Os
+.Sh NAME
+.Nm assert
+.Nd expression verification macro
+.Sh SYNOPSIS
+.In assert.h
+.Fn assert expression
+.Sh DESCRIPTION
+The
+.Fn assert
+macro tests the given
+.Fa expression
+and if it is false, the calling process is terminated.
+A diagnostic message is written to
+.Dv stderr
+and the
+.Xr abort 3
+function is called, effectively terminating the program.
+.Pp
+If
+.Fa expression
+is true, the
+.Fn assert
+macro does nothing.
+.Pp
+The
+.Fn assert
+macro may be removed at compile time with the
+.Xr cc 1
+option
+.Fl DNDEBUG .
+.Sh DIAGNOSTICS
+The following diagnostic message is written to
+.Dv stderr
+if
+.Fa expression
+is false:
+.Bd -literal -offset indent
+"assertion \e"%s\e" failed: file \e"%s\e", line %d\en", \e
+ "expression", __FILE__, __LINE__);
+.Ed
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr abort 3
+.Sh STANDARDS
+The
+.Fn assert
+macro conforms to
+.St -ansiC .
+.Sh HISTORY
+An
+.Fn assert
+macro first appeared in
+.At v7 .
diff --git a/static/openbsd/man3/bit_alloc.3 b/static/openbsd/man3/bit_alloc.3
new file mode 100644
index 00000000..8144d2e0
--- /dev/null
+++ b/static/openbsd/man3/bit_alloc.3
@@ -0,0 +1,175 @@
+.\" $OpenBSD: bit_alloc.3,v 1.3 2022/09/11 06:38:11 jmc Exp $
+.\" $NetBSD: bitstring.3,v 1.4 1994/11/30 15:24:31 jtc Exp $
+.\"
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Vixie.
+.\" 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.
+.\"
+.\" @(#)bitstring.3 8.1 (Berkeley) 7/19/93
+.\"
+.Dd $Mdocdate: September 11 2022 $
+.Dt BIT_ALLOC 3
+.Os
+.Sh NAME
+.Nm bit_alloc ,
+.Nm bit_clear ,
+.Nm bit_decl ,
+.Nm bit_ffc ,
+.Nm bit_ffs ,
+.Nm bit_nclear ,
+.Nm bit_nset ,
+.Nm bit_set ,
+.Nm bitstr_size ,
+.Nm bit_test
+.Nd bit-string manipulation macros
+.Sh SYNOPSIS
+.In bitstring.h
+.Ft bitstr_t *
+.Fn bit_alloc "int nbits"
+.Fn bit_clear "bit_str name" "int bit"
+.Fn bit_decl "bit_str name" "int nbits"
+.Fn bit_ffc "bit_str name" "int nbits" "int *value"
+.Fn bit_ffs "bit_str name" "int nbits" "int *value"
+.Fn bit_nclear "bit_str name" "int start" "int stop"
+.Fn bit_nset "bit_str name" "int start" "int stop"
+.Fn bit_set "bit_str name" "int bit"
+.Fn bitstr_size "int nbits"
+.Fn bit_test "bit_str name" "int bit"
+.Sh DESCRIPTION
+These macros operate on strings of bits.
+.Pp
+The
+.Fn bit_alloc
+macro returns a pointer of type
+.Vt bitstr_t *
+to sufficient space to store
+.Fa nbits
+bits, or
+.Dv NULL
+if no space is available.
+.Pp
+The
+.Fn bit_decl
+macro allocates sufficient space to store
+.Fa nbits
+bits on the stack.
+.Pp
+The
+.Fn bitstr_size
+macro returns the number of elements of type
+.Vt bitstr_t
+necessary to store
+.Fa nbits
+bits.
+This is useful for copying bit strings.
+.Pp
+The
+.Fn bit_clear
+and
+.Fn bit_set
+macros clear or set the zero-based numbered bit
+.Fa bit ,
+in the bit string
+.Ar name .
+.Pp
+The
+.Fn bit_nclear
+and
+.Fn bit_nset
+macros clear or set the zero-based numbered bits from
+.Fa start
+to
+.Fa stop
+in the bit string
+.Ar name .
+.Pp
+The
+.Fn bit_test
+macro evaluates to non-zero if the zero-based numbered bit
+.Fa bit
+of bit string
+.Fa name
+is set, and zero otherwise.
+.Pp
+The
+.Fn bit_ffs
+macro stores in the location referenced by
+.Fa value
+the zero-based number of the first bit set in the array of
+.Fa nbits
+bits referenced by
+.Fa name .
+If no bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The
+.Fn bit_ffc
+macro stores in the location referenced by
+.Fa value
+the zero-based number of the first bit not set in the array of
+.Fa nbits
+bits referenced by
+.Fa name .
+If all bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The arguments to these macros are evaluated only once and may safely
+have side effects.
+.Sh EXAMPLES
+.Bd -literal -offset indent
+#include <limits.h>
+#include <bitstring.h>
+
+\&...
+#define LPR_BUSY_BIT 0
+#define LPR_FORMAT_BIT 1
+#define LPR_DOWNLOAD_BIT 2
+\&...
+#define LPR_AVAILABLE_BIT 9
+#define LPR_MAX_BITS 10
+
+make_lpr_available()
+{
+ bitstr_t bit_decl(bitlist, LPR_MAX_BITS);
+ ...
+ bit_nclear(bitlist, 0, LPR_MAX_BITS - 1);
+ ...
+ if (!bit_test(bitlist, LPR_BUSY_BIT)) {
+ bit_clear(bitlist, LPR_FORMAT_BIT);
+ bit_clear(bitlist, LPR_DOWNLOAD_BIT);
+ bit_set(bitlist, LPR_AVAILABLE_BIT);
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr malloc 3
+.Sh HISTORY
+These functions first appeared in
+.Bx 4.3 Reno .
diff --git a/static/openbsd/man3/dl_iterate_phdr.3 b/static/openbsd/man3/dl_iterate_phdr.3
new file mode 100644
index 00000000..e2bb89a9
--- /dev/null
+++ b/static/openbsd/man3/dl_iterate_phdr.3
@@ -0,0 +1,83 @@
+.\" $OpenBSD: dl_iterate_phdr.3,v 1.6 2022/09/11 06:38:11 jmc Exp $
+.\"
+.\" Copyright (c) 2005 Mark Kettenis
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: September 11 2022 $
+.Dt DL_ITERATE_PHDR 3
+.Os
+.Sh NAME
+.Nm dl_iterate_phdr
+.Nd iterate over program headers
+.Sh SYNOPSIS
+.In link.h
+.Ft int
+.Fn dl_iterate_phdr "int (*callback)(struct dl_phdr_info *, size_t, void*)" "void *data"
+.Sh DESCRIPTION
+The
+.Fn dl_iterate_phdr
+function iterates over all shared objects loaded into a process's
+address space, calling
+.Fa callback
+for each shared object, passing it information about the object's
+program headers and the
+.Fa data
+argument.
+Iteration continues until either there are no more objects to
+iterate over or
+.Fa callback
+returns a non-zero value.
+.Pp
+The information about the program headers is passed in a structure
+that is defined as:
+.Bd -literal
+struct dl_phdr_info {
+ Elf_Addr dlpi_addr;
+ const char *dlpi_name;
+ const Elf_Phdr *dlpi_phdr;
+ Elf_Half dlpi_phnum;
+};
+.Ed
+.Pp
+The members of
+.Vt struct dl_phdr_info
+have the following meaning:
+.Bl -tag -width XXXdlpi_phdr
+.It Fa dlpi_addr
+The base address at which the shared object is mapped into the address
+space of the calling process.
+.It Fa dlpi_name
+The name of the shared object.
+.It Fa dlpi_phdr
+A pointer to the shared object's program headers.
+.It Fa dlpi_phnum
+The number of program headers in the shared object.
+.El
+.Pp
+Future versions of
+.Ox
+might add more members to this structure.
+To make it possible for programs to check whether any new members have
+been added, the size of the structure is passed as an argument to
+.Fa callback .
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr ld.so 1 ,
+.Xr dlfcn 3 ,
+.Xr elf 5
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Ox 3.7 .
diff --git a/static/openbsd/man3/dlfcn.3 b/static/openbsd/man3/dlfcn.3
new file mode 100644
index 00000000..b499b1a6
--- /dev/null
+++ b/static/openbsd/man3/dlfcn.3
@@ -0,0 +1,323 @@
+.\" $OpenBSD: dlfcn.3,v 1.37 2025/06/13 18:34:00 schwarze Exp $
+.\" $NetBSD: dlfcn.3,v 1.3 1996/01/09 19:43:34 pk Exp $
+.\"
+.\" Copyright (c) 1995 Paul Kranenburg
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Paul Kranenburg.
+.\" 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd $Mdocdate: June 13 2025 $
+.Dt DLOPEN 3
+.Os
+.Sh NAME
+.Nm dlopen ,
+.Nm dlclose ,
+.Nm dlsym ,
+.Nm dladdr ,
+.Nm dlctl ,
+.Nm dlerror
+.Nd dynamic link interface
+.Sh SYNOPSIS
+.In dlfcn.h
+.Ft void *
+.Fn dlopen "const char *path" "int mode"
+.Ft int
+.Fn dlclose "void *handle"
+.Ft void *
+.Fn dlsym "void *handle" "const char *symbol"
+.Ft int
+.Fn dladdr "const void *addr" "Dl_info *info"
+.Ft int
+.Fn dlctl "void *handle" "int cmd" "void *data"
+.Ft char *
+.Fn dlerror "void"
+.Sh DESCRIPTION
+These functions provide an interface to the run-time linker
+.Xr ld.so 1 .
+They allow new shared objects to be loaded into a process's address space
+under program control.
+.Pp
+The
+.Fn dlopen
+function takes the name of a shared object as its first argument.
+The shared object is mapped into the address space, relocated, and its external
+references are resolved in the same way as is done with the implicitly loaded
+shared libraries at program startup.
+.Pp
+The
+.Fa path
+parameter can be specified as either an absolute pathname to a shared library
+or just the name of the shared library itself.
+When an absolute pathname is specified,
+only the path provided will be searched for the shared library.
+When just a shared library is specified,
+the same paths will be searched that are used for
+.Dq intrinsic
+shared library searches.
+.Pp
+Shared libraries take the following form:
+.Pp
+.Dl lib<name>.so[.xx[.yy]]
+.Pp
+When a shared library is specified without a version or with a partial version,
+the same library search rules apply that are used for
+.Dq intrinsic
+shared library searches.
+A null pointer supplied for
+.Fa path
+will return a special
+.Fa handle
+that behaves the same as the
+.Dv RTLD_DEFAULT
+special
+.Fa handle .
+.Pp
+The
+.Fa mode
+parameter specifies symbol resolution time and symbol visibility.
+One of the following values may be used to specify symbol resolution time:
+.Bl -tag -width "RTLD_LAZYXX" -offset indent
+.It Sy RTLD_NOW
+Symbols are resolved immediately.
+.It Sy RTLD_LAZY
+Symbols are resolved when they are first referred to.
+This is the default value if resolution time is unspecified.
+.El
+.Pp
+One of the following values may be used to specify symbol visibility:
+.Bl -tag -width "RTLD_GLOBAL" -offset indent
+.It Sy RTLD_GLOBAL
+The object's symbols and the symbols of its dependencies will be visible to
+other objects.
+.It Sy RTLD_LOCAL
+The object's symbols and the symbols of its dependencies will not be visible to
+other objects.
+This is the default value if visibility is unspecified.
+.El
+.Pp
+To specify both resolution time and visibility, bitwise inclusive OR one of
+each of the above values together.
+If an object was opened with RTLD_LOCAL and later opened with RTLD_GLOBAL,
+then it is promoted to RTLD_GLOBAL.
+.Pp
+Additionally, the following flag may be ORed into the mode argument:
+.Bl -tag -width "RTLD_NODELETE" -offset indent
+.It Sy RTLD_NODELETE
+Prevents unload of the loaded object on
+.Fn dlclose .
+.It Sy RTLD_NOLOAD
+Only return valid handle for the object if it is already loaded in
+the process address space, otherwise NULL is returned.
+Other mode flags may be specified, which will be applied for promotion
+for the found object.
+.El
+.Pp
+The main executable's symbols are normally invisible to
+.Fn dlopen
+symbol resolution.
+Those symbols will be visible if linking is done with
+.Xr cc 1
+.Fl rdynamic ,
+which is equivalent to
+.Xr ld 1
+.Fl -export-dynamic .
+.Pp
+All shared objects loaded at program startup are globally visible.
+.Pp
+.Fn dlopen
+returns a
+.Fa handle
+to be used in calls to
+.Fn dlclose ,
+.Fn dlsym ,
+and
+.Fn dlctl .
+If the named shared object has already been loaded by a previous call to
+.Fn dlopen
+and not yet unloaded by
+.Fn dlclose ,
+a
+.Fa handle
+referring to the resident copy is returned.
+.Pp
+.Fn dlclose
+unlinks and removes the object referred to by
+.Fa handle
+from the process address space.
+If multiple calls to
+.Fn dlopen
+have been done on this object or the object is a dependency of another object
+then the object is removed when its reference count drops to zero.
+.Fn dlclose
+returns 0 on success and non-zero on failure.
+.Pp
+.Fn dlsym
+searches for a definition of
+.Fa symbol
+in the object designated by
+.Fa handle
+and all shared objects that it depends on.
+The symbol's address is returned.
+If the symbol cannot be resolved,
+.Dv NULL
+is returned.
+.Pp
+.Fn dlsym
+may also be called with special
+.Fa handles .
+.Fn dlsym
+respects symbol visibility as specified by the
+.Fn dlopen
+.Fa mode
+parameter.
+However, the symbols of an object's dependencies are always visible to it.
+The following special
+.Fa handles
+may be used with
+.Fn dlsym :
+.Bl -tag -width "RTLD_DEFAULTXX" -offset indent
+.It Sy NULL
+Interpreted as a reference to the executable or shared object
+from which the call is being made.
+Thus an object can reference its own symbols and the symbols of its
+dependencies without calling
+.Fn dlopen .
+.It Sy RTLD_DEFAULT
+All the visible shared objects and the executable will be searched
+in the order they were loaded.
+.It Sy RTLD_NEXT
+The search for
+.Fa symbol
+is limited to the visible shared objects which were loaded
+after the one issuing the call to
+.Fn dlsym .
+Thus, if
+.Fn dlsym
+is called from the main program, all the visible shared libraries are searched.
+If it is called from a shared library, all subsequently visible shared
+libraries are searched.
+.It Sy RTLD_SELF
+The search for
+.Fa symbol
+is limited to the shared object issuing the call to
+.Fn dlsym
+and those shared objects which were loaded after it that are visible.
+.El
+.Pp
+.Fn dladdr
+queries the dynamic linker for information about the shared object
+containing the address
+.Fa addr .
+The information is returned in the structure specified by
+.Fa info .
+The structure contains at least the following members:
+.Bl -tag -width "XXXconst char *dli_fname"
+.It Li "const char *dli_fname"
+The pathname of the shared object containing the address
+.Fa addr .
+.It Li "void *dli_fbase"
+The base address at which the shared object is mapped into the
+address space of the calling process.
+.It Li "const char *dli_sname"
+The name of the nearest run-time symbol with an address less than or
+equal to
+.Fa addr .
+.Pp
+If no symbol with a suitable address is found, both this field and
+.Va dli_saddr
+are set to
+.Dv NULL .
+.It Li "void *dli_saddr"
+The address of the symbol returned in
+.Va dli_sname .
+.El
+.Pp
+If a mapped shared object containing
+.Fa addr
+cannot be found,
+.Fn dladdr
+returns 0.
+In that case, a message detailing the failure can be retrieved by
+calling
+.Fn dlerror .
+On success, a non-zero value is returned.
+Note: both strings pointed at by
+.Va dli_fname
+and
+.Va dli_sname
+reside in memory private to the run-time linker module and should not
+be modified by the caller.
+.Pp
+In dynamically linked programs, the address of a global function will
+point to its program linkage table entry, rather than to the entry
+point of the function itself.
+This causes most global functions to appear to be defined within the
+main executable, rather than in the shared libraries where the actual
+code resides.
+.Pp
+.Fn dlctl
+provides an interface similar to
+.Xr ioctl 2
+to control several aspects of the run-time linker's operation.
+This interface is currently under development.
+.Pp
+.Fn dlerror
+returns a character string representing the most recent error that has
+occurred while processing one of the other functions described here.
+If no dynamic linking errors have occurred since the last invocation of
+.Fn dlerror ,
+.Fn dlerror
+returns
+.Dv NULL .
+Thus, invoking
+.Fn dlerror
+a second time, immediately following a prior invocation, will result in
+.Dv NULL
+being returned.
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr ld.so 1 ,
+.Xr elf 5
+.Sh STANDARDS
+The
+.Fn dladdr ,
+.Fn dlclose ,
+.Fn dlerror ,
+.Fn dlopen ,
+and
+.Fn dlsym
+functions conform to
+.St -p1003.1-2024 .
+.Sh HISTORY
+Some of the
+.Nm dl*
+functions first appeared in SunOS 4.
+.Sh CAVEATS
+Loading untrustworthy libraries into the process's address space with
+.Nm dlopen
+is very dangerous because system-dependent initialization steps occur
+including the calling of constructor functions, even if the library
+is otherwise unused.
diff --git a/static/openbsd/man3/end.3 b/static/openbsd/man3/end.3
new file mode 100644
index 00000000..e2391807
--- /dev/null
+++ b/static/openbsd/man3/end.3
@@ -0,0 +1,61 @@
+.\" $OpenBSD: end.3,v 1.11 2007/05/31 19:19:48 jmc Exp $
+.\" $NetBSD: end.3,v 1.5 1996/03/01 00:17:49 jtc Exp $
+.\"
+.\" Copyright (c) 1986
+.\" 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.
+.\"
+.\" @(#)end.3 6.4 (Berkeley) 1/24/94
+.\"
+.Dd $Mdocdate: May 31 2007 $
+.Dt END 3
+.Os
+.Sh NAME
+.Nm end ,
+.Nm etext ,
+.Nm edata
+.Nd end boundaries of image segments
+.Sh SYNOPSIS
+.Vt extern end;
+.Vt extern etext;
+.Vt extern edata;
+.Sh DESCRIPTION
+The addresses of the global symbols
+.Va etext ,
+.Va edata ,
+and
+.Va end
+correspond to the next address following the end of the text segment,
+the end of the initialized data segment, and the end of the data segment
+.Pq Tn BSS .
+.Sh SEE ALSO
+.Xr brk 2 ,
+.Xr malloc 3
+.Sh HISTORY
+An
+.Nm
+manual appeared in
+.At v6 .
diff --git a/static/openbsd/man3/intro.3 b/static/openbsd/man3/intro.3
new file mode 100644
index 00000000..ee0c5eaf
--- /dev/null
+++ b/static/openbsd/man3/intro.3
@@ -0,0 +1,527 @@
+.\" $OpenBSD: intro.3,v 1.100 2024/05/09 17:57:36 jmc Exp $
+.\" $NetBSD: intro.3,v 1.5 1995/05/10 22:46:24 jtc Exp $
+.\"
+.\" Copyright (c) 1980, 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.
+.\"
+.\" @(#)intro.3 8.1 (Berkeley) 6/5/93
+.\"
+.Dd $Mdocdate: May 9 2024 $
+.Dt INTRO 3
+.Os
+.Sh NAME
+.Nm intro
+.Nd introduction to the C libraries
+.Sh SYNOPSIS
+.Nm cc
+.Op Ar flags
+.Ar
+.Op Fl llibrary
+.Sh DESCRIPTION
+The manual pages in section 3 provide an overview of the C library
+functions, their error returns, and other common definitions and concepts.
+Most of these functions are available from the C library,
+.Em libc .
+Other libraries, such as the math library,
+.Em libm ,
+must be indicated at compile time with the
+.Fl l
+option of the compiler.
+.Pp
+The various libraries (followed by the loader flag):
+.Pp
+.Bl -tag -width "libkvm" -compact
+.It libLLVM Pq Fl lLLVM
+LLVM components in a single library.
+.Pp
+.It libagentx Pq Fl lagentx
+AgentX client library.
+Used for applications to export metrics to AgentX capable snmp daemons.
+See
+.Xr agentx 3 .
+.Pp
+.It libc Pq Fl lc
+Standard C library functions.
+When using the C compiler
+.Xr cc 1 ,
+it is not necessary to supply the loader flag
+.Fl lc
+for these functions.
+There are several
+.Dq libraries
+or groups of functions included inside of libc: the standard I/O routines,
+database routines,
+bit operators,
+string operators,
+character tests and character operators,
+cryptographic routines,
+storage allocation,
+time functions,
+signal handling,
+and more.
+.Pp
+.It libc++ Pq Fl lc++
+LLVM standard C++ library.
+Note: users do not normally have to explicitly link with this library.
+.Pp
+.It libc++abi Pq Fl lc++abi
+LLVM C++ runtime library.
+Note: users do not normally have to explicitly link with this library.
+.Pp
+.It libcbor Pq Fl lcbor
+An implementation of the Concise Binary Object Representation
+.Pq CBOR
+encoding format defined in RFC 7049.
+.Pp
+.It libcrypto Pq Fl lcrypto
+Provides functionality such as symmetric encryption, public key cryptography,
+digests, message authentication codes,
+and certificate handling.
+See
+.Xr crypto 3 .
+.Pp
+.It libcurses Pq Fl lcurses
+.It libncurses Pq Fl lncurses
+.It libncursesw Pq Fl lncursesw
+.It libtermcap Pq Fl ltermcap
+.It libtermlib Pq Fl ltermlib
+Terminal-independent screen management routines for two-dimensional
+non-bitmap display terminals.
+This implementation is
+.Dq new curses
+and is a replacement for
+.Bx 4.2
+classic curses.
+The libraries
+.Em libncurses ,
+.Em libncursesw ,
+.Em libtermcap ,
+and
+.Em libtermlib
+are all hard links to
+.Em libcurses .
+This is for compatibility purposes only;
+new programs should link with
+.Fl lcurses .
+See
+.Xr curses 3
+and
+.Xr termcap 3 .
+.Pp
+.It libedit Pq Fl ledit
+Generic line editing and history functions, similar to those found in
+.Xr sh 1 .
+Functions using the
+.Em libedit
+library must be linked with the
+.Em libcurses
+library, i.e.\&
+.Fl ledit lcurses .
+See
+.Xr editline 3 .
+.Pp
+.It libelf Pq Fl lelf
+Library routines for manipulating ELF objects.
+See
+.Xr elf 3 .
+.Pp
+.It libevent Pq Fl levent
+Provides a mechanism to execute a function when a specific event on a
+file descriptor occurs or after a given time has passed.
+See
+.Xr event 3 .
+.Pp
+.It libexecinfo Pq Fl lexecinfo
+Library providing backtrace functions.
+See
+.Xr backtrace 3 .
+.Pp
+.It libexpat Pq Fl lexpat
+Library routines for parsing XML documents.
+.Pp
+.It libfido2 Pq Fl lfido2
+Library for communication with U2F/FIDO2 devices over USB.
+.Pp
+.It libform Pq Fl lform
+.It libformw Pq Fl lformw
+Terminal-independent facilities for composing form screens on
+character-cell terminals.
+Functions using the
+.Em libform
+library must be linked with the
+.Em libcurses
+library, i.e.\&
+.Fl lform lcurses .
+.Em libformw
+is a hard link to
+.Em libform
+intended for use with
+.Em libncursesw
+wide-character functions.
+See
+.Xr form 3 .
+.Pp
+.It libfuse Pq Fl lfuse
+File system in userland library.
+See
+.Xr fuse_main 3 .
+.Pp
+.It libgcc Pq Fl lgcc
+GCC runtime support,
+including long arithmetic, propolice,
+and language independent exception support.
+Note: users do not normally have to explicitly link with this library.
+.Pp
+.It libiberty Pq Fl liberty
+Collection of subroutines missing in other operating systems,
+as well as the C++ demangler and other functions used by
+the GNU toolchain.
+.Pp
+.It libkeynote Pq Fl lkeynote
+System library for the keynote trust-management system.
+Trust-management systems provide standard, general-purpose mechanisms
+for specifying application security policies and credentials.
+Functions using the libkeynote library must be linked with the
+.Em libm
+and
+.Em libcrypto
+libraries, i.e.\&
+.Fl lkeynote lm lcrypto .
+See
+.Xr keynote 3
+and
+.Xr keynote 4 .
+.Pp
+.It libkvm Pq Fl lkvm
+Kernel memory interface library.
+Provides a uniform interface for accessing kernel virtual memory images,
+including live systems and crash dumps.
+See
+.Xr kvm 3 .
+.Pp
+.It libl Pq Fl l\&l
+.It libfl Pq Fl lfl
+The library for
+.Xr lex 1 ,
+a lexical analyzer generator.
+The
+.Em libfl
+library
+is a hard link to
+.Em libl .
+.Pp
+.It libm Pq Fl lm
+Mathematical functions which comprise the C math library,
+.Em libm .
+.Pp
+.It libmenu Pq Fl lmenu
+.It libmenuw Pq Fl lmenuw
+Terminal-independent facilities for composing menu systems on
+character-cell terminals.
+Functions using the
+.Em libmenu
+library must be linked with the
+.Em libcurses
+library, i.e.\&
+.Fl lmenu lcurses .
+.Em libmenuw
+is a hard link to
+.Em libmenu
+intended for use with
+.Em libncursesw
+wide-character functions.
+See
+.Xr menu 3 .
+.Pp
+.It libossaudio Pq Fl lossaudio
+Provides an emulation of the OSS
+.Pq Linux
+audio interface.
+This is used only for porting programs.
+See
+.Xr ossaudio 3 .
+.Pp
+.It libpanel Pq Fl lpanel
+.It libpanelw Pq Fl lpanelw
+Terminal-independent facilities for stacked windows on
+character-cell terminals.
+Functions using the
+.Em libpanel
+library must be linked with the
+.Em libcurses
+library, i.e.\&
+.Fl lpanel lcurses .
+.Em libpanelw
+is a hard link to
+.Em libpanel
+intended for use with
+.Em libncursesw
+wide-character functions.
+See
+.Xr panel 3 .
+.Pp
+.It libpcap Pq Fl lpcap
+Packet capture library.
+All packets on the network, even those destined for other hosts,
+are accessible through this library.
+See
+.Xr pcap_open_live 3 .
+.Pp
+.It libperl Pq Fl lperl
+Support routines for
+.Xr perl 1 .
+.Pp
+.It libpthread Pq Fl lpthread
+.St -p1003.1-2001
+threads API.
+See
+.Xr pthreads 3 .
+.Pp
+.It libradius Pq Fl lradius
+Support routines for the RADIUS library.
+See
+.Xr radius_new_request_packet 3 .
+.Pp
+.It libreadline Pq Fl lreadline
+Command line editing interface.
+See
+.Xr readline 3 .
+.Pp
+.It librpcsvc Pq Fl lrpcsvc
+Generated by
+.Xr rpcgen 1 ,
+containing stub functions for many common
+.Xr rpc 3
+protocols.
+.Pp
+.It libskey Pq Fl lskey
+Support library for the S/Key one time password
+.Pq OTP
+authentication toolkit.
+See
+.Xr skey 3 .
+.Pp
+.It libsndio Pq Fl lsndio
+Library for
+.Xr audio 4
+hardware and the
+.Xr sndiod 8
+audio server.
+See
+.Xr sio_open 3 .
+.Pp
+.It libssl Pq Fl lssl
+Implements the Transport Layer Security
+.Pq TLS
+protocol, the successor to the Secure Sockets Layer (SSL) protocol.
+See
+.Xr ssl 3 .
+.Pp
+.It libstdc++ Pq Fl lstdc++
+GNU standard C++ library.
+Note: users do not normally have to explicitly link with this library.
+.Pp
+.It libsupc++ Pq Fl lsupc++
+GNU C++ runtime library.
+Note: users do not normally have to explicitly link with this library.
+.Pp
+.It libtls Pq Fl ltls
+A Transport Layer Security library with a clean and easy to use interface.
+See
+.Xr tls_init 3 .
+.Pp
+.It libusbhid Pq Fl lusbhid
+Routines to extract data from USB Human Interface Devices
+.Pq HIDs .
+See
+.Xr usbhid 3 .
+.Pp
+.It libutil Pq Fl lutil
+System utility functions.
+.Pp
+.It liby Pq Fl ly
+The library for
+.Xr yacc 1 ,
+an LALR parser generator.
+.Pp
+.It libz Pq Fl lz
+General purpose data compression library.
+The functions in this library are documented in
+.Xr compress 3 .
+The data format is described in RFCs 1950 \- 1952.
+.El
+.Pp
+Platform-specific libraries:
+.Bl -tag -width "libkvm"
+.It libalpha Pq Fl lalpha
+Alpha I/O and memory access functions.
+See
+.Xr inb 2 .
+.It libamd64 Pq Fl lamd64
+AMD64 I/O and memory access functions.
+See
+.Xr amd64_iopl 2 .
+.It libi386 Pq Fl li386
+i386 I/O and memory access functions.
+See
+.Xr i386_iopl 2 .
+.El
+.Sh LIBRARY TYPES
+The system libraries are located in
+.Pa /usr/lib .
+Typically, a library will have a number of variants:
+.Bd -unfilled -offset indent
+libc.a
+libc_p.a
+libc.so.30.1
+.Ed
+.Pp
+Libraries with an
+.Sq .a
+suffix are static.
+When a program is linked against a library, all the library code
+will be linked into the binary.
+This means the binary can be run even when the libraries are unavailable.
+However, it can be inefficient with memory usage.
+The C compiler,
+.Xr cc 1 ,
+can be instructed to link statically by specifying the
+.Fl static
+flag.
+.Pp
+Libraries with a
+.Sq _p.a
+suffix are profiling libraries.
+They contain extra information suitable for analysing programs,
+such as execution speed and call counts.
+This in turn can be interpreted by utilities such as
+.Xr gprof 1 .
+The C compiler,
+.Xr cc 1 ,
+can be instructed to generate profiling code,
+or to link with profiling libraries, by specifying the
+.Fl pg
+flag.
+.Pp
+Libraries with a
+.Sq .so.X.Y
+suffix are dynamic libraries.
+When code is compiled dynamically, the library code that the application needs
+is not linked into the binary.
+Instead, data structures are added containing information about which dynamic
+libraries to link with.
+When the binary is executed, the run-time linker
+.Xr ld.so 1
+reads these data structures, and loads them at a virtual address using the
+.Xr mmap 2
+system call.
+.Pp
+.Sq X
+represents the major number of the library, and
+.Sq Y
+represents the minor number.
+In general, a binary will be able to use a dynamic library with a differing
+minor number, but the major numbers must match.
+In the example above, a binary linked with minor number
+.Sq 3
+would be linkable against libc.so.30.1,
+while a binary linked with major number
+.Sq 31
+would not.
+.Pp
+The advantages of dynamic libraries are that multiple instances of the same
+program can share address space, and the physical size of the binary is
+smaller.
+The disadvantage is the added complexity that comes with loading the
+libraries dynamically, and the extra time taken to load the libraries.
+Of course, if the libraries are not available, the binary will be unable
+to execute.
+The C compiler,
+.Xr cc 1 ,
+can be instructed to link dynamically by specifying the
+.Fl shared
+flag, although on systems that support it, this will be the default and
+need not be specified.
+.Pp
+Shared libraries, as well as static libraries on architectures which produce
+position-independent executables
+.Pq PIEs
+by default, contain position-independent code
+.Pq PIC .
+Normally, compilers produce relocatable code.
+Relocatable code needs to be modified at run-time, depending on where in
+memory it is to be run.
+PIC code does not need to be modified at run-time, but is less efficient than
+relocatable code.
+The C compiler,
+.Xr cc 1 ,
+can be instructed to generate PIC code by specifying the
+.Fl fpic
+or
+.Fl fPIC
+flags.
+.Pp
+With the exception of dynamic libraries, libraries are generated using the
+.Xr ar 1
+utility.
+The libraries contain an index to the contents of the library,
+stored within the library itself.
+The index lists each symbol defined by a member of a library that is a
+relocatable object file.
+This speeds up linking to the library, and allows routines in the library
+to call each other regardless of their placement within the library.
+The index is created by
+.Xr ranlib 1
+and can be viewed using
+.Xr nm 1 .
+.Pp
+The building of dynamic libraries can be prevented by setting the variable
+.Dv NOPIC
+in
+.Pa /etc/mk.conf .
+The building of profiling versions of libraries can
+be prevented by setting the variable
+.Dv NOPROFILE
+in
+.Pa /etc/mk.conf .
+See
+.Xr mk.conf 5
+for more details.
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr cc 1 ,
+.Xr gprof 1 ,
+.Xr ld 1 ,
+.Xr ld.so 1 ,
+.Xr nm 1 ,
+.Xr ranlib 1 ,
+.Xr mk.conf 5
+.Sh HISTORY
+An
+.Nm
+manual for section 3 first appeared in
+.At v7 .
diff --git a/static/openbsd/man3/makedev.3 b/static/openbsd/man3/makedev.3
new file mode 100644
index 00000000..5083ec9b
--- /dev/null
+++ b/static/openbsd/man3/makedev.3
@@ -0,0 +1,94 @@
+.\" $OpenBSD: makedev.3,v 1.2 2019/01/25 00:19:26 millert Exp $
+.\"
+.\" Copyright (c) 2014 Todd C. Miller <millert@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.
+.\"
+.Dd $Mdocdate: January 25 2019 $
+.Dt MAKEDEV 3
+.Os
+.Sh NAME
+.Nm makedev ,
+.Nm major ,
+.Nm minor
+.Nd create or extract device numbers
+.Sh SYNOPSIS
+.In sys/types.h
+.Ft dev_t
+.Fn makedev "unsigned int maj" "unsigned int min"
+.Ft unsigned int
+.Fn major "dev_t dev"
+.Ft unsigned int
+.Fn minor "dev_t dev"
+.Sh DESCRIPTION
+On
+.Ox ,
+all devices on the system are assigned a unique number which consists
+of a major and minor component.
+Typically, the major number identifies the kind of device and
+the minor number identifies a specific instance of the device.
+.Pp
+The
+.Fn makedev
+macro is used to combine a major and minor device number into
+a form suitable for use with the
+.Xr mknod 2
+system call.
+.Pp
+The
+.Fn major
+macro extracts the major number from the specified device number.
+.Pp
+The
+.Fn minor
+macro extracts the minor number from the specified device number.
+.Sh RETURN VALUES
+The
+.Fn makedev
+macro returns a combined device number from the specified major and
+minor numbers.
+.Pp
+The
+.Fn major
+macro returns the major number corresponding to the specified device number.
+.Pp
+The
+.Fn minor
+macro returns the minor number corresponding to the specified device number.
+.Sh SEE ALSO
+.Xr mknod 2 ,
+.Xr intro 4
+.Sh STANDARDS
+The
+.Fn makedev ,
+.Fn major ,
+and
+.Fn minor
+macros are not standardized by
+.St -p1003.1
+but are available on most systems.
+.Sh HISTORY
+The
+.Fn makedev ,
+.Fn major ,
+and
+.Fn minor
+macros first appeared in
+.At v7 .
+.Sh CAVEATS
+On some systems,
+.Fn makedev ,
+.Fn major ,
+and
+.Fn minor
+are implemented as functions rather than macros.
diff --git a/static/openbsd/man3/offsetof.3 b/static/openbsd/man3/offsetof.3
new file mode 100644
index 00000000..ccd16c1a
--- /dev/null
+++ b/static/openbsd/man3/offsetof.3
@@ -0,0 +1,46 @@
+.\" $OpenBSD: offsetof.3,v 1.3 2013/06/05 03:42:03 tedu Exp $
+.\"
+.\" Copyright (c) 2010 Thomas Pfaff <tpfaff@tp76.info>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: June 5 2013 $
+.Dt OFFSETOF 3
+.Os
+.Sh NAME
+.Nm offsetof
+.Nd offset of a structure member
+.Sh SYNOPSIS
+.In stddef.h
+.Ft size_t
+.Fn offsetof "type" "member"
+.Sh DESCRIPTION
+The
+.Fn offsetof
+macro expands to an integer constant expression of type
+.Ft size_t
+and yields the offset,
+in bytes, of the field
+.Ar member
+from the start of the structure
+.Ar type .
+.Pp
+A compiler error will result if
+.Ar member
+is not aligned to a byte boundary (i.e. it is a bit-field).
+.Sh STANDARDS
+The
+.Fn offsetof
+macro conforms to
+.St -ansiC .
diff --git a/static/openbsd/man3/queue.3 b/static/openbsd/man3/queue.3
new file mode 100644
index 00000000..28200a6b
--- /dev/null
+++ b/static/openbsd/man3/queue.3
@@ -0,0 +1,1196 @@
+.\" $OpenBSD: queue.3,v 1.71 2025/06/13 18:34:00 schwarze Exp $
+.\" $NetBSD: queue.3,v 1.4 1995/07/03 00:25:36 mycroft Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.\" @(#)queue.3 8.1 (Berkeley) 12/13/93
+.\"
+.Dd $Mdocdate: June 13 2025 $
+.Dt SLIST_INIT 3
+.Os
+.Sh NAME
+.Nm SLIST_ENTRY ,
+.Nm SLIST_HEAD ,
+.Nm SLIST_HEAD_INITIALIZER ,
+.Nm SLIST_FIRST ,
+.Nm SLIST_NEXT ,
+.Nm SLIST_EMPTY ,
+.Nm SLIST_FOREACH ,
+.Nm SLIST_FOREACH_SAFE ,
+.Nm SLIST_INIT ,
+.Nm SLIST_INSERT_AFTER ,
+.Nm SLIST_INSERT_HEAD ,
+.Nm SLIST_REMOVE_AFTER ,
+.Nm SLIST_REMOVE_HEAD ,
+.Nm SLIST_REMOVE ,
+.Nm LIST_ENTRY ,
+.Nm LIST_HEAD ,
+.Nm LIST_HEAD_INITIALIZER ,
+.Nm LIST_FIRST ,
+.Nm LIST_NEXT ,
+.Nm LIST_EMPTY ,
+.Nm LIST_FOREACH ,
+.Nm LIST_FOREACH_SAFE ,
+.Nm LIST_INIT ,
+.Nm LIST_INSERT_AFTER ,
+.Nm LIST_INSERT_BEFORE ,
+.Nm LIST_INSERT_HEAD ,
+.Nm LIST_REMOVE ,
+.Nm LIST_REPLACE ,
+.Nm SIMPLEQ_ENTRY ,
+.Nm SIMPLEQ_HEAD ,
+.Nm SIMPLEQ_HEAD_INITIALIZER ,
+.Nm SIMPLEQ_FIRST ,
+.Nm SIMPLEQ_NEXT ,
+.Nm SIMPLEQ_EMPTY ,
+.Nm SIMPLEQ_FOREACH ,
+.Nm SIMPLEQ_FOREACH_SAFE ,
+.Nm SIMPLEQ_INIT ,
+.Nm SIMPLEQ_INSERT_AFTER ,
+.Nm SIMPLEQ_INSERT_HEAD ,
+.Nm SIMPLEQ_INSERT_TAIL ,
+.Nm SIMPLEQ_REMOVE_AFTER ,
+.Nm SIMPLEQ_REMOVE_HEAD ,
+.Nm SIMPLEQ_CONCAT ,
+.Nm STAILQ_ENTRY ,
+.Nm STAILQ_HEAD ,
+.Nm STAILQ_HEAD_INITIALIZER ,
+.Nm STAILQ_FIRST ,
+.Nm STAILQ_NEXT ,
+.Nm STAILQ_LAST ,
+.Nm STAILQ_EMPTY ,
+.Nm STAILQ_FOREACH ,
+.Nm STAILQ_FOREACH_SAFE ,
+.Nm STAILQ_INIT ,
+.Nm STAILQ_INSERT_AFTER ,
+.Nm STAILQ_INSERT_HEAD ,
+.Nm STAILQ_INSERT_TAIL ,
+.Nm STAILQ_REMOVE ,
+.Nm STAILQ_REMOVE_AFTER ,
+.Nm STAILQ_REMOVE_HEAD ,
+.Nm STAILQ_CONCAT ,
+.Nm TAILQ_ENTRY ,
+.Nm TAILQ_HEAD ,
+.Nm TAILQ_HEAD_INITIALIZER ,
+.Nm TAILQ_FIRST ,
+.Nm TAILQ_NEXT ,
+.Nm TAILQ_LAST ,
+.Nm TAILQ_PREV ,
+.Nm TAILQ_EMPTY ,
+.Nm TAILQ_FOREACH ,
+.Nm TAILQ_FOREACH_SAFE ,
+.Nm TAILQ_FOREACH_REVERSE ,
+.Nm TAILQ_FOREACH_REVERSE_SAFE ,
+.Nm TAILQ_INIT ,
+.Nm TAILQ_INSERT_AFTER ,
+.Nm TAILQ_INSERT_BEFORE ,
+.Nm TAILQ_INSERT_HEAD ,
+.Nm TAILQ_INSERT_TAIL ,
+.Nm TAILQ_REMOVE ,
+.Nm TAILQ_REPLACE ,
+.Nm TAILQ_CONCAT
+.Nd intrusive singly-linked and doubly-linked lists, simple queues, singly-linked and doubly-linked tail queues
+.Sh SYNOPSIS
+.In sys/queue.h
+.Pp
+.Fn SLIST_ENTRY "TYPE"
+.Fn SLIST_HEAD "HEADNAME" "TYPE"
+.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
+.Ft struct TYPE *
+.Fn SLIST_FIRST "SLIST_HEAD *head"
+.Ft struct TYPE *
+.Fn SLIST_NEXT "struct TYPE *listelm" "FIELDNAME"
+.Ft int
+.Fn SLIST_EMPTY "SLIST_HEAD *head"
+.Fn SLIST_FOREACH "VARNAME" "SLIST_HEAD *head" "FIELDNAME"
+.Fn SLIST_FOREACH_SAFE "VARNAME" "SLIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME"
+.Ft void
+.Fn SLIST_INIT "SLIST_HEAD *head"
+.Ft void
+.Fn SLIST_INSERT_AFTER "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SLIST_REMOVE_AFTER "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "FIELDNAME"
+.Ft void
+.Fn SLIST_REMOVE "SLIST_HEAD *head" "struct TYPE *elm" "TYPE" "FIELDNAME"
+.Pp
+.Fn LIST_ENTRY "TYPE"
+.Fn LIST_HEAD "HEADNAME" "TYPE"
+.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
+.Ft struct TYPE *
+.Fn LIST_FIRST "LIST_HEAD *head"
+.Ft struct TYPE *
+.Fn LIST_NEXT "struct TYPE *listelm" "FIELDNAME"
+.Ft int
+.Fn LIST_EMPTY "LIST_HEAD *head"
+.Fn LIST_FOREACH "VARNAME" "LIST_HEAD *head" "FIELDNAME"
+.Fn LIST_FOREACH_SAFE "VARNAME" "LIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME"
+.Ft void
+.Fn LIST_INIT "LIST_HEAD *head"
+.Ft void
+.Fn LIST_INSERT_AFTER "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn LIST_INSERT_BEFORE "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn LIST_REMOVE "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn LIST_REPLACE "struct TYPE *elm" "struct TYPE *elm2" "FIELDNAME"
+.Pp
+.Fn SIMPLEQ_ENTRY "TYPE"
+.Fn SIMPLEQ_HEAD "HEADNAME" "TYPE"
+.Fn SIMPLEQ_HEAD_INITIALIZER "SIMPLEQ_HEAD head"
+.Ft struct TYPE *
+.Fn SIMPLEQ_FIRST "SIMPLEQ_HEAD *head"
+.Ft struct TYPE *
+.Fn SIMPLEQ_NEXT "struct TYPE *listelm" "FIELDNAME"
+.Ft int
+.Fn SIMPLEQ_EMPTY "SIMPLEQ_HEAD *head"
+.Fn SIMPLEQ_FOREACH "VARNAME" "SIMPLEQ_HEAD *head" "FIELDNAME"
+.Fn SIMPLEQ_FOREACH_SAFE "VARNAME" "SIMPLEQ_HEAD *head" "FIELDNAME" "TEMP_VARNAME"
+.Ft void
+.Fn SIMPLEQ_INIT "SIMPLEQ_HEAD *head"
+.Ft void
+.Fn SIMPLEQ_INSERT_AFTER "SIMPLEQ_HEAD *head" "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SIMPLEQ_INSERT_HEAD "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SIMPLEQ_INSERT_TAIL "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SIMPLEQ_REMOVE_AFTER "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn SIMPLEQ_REMOVE_HEAD "SIMPLEQ_HEAD *head" "FIELDNAME"
+.Fn SIMPLEQ_CONCAT "SIMPLEQ_HEAD *head1" "SIMPLEQ_HEAD *head2"
+.Pp
+.Fn STAILQ_ENTRY "TYPE"
+.Fn STAILQ_HEAD "HEADNAME" "TYPE"
+.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
+.Fn STAILQ_FIRST "STAILQ_HEAD *head"
+.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
+.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
+.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
+.Fn STAILQ_FOREACH "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_INIT "STAILQ_HEAD *head"
+.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_TAIL "STAILQ_HEAD *head" "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_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
+.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
+.Pp
+.Fn TAILQ_ENTRY "TYPE"
+.Fn TAILQ_HEAD "HEADNAME" "TYPE"
+.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
+.Ft struct TYPE *
+.Fn TAILQ_FIRST "TAILQ_HEAD *head"
+.Ft struct TYPE *
+.Fn TAILQ_NEXT "struct TYPE *listelm" "FIELDNAME"
+.Ft struct TYPE *
+.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
+.Ft struct TYPE *
+.Fn TAILQ_PREV "struct TYPE *listelm" "HEADNAME" "FIELDNAME"
+.Ft int
+.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
+.Fn TAILQ_FOREACH "VARNAME" "TAILQ_HEAD *head" "FIELDNAME"
+.Fn TAILQ_FOREACH_SAFE "VARNAME" "TAILQ_HEAD *head" "FIELDNAME" "TEMP_VARNAME"
+.Fn TAILQ_FOREACH_REVERSE "VARNAME" "TAILQ_HEAD *head" "HEADNAME" "FIELDNAME"
+.Fn TAILQ_FOREACH_REVERSE_SAFE "VARNAME" "TAILQ_HEAD *head" "HEADNAME" "FIELDNAME" "TEMP_VARNAME"
+.Ft void
+.Fn TAILQ_INIT "TAILQ_HEAD *head"
+.Ft void
+.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn TAILQ_INSERT_BEFORE "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
+.Ft void
+.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "struct TYPE *elm" "struct TYPE *elm2" "FIELDNAME"
+.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "FIELDNAME"
+.Sh DESCRIPTION
+These macros define and operate on five types of data structures:
+singly-linked lists, simple queues, lists, singly-linked tail queues,
+and tail queues.
+All five structures support the following functionality:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+Insertion of a new entry at the head of the list.
+.It
+Insertion of a new entry after any element in the list.
+.It
+Removal of an entry from the head of the list.
+.It
+Forward traversal through the list.
+.El
+.Pp
+The following table provides a quick overview
+of which types support which additional macros:
+.Bl -column -offset 6n "LAST, PREV, FOREACH_REVERSE" SLIST LIST SIMPLEQ STAILQ TAILQ
+.It LAST, PREV, FOREACH_REVERSE Ta - Ta - Ta - Ta - Ta TAILQ
+.It INSERT_BEFORE, REPLACE Ta - Ta LIST Ta - Ta - Ta TAILQ
+.It INSERT_TAIL, CONCAT Ta - Ta - Ta SIMPLEQ Ta STAILQ Ta TAILQ
+.It REMOVE_AFTER, REMOVE_HEAD Ta SLIST Ta - Ta SIMPLEQ Ta STAILQ Ta -
+.It REMOVE Ta SLIST Ta LIST Ta - Ta STAILQ Ta TAILQ
+.El
+.Pp
+Singly-linked lists are the simplest of the five data structures
+and support only the above functionality.
+Singly-linked lists are ideal for applications with large datasets
+and few or no removals, or for implementing a LIFO queue.
+.Pp
+Simple queues and singly-linked tail queues add the following functionality:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+Entries can be added at the end of a list.
+.El
+.Pp
+However:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+All list insertions must specify the head of the list.
+.It
+Each head entry requires two pointers rather than one.
+.It
+Code size is about 15% greater and operations run about 20% slower
+than singly-linked lists.
+.El
+.Pp
+Simple queues and singly-linked tail queues are ideal for applications with
+large datasets and few or no removals, or for implementing a FIFO queue.
+.Pp
+All doubly linked types of data structures (lists and tail queues)
+additionally allow:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+Insertion of a new entry before any element in the list.
+.It
+Removal of any entry in the list.
+.El
+.Pp
+However:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+Each element requires two pointers rather than one.
+.It
+Code size and execution time of operations (except for removal) is about
+twice that of the singly-linked data-structures.
+.El
+.Pp
+Lists are the simplest of the doubly linked data structures and support
+only the above functionality over singly-linked lists.
+.Pp
+Tail queues add the following functionality:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+Entries can be added at the end of a list.
+.It
+They may be traversed backwards, at a cost.
+.El
+.Pp
+However:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+All list insertions and removals must specify the head of the list.
+.It
+Each head entry requires two pointers rather than one.
+.It
+Code size is about 15% greater and operations run about 20% slower
+than singly-linked lists.
+.El
+.Pp
+An additional type of data structure, circular queues, violated the C
+language aliasing rules and were miscompiled as a result.
+All code using them should be converted to another structure;
+tail queues are usually the easiest to convert to.
+.Pp
+All these lists and queues are intrusive: they link together user
+defined structures containing a field of type
+.Li SLIST_ENTRY ,
+.Li LIST_ENTRY ,
+.Li SIMPLEQ_ENTRY ,
+.Li STAILQ_ENTRY ,
+or
+.Li TAILQ_ENTRY .
+In the macro definitions,
+.Fa TYPE
+is the name tag of the user defined structure and
+.Fa FIELDNAME
+is the name of the
+.Li *_ENTRY
+field.
+If an instance of the user defined structure needs to be a member of
+multiple lists at the same time, the structure requires multiple
+.Li *_ENTRY
+fields, one for each list.
+.Pp
+The argument
+.Fa HEADNAME
+is the name tag of a user defined structure that must be declared
+using the macros
+.Fn SLIST_HEAD ,
+.Fn LIST_HEAD ,
+.Fn SIMPLEQ_HEAD ,
+.Fn STAILQ_HEAD ,
+or
+.Fn TAILQ_HEAD .
+See the examples below for further explanation of how these macros are used.
+.Sh SINGLY-LINKED LISTS
+A singly-linked list is headed by a structure defined by the
+.Fn SLIST_HEAD
+macro.
+This structure contains a single pointer to the first element on the list.
+The elements are singly linked for minimum space and pointer manipulation
+overhead at the expense of O(n) removal for arbitrary elements.
+New elements can be added to the list after an existing element or
+at the head of the list.
+A
+.Fa SLIST_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+SLIST_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be linked into the list.
+A pointer to the head of the list can later be declared as:
+.Bd -literal -offset indent
+struct HEADNAME *headp;
+.Ed
+.Pp
+(The names
+.Li head
+and
+.Li headp
+are user selectable.)
+.Pp
+The
+.Fa HEADNAME
+facility is often not used, leading to the following bizarre code:
+.Bd -literal -offset indent
+SLIST_HEAD(, TYPE) head, *headp;
+.Ed
+.Pp
+The
+.Fn SLIST_ENTRY
+macro declares a structure that connects the elements in the list.
+.Pp
+The
+.Fn SLIST_INIT
+macro initializes the list referenced by
+.Fa head .
+.Pp
+The list can also be initialized statically by using the
+.Fn SLIST_HEAD_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+SLIST_HEAD(HEADNAME, TYPE) head = SLIST_HEAD_INITIALIZER(head);
+.Ed
+.Pp
+The
+.Fn SLIST_INSERT_HEAD
+macro inserts the new element
+.Fa elm
+at the head of the list.
+.Pp
+The
+.Fn SLIST_INSERT_AFTER
+macro inserts the new element
+.Fa elm
+after the element
+.Fa listelm .
+.Pp
+The
+.Fn SLIST_REMOVE_HEAD
+macro removes the first element of the list pointed by
+.Fa head .
+.Pp
+The
+.Fn SLIST_REMOVE_AFTER
+macro removes the list element immediately following
+.Fa elm .
+.Pp
+The
+.Fn SLIST_REMOVE
+macro removes the element
+.Fa elm
+of the list pointed by
+.Fa head .
+.Pp
+The
+.Fn SLIST_FIRST
+and
+.Fn SLIST_NEXT
+macros can be used to traverse the list:
+.Bd -literal -offset indent
+for (np = SLIST_FIRST(&head); np != NULL; np = SLIST_NEXT(np, FIELDNAME))
+.Ed
+.Pp
+Or, for simplicity, one can use the
+.Fn SLIST_FOREACH
+macro:
+.Bd -literal -offset indent
+SLIST_FOREACH(np, head, FIELDNAME)
+.Ed
+.Pp
+The macro
+.Fn SLIST_FOREACH_SAFE
+traverses the list referenced by head in a
+forward direction, assigning each element in turn to var.
+However, unlike
+.Fn SLIST_FOREACH
+it is permitted to remove var as well
+as free it from within the loop safely without interfering with the traversal.
+.Pp
+The
+.Fn SLIST_EMPTY
+macro should be used to check whether a simple list is empty.
+.Sh SINGLY-LINKED LIST EXAMPLE
+.Bd -literal
+SLIST_HEAD(listhead, entry) head;
+struct entry {
+ ...
+ SLIST_ENTRY(entry) entries; /* Simple list. */
+ ...
+} *n1, *n2, *np;
+
+SLIST_INIT(&head); /* Initialize simple list. */
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
+SLIST_INSERT_HEAD(&head, n1, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert after. */
+SLIST_INSERT_AFTER(n1, n2, entries);
+
+SLIST_FOREACH(np, &head, entries) /* Forward traversal. */
+ np-> ...
+
+while (!SLIST_EMPTY(&head)) { /* Delete. */
+ n1 = SLIST_FIRST(&head);
+ SLIST_REMOVE_HEAD(&head, entries);
+ free(n1);
+}
+
+.Ed
+.Sh LISTS
+A list is headed by a structure defined by the
+.Fn LIST_HEAD
+macro.
+This structure contains a single pointer to the first element on the list.
+The elements are doubly linked so that an arbitrary element can be
+removed without traversing the list.
+New elements can be added to the list after an existing element,
+before an existing element, or at the head of the list.
+A
+.Fa LIST_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+LIST_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be linked into the list.
+A pointer to the head of the list can later be declared as:
+.Bd -literal -offset indent
+struct HEADNAME *headp;
+.Ed
+.Pp
+(The names
+.Li head
+and
+.Li headp
+are user selectable.)
+.Pp
+The
+.Fa HEADNAME
+facility is often not used, leading to the following bizarre code:
+.Bd -literal -offset indent
+LIST_HEAD(, TYPE) head, *headp;
+.Ed
+.Pp
+The
+.Fn LIST_ENTRY
+macro declares a structure that connects the elements in the list.
+.Pp
+The
+.Fn LIST_INIT
+macro initializes the list referenced by
+.Fa head .
+.Pp
+The list can also be initialized statically by using the
+.Fn LIST_HEAD_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+LIST_HEAD(HEADNAME, TYPE) head = LIST_HEAD_INITIALIZER(head);
+.Ed
+.Pp
+The
+.Fn LIST_INSERT_HEAD
+macro inserts the new element
+.Fa elm
+at the head of the list.
+.Pp
+The
+.Fn LIST_INSERT_AFTER
+macro inserts the new element
+.Fa elm
+after the element
+.Fa listelm .
+.Pp
+The
+.Fn LIST_INSERT_BEFORE
+macro inserts the new element
+.Fa elm
+before the element
+.Fa listelm .
+.Pp
+The
+.Fn LIST_REMOVE
+macro removes the element
+.Fa elm
+from the list.
+.Pp
+The
+.Fn LIST_REPLACE
+macro replaces the list element
+.Fa elm
+with the new element
+.Fa elm2 .
+.Pp
+The
+.Fn LIST_FIRST
+and
+.Fn LIST_NEXT
+macros can be used to traverse the list:
+.Bd -literal -offset indent
+for (np = LIST_FIRST(&head); np != NULL; np = LIST_NEXT(np, FIELDNAME))
+.Ed
+.Pp
+Or, for simplicity, one can use the
+.Fn LIST_FOREACH
+macro:
+.Bd -literal -offset indent
+LIST_FOREACH(np, head, FIELDNAME)
+.Ed
+.Pp
+The macro
+.Fn LIST_FOREACH_SAFE
+traverses the list referenced by head in a
+forward direction, assigning each element in turn to var.
+However, unlike
+.Fn LIST_FOREACH
+it is permitted to remove var as well
+as free it from within the loop safely without interfering with the traversal.
+.Pp
+The
+.Fn LIST_EMPTY
+macro should be used to check whether a list is empty.
+.Sh LIST EXAMPLE
+.Bd -literal
+LIST_HEAD(listhead, entry) head;
+struct entry {
+ ...
+ LIST_ENTRY(entry) entries; /* List. */
+ ...
+} *n1, *n2, *np;
+
+LIST_INIT(&head); /* Initialize list. */
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
+LIST_INSERT_HEAD(&head, n1, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert after. */
+LIST_INSERT_AFTER(n1, n2, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert before. */
+LIST_INSERT_BEFORE(n1, n2, entries);
+ /* Forward traversal. */
+LIST_FOREACH(np, &head, entries)
+ np-> ...
+
+while (!LIST_EMPTY(&head)) { /* Delete. */
+ n1 = LIST_FIRST(&head);
+ LIST_REMOVE(n1, entries);
+ free(n1);
+}
+.Ed
+.Sh SIMPLE QUEUES
+A simple queue is headed by a structure defined by the
+.Fn SIMPLEQ_HEAD
+macro.
+This structure contains a pair of pointers, one to the first element in the
+simple queue and the other to the last element in the simple queue.
+The elements are singly linked.
+New elements can be added to the queue after an existing element,
+at the head of the queue or at the tail of the queue.
+A
+.Fa SIMPLEQ_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+SIMPLEQ_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be linked into the queue.
+A pointer to the head of the queue can later be declared as:
+.Bd -literal -offset indent
+struct HEADNAME *headp;
+.Ed
+.Pp
+(The names
+.Li head
+and
+.Li headp
+are user selectable.)
+.Pp
+The
+.Fn SIMPLEQ_ENTRY
+macro declares a structure that connects the elements in
+the queue.
+.Pp
+The
+.Fn SIMPLEQ_INIT
+macro initializes the queue referenced by
+.Fa head .
+.Pp
+The queue can also be initialized statically by using the
+.Fn SIMPLEQ_HEAD_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+SIMPLEQ_HEAD(HEADNAME, TYPE) head = SIMPLEQ_HEAD_INITIALIZER(head);
+.Ed
+.Pp
+The
+.Fn SIMPLEQ_INSERT_AFTER
+macro inserts the new element
+.Fa elm
+after the element
+.Fa listelm .
+.Pp
+The
+.Fn SIMPLEQ_INSERT_HEAD
+macro inserts the new element
+.Fa elm
+at the head of the queue.
+.Pp
+The
+.Fn SIMPLEQ_INSERT_TAIL
+macro inserts the new element
+.Fa elm
+at the end of the queue.
+.Pp
+The
+.Fn SIMPLEQ_REMOVE_AFTER
+macro removes the queue element immediately following
+.Fa elm .
+.Pp
+The
+.Fn SIMPLEQ_REMOVE_HEAD
+macro removes the first element
+from the queue.
+.Pp
+The
+.Fn SIMPLEQ_CONCAT
+macro concatenates all the elements of the queue referenced by
+.Fa head2
+to the end of the queue referenced by
+.Fa head1 ,
+emptying
+.Fa head2
+in the process.
+This is more efficient than removing and inserting the individual elements
+as it does not actually traverse
+.Fa head2 .
+.Pp
+The
+.Fn SIMPLEQ_FIRST
+and
+.Fn SIMPLEQ_NEXT
+macros can be used to traverse the queue.
+The
+.Fn SIMPLEQ_FOREACH
+macro is used for queue traversal:
+.Bd -literal -offset indent
+SIMPLEQ_FOREACH(np, head, FIELDNAME)
+.Ed
+.Pp
+The macro
+.Fn SIMPLEQ_FOREACH_SAFE
+traverses the queue referenced by head in a
+forward direction, assigning each element in turn to var.
+However, unlike
+.Fn SIMPLEQ_FOREACH
+it is permitted to remove var as well
+as free it from within the loop safely without interfering with the traversal.
+.Pp
+The
+.Fn SIMPLEQ_EMPTY
+macro should be used to check whether a list is empty.
+.Sh SIMPLE QUEUE EXAMPLE
+.Bd -literal
+SIMPLEQ_HEAD(listhead, entry) head = SIMPLEQ_HEAD_INITIALIZER(head);
+struct entry {
+ ...
+ SIMPLEQ_ENTRY(entry) entries; /* Simple queue. */
+ ...
+} *n1, *n2, *np;
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
+SIMPLEQ_INSERT_HEAD(&head, n1, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert after. */
+SIMPLEQ_INSERT_AFTER(&head, n1, n2, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert at the tail. */
+SIMPLEQ_INSERT_TAIL(&head, n2, entries);
+ /* Forward traversal. */
+SIMPLEQ_FOREACH(np, &head, entries)
+ np-> ...
+ /* Delete. */
+while (!SIMPLEQ_EMPTY(&head)) {
+ n1 = SIMPLEQ_FIRST(&head);
+ SIMPLEQ_REMOVE_HEAD(&head, entries);
+ free(n1);
+}
+.Ed
+.Sh SINGLY-LINKED TAIL QUEUES
+A singly-linked tail queue is headed by a structure defined by the
+.Fn STAILQ_HEAD
+macro.
+This structure contains a pair of pointers, one to the first element in
+the tail queue and the other to the last element in the tail queue.
+The elements are singly linked for minimum space and pointer manipulation
+overhead at the expense of O(n) removal for arbitrary elements.
+New elements can be added to the tail queue after an existing element,
+at the head of the tail queue or at the end of the tail queue.
+A
+.Fa STAILQ_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+STAILQ_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be linked into the tail queue.
+A pointer to the head of the tail queue can later be declared as:
+.Bd -literal -offset indent
+struct HEADNAME *headp;
+.Ed
+.Pp
+(The names
+.Li head
+and
+.Li headp
+are user selectable.)
+.Pp
+The
+.Fn STAILQ_ENTRY
+macro declares a structure that connects the elements in
+the tail queue.
+.Pp
+The
+.Fn STAILQ_INIT
+macro initializes the tail queue referenced by
+.Fa head .
+.Pp
+The tail queue can also be initialized statically by using the
+.Fn STAILQ_HEAD_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+STAILQ_HEAD(HEADNAME, TYPE) head = STAILQ_HEAD_INITIALIZER(head);
+.Ed
+.Pp
+The
+.Fn STAILQ_INSERT_AFTER
+macro inserts the new element
+.Fa elm
+after the element
+.Fa listelm .
+.Pp
+The
+.Fn STAILQ_INSERT_HEAD
+macro inserts the new element
+.Fa elm
+at the head of the tail queue.
+.Pp
+The
+.Fn STAILQ_INSERT_TAIL
+macro inserts the new element
+.Fa elm
+at the end of the tail queue.
+.Pp
+The
+.Fn STAILQ_REMOVE_AFTER
+macro removes the queue element immediately following
+.Fa elm .
+Unlike
+.Fa STAILQ_REMOVE ,
+this macro does not traverse the entire tail queue.
+.Pp
+The
+.Fn STAILQ_REMOVE_HEAD
+macro removes the first element
+from the tail queue.
+For optimum efficiency,
+elements being removed from the head of the tail queue should
+use this macro explicitly rather than the generic
+.Fa STAILQ_REMOVE
+macro.
+.Pp
+The
+.Fn STAILQ_REMOVE
+macro removes the element
+.Fa elm
+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
+The
+.Fn STAILQ_CONCAT
+macro concatenates all the elements of the tail queue referenced by
+.Fa head2
+to the end of the tail queue referenced by
+.Fa head1 ,
+emptying
+.Fa head2
+in the process.
+This is more efficient than removing and inserting the individual elements
+as it does not actually traverse
+.Fa head2 .
+.Pp
+The
+.Fn STAILQ_FOREACH
+macro is used for queue traversal:
+.Bd -literal -offset indent
+STAILQ_FOREACH(np, head, FIELDNAME)
+.Ed
+.Pp
+The macro
+.Fn STAILQ_FOREACH_SAFE
+traverses the queue referenced by head in a
+forward direction, assigning each element in turn to var.
+However, unlike
+.Fn STAILQ_FOREACH
+it is permitted to remove var as well
+as free it from within the loop safely without interfering with the traversal.
+.Pp
+The
+.Fn STAILQ_FIRST ,
+.Fn STAILQ_NEXT ,
+and
+.Fn STAILQ_LAST
+macros can be used to manually traverse a tail queue or an arbitrary part of
+one.
+The
+.Fn STAILQ_EMPTY
+macro should be used to check whether a tail queue is empty.
+.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
+.Bd -literal
+STAILQ_HEAD(listhead, entry) head = STAILQ_HEAD_INITIALIZER(head);
+struct entry {
+ ...
+ STAILQ_ENTRY(entry) entries; /* Singly-linked tail queue. */
+ ...
+} *n1, *n2, *np;
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
+STAILQ_INSERT_HEAD(&head, n1, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert at the tail. */
+STAILQ_INSERT_TAIL(&head, n2, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert after. */
+STAILQ_INSERT_AFTER(&head, n1, n2, entries);
+
+ /* Deletion. */
+STAILQ_REMOVE(&head, n2, entry, entries);
+free(n2);
+ /* Deletion from the head. */
+n3 = STAILQ_FIRST(&head);
+STAILQ_REMOVE_HEAD(&head, entries);
+free(n3);
+ /* Forward traversal. */
+STAILQ_FOREACH(np, &head, entries)
+ np-> ...
+ /* Safe forward traversal. */
+STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
+ np-> ...
+ STAILQ_REMOVE(&head, np, entry, entries);
+ free(np);
+}
+ /* Delete. */
+while (!STAILQ_EMPTY(&head)) {
+ n1 = STAILQ_FIRST(&head);
+ STAILQ_REMOVE_HEAD(&head, entries);
+ free(n1);
+}
+.Ed
+.Sh TAIL QUEUES
+A tail queue is headed by a structure defined by the
+.Fn TAILQ_HEAD
+macro.
+This structure contains a pair of pointers,
+one to the first element in the tail queue and the other to
+the last element in the tail queue.
+The elements are doubly linked so that an arbitrary element can be
+removed without traversing the tail queue.
+New elements can be added to the queue after an existing element,
+before an existing element, at the head of the queue, or at the end
+of the queue.
+A
+.Fa TAILQ_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+TAILQ_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be linked into the tail queue.
+A pointer to the head of the tail queue can later be declared as:
+.Bd -literal -offset indent
+struct HEADNAME *headp;
+.Ed
+.Pp
+(The names
+.Li head
+and
+.Li headp
+are user selectable.)
+.Pp
+The
+.Fn TAILQ_ENTRY
+macro declares a structure that connects the elements in
+the tail queue.
+.Pp
+The
+.Fn TAILQ_INIT
+macro initializes the tail queue referenced by
+.Fa head .
+.Pp
+The tail queue can also be initialized statically by using the
+.Fn TAILQ_HEAD_INITIALIZER
+macro.
+.Pp
+The
+.Fn TAILQ_INSERT_HEAD
+macro inserts the new element
+.Fa elm
+at the head of the tail queue.
+.Pp
+The
+.Fn TAILQ_INSERT_TAIL
+macro inserts the new element
+.Fa elm
+at the end of the tail queue.
+.Pp
+The
+.Fn TAILQ_INSERT_AFTER
+macro inserts the new element
+.Fa elm
+after the element
+.Fa listelm .
+.Pp
+The
+.Fn TAILQ_INSERT_BEFORE
+macro inserts the new element
+.Fa elm
+before the element
+.Fa listelm .
+.Pp
+The
+.Fn TAILQ_REMOVE
+macro removes the element
+.Fa elm
+from the tail queue.
+.Pp
+The
+.Fn TAILQ_REPLACE
+macro replaces the list element
+.Fa elm
+with the new element
+.Fa elm2 .
+.Pp
+The
+.Fn TAILQ_CONCAT
+macro concatenates all the elements of the tail queue referenced by
+.Fa head2
+to the end of the tail queue referenced by
+.Fa head1 ,
+emptying
+.Fa head2
+in the process.
+This is more efficient than removing and inserting the individual elements
+as it does not actually traverse
+.Fa head2 .
+.Pp
+.Fn TAILQ_FOREACH
+and
+.Fn TAILQ_FOREACH_REVERSE
+are used for traversing a tail queue.
+.Fn TAILQ_FOREACH
+starts at the first element and proceeds towards the last.
+.Fn TAILQ_FOREACH_REVERSE
+starts at the last element and proceeds towards the first.
+.Bd -literal -offset indent
+TAILQ_FOREACH(np, &head, FIELDNAME)
+TAILQ_FOREACH_REVERSE(np, &head, HEADNAME, FIELDNAME)
+.Ed
+.Pp
+The macros
+.Fn TAILQ_FOREACH_SAFE
+and
+.Fn TAILQ_FOREACH_REVERSE_SAFE
+traverse the list referenced by head
+in a forward or reverse direction respectively,
+assigning each element in turn to var.
+However, unlike their unsafe counterparts,
+they permit both the removal of var
+as well as freeing it from within the loop safely
+without interfering with the traversal.
+.Pp
+The
+.Fn TAILQ_FIRST ,
+.Fn TAILQ_NEXT ,
+.Fn TAILQ_LAST
+and
+.Fn TAILQ_PREV
+macros can be used to manually traverse a tail queue or an arbitrary part of
+one.
+.Pp
+The
+.Fn TAILQ_EMPTY
+macro should be used to check whether a tail queue is empty.
+.Sh TAIL QUEUE EXAMPLE
+.Bd -literal
+TAILQ_HEAD(tailhead, entry) head;
+struct entry {
+ ...
+ TAILQ_ENTRY(entry) entries; /* Tail queue. */
+ ...
+} *n1, *n2, *np;
+
+TAILQ_INIT(&head); /* Initialize queue. */
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
+TAILQ_INSERT_HEAD(&head, n1, entries);
+
+n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
+TAILQ_INSERT_TAIL(&head, n1, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert after. */
+TAILQ_INSERT_AFTER(&head, n1, n2, entries);
+
+n2 = malloc(sizeof(struct entry)); /* Insert before. */
+TAILQ_INSERT_BEFORE(n1, n2, entries);
+ /* Forward traversal. */
+TAILQ_FOREACH(np, &head, entries)
+ np-> ...
+ /* Manual forward traversal. */
+for (np = n2; np != NULL; np = TAILQ_NEXT(np, entries))
+ np-> ...
+ /* Delete. */
+while ((np = TAILQ_FIRST(&head))) {
+ TAILQ_REMOVE(&head, np, entries);
+ free(np);
+}
+
+.Ed
+.Sh SEE ALSO
+.Xr tree 3
+.Sh NOTES
+It is an error to assume the next and previous fields are preserved
+after an element has been removed from a list or queue.
+Using any macro (except the various forms of insertion) on an element
+removed from a list or queue is incorrect.
+An example of erroneous usage is removing the same element twice.
+.Pp
+The
+.Fn SLIST_END ,
+.Fn LIST_END ,
+.Fn SIMPLEQ_END ,
+.Fn STAILQ_END
+and
+.Fn TAILQ_END
+macros are deprecated; they provided symmetry with the historical
+.Fn CIRCLEQ_END
+and just expand to
+.Dv NULL .
+.Pp
+Trying to free a list in the following way is a common error:
+.Bd -literal -offset indent
+LIST_FOREACH(var, head, entry)
+ free(var);
+free(head);
+.Ed
+.Pp
+Since
+.Va var
+is free'd, the FOREACH macros refer to a pointer that may have been
+reallocated already.
+A similar situation occurs when the current element is deleted
+from the list.
+In cases like these the data structure's FOREACH_SAFE macros should be used
+instead.
+.Sh HISTORY
+The
+.Nm queue
+functions first appeared in
+.Bx 4.4 .
+The historical circle queue macros were deprecated in
+.Ox 5.5 .
diff --git a/static/openbsd/man3/sysexits.3 b/static/openbsd/man3/sysexits.3
new file mode 100644
index 00000000..eace75dc
--- /dev/null
+++ b/static/openbsd/man3/sysexits.3
@@ -0,0 +1,137 @@
+.\"
+.\" Copyright (c) 1987, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" 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 DEVELOPERS ``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 DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $OpenBSD: sysexits.3,v 1.13 2017/04/11 17:01:11 schwarze Exp $
+.\" $FreeBSD: src/share/man/man3/sysexits.3,v 1.4.2.1 1999/08/29 16:45:41 peter Exp $
+.\"
+.Dd $Mdocdate: April 11 2017 $
+.Dt SYSEXITS 3
+.Os
+.Sh NAME
+.Nm sysexits
+.Nd exit codes for programs
+.Sh SYNOPSIS
+.In sysexits.h
+.Sh DESCRIPTION
+A few programs exit with the following non-portable error codes.
+Do not use them.
+.Pp
+The successful exit is always indicated by a status of 0, or
+.Dv EX_OK .
+Error numbers begin at
+.Dv EX__BASE
+to reduce the possibility of clashing with other exit statuses that
+random programs may already return.
+The meaning of the code is approximately as follows:
+.Bl -tag -width "EX_UNAVAILABLEXX(XX)"
+.It Dv EX_USAGE Pq 64
+The command was used incorrectly, e.g., with the wrong number of
+arguments, a bad flag, bad syntax in a parameter, or whatever.
+.It Dv EX_DATAERR Pq 65
+The input data was incorrect in some way.
+This should only be used for user's data and not system files.
+.It Dv EX_NOINPUT Pq 66
+An input file (not a system file) did not exist or was not readable.
+This could also include errors like
+.Dq \&No message
+to a mailer (if it cared to catch it).
+.It Dv EX_NOUSER Pq 67
+The user specified did not exist.
+This might be used for mail addresses or remote logins.
+.It Dv EX_NOHOST Pq 68
+The host specified did not exist.
+This is used in mail addresses or network requests.
+.It Dv EX_UNAVAILABLE Pq 69
+A service is unavailable.
+This can occur if a support program or file does not exist.
+This can also be used as a catch-all message when something you wanted
+to do doesn't work, but you don't know why.
+.It Dv EX_SOFTWARE Pq 70
+An internal software error has been detected.
+This should be limited to non-operating system related errors if possible.
+.It Dv EX_OSERR Pq 71
+An operating system error has been detected.
+This is intended to be used for such things as
+.Dq cannot fork ,
+or
+.Dq cannot create pipe .
+It includes things like
+.Xr getuid 2
+returning a user that does not exist in the passwd file.
+.It Dv EX_OSFILE Pq 72
+Some system file (e.g.,
+.Pa /etc/passwd ,
+.Pa /var/run/utmp )
+does not exist, cannot be opened, or has some sort of error
+(e.g., syntax error).
+.It Dv EX_CANTCREAT Pq 73
+A (user specified) output file cannot be created.
+.It Dv EX_IOERR Pq 74
+An error occurred while doing I/O on some file.
+.It Dv EX_TEMPFAIL Pq 75
+Temporary failure, indicating something that is not really an error.
+For example that a mailer could not create a
+connection, and the request should be reattempted later.
+.It Dv EX_PROTOCOL Pq 76
+The remote system returned something that was
+.Dq not possible
+during a protocol exchange.
+.It Dv EX_NOPERM Pq 77
+You did not have sufficient permission to perform the operation.
+This is not intended for file system problems, which should use
+.Dv EX_NOINPUT
+or
+.Dv EX_CANTCREAT ,
+but rather for higher level permissions.
+.It Dv EX_CONFIG Pq 78
+Something was found in an unconfigured or misconfigured state.
+.El
+.Pp
+The numerical values corresponding to the symbolical ones are given in
+parentheses for easy reference.
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr exit 3
+.Sh HISTORY
+The
+.Nm
+file first appeared in
+.Bx 4.0
+for use by the delivermail utility, later renamed to
+.Xr sendmail 8 .
+.Sh AUTHORS
+.An -nosplit
+.An Eric Allman
+invented the
+.Nm
+file in 1980.
+This man page was written by
+.An Joerg Wunsch ,
+based on Eric's original comments found in
+.In sysexits.h .
+.Sh BUGS
+The choice of an appropriate exit value is often ambiguous.
diff --git a/static/openbsd/man3/timeradd.3 b/static/openbsd/man3/timeradd.3
new file mode 100644
index 00000000..d89bac11
--- /dev/null
+++ b/static/openbsd/man3/timeradd.3
@@ -0,0 +1,202 @@
+.\" $OpenBSD: timeradd.3,v 1.3 2019/05/10 19:14:12 cheloha Exp $
+.\" $NetBSD: getitimer.2,v 1.6 1995/10/12 15:40:54 jtc Exp $
+.\"
+.\" Copyright (c) 1983, 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.
+.\"
+.\" @(#)getitimer.2 8.2 (Berkeley) 12/11/93
+.\"
+.Dd $Mdocdate: May 10 2019 $
+.Dt TIMERADD 3
+.Os
+.Sh NAME
+.Nm timerclear ,
+.Nm timerisset ,
+.Nm timerisvalid ,
+.Nm timercmp ,
+.Nm timersub ,
+.Nm timeradd ,
+.Nm timespecclear ,
+.Nm timespecisset ,
+.Nm timespecisvalid ,
+.Nm timespeccmp ,
+.Nm timespecsub ,
+.Nm timespecadd ,
+.Nm TIMEVAL_TO_TIMESPEC ,
+.Nm TIMESPEC_TO_TIMEVAL
+.Nd manipulate time structures
+.Sh SYNOPSIS
+.In sys/time.h
+.Ft void
+.Fn timerclear "struct timeval *a"
+.Ft int
+.Fn timerisset "struct timeval *a"
+.Ft int
+.Fn timerisvalid "struct timeval *a"
+.Ft int
+.Fn timercmp "struct timeval *a" "struct timeval *b" operator
+.Ft void
+.Fn timersub "struct timeval *a" "struct timeval *b" "struct timeval *c"
+.Ft void
+.Fn timeradd "struct timeval *a" "struct timeval *b" "struct timeval *c"
+.Ft void
+.Fn timespecclear "struct timespec *a"
+.Ft int
+.Fn timespecisset "struct timespec *a"
+.Ft int
+.Fn timespecisvalid "struct timespec *a"
+.Ft int
+.Fn timespeccmp "struct timespec *a" "struct timespec *b" operator
+.Ft void
+.Fn timespecsub "struct timespec *a" "struct timespec *b" "struct timespec *c"
+.Ft void
+.Fn timespecadd "struct timespec *a" "struct timespec *b" "struct timespec *c"
+.Ft void
+.Fn TIMEVAL_TO_TIMESPEC "struct timeval *tv" "struct timespec *ts"
+.Ft void
+.Fn TIMESPEC_TO_TIMEVAL "struct timeval *tv" "struct timespec *ts"
+.Sh DESCRIPTION
+The
+.Fn timer*
+and
+.Fn timespec*
+macros defined in
+.In sys/time.h
+simplify the use of
+.Vt timeval
+and
+.Vt timespec
+structures,
+respectively.
+.Pp
+The following macros are available:
+.Bl -tag -width Ds
+.It Fn timerclear a , Fn timespecclear a
+Set the time value in
+.Fa a
+to zero.
+.It Fn timerisset a , Fn timespecisset a
+Test if the time value in
+.Fa a
+is non-zero.
+.It Fn timerisvalid a
+Test if the microsecond value in
+.Fa a
+is greater than or equal to zero and less than one million.
+.It Fn timespecisvalid a
+Test if the nanosecond value in
+.Fa a
+is greater than or equal to zero and less than one billion.
+.It Fn timercmp a b operator , Fn timespeccmp a b operator
+Test if the expression
+.Fa a operator b
+is true,
+where
+.Fa operator
+is one of
+.Cm < ,
+.Cm <= ,
+.Cm == ,
+.Cm != ,
+.Cm >= ,
+or
+.Cm > .
+.It Fn timersub a b c , Fn timespecsub a b c
+Subtract
+.Fa b
+from
+.Fa a
+and store the result in
+.Fa c .
+.It Fn timeradd a b c , Fn timespecadd a b c
+Add
+.Fa b
+to
+.Fa a
+and store the result in
+.Fa c .
+.It Fn TIMEVAL_TO_TIMESPEC tv ts
+Convert
+.Fa tv
+to a
+.Vt struct timespec
+and store the result in
+.Fa ts .
+.It Fn TIMESPEC_TO_TIMEVAL tv ts
+Convert
+.Fa ts
+to a
+.Vt struct timeval
+and store the result in
+.Fa tv .
+.El
+.Sh RETURN VALUES
+The macros returning
+.Vt int
+return 1 if the tested condition holds or 0 otherwise.
+.Sh SEE ALSO
+.Xr adjtime 2 ,
+.Xr clock_gettime 2 ,
+.Xr futex 2 ,
+.Xr futimens 2 ,
+.Xr futimes 2 ,
+.Xr getitimer 2 ,
+.Xr gettimeofday 2 ,
+.Xr kevent 2 ,
+.Xr nanosleep 2 ,
+.Xr ppoll 2 ,
+.Xr pselect 2
+.Sh STANDARDS
+These macros are non-standard,
+though many systems offer them.
+Similar interfaces are often available in their absence.
+.Sh HISTORY
+The macros
+.Fn timerclear ,
+.Fn timerisset ,
+and
+.Fn timercmp
+first appeared in
+.Bx 4.1c ,
+.Fn TIMEVAL_TO_TIMESPEC
+and
+.Fn TIMESPEC_TO_TIMEVAL
+in
+.Bx 4.4 ,
+.Fn timersub
+and
+.Fn timeradd
+in
+.Nx 1.1 ,
+and
+.Fn timerisvalid
+in
+.Ox 6.5 .
+.Sh CAVEATS
+The argument ordering for
+.Fn TIMESPEC_TO_TIMEVAL
+is unintuitive.
diff --git a/static/openbsd/man3/tree.3 b/static/openbsd/man3/tree.3
new file mode 100644
index 00000000..d080880c
--- /dev/null
+++ b/static/openbsd/man3/tree.3
@@ -0,0 +1,583 @@
+.\" $OpenBSD: tree.3,v 1.31 2025/06/13 18:34:00 schwarze Exp $
+.\"/*
+.\" * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+.\" * 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 ``AS IS'' AND ANY EXPRESS OR
+.\" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.Dd $Mdocdate: June 13 2025 $
+.Dt SPLAY_INIT 3
+.Os
+.Sh NAME
+.Nm SPLAY_PROTOTYPE ,
+.Nm SPLAY_GENERATE ,
+.Nm SPLAY_ENTRY ,
+.Nm SPLAY_HEAD ,
+.Nm SPLAY_INITIALIZER ,
+.Nm SPLAY_ROOT ,
+.Nm SPLAY_EMPTY ,
+.Nm SPLAY_NEXT ,
+.Nm SPLAY_MIN ,
+.Nm SPLAY_MAX ,
+.Nm SPLAY_FIND ,
+.Nm SPLAY_LEFT ,
+.Nm SPLAY_RIGHT ,
+.Nm SPLAY_FOREACH ,
+.Nm SPLAY_INIT ,
+.Nm SPLAY_INSERT ,
+.Nm SPLAY_REMOVE ,
+.Nm RB_PROTOTYPE ,
+.Nm RB_PROTOTYPE_STATIC ,
+.Nm RB_GENERATE ,
+.Nm RB_GENERATE_STATIC ,
+.Nm RB_ENTRY ,
+.Nm RB_HEAD ,
+.Nm RB_INITIALIZER ,
+.Nm RB_ROOT ,
+.Nm RB_EMPTY ,
+.Nm RB_NEXT ,
+.Nm RB_PREV ,
+.Nm RB_MIN ,
+.Nm RB_MAX ,
+.Nm RB_FIND ,
+.Nm RB_NFIND ,
+.Nm RB_LEFT ,
+.Nm RB_RIGHT ,
+.Nm RB_PARENT ,
+.Nm RB_FOREACH ,
+.Nm RB_FOREACH_SAFE ,
+.Nm RB_FOREACH_REVERSE ,
+.Nm RB_FOREACH_REVERSE_SAFE ,
+.Nm RB_INIT ,
+.Nm RB_INSERT ,
+.Nm RB_REMOVE
+.Nd implementations of splay and red-black trees
+.Sh SYNOPSIS
+.In sys/tree.h
+.Pp
+.Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
+.Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP"
+.Fn SPLAY_ENTRY "TYPE"
+.Fn SPLAY_HEAD "HEADNAME" "TYPE"
+.Ft struct TYPE *
+.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
+.Fn SPLAY_ROOT "SPLAY_HEAD *head"
+.Ft int
+.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
+.Ft struct TYPE *
+.Fn SPLAY_NEXT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn SPLAY_MIN "NAME" "SPLAY_HEAD *head"
+.Ft struct TYPE *
+.Fn SPLAY_MAX "NAME" "SPLAY_HEAD *head"
+.Ft struct TYPE *
+.Fn SPLAY_FIND "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
+.Ft struct TYPE *
+.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
+.Fn SPLAY_FOREACH "VARNAME" "NAME" "SPLAY_HEAD *head"
+.Ft void
+.Fn SPLAY_INIT "SPLAY_HEAD *head"
+.Ft struct TYPE *
+.Fn SPLAY_INSERT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn SPLAY_REMOVE "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
+.Pp
+.Fn RB_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
+.Fn RB_PROTOTYPE_STATIC "NAME" "TYPE" "FIELD" "CMP"
+.Fn RB_GENERATE "NAME" "TYPE" "FIELD" "CMP"
+.Fn RB_GENERATE_STATIC "NAME" "TYPE" "FIELD" "CMP"
+.Fn RB_ENTRY "TYPE"
+.Fn RB_HEAD "HEADNAME" "TYPE"
+.Fn RB_INITIALIZER "RB_HEAD *head"
+.Ft struct TYPE *
+.Fn RB_ROOT "RB_HEAD *head"
+.Ft int
+.Fn RB_EMPTY "RB_HEAD *head"
+.Ft struct TYPE *
+.Fn RB_NEXT "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn RB_PREV "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn RB_MIN "NAME" "RB_HEAD *head"
+.Ft struct TYPE *
+.Fn RB_MAX "NAME" "RB_HEAD *head"
+.Ft struct TYPE *
+.Fn RB_FIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn RB_NFIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
+.Ft struct TYPE *
+.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
+.Ft struct TYPE *
+.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
+.Fn RB_FOREACH "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
+.Fn RB_INIT "RB_HEAD *head"
+.Ft struct TYPE *
+.Fn RB_INSERT "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn RB_REMOVE "NAME" "RB_HEAD *head" "struct TYPE *elm"
+.Sh DESCRIPTION
+These macros define data structures for different types of trees:
+splay trees and red-black trees.
+.Pp
+In the macro definitions,
+.Fa TYPE
+is the name tag of a user defined structure that must contain a field named
+.Fa FIELD ,
+of type
+.Li SPLAY_ENTRY
+or
+.Li RB_ENTRY .
+The argument
+.Fa HEADNAME
+is the name tag of a user defined structure that must be declared
+using the macros
+.Fn SPLAY_HEAD
+or
+.Fn RB_HEAD .
+The argument
+.Fa NAME
+has to be a unique name prefix for every tree that is defined.
+.Pp
+The function prototypes are declared with
+.Li SPLAY_PROTOTYPE ,
+.Li RB_PROTOTYPE ,
+or
+.Li RB_PROTOTYPE_STATIC .
+The function bodies are generated with
+.Li SPLAY_GENERATE ,
+.Li RB_GENERATE ,
+or
+.Li RB_GENERATE_STATIC .
+See the examples below for further explanation of how these macros are used.
+.Sh SPLAY TREES
+A splay tree is a self-organizing data structure.
+Every operation on the tree causes a splay to happen.
+The splay moves the requested node to the root of the tree and partly
+rebalances it.
+.Pp
+This has the benefit that request locality causes faster lookups as
+the requested nodes move to the top of the tree.
+On the other hand, every lookup causes memory writes.
+.Pp
+The Balance Theorem bounds the total access time for m operations
+and n inserts on an initially empty tree as O((m + n)lg n).
+The amortized cost for a sequence of m accesses to a splay tree is O(lg n).
+.Pp
+A splay tree is headed by a structure defined by the
+.Fn SPLAY_HEAD
+macro.
+A
+.Fa SPLAY_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+SPLAY_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be inserted into the tree.
+.Pp
+The
+.Fn SPLAY_ENTRY
+macro declares a structure that allows elements to be connected in the tree.
+.Pp
+In order to use the functions that manipulate the tree structure,
+their prototypes need to be declared with the
+.Fn SPLAY_PROTOTYPE
+macro,
+where
+.Fa NAME
+is a unique identifier for this particular tree.
+The
+.Fa TYPE
+argument is the type of the structure that is being managed
+by the tree.
+The
+.Fa FIELD
+argument is the name of the element defined by
+.Fn SPLAY_ENTRY .
+.Pp
+The function bodies are generated with the
+.Fn SPLAY_GENERATE
+macro.
+It takes the same arguments as the
+.Fn SPLAY_PROTOTYPE
+macro, but should be used only once.
+.Pp
+Finally,
+the
+.Fa CMP
+argument is the name of a function used to compare trees' nodes
+with each other.
+The function takes two arguments of type
+.Fa "struct TYPE *" .
+If the first argument is smaller than the second, the function returns a
+value smaller than zero.
+If they are equal, the function returns zero.
+Otherwise, it should return a value greater than zero.
+The compare function defines the order of the tree elements.
+.Pp
+The
+.Fn SPLAY_INIT
+macro initializes the tree referenced by
+.Fa head .
+.Pp
+The splay tree can also be initialized statically by using the
+.Fn SPLAY_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+SPLAY_HEAD(HEADNAME, TYPE) head = SPLAY_INITIALIZER(&head);
+.Ed
+.Pp
+The
+.Fn SPLAY_INSERT
+macro inserts the new element
+.Fa elm
+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
+The
+.Fn SPLAY_REMOVE
+macro removes the element
+.Fa elm
+from the tree pointed by
+.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
+The
+.Fn SPLAY_FIND
+macro can be used to find a particular element in the tree.
+.Bd -literal -offset indent
+struct TYPE find, *res;
+find.key = 30;
+res = SPLAY_FIND(NAME, &head, &find);
+.Ed
+.Pp
+The
+.Fn SPLAY_ROOT ,
+.Fn SPLAY_MIN ,
+.Fn SPLAY_MAX ,
+and
+.Fn SPLAY_NEXT
+macros can be used to traverse the tree:
+.Bd -literal -offset indent
+for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
+.Ed
+.Pp
+Or, for simplicity, one can use the
+.Fn SPLAY_FOREACH
+macro:
+.Bd -literal -offset indent
+SPLAY_FOREACH(np, NAME, &head)
+.Ed
+.Pp
+The
+.Fn SPLAY_EMPTY
+macro should be used to check whether a splay tree is empty.
+.Sh RED-BLACK TREES
+A red-black tree is a binary search tree with the node color as an
+extra attribute.
+It fulfills a set of conditions:
+.Pp
+.Bl -enum -compact -offset indent
+.It
+every search path from the root to a leaf consists of the same number of
+black nodes,
+.It
+each red node (except for the root) has a black parent,
+.It
+each leaf node is black.
+.El
+.Pp
+Every operation on a red-black tree is bounded as O(lg n).
+The maximum height of a red-black tree is 2lg (n+1).
+.Pp
+A red-black tree is headed by a structure defined by the
+.Fn RB_HEAD
+macro.
+A
+.Fa RB_HEAD
+structure is declared as follows:
+.Bd -literal -offset indent
+RB_HEAD(HEADNAME, TYPE) head;
+.Ed
+.Pp
+where
+.Fa HEADNAME
+is the name of the structure to be defined, and struct
+.Fa TYPE
+is the type of the elements to be inserted into the tree.
+.Pp
+The
+.Fn RB_ENTRY
+macro declares a structure that allows elements to be connected in the tree.
+.Pp
+In order to use the functions that manipulate the tree structure,
+their prototypes need to be declared with the
+.Fn RB_PROTOTYPE
+or
+.Fn RB_PROTOTYPE_STATIC
+macros,
+where
+.Fa NAME
+is a unique identifier for this particular tree.
+The
+.Fa TYPE
+argument is the type of the structure that is being managed
+by the tree.
+The
+.Fa FIELD
+argument is the name of the element defined by
+.Fn RB_ENTRY .
+.Pp
+The function bodies are generated with the
+.Fn RB_GENERATE
+or
+.Fn RB_GENERATE_STATIC
+macros.
+These macros take the same arguments as the
+.Fn RB_PROTOTYPE
+and
+.Fn RB_PROTOTYPE_STATIC
+macros, but should be used only once.
+.Pp
+Finally,
+the
+.Fa CMP
+argument is the name of a function used to compare trees' nodes
+with each other.
+The function takes two arguments of type
+.Fa "struct TYPE *" .
+If the first argument is smaller than the second, the function returns a
+value smaller than zero.
+If they are equal, the function returns zero.
+Otherwise, it should return a value greater than zero.
+The compare function defines the order of the tree elements.
+.Pp
+The
+.Fn RB_INIT
+macro initializes the tree referenced by
+.Fa head .
+.Pp
+The red-black tree can also be initialized statically by using the
+.Fn RB_INITIALIZER
+macro like this:
+.Bd -literal -offset indent
+RB_HEAD(HEADNAME, TYPE) head = RB_INITIALIZER(&head);
+.Ed
+.Pp
+The
+.Fn RB_INSERT
+macro inserts the new element
+.Fa elm
+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
+The
+.Fn RB_REMOVE
+macro removes the element
+.Fa elm
+from the tree pointed by
+.Fa head .
+.Fn RB_REMOVE
+returns
+.Fa elm .
+.Pp
+The
+.Fn RB_FIND
+and
+.Fn RB_NFIND
+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
+struct TYPE find, *res;
+find.key = 30;
+res = RB_FIND(NAME, &head, &find);
+.Ed
+.Pp
+The
+.Fn RB_ROOT ,
+.Fn RB_MIN ,
+.Fn RB_MAX ,
+.Fn RB_NEXT ,
+and
+.Fn RB_PREV
+macros can be used to traverse the tree:
+.Bd -literal -offset indent
+for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))
+.Ed
+.Pp
+Or, for simplicity, one can use the
+.Fn RB_FOREACH
+or
+.Fn RB_FOREACH_REVERSE
+macros:
+.Bd -literal -offset indent
+RB_FOREACH(np, NAME, &head)
+.Ed
+.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
+.Fn RB_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 3
+.Sh NOTES
+Trying to free a tree in the following way is a common error:
+.Bd -literal -offset indent
+SPLAY_FOREACH(var, NAME, &head) {
+ SPLAY_REMOVE(NAME, &head, var);
+ free(var);
+}
+free(head);
+.Ed
+.Pp
+Since
+.Va var
+is free'd, the
+.Fn FOREACH
+macro refers to a pointer that may have been reallocated already.
+Proper code needs a second variable.
+.Bd -literal -offset indent
+for (var = SPLAY_MIN(NAME, &head); var != NULL; var = nxt) {
+ nxt = SPLAY_NEXT(NAME, &head, var);
+ SPLAY_REMOVE(NAME, &head, var);
+ free(var);
+}
+.Ed
+.Sh AUTHORS
+The author of the tree macros is
+.An Niels Provos .
diff --git a/static/openbsd/man3/va_start.3 b/static/openbsd/man3/va_start.3
new file mode 100644
index 00000000..a3452677
--- /dev/null
+++ b/static/openbsd/man3/va_start.3
@@ -0,0 +1,268 @@
+.\" $OpenBSD: va_start.3,v 1.1 2019/08/30 18:33:17 deraadt Exp $
+.\" $NetBSD: stdarg.3,v 1.15 2002/08/18 08:57:07 yamt Exp $
+.\"
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)stdarg.3 8.1 (Berkeley) 6/5/93
+.\"
+.Dd $Mdocdate: August 30 2019 $
+.Dt VA_START 3
+.Os
+.Sh NAME
+.Nm va_start ,
+.Nm va_arg ,
+.Nm va_copy ,
+.Nm va_end
+.Nd variable argument lists
+.Sh SYNOPSIS
+.In stdarg.h
+.Ft void
+.Fn va_start "va_list ap" last
+.Ft type
+.Fn va_arg "va_list ap" type
+.Ft void
+.Fn va_copy "va_list dst" "va_list src"
+.Ft void
+.Fn va_end "va_list ap"
+.Sh DESCRIPTION
+A function may be called with a varying number of arguments of varying
+types.
+The include file
+.In stdarg.h
+declares a type
+.Vt va_list
+and defines three macros for stepping
+through a list of arguments whose number and types are not known to
+the called function.
+.Pp
+The called function must declare an object of type
+.Vt va_list
+which is used by the macros
+.Fn va_start ,
+.Fn va_arg ,
+.Fn va_end ,
+and, optionally,
+.Fn va_copy .
+.Pp
+The
+.Fn va_start
+macro initializes
+.Fa ap
+for subsequent use by
+.Fn va_arg ,
+.Fn va_copy
+and
+.Fn va_end ,
+and must be called first.
+.Pp
+The parameter
+.Fa last
+is the name of the last parameter before the variable argument list,
+i.e., the last parameter of which the calling function knows the type.
+.Pp
+Because the address of this parameter is used in the
+.Fn va_start
+macro, it should not be declared as a register variable, nor as a
+function, nor an array type.
+.Pp
+The
+.Fn va_arg
+macro expands to an expression that has the type and value of the next
+argument in the call.
+The parameter
+.Fa ap
+is the
+.Va va_list ap
+initialized by
+.Fn va_start .
+Each call to
+.Fn va_arg
+modifies
+.Fa ap
+so that the next call returns the next argument.
+The parameter
+.Fa type
+is a type name specified so that the type of a pointer to an
+object that has the specified type can be obtained simply by
+adding a
+.Ql *
+to
+.Fa type .
+.Pp
+If there is no next argument, or if
+.Fa type
+is not compatible with the type of the actual next argument
+(as promoted according to the default argument promotions, see below),
+random errors will occur.
+.Pp
+If the type in question is one that would normally be promoted, the
+promoted type should be used as the argument to
+.Fn va_arg .
+The following describes which types should be promoted (and to what):
+.Bl -dash -compact
+.It
+.Vt short
+is promoted to
+.Vt int
+.It
+.Vt float
+is promoted to
+.Vt double
+.It
+.Vt char
+is promoted to
+.Vt int
+.El
+.Pp
+The same rules apply to unsigned versions of the above types, as well
+as their bit-type equivalents (e.g.\&
+.Vt int8_t
+and
+.Vt int16_t ) .
+.Pp
+The
+.Fn va_copy
+macro makes
+.Fa dst
+a copy of
+.Fa src
+as if the
+.Fn va_start
+macro had been applied to it followed by the same sequence of uses of the
+.Fn va_arg
+macro as had previously been used to reach the present state of
+.Fa src .
+.Pp
+The
+.Fn va_end
+macro handles a normal return from the function whose variable argument
+list was initialized by
+.Fn va_start
+or
+.Fn va_copy .
+.Sh RETURN VALUES
+The first use of the
+.Fn va_arg
+macro after that of the
+.Fn va_start
+macro returns the argument after
+.Fa last .
+Successive invocations return the values of the remaining
+arguments.
+.Pp
+The
+.Fn va_start ,
+.Fn va_copy
+and
+.Fn va_end
+macros return no value.
+.Sh EXAMPLES
+The function
+.Fn foo
+takes a string of format characters and prints out the argument
+associated with each format character based on the type.
+.Bd -literal -offset indent
+void
+foo(char *fmt, ...)
+{
+ va_list ap;
+ int d, c;
+ char *s;
+ double f;
+
+ va_start(ap, fmt);
+ while (*fmt)
+ switch (*fmt++) {
+ case 's': /* string */
+ s = va_arg(ap, char *);
+ printf("string %s\en", s);
+ break;
+ case 'd': /* int */
+ d = va_arg(ap, int);
+ printf("int %d\en", d);
+ break;
+ case 'c': /* char */
+ c = va_arg(ap, int); /* promoted */
+ printf("char %c\en", c);
+ break;
+ case 'f': /* float */
+ f = va_arg(ap, double); /* promoted */
+ printf("float %f\en", f);
+ }
+ va_end(ap);
+}
+.Ed
+.Sh STANDARDS
+These macros are
+.Em not
+compatible with the historic macros they replace.
+A backward compatible version can be found in the include
+file
+.In varargs.h .
+.Pp
+The
+.Fn va_start ,
+.Fn va_arg
+and
+.Fn va_end
+macros conform to
+.St -isoC-99 .
+.Sh HISTORY
+The
+.Fn va_start ,
+.Fn va_arg
+and
+.Fn va_end
+macros were introduced in
+.St -ansiC .
+The
+.Fn va_copy
+macro was introduced in
+.St -isoC-99 .
+.Sh BUGS
+Unlike the
+.Em varargs
+macros, the
+.Nm stdarg
+macros do not permit programmers to
+code a function with no fixed arguments.
+This problem generates work mainly when converting
+.Em varargs
+code to
+.Nm stdarg
+code,
+but it also creates difficulties for variadic functions that
+wish to pass all of their arguments on to a function
+that takes an argument of type
+.Vt va_list ,
+such as
+.Xr vfprintf 3 .