Files
vx/src/compat-headers/compat.h
T

274 lines
9.8 KiB
C

/*
* compat.h - Portability shim for building BSD userland on Linux.
*
* Must be included before any system headers (either directly or via
* the compiler's -include flag).
*/
#ifndef VX_COMPAT_H
#define VX_COMPAT_H
/*
* Feature-test macros -- unlock POSIX/GNU extensions in glibc headers.
* This exposes: strdup, asprintf, mkstemp, reallocarray, madvise,
* MADV_SEQUENTIAL, isascii, PATH_MAX, among others.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <stddef.h>
#include <stdio.h>
/* ------------------------------------------------------------------ */
/* sys/cdefs.h compat -- BSD compiler attribute macros */
/* ------------------------------------------------------------------ */
#ifndef __dead2
#define __dead2 __attribute__((noreturn))
#endif
#ifndef __unused
#define __unused __attribute__((unused))
#endif
#ifndef __DECONST
#define __DECONST(type, var) ((type)(unsigned long)(const void *)(var))
#endif
/* ------------------------------------------------------------------ */
/* Capsicum / sandbox stubs -- Linux has no Capsicum */
/* ------------------------------------------------------------------ */
#ifndef __FreeBSD__
typedef struct { int cr_rights; } cap_rights_t;
#define cap_rights_init(r, ...) ((void)0)
#define cap_rights_set(r, ...) ((void)0)
#define caph_rights_limit(fd, r) (0)
#define caph_limit_stream(fd, r) (0)
#define caph_limit_stdio() (0)
#define caph_limit_stdin() (0)
#define caph_limit_stdout() (0)
#define caph_limit_stderr() (0)
#define caph_cache_catpages() (0)
#define caph_cache_tzdata() (0)
#define caph_enter() (0)
#define CAP_READ 0
#define CAP_WRITE 0
#define CAP_FSTAT 0
#define CAP_SEEK 0
#define CAP_MMAP_R 0
#define CAP_FCNTL 0
#define CAP_EVENT 0
#define CAPH_READ 0
#define CAPH_WRITE 0
#define CAPH_IGNORE_EBADF 0
#endif
/* ------------------------------------------------------------------ */
/* SIGINFO -- BSD-only signal; not available on Linux */
/* ------------------------------------------------------------------ */
#ifndef SIGINFO
#define SIGINFO SIGUSR1
#endif
/* ------------------------------------------------------------------ */
/* sig_t -- BSD typedef for signal handler function pointer */
/* ------------------------------------------------------------------ */
#ifndef __OpenBSD__
#include <signal.h>
#ifndef __FreeBSD__
typedef void (*sig_t)(int);
#endif
#endif
/* ------------------------------------------------------------------ */
/* d_namlen -- BSD struct dirent member; Linux lacks it */
/* ------------------------------------------------------------------ */
#include <string.h>
#include <dirent.h>
#ifndef _DIRENT_HAVE_D_NAMLEN
#define DIRENT_NAMLEN(dp) strlen((dp)->d_name)
#else
#define DIRENT_NAMLEN(dp) ((dp)->d_namlen)
#endif
/*
* d_fileno -- BSD name for inode number in struct dirent.
* Linux uses d_ino.
*/
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
#define d_fileno d_ino
#endif
/* ------------------------------------------------------------------ */
/* fgetln -- BSD line-reading function; see fgetln.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
char *fgetln(FILE *fp, size_t *lenp);
#endif
/* ------------------------------------------------------------------ */
/* strlcpy / strlcat -- bounded string ops from OpenBSD */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
#if !defined(__GLIBC__) || (__GLIBC__ < 2) || \
(__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)
size_t strlcpy(char *dst, const char *src, size_t dsize);
size_t strlcat(char *dst, const char *src, size_t dsize);
#define VX_NEED_STRLCPY 1
#endif
#endif
/* ------------------------------------------------------------------ */
/* reallocf -- frees original on failure; see reallocf.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
void *reallocf(void *ptr, size_t size);
#endif
/* ------------------------------------------------------------------ */
/* strtonum -- safe string-to-number; see strtonum.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
long long strtonum(const char *nptr, long long minval,
long long maxval, const char **errstrp);
#endif
/* ------------------------------------------------------------------ */
/* errc / warnc -- BSD err.h variants with explicit errno */
/* ------------------------------------------------------------------ */
#include <err.h>
#include <errno.h>
#if !defined(__FreeBSD__)
#define errc(eval, code, ...) do { errno = (code); err((eval), __VA_ARGS__); } while (0)
#define warnc(code, ...) do { errno = (code); warn(__VA_ARGS__); } while (0)
#endif
/* ------------------------------------------------------------------ */
/* expand_number -- FreeBSD libutil; see expand_number.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__)
#include <stdint.h>
int expand_number(const char *buf, uint64_t *num);
#endif
/* ------------------------------------------------------------------ */
/* stdckdint.h -- C23 checked integer arithmetic */
/* Provide fallback using GCC/Clang builtins. */
/* ------------------------------------------------------------------ */
#if defined(__has_include)
#if __has_include(<stdckdint.h>)
#include <stdckdint.h>
#define VX_HAVE_STDCKDINT 1
#endif
#endif
#ifndef VX_HAVE_STDCKDINT
#define ckd_add(result, a, b) __builtin_add_overflow((a), (b), (result))
#define ckd_sub(result, a, b) __builtin_sub_overflow((a), (b), (result))
#define ckd_mul(result, a, b) __builtin_mul_overflow((a), (b), (result))
#endif
/* ------------------------------------------------------------------ */
/* roundup macro -- BSD sys/param.h; may be missing */
/* ------------------------------------------------------------------ */
#ifndef roundup
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#endif
/* ------------------------------------------------------------------ */
/* optreset -- BSD getopt extension */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
#include <getopt.h>
static int vx_optreset_dummy_ __attribute__((unused));
#define optreset vx_optreset_dummy_
#endif
/* ------------------------------------------------------------------ */
/* strmode -- convert mode_t to ls-style string; see strmode.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
void strmode(mode_t mode, char *p);
#endif
/* ------------------------------------------------------------------ */
/* user_from_uid / group_from_gid -- cached passwd/group lookups */
/* see ugid.c */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
const char *user_from_uid(uid_t uid, int nouser);
const char *group_from_gid(gid_t gid, int nogroup);
#endif
/* ------------------------------------------------------------------ */
/* MAXLOGNAME -- BSD login name limit; Linux uses LOGIN_NAME_MAX */
/* ------------------------------------------------------------------ */
#ifndef MAXLOGNAME
#include <limits.h>
#ifdef LOGIN_NAME_MAX
#define MAXLOGNAME LOGIN_NAME_MAX
#else
#define MAXLOGNAME 17
#endif
#endif
/* ------------------------------------------------------------------ */
/* D_MD_ORDER -- BSD langinfo constant for month/day ordering */
/* Not available on Linux; define a harmless fallback. */
/* ------------------------------------------------------------------ */
#include <langinfo.h>
#ifndef D_MD_ORDER
#define D_MD_ORDER D_FMT
#endif
/* ------------------------------------------------------------------ */
/* MAXPATHLEN -- BSD path limit constant; Linux uses PATH_MAX */
/* ------------------------------------------------------------------ */
#ifndef MAXPATHLEN
#include <limits.h>
#ifdef PATH_MAX
#define MAXPATHLEN PATH_MAX
#else
#define MAXPATHLEN 4096
#endif
#endif
/* ------------------------------------------------------------------ */
/* REG_BASIC -- BSD regex constant; 0 on Linux (default) */
/* ------------------------------------------------------------------ */
#ifndef REG_BASIC
#define REG_BASIC 0
#endif
/* ------------------------------------------------------------------ */
/* S_ISTXT -- BSD sticky bit name; Linux uses S_ISVTX */
/* ------------------------------------------------------------------ */
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
#endif
/* ------------------------------------------------------------------ */
/* QUAD_MAX -- BSD quad_t limit; use LLONG_MAX */
/* ------------------------------------------------------------------ */
#ifndef QUAD_MAX
#include <limits.h>
#define QUAD_MAX LLONG_MAX
#endif
/* ------------------------------------------------------------------ */
/* setmode / getmode -- BSD file mode parsing */
/* ------------------------------------------------------------------ */
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
void *setmode(const char *p);
mode_t getmode(const void *set, mode_t omode);
#endif
/* ------------------------------------------------------------------ */
/* makedev -- Linux needs sys/sysmacros.h */
/* ------------------------------------------------------------------ */
#ifdef __linux__
#include <sys/sysmacros.h>
#endif
#endif /* VX_COMPAT_H */