portability.h revision 44b9d043ccbe9a6e4bd2dbabe64a0854dbe5a7ac
1// Workarounds for horrible build environment idiosyncrasies. 2// Instead of polluting the code with strange #ifdefs to work around bugs 3// in specific compiler, library, or OS versions, localize all that here 4// and in portability.c 5 6// The tendency of gcc to produce stupid warnings continues with 7// warn_unused_result, which warns about things like ignoring the return code 8// of nice(2) (which is completely useless since -1 is a legitimate return 9// value on success and even the man page tells you to use errno instead). 10 11// This makes it stop. 12 13#undef _FORTIFY_SOURCE 14 15// Always use long file support. 16#define _FILE_OFFSET_BITS 64 17 18// This isn't in the spec, but it's how we determine what we're using. 19 20#include <features.h> 21 22// Various constants old build environments might not have even if kernel does 23 24#ifndef O_DIRECTORY 25#define O_DIRECTORY 0200000 26#endif 27 28#ifndef O_NOFOLLOW 29#define O_NOFOLLOW 0400000 30#endif 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#if defined(__GLIBC__) 45// "Function prototypes shall be provided." but aren't. 46// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html 47char *crypt(const char *key, const char *salt); 48 49// An SUSv4 function that glibc refuses to #define without crazy #defines, 50// see http://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html 51#include <time.h> 52char *strptime(const char *buf, const char *format, struct tm *tm); 53 54// uClibc pretends to be glibc and copied a lot of its bugs, but has a few more 55#if defined(__UCLIBC__) 56#include <unistd.h> 57#include <stdio.h> 58ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 59 60// When building under obsolete glibc, hold its hand a bit. 61#elif __GLIBC__ == 2 && __GLIBC_MINOR__ < 10 62#define fstatat fstatat64 63int fstatat64(int dirfd, const char *pathname, void *buf, int flags); 64int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz); 65char *stpcpy(char *dest, const char *src); 66#include <sys/stat.h> 67int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); 68int openat(int dirfd, const char *pathname, int flags, ...); 69#include <dirent.h> 70DIR *fdopendir(int fd); 71#include <unistd.h> 72int fchownat(int dirfd, const char *pathname, 73 uid_t owner, gid_t group, int flags); 74int isblank(int c); 75int unlinkat(int dirfd, const char *pathname, int flags); 76#include <stdio.h> 77ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 78 79// Straight from posix-2008, things old glibc didn't define 80 81int faccessat(int fd, const char *path, int amode, int flag); 82int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); 83int mkdirat(int fd, const char *path, mode_t mode); 84int symlinkat(const char *path1, int fd, const char *path2); 85int mknodat(int fd, const char *path, mode_t mode, dev_t dev); 86#include <sys/time.h> 87int futimens(int fd, const struct timespec times[2]); 88int utimensat(int fd, const char *path, const struct timespec times[2], int flag); 89#endif 90 91#endif 92 93// Test for gcc 94 95#ifdef __GNUC__ 96#define noreturn __attribute__((noreturn)) 97#else 98#define noreturn 99#endif 100 101#ifndef __APPLE__ 102#include <byteswap.h> 103#include <endian.h> 104 105#if __BYTE_ORDER == __BIG_ENDIAN 106#define IS_BIG_ENDIAN 1 107#else 108#define IS_BIG_ENDIAN 0 109#endif 110 111int clearenv(void); 112#else 113 114#ifdef __BIG_ENDIAN__ 115#define IS_BIG_ENDIAN 1 116#else 117#define IS_BIG_ENDIAN 0 118#endif 119 120#endif 121 122#if IS_BIG_ENDIAN 123#define IS_LITTLE_ENDIAN 0 124#define SWAP_BE16(x) (x) 125#define SWAP_BE32(x) (x) 126#define SWAP_BE64(x) (x) 127#define SWAP_LE16(x) bswap_16(x) 128#define SWAP_LE32(x) bswap_32(x) 129#define SWAP_LE64(x) bswap_64(x) 130#else 131#define IS_LITTLE_ENDIAN 1 132#define SWAP_BE16(x) bswap_16(x) 133#define SWAP_BE32(x) bswap_32(x) 134#define SWAP_BE64(x) bswap_64(x) 135#define SWAP_LE16(x) (x) 136#define SWAP_LE32(x) (x) 137#define SWAP_LE64(x) (x) 138#endif 139 140#if defined(__APPLE__) || defined(__ANDROID__) 141ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 142ssize_t getline(char **lineptr, size_t *n, FILE *stream); 143#endif 144