toybox/lib/portability.h
<<
>>
Prefs
   1// Workarounds for horrible build environment idiosyncrasies.
   2
   3// Instead of polluting the code with strange #ifdefs to work around bugs
   4// in specific compiler, library, or OS versions, localize all that here
   5// and in portability.c
   6
   7// For musl
   8#define _ALL_SOURCE
   9
  10#ifdef __APPLE__
  11// macOS 10.13 doesn't have the POSIX 2008 direct access to timespec in
  12// struct stat, but we can ask it to give us something equivalent...
  13// (This must come before any #include!)
  14#define _DARWIN_C_SOURCE
  15// ...and then use macros to paper over the difference.
  16#define st_atim st_atimespec
  17#define st_ctim st_ctimespec
  18#define st_mtim st_mtimespec
  19#endif
  20
  21// Test for gcc (using compiler builtin #define)
  22
  23#ifdef __GNUC__
  24#define printf_format   __attribute__((format(printf, 1, 2)))
  25#else
  26#define printf_format
  27#endif
  28
  29// Always use long file support.
  30#define _FILE_OFFSET_BITS 64
  31
  32// This isn't in the spec, but it's how we determine what libc we're using.
  33
  34// Types various replacement prototypes need.
  35// This also lets us determine what libc we're using. Systems that
  36// have <features.h> will transitively include it, and ones that don't --
  37// macOS -- won't break.
  38#include <sys/types.h>
  39
  40// Various constants old build environments might not have even if kernel does
  41
  42#ifndef AT_FDCWD
  43#define AT_FDCWD -100
  44#endif
  45
  46#ifndef AT_SYMLINK_NOFOLLOW
  47#define AT_SYMLINK_NOFOLLOW 0x100
  48#endif
  49
  50#ifndef AT_REMOVEDIR
  51#define AT_REMOVEDIR 0x200
  52#endif
  53
  54#ifndef RLIMIT_RTTIME
  55#define RLIMIT_RTTIME 15
  56#endif
  57
  58// Introduced in Linux 3.1
  59#ifndef SEEK_DATA
  60#define SEEK_DATA 3
  61#endif
  62#ifndef SEEK_HOLE
  63#define SEEK_HOLE 4
  64#endif
  65
  66// We don't define GNU_dammit because we're not part of the gnu project, and
  67// don't want to get any FSF on us. Unfortunately glibc (gnu libc)
  68// won't give us Linux syscall wrappers without claiming to be part of the
  69// gnu project (because Stallman's "GNU owns Linux" revisionist history
  70// crusade includes the kernel, even though Linux was inspired by Minix).
  71
  72// We use most non-posix Linux syscalls directly through the syscall() wrapper,
  73// but even many posix-2008 functions aren't provided by glibc unless you
  74// claim it's in the name of Gnu.
  75
  76#if defined(__GLIBC__)
  77// "Function prototypes shall be provided." but aren't.
  78// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html
  79char *crypt(const char *key, const char *salt);
  80
  81// According to posix, #include header, get a function definition. But glibc...
  82// http://pubs.opengroup.org/onlinepubs/9699919799/functions/wcwidth.html
  83#include <wchar.h>
  84int wcwidth(wchar_t wc);
  85
  86// see http://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html
  87#include <time.h>
  88char *strptime(const char *buf, const char *format, struct tm *tm);
  89
  90// They didn't like posix basename so they defined another function with the
  91// same name and if you include libgen.h it #defines basename to something
  92// else (where they implemented the real basename), and that define breaks
  93// the table entry for the basename command. They didn't make a new function
  94// with a different name for their new behavior because gnu.
  95//
  96// Solution: don't use their broken header, provide an inline to redirect the
  97// correct name to the broken name.
  98
  99char *dirname(char *path);
 100char *__xpg_basename(char *path);
 101static inline char *basename(char *path) { return __xpg_basename(path); }
 102char *strcasestr(const char *haystack, const char *needle);
 103#endif // defined(glibc)
 104
 105#if !defined(__GLIBC__)
 106// POSIX basename.
 107#include <libgen.h>
 108#endif
 109
 110// Work out how to do endianness
 111
 112#ifdef __APPLE__
 113
 114#include <libkern/OSByteOrder.h>
 115
 116#ifdef __BIG_ENDIAN__
 117#define IS_BIG_ENDIAN 1
 118#else
 119#define IS_BIG_ENDIAN 0
 120#endif
 121
 122#define bswap_16(x) OSSwapInt16(x)
 123#define bswap_32(x) OSSwapInt32(x)
 124#define bswap_64(x) OSSwapInt64(x)
 125
 126int clearenv(void);
 127
 128#elif defined(__FreeBSD__)
 129
 130#include <sys/endian.h>
 131
 132#if _BYTE_ORDER == _BIG_ENDIAN
 133#define IS_BIG_ENDIAN 1
 134#else
 135#define IS_BIG_ENDIAN 0
 136#endif
 137
 138#else
 139
 140#include <byteswap.h>
 141#include <endian.h>
 142
 143#if __BYTE_ORDER == __BIG_ENDIAN
 144#define IS_BIG_ENDIAN 1
 145#else
 146#define IS_BIG_ENDIAN 0
 147#endif
 148
 149#endif
 150
 151#if IS_BIG_ENDIAN
 152#define IS_LITTLE_ENDIAN 0
 153#define SWAP_BE16(x) (x)
 154#define SWAP_BE32(x) (x)
 155#define SWAP_BE64(x) (x)
 156#define SWAP_LE16(x) bswap_16(x)
 157#define SWAP_LE32(x) bswap_32(x)
 158#define SWAP_LE64(x) bswap_64(x)
 159#else
 160#define IS_LITTLE_ENDIAN 1
 161#define SWAP_BE16(x) bswap_16(x)
 162#define SWAP_BE32(x) bswap_32(x)
 163#define SWAP_BE64(x) bswap_64(x)
 164#define SWAP_LE16(x) (x)
 165#define SWAP_LE32(x) (x)
 166#define SWAP_LE64(x) (x)
 167#endif
 168
 169// Linux headers not listed by POSIX or LSB
 170#include <sys/mount.h>
 171#ifdef __linux__
 172#include <sys/statfs.h>
 173#include <sys/swap.h>
 174#include <sys/sysinfo.h>
 175#endif
 176
 177#ifdef __APPLE__
 178#include <util.h>
 179#elif !defined(__FreeBSD__)
 180#include <pty.h>
 181#else
 182#include <termios.h>
 183#ifndef IUTF8
 184#define IUTF8 0
 185#endif
 186#endif
 187
 188#ifndef __FreeBSD__
 189#include <sys/xattr.h>
 190#endif
 191
 192// Android is missing some headers and functions
 193// "generated/config.h" is included first
 194#if CFG_TOYBOX_SHADOW
 195#include <shadow.h>
 196#endif
 197#if CFG_TOYBOX_UTMPX
 198#include <utmpx.h>
 199#else
 200struct utmpx {int ut_type;};
 201#define USER_PROCESS 0
 202static inline struct utmpx *getutxent(void) {return 0;}
 203static inline void setutxent(void) {;}
 204static inline void endutxent(void) {;}
 205#endif
 206
 207// Some systems don't define O_NOFOLLOW, and it varies by architecture, so...
 208#include <fcntl.h>
 209#ifndef O_NOFOLLOW
 210#define O_NOFOLLOW 0
 211#endif
 212#ifndef O_NOATIME
 213#define O_NOATIME 01000000
 214#endif
 215#ifndef O_CLOEXEC
 216#define O_CLOEXEC 02000000
 217#endif
 218#ifndef O_PATH
 219#define O_PATH   010000000
 220#endif
 221#ifndef SCHED_RESET_ON_FORK
 222#define SCHED_RESET_ON_FORK (1<<30)
 223#endif
 224
 225// Glibc won't give you linux-kernel constants unless you say "no, a BUD lite"
 226// even though linux has nothing to do with the FSF and never has.
 227#ifndef F_SETPIPE_SZ
 228#define F_SETPIPE_SZ 1031
 229#endif
 230
 231#ifndef F_GETPIPE_SZ
 232#define F_GETPIPE_SZ 1032
 233#endif
 234
 235#if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_LONG__) \
 236    && __SIZEOF_DOUBLE__ <= __SIZEOF_LONG__
 237typedef double FLOAT;
 238#else
 239typedef float FLOAT;
 240#endif
 241
 242#ifndef __uClinux__
 243pid_t xfork(void);
 244#endif
 245
 246//#define strncpy(...) @@strncpyisbadmmkay@@
 247//#define strncat(...) @@strncatisbadmmkay@@
 248
 249// Support building the Android tools on glibc, so hermetic AOSP builds can
 250// use toybox before they're ready to switch to host bionic.
 251#ifdef __BIONIC__
 252#include <android/log.h>
 253#include <sys/system_properties.h>
 254#else
 255typedef enum android_LogPriority {
 256  ANDROID_LOG_UNKNOWN = 0,
 257  ANDROID_LOG_DEFAULT,
 258  ANDROID_LOG_VERBOSE,
 259  ANDROID_LOG_DEBUG,
 260  ANDROID_LOG_INFO,
 261  ANDROID_LOG_WARN,
 262  ANDROID_LOG_ERROR,
 263  ANDROID_LOG_FATAL,
 264  ANDROID_LOG_SILENT,
 265} android_LogPriority;
 266static inline int __android_log_write(int pri, const char *tag, const char *msg)
 267{
 268  return -1;
 269}
 270#define PROP_VALUE_MAX 92
 271static inline int __system_property_set(const char *key, const char *value)
 272{
 273  return -1;
 274}
 275#endif
 276
 277// libcutils is in AOSP but not Android NDK r18
 278#if defined(__BIONIC__) && !defined(__ANDROID_NDK__)
 279#include <cutils/sched_policy.h>
 280#else
 281static inline int get_sched_policy(int tid, void *policy) {return 0;}
 282static inline char *get_sched_policy_name(int policy) {return "unknown";}
 283#endif
 284
 285// Android NDKv18 has liblog.so but not liblog.c for static builds,
 286// stub it out for now.
 287#ifdef __ANDROID_NDK__
 288#define __android_log_write(a, b, c) (0)
 289#define adjtime(x, y) (0)
 290#endif
 291
 292#ifndef SYSLOG_NAMES
 293typedef struct {char *c_name; int c_val;} CODE;
 294extern CODE prioritynames[], facilitynames[];
 295#endif
 296
 297#if CFG_TOYBOX_GETRANDOM
 298#include <sys/random.h>
 299#endif
 300int xgetrandom(void *buf, unsigned len, unsigned flags);
 301
 302// Android's bionic libc doesn't have confstr.
 303#ifdef __BIONIC__
 304#define _CS_PATH        0
 305#define _CS_V7_ENV      1
 306#include <string.h>
 307static inline void confstr(int a, char *b, int c) {strcpy(b, a ? "POSIXLY_CORRECT=1" : "/bin:/usr/bin");}
 308#endif
 309