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