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// Test for gcc (using compiler builtin #define) 11 12#ifdef __GNUC__ 13#define noreturn __attribute__((noreturn)) 14#define printf_format __attribute__((format(printf, 1, 2))) 15#else 16#define noreturn 17#define printf_format 18#endif 19 20// Always use long file support. 21#define _FILE_OFFSET_BITS 64 22 23// This isn't in the spec, but it's how we determine what libc we're using. 24 25#include <features.h> 26 27// Types various replacement prototypes need 28#include <sys/types.h> 29 30// Various constants old build environments might not have even if kernel does 31 32#ifndef AT_FDCWD 33#define AT_FDCWD -100 34#endif 35 36#ifndef AT_SYMLINK_NOFOLLOW 37#define AT_SYMLINK_NOFOLLOW 0x100 38#endif 39 40#ifndef AT_REMOVEDIR 41#define AT_REMOVEDIR 0x200 42#endif 43 44#ifndef RLIMIT_RTTIME 45#define RLIMIT_RTTIME 15 46#endif 47 48#ifndef SEEK_DATA 49#define SEEK_DATA 3 50#endif 51 52// We don't define GNU_dammit because we're not part of the gnu project, and 53// don't want to get any FSF on us. Unfortunately glibc (gnu libc) 54// won't give us Linux syscall wrappers without claiming to be part of the 55// gnu project (because Stallman's "GNU owns Linux" revisionist history 56// crusade includes the kernel, even though Linux was inspired by Minix). 57 58// We use most non-posix Linux syscalls directly through the syscall() wrapper, 59// but even many posix-2008 functions aren't provided by glibc unless you 60// claim it's in the name of Gnu. 61 62#if defined(__GLIBC__) 63// "Function prototypes shall be provided." but aren't. 64// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html 65char *crypt(const char *key, const char *salt); 66 67// According to posix, #include header, get a function definition. But glibc... 68// http://pubs.opengroup.org/onlinepubs/9699919799/functions/wcwidth.html 69#include <wchar.h> 70int wcwidth(wchar_t wc); 71 72// see http://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html 73#include <time.h> 74char *strptime(const char *buf, const char *format, struct tm *tm); 75 76// They didn't like posix basename so they defined another function with the 77// same name and if you include libgen.h it #defines basename to something 78// else (where they implemented the real basename), and that define breaks 79// the table entry for the basename command. They didn't make a new function 80// with a different name for their new behavior because gnu. 81// 82// Solution: don't use their broken header, provide an inline to redirect the 83// correct name to the broken name. 84 85char *dirname(char *path); 86char *__xpg_basename(char *path); 87static inline char *basename(char *path) { return __xpg_basename(path); } 88 89// uClibc pretends to be glibc and copied a lot of its bugs, but has a few more 90#if defined(__UCLIBC__) 91#include <unistd.h> 92#include <stdio.h> 93ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 94char *stpcpy(char *dest, const char *src); 95pid_t getsid(pid_t pid); 96 97// uClibc's last-ever release was in 2012, so of course it doesn't define 98// any flag newer than MS_MOVE, which was added in 2001 (linux 2.5.0.5), 99// eleven years earlier. 100 101#include <sys/mount.h> 102#ifndef MS_MOVE 103#define MS_MOVE (1<<13) 104#endif 105#ifndef MS_REC 106#define MS_REC (1<<14) 107#endif 108#ifndef MS_SILENT 109#define MS_SILENT (1<<15) 110#endif 111#ifndef MS_UNBINDABLE 112#define MS_UNBINDABLE (1<<17) 113#endif 114#ifndef MS_PRIVATE 115#define MS_PRIVATE (1<<18) 116#endif 117#ifndef MS_SLAVE 118#define MS_SLAVE (1<<19) 119#endif 120#ifndef MS_SHARED 121#define MS_SHARED (1<<20) 122#endif 123#ifndef MS_RELATIME 124#define MS_RELATIME (1<<21) 125#endif 126 127// When building under obsolete glibc (Ubuntu 8.04-ish), hold its hand a bit. 128#elif __GLIBC__ == 2 && __GLIBC_MINOR__ < 10 129#define fstatat fstatat64 130int fstatat64(int dirfd, const char *pathname, void *buf, int flags); 131int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz); 132char *stpcpy(char *dest, const char *src); 133#include <sys/stat.h> 134int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); 135int openat(int dirfd, const char *pathname, int flags, ...); 136#include <dirent.h> 137DIR *fdopendir(int fd); 138#include <unistd.h> 139int fchownat(int dirfd, const char *pathname, 140 uid_t owner, gid_t group, int flags); 141int isblank(int c); 142int unlinkat(int dirfd, const char *pathname, int flags); 143#include <stdio.h> 144ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 145 146// Straight from posix-2008, things old glibc had but didn't prototype 147 148int faccessat(int fd, const char *path, int amode, int flag); 149int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); 150int mkdirat(int fd, const char *path, mode_t mode); 151int symlinkat(const char *path1, int fd, const char *path2); 152int mknodat(int fd, const char *path, mode_t mode, dev_t dev); 153#include <sys/time.h> 154int futimens(int fd, const struct timespec times[2]); 155int utimensat(int fd, const char *path, const struct timespec times[2], int flag); 156 157#ifndef MNT_DETACH 158#define MNT_DETACH 2 159#endif 160#endif // Old glibc 161 162#endif // glibc in general 163 164#if !defined(__GLIBC__) 165// POSIX basename. 166#include <libgen.h> 167#endif 168 169// Work out how to do endianness 170 171#ifndef __APPLE__ 172#include <byteswap.h> 173#include <endian.h> 174 175#if __BYTE_ORDER == __BIG_ENDIAN 176#define IS_BIG_ENDIAN 1 177#else 178#define IS_BIG_ENDIAN 0 179#endif 180 181int clearenv(void); 182#else 183 184#ifdef __BIG_ENDIAN__ 185#define IS_BIG_ENDIAN 1 186#else 187#define IS_BIG_ENDIAN 0 188#endif 189 190#endif 191 192#if IS_BIG_ENDIAN 193#define IS_LITTLE_ENDIAN 0 194#define SWAP_BE16(x) (x) 195#define SWAP_BE32(x) (x) 196#define SWAP_BE64(x) (x) 197#define SWAP_LE16(x) bswap_16(x) 198#define SWAP_LE32(x) bswap_32(x) 199#define SWAP_LE64(x) bswap_64(x) 200#else 201#define IS_LITTLE_ENDIAN 1 202#define SWAP_BE16(x) bswap_16(x) 203#define SWAP_BE32(x) bswap_32(x) 204#define SWAP_BE64(x) bswap_64(x) 205#define SWAP_LE16(x) (x) 206#define SWAP_LE32(x) (x) 207#define SWAP_LE64(x) (x) 208#endif 209 210#if defined(__APPLE__) \ 211 || (defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 10) 212ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 213ssize_t getline(char **lineptr, size_t *n, FILE *stream); 214#endif 215 216// Linux headers not listed by POSIX or LSB 217#include <sys/mount.h> 218#include <sys/swap.h> 219 220// Android is missing some headers and functions 221// "generated/config.h" is included first 222#if CFG_TOYBOX_SHADOW 223#include <shadow.h> 224#endif 225#if CFG_TOYBOX_UTMPX 226#include <utmpx.h> 227#else 228struct utmpx {int ut_type;}; 229#define USER_PROCESS 0 230static inline struct utmpx *getutxent(void) {return 0;} 231static inline void setutxent(void) {;} 232static inline void endutxent(void) {;} 233#endif 234 235// Some systems don't define O_NOFOLLOW, and it varies by architecture, so... 236#include <fcntl.h> 237#ifndef O_NOFOLLOW 238#define O_NOFOLLOW 0 239#endif 240 241#ifndef O_NOATIME 242#define O_NOATIME 01000000 243#endif 244 245#ifndef O_CLOEXEC 246#define O_CLOEXEC 02000000 247#endif 248 249#ifndef O_PATH 250#define O_PATH 010000000 251#endif 252 253// Glibc won't give you linux-kernel constants unless you say "no, a BUD lite" 254// even though linux has nothing to do with the FSF and never has. 255#ifndef F_SETPIPE_SZ 256#define F_SETPIPE_SZ 1031 257#endif 258 259#ifndef F_GETPIPE_SZ 260#define F_GETPIPE_SZ 1032 261#endif 262 263#if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_LONG__) \ 264 && __SIZEOF_DOUBLE__ <= __SIZEOF_LONG__ 265typedef double FLOAT; 266#else 267typedef float FLOAT; 268#endif 269 270#ifndef __uClinux__ 271pid_t xfork(void); 272#endif 273 274//#define strncpy(...) @@strncpyisbadmmkay@@ 275//#define strncat(...) @@strncatisbadmmkay@@ 276 277#ifdef __ANDROID__ 278#include <cutils/sched_policy.h> 279#else 280static inline int get_sched_policy(int tid, void *policy) {return 0;} 281static inline char *get_sched_policy_name(int policy) {return "unknown";} 282#endif 283