summaryrefslogtreecommitdiffstats
path: root/src/lib/compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/compat.h')
-rw-r--r--src/lib/compat.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/lib/compat.h b/src/lib/compat.h
new file mode 100644
index 0000000..ce3127d
--- /dev/null
+++ b/src/lib/compat.h
@@ -0,0 +1,323 @@
+#ifndef COMPAT_H
+#define COMPAT_H
+
+/* _ILP32 and _LP64 are common but not universal, make sure that exactly one
+ of them is defined. */
+#if !defined(_ILP32) && \
+ (SIZEOF_INT == 4) && (SIZEOF_LONG == 4) && (SIZEOF_VOID_P == 4)
+# define _ILP32
+#endif
+#if !defined(_LP64) && \
+ (SIZEOF_INT == 4) && (SIZEOF_LONG == 8) && (SIZEOF_VOID_P == 8)
+# define _LP64
+#endif
+#if defined(_ILP32) && defined(_LP64)
+# error "Cannot have both _ILP32 and _LP64 defined"
+#elif !defined(_ILP32) && !defined(_LP64)
+# error "Must have one of _ILP32 and _LP64 defined"
+#endif
+
+/* well, this is obviously wrong since it assumes it's 64bit, but older
+ GCCs don't define it and we really want it. */
+#ifndef LLONG_MAX
+# define LLONG_MAX 9223372036854775807LL
+#endif
+
+#if ((__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) && \
+ defined(HAVE_TYPEOF)) && !defined(__cplusplus)
+# define HAVE_TYPE_CHECKS
+#endif
+
+/* We really want NULL to be a pointer, since we have various type-checks
+ that may result in compiler warnings/errors if it's not. Do this only when
+ type checking is used - it's not otherwise needed and causes compiling
+ problems with e.g. Sun C compiler. */
+#ifdef HAVE_TYPE_CHECKS
+# undef NULL
+# define NULL ((void *)0)
+#endif
+
+#ifndef __has_extension
+ #define __has_extension(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#if (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) || \
+ (defined(__clang__) && (__has_extension(attribute_deprecated_with_message)))
+# define HAVE_ATTR_DEPRECATED
+int rand(void) __attribute__((deprecated("Do not use rand, use i_rand")));
+int rand_r(unsigned int*) __attribute__((deprecated("Do not use rand_r, use i_rand")));
+#endif
+
+#ifndef __cplusplus
+#ifdef HAVE__BOOL
+typedef _Bool bool;
+#else
+typedef int bool;
+#endif
+#endif
+
+#if defined (HAVE_UOFF_T)
+/* native support */
+#elif defined (UOFF_T_INT)
+typedef unsigned int uoff_t;
+#elif defined (UOFF_T_LONG)
+typedef unsigned long uoff_t;
+#elif defined (UOFF_T_LONG_LONG)
+typedef unsigned long long uoff_t;
+#else
+# error uoff_t size not set
+#endif
+
+#ifndef HAVE_UINTMAX_T
+# if SIZEOF_LONG_LONG > 0
+typedef unsigned long long uintmax_t;
+# else
+typedef unsigned long uintmax_t;
+# endif
+#endif
+
+#ifndef HAVE_UINT_FAST32_T
+# if SIZEOF_INT >= 4
+typedef unsigned int uint_fast32_t;
+# else
+typedef unsigned long uint_fast32_t;
+# endif
+#endif
+
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+/* WORDS_BIGENDIAN needs to be undefined if not enabled */
+#if defined(WORDS_BIGENDIAN) && WORDS_BIGENDIAN == 0
+# undef WORDS_BIGENDIAN
+#endif
+
+#ifdef HAVE_SYS_SYSMACROS_H
+# include <sys/sysmacros.h>
+# ifdef HAVE_SYS_MKDEV_H
+# include <sys/mkdev.h> /* UnixWare */
+# endif
+# define CMP_DEV_T(a, b) (major(a) == major(b) && minor(a) == minor(b))
+#elif !defined (DEV_T_STRUCT)
+# define CMP_DEV_T(a, b) ((a) == (b))
+#else
+# error I do not know how to compare dev_t
+#endif
+
+#ifdef HAVE_STAT_XTIM
+# define HAVE_ST_NSECS
+# define ST_ATIME_NSEC(st) ((unsigned long)(st).st_atim.tv_nsec)
+# define ST_MTIME_NSEC(st) ((unsigned long)(st).st_mtim.tv_nsec)
+# define ST_CTIME_NSEC(st) ((unsigned long)(st).st_ctim.tv_nsec)
+#elif defined (HAVE_STAT_XTIMESPEC)
+# define HAVE_ST_NSECS
+# define ST_ATIME_NSEC(st) ((unsigned long)(st).st_atimespec.tv_nsec)
+# define ST_MTIME_NSEC(st) ((unsigned long)(st).st_mtimespec.tv_nsec)
+# define ST_CTIME_NSEC(st) ((unsigned long)(st).st_ctimespec.tv_nsec)
+#else
+# define ST_ATIME_NSEC(st) 0UL
+# define ST_MTIME_NSEC(st) 0UL
+# define ST_CTIME_NSEC(st) 0UL
+#endif
+
+#ifdef HAVE_ST_NSECS
+/* TRUE if a nanosecond timestamp from struct stat matches another nanosecond.
+ If nanoseconds aren't supported in struct stat, returns always TRUE (useful
+ with NFS if some hosts support nanoseconds and others don't). */
+# define ST_NTIMES_EQUAL(ns1, ns2) ((ns1) == (ns2))
+#else
+# define ST_NTIMES_EQUAL(ns1, ns2) TRUE
+#endif
+
+#define CMP_ST_MTIME(st1, st2) \
+ ((st1)->st_mtime == (st2)->st_mtime && \
+ ST_NTIMES_EQUAL(ST_MTIME_NSEC(*(st1)), ST_MTIME_NSEC(*(st2))))
+#define CMP_ST_CTIME(st1, st2) \
+ ((st1)->st_ctime == (st2)->st_ctime && \
+ ST_NTIMES_EQUAL(ST_CTIME_NSEC(*(st1)), ST_CTIME_NSEC(*(st2))))
+
+/* strcasecmp(), strncasecmp() */
+#ifndef HAVE_STRCASECMP
+# ifdef HAVE_STRICMP
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+# else
+# define strcasecmp i_my_strcasecmp
+# define strncasecmp i_my_strncasecmp
+int i_my_strcasecmp(const char *s1, const char *s2);
+int i_my_strncasecmp(const char *s1, const char *s2, size_t max_chars);
+# endif
+#endif
+
+#ifndef HAVE_INET_ATON
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# define inet_aton i_my_inet_aton
+int i_my_inet_aton(const char *cp, struct in_addr *inp);
+#endif
+
+#ifndef HAVE_VSYSLOG
+# define vsyslog i_my_vsyslog
+void i_my_vsyslog(int priority, const char *format, va_list args);
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+# define getpagesize i_my_getpagesize
+int i_my_getpagesize(void);
+#endif
+
+#ifndef HAVE_FDATASYNC
+# define fdatasync fsync
+#endif
+
+struct const_iovec {
+ const void *iov_base;
+ size_t iov_len;
+};
+
+#ifndef HAVE_STRUCT_IOVEC
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+
+/* IOV_MAX should be in limits.h nowadays. Linux still (2005) requires
+ defining _XOPEN_SOURCE to get that value. UIO_MAXIOV works with it though,
+ so use it instead. 16 is the lowest acceptable value for all OSes. */
+#ifndef IOV_MAX
+# include <sys/uio.h>
+# ifdef UIO_MAXIOV
+# define IOV_MAX UIO_MAXIOV
+# else
+# define IOV_MAX 16
+# endif
+#endif
+
+#ifndef HAVE_WRITEV
+# define writev i_my_writev
+struct iovec;
+ssize_t i_my_writev(int fd, const struct iovec *iov, int iov_len);
+#endif
+
+#if !defined(HAVE_PREAD) || defined(PREAD_WRAPPERS) || defined(PREAD_BROKEN)
+# ifndef IN_COMPAT_C
+# define pread i_my_pread
+# define pwrite i_my_pwrite
+# endif
+ssize_t i_my_pread(int fd, void *buf, size_t count, off_t offset);
+ssize_t i_my_pwrite(int fd, const void *buf, size_t count, off_t offset);
+#endif
+
+#ifndef HAVE_SETEUID
+# define seteuid i_my_seteuid
+int i_my_seteuid(uid_t euid);
+#endif
+
+#ifndef HAVE_SETEGID
+# define setegid i_my_setegid
+int i_my_setegid(gid_t egid);
+#endif
+
+#ifndef HAVE_LIBGEN_H
+# define basename i_my_basename
+char *i_my_basename(char *path);
+#endif
+
+#ifdef HAVE_OLD_VSNPRINTF
+# include <stdio.h>
+# define vsnprintf i_my_vsnprintf
+int i_my_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+#endif
+
+#ifndef HAVE_CLOCK_GETTIME
+# include <time.h>
+# undef CLOCK_REALTIME
+# define CLOCK_REALTIME 1
+# define clock_gettime i_my_clock_gettime
+int i_my_clock_gettime(int clk_id, struct timespec *tp);
+#endif
+
+/* ctype.h isn't safe with signed chars,
+ use our own instead if really needed */
+#define i_toupper(x) ((char) toupper((int) (unsigned char) (x)))
+#define i_tolower(x) ((char) tolower((int) (unsigned char) (x)))
+#define i_isalnum(x) (isalnum((int) (unsigned char) (x)) != 0)
+#define i_isalpha(x) (isalpha((int) (unsigned char) (x)) != 0)
+#define i_isascii(x) (isascii((int) (unsigned char) (x)) != 0)
+#define i_isblank(x) (isblank((int) (unsigned char) (x)) != 0)
+#define i_iscntrl(x) (iscntrl((int) (unsigned char) (x)) != 0)
+#define i_isdigit(x) (isdigit((int) (unsigned char) (x)) != 0)
+#define i_isgraph(x) (isgraph((int) (unsigned char) (x)) != 0)
+#define i_islower(x) (islower((int) (unsigned char) (x)) != 0)
+#define i_isprint(x) (isprint((int) (unsigned char) (x)) != 0)
+#define i_ispunct(x) (ispunct((int) (unsigned char) (x)) != 0)
+#define i_isspace(x) (isspace((int) (unsigned char) (x)) != 0)
+#define i_isupper(x) (isupper((int) (unsigned char) (x)) != 0)
+#define i_isxdigit(x) (isxdigit((int) (unsigned char) (x)) != 0)
+
+#ifndef EOVERFLOW
+# define EOVERFLOW ERANGE
+#endif
+
+#ifdef EDQUOT
+# define ENOSPACE(errno) ((errno) == ENOSPC || (errno) == EDQUOT)
+# define ENOQUOTA(errno) ((errno) == EDQUOT)
+#else
+/* probably all modern OSes have EDQUOT, but just in case one doesn't assume
+ that ENOSPC is the same as "over quota". */
+# define ENOSPACE(errno) ((errno) == ENOSPC)
+# define ENOQUOTA(errno) ((errno) == ENOSPC)
+#endif
+
+/* EPERM is returned sometimes if device doesn't support such modification */
+#ifdef EROFS
+# define ENOACCESS(errno) \
+ ((errno) == EACCES || (errno) == EROFS || (errno) == EPERM)
+#else
+# define ENOACCESS(errno) ((errno) == EACCES || (errno) == EPERM)
+#endif
+
+#define ENOTFOUND(errno) \
+ ((errno) == ENOENT || (errno) == ENOTDIR || \
+ (errno) == ELOOP || (errno) == ENAMETOOLONG)
+
+#define ECANTLINK(errno) \
+ ((errno) == EXDEV || (errno) == EMLINK || (errno) == EPERM)
+
+/* Returns TRUE if unlink() failed because it attempted to delete a directory */
+#define UNLINK_EISDIR(errno) \
+ ((errno) == EPERM || /* POSIX */ \
+ (errno) == EISDIR) /* Linux */
+
+/* EBUSY is given by some NFS implementations */
+#define EDESTDIREXISTS(errno) \
+ ((errno) == EEXIST || (errno) == ENOTEMPTY || (errno) == EBUSY)
+
+/* fstat() returns ENOENT instead of ESTALE with some Linux versions */
+#define ESTALE_FSTAT(errno) \
+ ((errno) == ESTALE || (errno) == ENOENT)
+
+#if !defined(_POSIX_SYNCHRONIZED_IO) && \
+ defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
+ (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060)
+/* OS X Snow Leopard has fdatasync(), but no prototype for it. */
+int fdatasync(int);
+#endif
+
+/* Try to keep IO operations at least this size */
+#ifndef IO_BLOCK_SIZE
+# define IO_BLOCK_SIZE 8192
+#endif
+/* Default size for data blocks transferred over the network */
+#ifndef NET_BLOCK_SIZE
+# define NET_BLOCK_SIZE (128*1024)
+#endif
+
+#if !defined(PIPE_BUF) && defined(_POSIX_PIPE_BUF)
+# define PIPE_BUF (8 * _POSIX_PIPE_BUF) /* for HURD */
+#endif
+
+#endif