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