diff options
Diffstat (limited to 'git-compat-util.h')
-rw-r--r-- | git-compat-util.h | 136 |
1 files changed, 125 insertions, 11 deletions
diff --git a/git-compat-util.h b/git-compat-util.h index 9f941e42b1..40498b33c9 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -28,6 +28,24 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define bitsizeof(x) (CHAR_BIT * sizeof(x)) +#define maximum_signed_value_of_type(a) \ + (INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a))) + +#define maximum_unsigned_value_of_type(a) \ + (UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a))) + +/* + * Signed integer overflow is undefined in C, so here's a helper macro + * to detect if the sum of two integers will overflow. + * + * Requires: a >= 0, typeof(a) equals typeof(b) + */ +#define signed_add_overflows(a, b) \ + ((b) > maximum_signed_value_of_type(a) - (a)) + +#define unsigned_add_overflows(a, b) \ + ((b) > maximum_unsigned_value_of_type(a) - (a)) + #ifdef __GNUC__ #define TYPEOF(x) (__typeof__(x)) #else @@ -55,18 +73,23 @@ # else # define _XOPEN_SOURCE 500 # endif -#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX) && !defined(sgi) +#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \ + !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */ -#ifndef __sun__ #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */ #endif -#endif #define _ALL_SOURCE 1 #define _GNU_SOURCE 1 #define _BSD_SOURCE 1 #define _NETBSD_SOURCE 1 #define _SGI_SOURCE 1 +#ifdef WIN32 /* Both MinGW and MSVC */ +#define WIN32_LEAN_AND_MEAN /* stops windows.h including winsock.h */ +#include <winsock2.h> +#include <windows.h> +#endif + #include <unistd.h> #include <stdio.h> #include <sys/stat.h> @@ -87,11 +110,18 @@ #include <assert.h> #include <regex.h> #include <utime.h> +#include <syslog.h> +#ifndef NO_SYS_POLL_H +#include <sys/poll.h> +#else +#include <poll.h> +#endif #ifndef __MINGW32__ #include <sys/wait.h> -#include <sys/poll.h> +#include <sys/resource.h> #include <sys/socket.h> #include <sys/ioctl.h> +#include <termios.h> #ifndef NO_SYS_SELECT_H #include <sys/select.h> #endif @@ -100,7 +130,11 @@ #include <arpa/inet.h> #include <netdb.h> #include <pwd.h> +#ifndef NO_INTTYPES_H #include <inttypes.h> +#else +#include <stdint.h> +#endif #if defined(__CYGWIN__) #undef _XOPEN_SOURCE #include <grp.h> @@ -115,6 +149,9 @@ /* pull in Windows compatibility stuff */ #include "compat/mingw.h" #endif /* __MINGW32__ */ +#ifdef _MSC_VER +#include "compat/msvc.h" +#endif #ifndef NO_LIBGEN_H #include <libgen.h> @@ -151,10 +188,21 @@ extern char *gitbasename(char *); #define PRIx32 "x" #endif +#ifndef PRIo32 +#define PRIo32 "o" +#endif + #ifndef PATH_SEP #define PATH_SEP ':' #endif +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +#ifndef _PATH_DEFPATH +#define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin" +#endif + #ifndef STRIP_EXTENSION #define STRIP_EXTENSION "" #endif @@ -167,26 +215,38 @@ extern char *gitbasename(char *); #define is_dir_sep(c) ((c) == '/') #endif -#ifdef __GNUC__ +#if __HP_cc >= 61000 +#define NORETURN __attribute__((noreturn)) +#define NORETURN_PTR +#elif defined(__GNUC__) #define NORETURN __attribute__((__noreturn__)) +#define NORETURN_PTR __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define NORETURN __declspec(noreturn) +#define NORETURN_PTR #else #define NORETURN +#define NORETURN_PTR #ifndef __attribute__ #define __attribute__(x) #endif #endif +#include "compat/bswap.h" + /* General helper functions */ -extern void usage(const char *err) NORETURN; -extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); -extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); +extern void vreportf(const char *prefix, const char *err, va_list params); +extern NORETURN void usage(const char *err); +extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2))); +extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2))); +extern NORETURN void die_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); -extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); +extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); extern int prefixcmp(const char *str, const char *prefix); -extern time_t tm_to_time_t(const struct tm *tm); +extern int suffixcmp(const char *str, const char *suffix); static inline const char *skip_prefix(const char *str, const char *prefix) { @@ -200,7 +260,6 @@ static inline const char *skip_prefix(const char *str, const char *prefix) #define PROT_READ 1 #define PROT_WRITE 2 #define MAP_PRIVATE 1 -#define MAP_FAILED ((void*)-1) #endif #define mmap git_mmap @@ -229,6 +288,10 @@ extern int git_munmap(void *start, size_t length); #endif /* NO_MMAP */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + #ifdef NO_ST_BLOCKS_IN_STRUCT_STAT #define on_disk_bytes(st) ((st).st_size) #else @@ -284,6 +347,11 @@ extern size_t gitstrlcpy(char *, const char *, size_t); extern uintmax_t gitstrtoumax(const char *, char **, int); #endif +#ifdef NO_STRTOK_R +#define strtok_r gitstrtok_r +extern char *gitstrtok_r(char *s, const char *delim, char **save_ptr); +#endif + #ifdef NO_HSTRERROR #define hstrerror githstrerror extern const char *githstrerror(int herror); @@ -315,6 +383,7 @@ extern int git_vsnprintf(char *str, size_t maxsize, #ifdef __GLIBC_PREREQ #if __GLIBC_PREREQ(2, 1) #define HAVE_STRCHRNUL +#define HAVE_MEMPCPY #endif #endif @@ -328,10 +397,30 @@ static inline char *gitstrchrnul(const char *s, int c) } #endif +#ifndef HAVE_MEMPCPY +#define mempcpy gitmempcpy +static inline void *gitmempcpy(void *dest, const void *src, size_t n) +{ + return (char *)memcpy(dest, src, n) + n; +} +#endif + +#ifdef NO_INET_PTON +int inet_pton(int af, const char *src, void *dst); +#endif + +#ifdef NO_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + extern void release_pack_memory(size_t, int); +typedef void (*try_to_free_t)(size_t); +extern try_to_free_t set_try_to_free_routine(try_to_free_t); + extern char *xstrdup(const char *str); extern void *xmalloc(size_t size); +extern void *xmallocz(size_t size); extern void *xmemdupz(const void *data, size_t len); extern char *xstrndup(const char *str, size_t len); extern void *xrealloc(void *ptr, size_t size); @@ -342,11 +431,14 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len); extern int xdup(int fd); extern FILE *xfdopen(int fd, const char *mode); extern int xmkstemp(char *template); +extern int xmkstemp_mode(char *template, int mode); extern int odb_mkstemp(char *template, size_t limit, const char *pattern); extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1); static inline size_t xsize_t(off_t len) { + if (len > (size_t) len) + die("Cannot handle files this big"); return (size_t)len; } @@ -447,10 +539,32 @@ void git_qsort(void *base, size_t nmemb, size_t size, #define fstat_is_reliable() 1 #endif +#ifndef va_copy +/* + * Since an obvious implementation of va_list would be to make it a + * pointer into the stack frame, a simple assignment will work on + * many systems. But let's try to be more portable. + */ +#ifdef __va_copy +#define va_copy(dst, src) __va_copy(dst, src) +#else +#define va_copy(dst, src) ((dst) = (src)) +#endif +#endif + /* * Preserves errno, prints a message, but gives no warning for ENOENT. * Always returns the return value of unlink(2). */ int unlink_or_warn(const char *path); +/* + * Likewise for rmdir(2). + */ +int rmdir_or_warn(const char *path); +/* + * Calls the correct function out of {unlink,rmdir}_or_warn based on + * the supplied file mode. + */ +int remove_or_warn(unsigned int mode, const char *path); #endif |