Home | History | Annotate | Download | only in lib
      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
     79 char *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>
     84 int wcwidth(wchar_t wc);
     85 
     86 // see http://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html
     87 #include <time.h>
     88 char *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 
     99 char *dirname(char *path);
    100 char *__xpg_basename(char *path);
    101 static inline char *basename(char *path) { return __xpg_basename(path); }
    102 char *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 
    126 int 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
    200 struct utmpx {int ut_type;};
    201 #define USER_PROCESS 0
    202 static inline struct utmpx *getutxent(void) {return 0;}
    203 static inline void setutxent(void) {;}
    204 static 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__
    237 typedef double FLOAT;
    238 #else
    239 typedef float FLOAT;
    240 #endif
    241 
    242 #ifndef __uClinux__
    243 pid_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
    255 typedef 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;
    266 static inline int __android_log_write(int pri, const char *tag, const char *msg)
    267 {
    268   return -1;
    269 }
    270 #define PROP_VALUE_MAX 92
    271 static 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
    281 static inline int get_sched_policy(int tid, void *policy) {return 0;}
    282 static 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
    293 typedef struct {char *c_name; int c_val;} CODE;
    294 extern CODE prioritynames[], facilitynames[];
    295 #endif
    296 
    297 #if CFG_TOYBOX_GETRANDOM
    298 #include <sys/random.h>
    299 #endif
    300 int 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>
    307 static inline void confstr(int a, char *b, int c) {strcpy(b, a ? "POSIXLY_CORRECT=1" : "/bin:/usr/bin");}
    308 #endif
    309