at v2.6.34-rc2 409 lines 9.5 kB view raw
1#ifndef GIT_COMPAT_UTIL_H 2#define GIT_COMPAT_UTIL_H 3 4#define _FILE_OFFSET_BITS 64 5 6#ifndef FLEX_ARRAY 7/* 8 * See if our compiler is known to support flexible array members. 9 */ 10#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 11# define FLEX_ARRAY /* empty */ 12#elif defined(__GNUC__) 13# if (__GNUC__ >= 3) 14# define FLEX_ARRAY /* empty */ 15# else 16# define FLEX_ARRAY 0 /* older GNU extension */ 17# endif 18#endif 19 20/* 21 * Otherwise, default to safer but a bit wasteful traditional style 22 */ 23#ifndef FLEX_ARRAY 24# define FLEX_ARRAY 1 25#endif 26#endif 27 28#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 29 30#ifdef __GNUC__ 31#define TYPEOF(x) (__typeof__(x)) 32#else 33#define TYPEOF(x) 34#endif 35 36#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits)))) 37#define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */ 38 39/* Approximation of the length of the decimal representation of this type. */ 40#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) 41 42#define _ALL_SOURCE 1 43#define _GNU_SOURCE 1 44#define _BSD_SOURCE 1 45 46#include <unistd.h> 47#include <stdio.h> 48#include <sys/stat.h> 49#include <sys/statfs.h> 50#include <fcntl.h> 51#include <stddef.h> 52#include <stdlib.h> 53#include <stdarg.h> 54#include <string.h> 55#include <errno.h> 56#include <limits.h> 57#include <sys/param.h> 58#include <sys/types.h> 59#include <dirent.h> 60#include <sys/time.h> 61#include <time.h> 62#include <signal.h> 63#include <fnmatch.h> 64#include <assert.h> 65#include <regex.h> 66#include <utime.h> 67#include <sys/wait.h> 68#include <sys/poll.h> 69#include <sys/socket.h> 70#include <sys/ioctl.h> 71#ifndef NO_SYS_SELECT_H 72#include <sys/select.h> 73#endif 74#include <netinet/in.h> 75#include <netinet/tcp.h> 76#include <arpa/inet.h> 77#include <netdb.h> 78#include <pwd.h> 79#include <inttypes.h> 80#include "../../../include/linux/magic.h" 81 82 83#ifndef NO_ICONV 84#include <iconv.h> 85#endif 86 87extern const char *graph_line; 88extern const char *graph_dotted_line; 89 90/* On most systems <limits.h> would have given us this, but 91 * not on some systems (e.g. GNU/Hurd). 92 */ 93#ifndef PATH_MAX 94#define PATH_MAX 4096 95#endif 96 97#ifndef PRIuMAX 98#define PRIuMAX "llu" 99#endif 100 101#ifndef PRIu32 102#define PRIu32 "u" 103#endif 104 105#ifndef PRIx32 106#define PRIx32 "x" 107#endif 108 109#ifndef PATH_SEP 110#define PATH_SEP ':' 111#endif 112 113#ifndef STRIP_EXTENSION 114#define STRIP_EXTENSION "" 115#endif 116 117#ifndef has_dos_drive_prefix 118#define has_dos_drive_prefix(path) 0 119#endif 120 121#ifndef is_dir_sep 122#define is_dir_sep(c) ((c) == '/') 123#endif 124 125#ifdef __GNUC__ 126#define NORETURN __attribute__((__noreturn__)) 127#else 128#define NORETURN 129#ifndef __attribute__ 130#define __attribute__(x) 131#endif 132#endif 133 134/* General helper functions */ 135extern void usage(const char *err) NORETURN; 136extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 137extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 138extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 139 140#include "../../../include/linux/stringify.h" 141 142#define DIE_IF(cnd) \ 143 do { if (cnd) \ 144 die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \ 145 __stringify(cnd) "\n"); \ 146 } while (0) 147 148 149extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 150 151extern int prefixcmp(const char *str, const char *prefix); 152extern time_t tm_to_time_t(const struct tm *tm); 153 154static inline const char *skip_prefix(const char *str, const char *prefix) 155{ 156 size_t len = strlen(prefix); 157 return strncmp(str, prefix, len) ? NULL : str + len; 158} 159 160#if defined(NO_MMAP) || defined(USE_WIN32_MMAP) 161 162#ifndef PROT_READ 163#define PROT_READ 1 164#define PROT_WRITE 2 165#define MAP_PRIVATE 1 166#define MAP_FAILED ((void*)-1) 167#endif 168 169#define mmap git_mmap 170#define munmap git_munmap 171extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); 172extern int git_munmap(void *start, size_t length); 173 174#else /* NO_MMAP || USE_WIN32_MMAP */ 175 176#include <sys/mman.h> 177 178#endif /* NO_MMAP || USE_WIN32_MMAP */ 179 180#ifdef NO_MMAP 181 182/* This value must be multiple of (pagesize * 2) */ 183#define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024) 184 185#else /* NO_MMAP */ 186 187/* This value must be multiple of (pagesize * 2) */ 188#define DEFAULT_PACKED_GIT_WINDOW_SIZE \ 189 (sizeof(void*) >= 8 \ 190 ? 1 * 1024 * 1024 * 1024 \ 191 : 32 * 1024 * 1024) 192 193#endif /* NO_MMAP */ 194 195#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT 196#define on_disk_bytes(st) ((st).st_size) 197#else 198#define on_disk_bytes(st) ((st).st_blocks * 512) 199#endif 200 201#define DEFAULT_PACKED_GIT_LIMIT \ 202 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256)) 203 204#ifdef NO_PREAD 205#define pread git_pread 206extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset); 207#endif 208/* 209 * Forward decl that will remind us if its twin in cache.h changes. 210 * This function is used in compat/pread.c. But we can't include 211 * cache.h there. 212 */ 213extern ssize_t read_in_full(int fd, void *buf, size_t count); 214 215#ifdef NO_SETENV 216#define setenv gitsetenv 217extern int gitsetenv(const char *, const char *, int); 218#endif 219 220#ifdef NO_MKDTEMP 221#define mkdtemp gitmkdtemp 222extern char *gitmkdtemp(char *); 223#endif 224 225#ifdef NO_UNSETENV 226#define unsetenv gitunsetenv 227extern void gitunsetenv(const char *); 228#endif 229 230#ifdef NO_STRCASESTR 231#define strcasestr gitstrcasestr 232extern char *gitstrcasestr(const char *haystack, const char *needle); 233#endif 234 235#ifdef NO_STRLCPY 236#define strlcpy gitstrlcpy 237extern size_t gitstrlcpy(char *, const char *, size_t); 238#endif 239 240#ifdef NO_STRTOUMAX 241#define strtoumax gitstrtoumax 242extern uintmax_t gitstrtoumax(const char *, char **, int); 243#endif 244 245#ifdef NO_HSTRERROR 246#define hstrerror githstrerror 247extern const char *githstrerror(int herror); 248#endif 249 250#ifdef NO_MEMMEM 251#define memmem gitmemmem 252void *gitmemmem(const void *haystack, size_t haystacklen, 253 const void *needle, size_t needlelen); 254#endif 255 256#ifdef FREAD_READS_DIRECTORIES 257#ifdef fopen 258#undef fopen 259#endif 260#define fopen(a,b) git_fopen(a,b) 261extern FILE *git_fopen(const char*, const char*); 262#endif 263 264#ifdef SNPRINTF_RETURNS_BOGUS 265#define snprintf git_snprintf 266extern int git_snprintf(char *str, size_t maxsize, 267 const char *format, ...); 268#define vsnprintf git_vsnprintf 269extern int git_vsnprintf(char *str, size_t maxsize, 270 const char *format, va_list ap); 271#endif 272 273#ifdef __GLIBC_PREREQ 274#if __GLIBC_PREREQ(2, 1) 275#define HAVE_STRCHRNUL 276#endif 277#endif 278 279#ifndef HAVE_STRCHRNUL 280#define strchrnul gitstrchrnul 281static inline char *gitstrchrnul(const char *s, int c) 282{ 283 while (*s && *s != c) 284 s++; 285 return (char *)s; 286} 287#endif 288 289/* 290 * Wrappers: 291 */ 292extern char *xstrdup(const char *str); 293extern void *xmalloc(size_t size) __attribute__((weak)); 294extern void *xmemdupz(const void *data, size_t len); 295extern char *xstrndup(const char *str, size_t len); 296extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); 297 298static inline void *zalloc(size_t size) 299{ 300 return calloc(1, size); 301} 302 303static inline size_t xsize_t(off_t len) 304{ 305 return (size_t)len; 306} 307 308static inline int has_extension(const char *filename, const char *ext) 309{ 310 size_t len = strlen(filename); 311 size_t extlen = strlen(ext); 312 return len > extlen && !memcmp(filename + len - extlen, ext, extlen); 313} 314 315/* Sane ctype - no locale, and works with signed chars */ 316#undef isascii 317#undef isspace 318#undef isdigit 319#undef isxdigit 320#undef isalpha 321#undef isprint 322#undef isalnum 323#undef tolower 324#undef toupper 325extern unsigned char sane_ctype[256]; 326#define GIT_SPACE 0x01 327#define GIT_DIGIT 0x02 328#define GIT_ALPHA 0x04 329#define GIT_GLOB_SPECIAL 0x08 330#define GIT_REGEX_SPECIAL 0x10 331#define GIT_PRINT_EXTRA 0x20 332#define GIT_PRINT 0x3E 333#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) 334#define isascii(x) (((x) & ~0x7f) == 0) 335#define isspace(x) sane_istest(x,GIT_SPACE) 336#define isdigit(x) sane_istest(x,GIT_DIGIT) 337#define isxdigit(x) \ 338 (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G') 339#define isalpha(x) sane_istest(x,GIT_ALPHA) 340#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) 341#define isprint(x) sane_istest(x,GIT_PRINT) 342#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL) 343#define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL) 344#define tolower(x) sane_case((unsigned char)(x), 0x20) 345#define toupper(x) sane_case((unsigned char)(x), 0) 346 347static inline int sane_case(int x, int high) 348{ 349 if (sane_istest(x, GIT_ALPHA)) 350 x = (x & ~0x20) | high; 351 return x; 352} 353 354static inline int strtoul_ui(char const *s, int base, unsigned int *result) 355{ 356 unsigned long ul; 357 char *p; 358 359 errno = 0; 360 ul = strtoul(s, &p, base); 361 if (errno || *p || p == s || (unsigned int) ul != ul) 362 return -1; 363 *result = ul; 364 return 0; 365} 366 367static inline int strtol_i(char const *s, int base, int *result) 368{ 369 long ul; 370 char *p; 371 372 errno = 0; 373 ul = strtol(s, &p, base); 374 if (errno || *p || p == s || (int) ul != ul) 375 return -1; 376 *result = ul; 377 return 0; 378} 379 380#ifdef INTERNAL_QSORT 381void git_qsort(void *base, size_t nmemb, size_t size, 382 int(*compar)(const void *, const void *)); 383#define qsort git_qsort 384#endif 385 386#ifndef DIR_HAS_BSD_GROUP_SEMANTICS 387# define FORCE_DIR_SET_GID S_ISGID 388#else 389# define FORCE_DIR_SET_GID 0 390#endif 391 392#ifdef NO_NSEC 393#undef USE_NSEC 394#define ST_CTIME_NSEC(st) 0 395#define ST_MTIME_NSEC(st) 0 396#else 397#ifdef USE_ST_TIMESPEC 398#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec)) 399#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec)) 400#else 401#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec)) 402#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec)) 403#endif 404#endif 405 406int mkdir_p(char *path, mode_t mode); 407int copyfile(const char *from, const char *to); 408 409#endif