/* * 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 #include #include /* ------------------------------------------------------------------ */ /* 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 #ifndef __FreeBSD__ typedef void (*sig_t)(int); #endif #endif /* ------------------------------------------------------------------ */ /* d_namlen -- BSD struct dirent member; Linux lacks it */ /* ------------------------------------------------------------------ */ #include #include #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 #include #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 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() #include #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 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 #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 #ifndef D_MD_ORDER #define D_MD_ORDER D_FMT #endif /* ------------------------------------------------------------------ */ /* MAXPATHLEN -- BSD path limit constant; Linux uses PATH_MAX */ /* ------------------------------------------------------------------ */ #ifndef MAXPATHLEN #include #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 #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 #endif #endif /* VX_COMPAT_H */