diff options
Diffstat (limited to 'lib/portability.h')
-rw-r--r-- | lib/portability.h | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/lib/portability.h b/lib/portability.h index 77b6a2a6..f35ce77f 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -8,13 +8,6 @@ // This must come before we #include any system header file to take effect! #define _FILE_OFFSET_BITS 64 -// For musl -#define _ALL_SOURCE -#include <regex.h> -#ifndef REG_STARTEND -#define REG_STARTEND 0 -#endif - #ifdef __APPLE__ // macOS 10.13 doesn't have the POSIX 2008 direct access to timespec in // struct stat, but we can ask it to give us something equivalent... @@ -26,6 +19,27 @@ #define st_mtim st_mtimespec #endif +// For musl +#define _ALL_SOURCE +#include <regex.h> +#ifndef REG_STARTEND +#define REG_STARTEND 0 +#endif + +// for some reason gnu/libc only sets these if you #define ia_ia_stallman_ftaghn +// despite FreeBSD and MacOS having both with the same value, and bionic's +// "upstream-openbsd" directory documenting them as "BSD extensions". +// (The flexible extension would have been an fnmatch() that returns length +// matched at location so we could check trailing data ourselves, but no. +// And it's ANSI only case matching instead of UTF8...) +#include <fnmatch.h> +#ifndef FNM_LEADING_DIR +#define FNM_LEADING_DIR 8 +#endif +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD 16 +#endif + // Test for gcc (using compiler builtin #define) #ifdef __GNUC__ @@ -39,17 +53,13 @@ #define printf_format #endif -// This isn't in the spec, but it's how we determine what libc we're using. - -// Types various replacement prototypes need. -// This also lets us determine what libc we're using. Systems that -// have <features.h> will transitively include it, and ones that don't -- -// macOS -- won't break. +// This lets us determine what libc we're using: systems that have <features.h> +// will transitively include it, and ones that don't (macOS) won't break. #include <sys/types.h> // Various constants old build environments might not have even if kernel does -#ifndef AT_FDCWD +#ifndef AT_FDCWD // Kernel commit 5590ff0d5528 2006 #define AT_FDCWD -100 #endif @@ -61,11 +71,11 @@ #define AT_REMOVEDIR 0x200 #endif -#ifndef RLIMIT_RTTIME +#ifndef RLIMIT_RTTIME // Commit 78f2c7db6068f 2008 #define RLIMIT_RTTIME 15 #endif -// Introduced in Linux 3.1 +// Introduced in Linux 3.1 (Commit 982d816581eee 2011) #ifndef SEEK_DATA #define SEEK_DATA 3 #endif @@ -84,7 +94,7 @@ // claim it's in the name of Gnu. #if defined(__GLIBC__) -// "Function prototypes shall be provided." but aren't. +// Glibc violates posix: "Function prototypes shall be provided." but aren't. // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html char *crypt(const char *key, const char *salt); @@ -97,14 +107,14 @@ int wcwidth(wchar_t wc); #include <time.h> char *strptime(const char *buf, const char *format, struct tm *tm); -// They didn't like posix basename so they defined another function with the +// Gnu didn't like posix basename so they defined another function with the // same name and if you include libgen.h it #defines basename to something // else (where they implemented the real basename), and that define breaks // the table entry for the basename command. They didn't make a new function // with a different name for their new behavior because gnu. // -// Solution: don't use their broken header, provide an inline to redirect the -// correct name to the broken name. +// Solution: don't use their broken header and provide an inline to redirect +// the standard name to the renamed function with the standard behavior. char *dirname(char *path); char *__xpg_basename(char *path); @@ -114,9 +124,6 @@ void *memmem(const void *haystack, size_t haystack_length, const void *needle, size_t needle_length); #endif // defined(glibc) -// getopt_long(), getopt_long_only(), and struct option. -#include <getopt.h> - #if !defined(__GLIBC__) // POSIX basename. #include <libgen.h> @@ -148,6 +155,10 @@ void *memmem(const void *haystack, size_t haystack_length, #define IS_BIG_ENDIAN 0 #endif +#define bswap_16(x) bswap16(x) +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) + #else #include <byteswap.h> @@ -229,7 +240,7 @@ int posix_fallocate(int, off_t, off_t); #include <xlocale.h> #endif -#if defined(__APPLE__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) static inline long statfs_bsize(struct statfs *sf) { return sf->f_iosize; } static inline long statfs_frsize(struct statfs *sf) { return sf->f_bsize; } #else @@ -240,10 +251,10 @@ static inline long statfs_frsize(struct statfs *sf) { return sf->f_frsize; } // Android is missing some headers and functions // "generated/config.h" is included first -#if CFG_TOYBOX_SHADOW +#if __has_include(<shadow.h>) #include <shadow.h> #endif -#if CFG_TOYBOX_UTMPX +#if __has_include(<utmpx.h>) #include <utmpx.h> #else struct utmpx {int ut_type;}; @@ -255,6 +266,9 @@ static inline void endutxent(void) {;} // Some systems don't define O_NOFOLLOW, and it varies by architecture, so... #include <fcntl.h> +#if defined(__APPLE__) +#define O_PATH 0 +#else #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif @@ -270,6 +284,7 @@ static inline void endutxent(void) {;} #ifndef SCHED_RESET_ON_FORK #define SCHED_RESET_ON_FORK (1<<30) #endif +#endif // Glibc won't give you linux-kernel constants unless you say "no, a BUD lite" // even though linux has nothing to do with the FSF and never has. @@ -292,8 +307,12 @@ typedef float FLOAT; pid_t xfork(void); #endif -//#define strncpy(...) @@strncpyisbadmmkay@@ -//#define strncat(...) @@strncatisbadmmkay@@ +// gratuitously memsets ALL the extra space with zeroes (not just a terminator) +// but to make up for it truncating doesn't null terminate the output at all. +// There are occasions to use it, but it is NOT A GENERAL PURPOSE FUNCTION. +// #define strncpy(...) @@strncpyisbadmmkay@@ +// strncat writes a null terminator one byte PAST the buffer size it's given. +#define strncat(...) strncatisbadmmkay(__VA_ARGS__) // Support building the Android tools on glibc, so hermetic AOSP builds can // use toybox before they're ready to switch to host bionic. @@ -343,10 +362,10 @@ typedef struct {char *c_name; int c_val;} CODE; extern CODE prioritynames[], facilitynames[]; #endif -#if CFG_TOYBOX_GETRANDOM +#if __has_include (<sys/random.h>) #include <sys/random.h> #endif -int xgetrandom(void *buf, unsigned len, unsigned flags); +void xgetrandom(void *buf, unsigned len); // Android's bionic libc doesn't have confstr. #ifdef __BIONIC__ @@ -393,7 +412,8 @@ struct itimerspec { }; int timer_create(clock_t c, struct sigevent *se, timer_t *t); int timer_settime(timer_t t, int flags, struct itimerspec *new, void *old); -#elif !CFG_TOYBOX_HASTIMERS +#elif defined(__GLIBC__) +// Work around a glibc bug that interacts badly with a gcc bug. #include <syscall.h> #include <signal.h> #include <time.h> |