Compatibility functions
arc4random(), …
Tests and compatibility for
arc4random(3)
functions in stdlib.h, defining
HAVE_ARC4RANDOM with the result.
#if HAVE_ARC4RANDOM
# include <stdlib.h> /* arc4random, arc4random_buf... */
#endif
The compatibility functions provide the same quality
(via the same source) as OpenBSD, using the
host’s getentropy() function for
seed.
blf_enc(), blf_dec(), …
Tests and compatibility for blf_enc(3) functions including the raw block functions (not documented on OpenBSD, but still in the public API).
#if HAVE_BLOWFISH
# include <blf.h> /* blf_enc ... */
#endif
b64_ntop(), b64_pton()
Tests and compatibility for these functions, which do not have manpages on OpenBSD despite existing and being usable. On some systems, the functions are only declared, but not defined. To avoid superfluous inclusions, their usage should be guarded:
#if HAVE_B64_NTOP
# include <netinet/in.h>
# include <resolv.h>
#endif
Some systems (Linux only?) with
HAVE_B64_NTOP need
-lresolv during linking. If so,
LDADD_B64_NTOP is defined in
Makefile.configure to
-lresolv. Otherwise, it is empty.
Since these functions are always poorly documented,
the following demonstrates usage for
b64_ntop(), which translates
src into
an encoded NUL-terminated string
dst and
returns the string length or -1. The
dstsz is the
maximum size required for encoding.
srcsz = strlen(src);
dstsz = ((srcsz + 2) / 3 * 4) + 1;
dst = malloc(dstsz);
if (b64_ntop(src, srcsz, dst, dstsz) == -1)
goto bad_size;
b64_pton() reverses this situation from an
encoded NUL-terminated string
src into the
decoded and NUL-terminated string
dst (it’s
common not to need the NUL-terminator for the
decoded string, which is meant to be binary). The
dstsz is the
maximum size required for decoding.
srcsz = strlen(src);
dstsz = srscsz / 4 * 3;
dst = malloc(dstsz + 1); /* NUL terminator */
if ((c = b64_pton(src, dst, dstsz)) == -1)
goto bad_data;
dst[c] = '\0'; /* NUL termination */
crypt_newhash(), …
Tests and compatibility for the
crypt(3)-replacing
functions
crypt_newhash(3)
and
crypt_checkpass(3)
functions, defining HAVE_CRYPT_NEWHASH
with the result.
The portability functions only provide
bcrypt() functionality.
htole32(), be32toh(), …
On most operating systems (Linux, OpenBSD), endian.h provides the POSIX.1 endian functions, e.g., htole32(3), be32toh(3), etc. On FreeBSD, however, these are in sys/endian.h. Mac OS X and SunOS have their own functions in their own places.
The required invocation to use the endian functions is:
#if HAVE_ENDIAN_H
# include <endian.h>
#elif HAVE_SYS_ENDIAN_H
# include <sys/endian.h>
#elif HAVE_OSBYTEORDER_H
# include <libkern/OSByteOrder.h>
#elif HAVE_SYS_BYTEORDER_H
# include <sys/byteorder.h>
#endif
Compatibility for the Mac OS X and SunOS functions
to the usual htole32() style is provided.
To make this easier, the
COMPAT_ENDIAN_H is also defined:
#include COMPAT_ENDIAN_H
This will paste the appropriate location.
Source: test
err(), warn(), …
Tests for the
err(3) functions,
defining HAVE_ERR variable with the result.
Provides compatibility functions if not found. The
functions are for err(),
errx(), errc(),
warn(), warnx(),
warnc(), and the variable-argument
versions of each.
#if HAVE_ERR
# include <err.h>
#endif
The err.h header needs to be guarded to prevent systems using the compatibility functions for failing, as the header does not exist.
It’s worth noting that
glibc
defines many of these functions, but misses the
errc() and warnc() variations.
oconfigure considers it all or
nothing, so will not define HAVE_ERR in
this case.
explicit_bzero()
Tests for
explicit_bzero(3)
in string.h, defining
HAVE_EXPLICIT_BZERO with the result.
#include <string.h> /* explicit_bzero */
Provides a compatibility function if not found. The
compatibility function will use
memset_s,
if found. HAVE_EXPLICIT_BZERO
shouldn’t be directly used in most
circumstances.
fts_open(), fts_read(), …
Tests for
fts_open(3)
functions in fts.h, defining
HAVE_FTS with the result.
#if HAVE_FTS
# include <sys/types.h>
# include <fts.h> /* fts_open(3) et al. */
#endif
The fts.h header needs to be guarded to prevent systems using the compatibility functions for failing, as the header does not exist.
Provides compatibility functions if not found.
getprogname()
Tests for
getprogname(3)
in stdlib.h, defining
HAVE_GETPROGNAME with the result.
#include <stdlib.h> /* getprogname */
Provides a compatibility function if not found. The
compatibility function tries to use
__progname,
program_invocation_short_name, or
getexecname(). If none of these interfaces may
be found, it will emit a compile-time error.
HAVE_GETPROGNAME shouldn’t be directly
used in most circumstances.
INFTIM
Tests for the INFTIM macro value in
poll(2),
defining HAVE_INFTIM with the result.
#include <poll.h> /* INFTIM */
Provides a compatibility value if not found. Since
a compatibility value is provided,
HAVE_INFTIM shouldn’t be directly
used in most circumstances.
Source: test
MD5Init(), MD5Update(), …
Tests for the standalone
md5(3)
functions, defining HAVE_MD5 with the
result.
If not found, provides a full complement of
standalone (i.e., not needing any crypto libraries)
MD5 hashing functions. These are
MD5Init, MD5Update,
MD5Pad, MD5Transform,
MD5End, and MD5Final. The
preprocessor macros MD5_BLOCK_LENGTH,
MD5_DIGEST_LENGTH, and
MD5_DIGEST_STRING_LENGTH are also
defined.
These differ ever-so-slightly from the OpenBSD
versions in that they use C99 types for greater
portability, e.g., uint8_t instead of
u_int8_t.
If using these functions, you’ll want to guard an inclusion of the system-default. Otherwise a partial md5.h may conflict with results, or a missing md5.h may terminate compilation.
#if HAVE_MD5
# include <sys/types.h>
# include <md5.h>
#endif
On some systems (FreeBSD or those with
Guillem Jover’s libmd)
with HAVE_MD5, you’ll also need
to add -lmd when you compile your
system, else it will fail with undefined references.
The LDADD_MD5 value provided in
Makefile.configure will be set to
-lmd if it’s required. Otherwise
it is empty.
memmem()
Tests for
memmem(3) in
string.h, defining HAVE_MEMMEM with
the result.
#include <string.h> /* memmem */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_MEMMEM shouldn’t be directly used in
most circumstances.
memrchr()
Tests for
memrchr(3)
in string.h, defining HAVE_MEMRCHR
with the result.
#include <string.h> /* memrchr */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_MEMRCHR shouldn’t be directly used
in most circumstances.
WAIT_ANY
Tests for WAIT_ANY in
waitpid(2),
defining HAVE_WAIT_ANY with the result.
#include <sys/wait.h> /* WAIT_ANY, WAIT_MYPGRP */
Provides a compatibility value for both
WAIT_ANY and WAIT_MYPGRP
if not found. Since a compatibility function is
provided, HAVE_WAIT_ANY shouldn’t
be directly used in most circumstances.
Source: test
mkfifoat()
Tests for the
mkfifoat(3)
function, defining HAVE_MKFIFOAT with
the result.
Provides a compatibility function if not found. This is not a direct replacement, as the function is not atomic: it internally gets a reference to the current directory, changes into the “at” directory, runs the function, then returns to the prior current. Upon errors, it makes a best effort to restore the current working directory to what it was.
mknodat()
Tests for the mknodat(3)
function, defining HAVE_MKNODAT with the
result.
Provides a compatibility function if not found. This is not a direct replacement, as the function is not atomic: it internally gets a reference to the current directory, changes into the “at” directory, runs the function, then returns to the prior current. Upon errors, it makes a best effort to restore the current working directory to what it was.
PATH_MAX
Tests for the PATH_MAX variable in
limits.h, defining
HAVE_PATH_MAX with the result.
#include <limits.h> /* PATH_MAX */
If not found, defines the PATH_MAX
macro to be 4096. Since a compatibility value is
provided, HAVE_PATH_MAX shouldn’t
be directly used in most circumstances.
Source: test
readpassphrase()
Tests for the
readpassphrase(3)
function, defining HAVE_READPASSPHRASE
with the result.
The readpassphrase.h header
inclusion needs to be guarded for systems that
include it by default; otherwise, the definitions
are provided in the generated config.h:
#if HAVE_READPASSPHRASE
# include <readpassphrase.h>
#endif
Provides a compatibility function if not found. If using this function, makes sure you explicitly zero the passphrase buffer as described in readpassphrase(3).
reallocarray()
Tests for
reallocarray(3)
in stdlib.h, defining
HAVE_REALLOCARRAY with the result.
#include <stdlib.h> /* reallocarray */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_REALLOCARRAY shouldn’t be
directly used in most circumstances.
recallocarray()
Tests for
recallocarray(3)
in stdlib.h, defining
HAVE_RECALLOCARRAY with the result.
#include <stdlib.h> /* recallocarray */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_RECALLOCARRAY shouldn’t be
directly used in most circumstances.
scan_scaled(), fmt_scaled()
Tests for OpenBSD’s
scan_scaled(3),
defining HAVE_SCAN_SCALED if it was
found.
#if HAVE_SCAN_SCALED
# include <util.h>
#endif
Provides compatibility functions if not found. If
this is required, the LDADD_SCAN_SCALED
variable in Makefile.configure will be set
to the required library (-lutil).
SHA256Init(), SHA256Update(), …
Tests for the standalone
sha2(3)
functions, defining HAVE_SHA2 with the
result. This was previously provided as
HAVE_SHA2_H, which still works as an
alias for HAVE_SHA2.
If not found, provides a full complement of
standalone SHA2 hashing functions. These are
SHA256Init(), SHA256Transform(),
SHA256Update(), SHA256Pad(),
SHA256Final(), SHA256End(),
SHA256File(), SHA256FileChunk(), and
SHA256Data(). The preprocessor macros
SHA256_BLOCK_LENGTH,
SHA256_DIGEST_LENGTH, and
SHA256_DIGEST_STRING_LENGTH are also
defined.
The SHA2 functions and macros are provided for
SHA256, SHA384, and SHA512. So for example the
SHA512Final() function is also provided.
If using these functions, you’ll want to guard an inclusion of the system-default. Otherwise a partial sha2.h may conflict with results, or a missing sha2.h may terminate compilation.
#if HAVE_SHA2
# include <sys/types.h>
# include <sha2.h>
#endif
On some systems (such as those with
Guillem Jover’s libmd)
with HAVE_SHA2, you’ll also need
to add -lmd when you compile your
system, else it will fail with undefined references.
The LDADD_SHA2 value provided in
Makefile.configure will be set to
-lmd if it’s required. Otherwise
it is empty.
strlcat()
Tests for
strlcat(3)
in string.h, defining
HAVE_STRLCAT with the result.
#include <string.h> /* strlcat */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_STRLCAT shouldn’t be
directly used in most circumstances.
strlcpy()
Tests for
strlcpy(3)
in string.h, defining
HAVE_STRLCPY with the result.
#include <string.h> /* strlcpy */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_STRLCPY shouldn’t be
directly used in most circumstances.
strndup()
Tests for
strndup(3)
in string.h, defining HAVE_STRNDUP
with the result.
#include <string.h> /* strndup */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_STRNDUP shouldn’t be
directly used in most circumstances.
strnlen()
Tests for
strnlen(3)
in string.h, defining HAVE_STRNLEN
with the result.
#include <string.h> /* strnlen */
Provides a compatibility function if not found.
Since a compatibility function is provided,
HAVE_STRNLEN shouldn’t be
directly used in most circumstances.
strtonum()
Tests for
strtonum(3)
in stdlib.h, defining
HAVE_STRTONUM with the result.
#include <stdlib.h> /* strtonum */
Provides a compatibility function if not found.
Since a compatibility value is provided,
HAVE_STRTONUM shouldn’t be
directly used in most circumstances.
LIST_HEAD(), TAILQ_HEAD(), …
Tests for the
queue(3)
header, sys/queue.h. Defines
HAVE_SYS_QUEUE if found. To use these
macros, make sure to guard inclusion:
#if HAVE_SYS_QUEUE
# include <sys/queue.h>
#endif
Provides all of the queue macros if not. This uses
TAILQ_FOREACH_SAFE as a basis for
determining whether the header exists and is
well-formed. This is because glibc provides a
skeleton sys/queue.h without this
critical macro.
SPLAY_INIT(), RB_INIT(), …
Tests for the
tree(3) header,
sys/tree.h. Defines
HAVE_SYS_TREE if found.
To use these macros,
make sure to guard inclusion:
#if HAVE_SYS_TREE
# include <sys/tree.h>
#endif
Provides all of the tree macros if not found.
timingsafe_bcmp()
Tests for the
timingsafe_bcmp(3)
functions in string.h, defining
HAVE_TIMINGSAFE_BCMP with the result.
#if HAVE_TIMINGSAFE_BCMP
# include <string.h> /* timingsafe_bcmp... */
#endif
If not found, provides compatibility functions.
Feature tests
Capsicum
Tests for
FreeBSD’s
Capsicum
subsystem, defining the HAVE_CAPSICUM variable
with the result.
#if HAVE_CAPSICUM
# include <sys/resource.h>
# include <sys/capsicum.h>
#endif
The guard is required for systems without these headers.
crypt()
On OpenBSD, passwords are managed primarily through crypt_newhash(3) and friends. However, the old crypt(3) function is still used in portable applications. Even though it’s not very portable.
This tests for
crypt(3),
defining HAVE_CRYPT with the result.
On many systems with HAVE_CRYPT, you’ll
also need to add -lcrypt when you compile your
system, else it will fail with undefined references.
The LDADD_CRYPT value provided in
Makefile.configure will be set to
-lcrypt if it’s required. Otherwise it is
empty.
Source: test
landlock
Tests for Linux’s
landlock) LSM. Defines
HAVE_LANDLOCK if found.
This test does not mean that the module is enabled.
You’ll need to perform a run-time check for
landlock_restrict_self()’s return value in
your sources.
To actually use Landlock, you’ll need to modify your system’s LSM at boot time.
Source: test
libsocket
On IllumOS-based distributions, all socket functions (bind(2), listen(2), socketpair(2), etc.) require linking to the -lsocket and -lnsl libraries.
If this is required, the LDADD_LIB_SOCKET
variable in Makefile.configure will be set to the
required libraries.
minor(), major(), …
major(2), minor(2), and makedev(2) all live in different places on different systems.
#if HAVE_SYS_MKDEV_H
# include <sys/types.h> /* dev_t */
# include <sys/mkdev.h> /* minor/major/makedev */
#elif HAVE_SYS_SYSMACROS_H
# include <sys/sysmacros.h> /* minor/major/makedev */
#else
# include <sys/types.h> /* minor/major/makedev */
#endif
This can be made much easier as follows, where
COMPAT_MAJOR_MINOR_H is set to one of the
above. sys/types.h may be included twice.
#include <sys/types.h>
#include COMPAT_MAJOR_MINOR_H
pledge()
Test for
pledge(2),
defining HAVE_PLEDGE with the result. Does not
provide any compatibility.
#include <unistd.h> /* pledge */
The HAVE_PLEDGE guard is not required except
around the function invocation.
Source: test
sandbox_init()
Tests for
sandbox_init(3),
defining HAVE_SANDBOX_INIT with the result.
Does not provide any compatibility.
Source: test
seccomp
Tests for Linux’s prctl(2) function, which is the gateway for seccomp(2). This defines several variables:
-
HAVE_SECCOMP_HEADER: Compile-time support exists for seccomp. -
SECCOMP_AUDIT_ARCH: IfHAVE_SECCOMP_HEADERis set, this is set to the architecture used for seccomp operations (e.g.,AUDIT_ARCH_ARM). If this is not set andHAVE_SECCOMP_HEADERis set, seccomp is enabled in the kernel but the hardware architecture is not known by oconfigure. Please create an issue or pull request with youruname -mand hardware profile. -
HAVE_SECCOMP_FILTER: Set if bothHAVE_SECCOMP_HEADERandSECCOMP_AUDIT_ARCHare set.
This test does not mean that the sandboxing is
enabled. You’ll need to perform a run-time check
for prctl()’s return value in your sources.
Source: test
SOCK_NONBLOCK
Tests for
socketpair(2)
in sys/socket.h supporting the
SOCK_NONBLOCK mask as found on OpenBSD.
Defines the HAVE_SOCK_NONBLOCK variable.
#if HAVE_SOCK_NONBLOCK
socketpair(AF_UNIX, flags|SOCK_NONBLOCK, 0, fd);
#else
socketpair(AF_UNIX, flags, 0, fd);
fcntl(fd[0], F_SETFL,
fcntl(fd[0], F_GETFL, 0)|O_NONBLOCK);
fcntl(fd[1], F_SETFL,
fcntl(fd[1], F_GETFL, 0)|O_NONBLOCK);
#endif
The guard is not required only around the variable usage,
not header inclusion. However, the above example could have
the fcntl.h header guarded by
!HAVE_SOCK_NONBLOCK.
Source: test
systrace
Tests for the deprecated systrace(4) interface. Defines
HAVE_SYSTRACE if found. Does not provide any
compatibility.
This function is never “found”.
Source: test
termios
Tests for whether
termios(4)
exists, defining HAVE_TERMIOS with the result,
specifically with the use case of testing terminal widths
via ioctl(2)
and TIOCGWINSZ (which must also exist). Does
not provide any compaibility.
Source: test