aboutsummaryrefslogtreecommitdiff
path: root/lib/portability.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portability.h')
-rw-r--r--lib/portability.h82
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>