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 87 extern const char *graph_line; 88 extern 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 */ 135 extern void usage(const char *err) NORETURN; 136 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 137 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 138 extern 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 149 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 150 151 extern int prefixcmp(const char *str, const char *prefix); 152 extern time_t tm_to_time_t(const struct tm *tm); 153 154 static 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 171 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); 172 extern 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 206 extern 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 */ 213 extern ssize_t read_in_full(int fd, void *buf, size_t count); 214 215 #ifdef NO_SETENV 216 #define setenv gitsetenv 217 extern int gitsetenv(const char *, const char *, int); 218 #endif 219 220 #ifdef NO_MKDTEMP 221 #define mkdtemp gitmkdtemp 222 extern char *gitmkdtemp(char *); 223 #endif 224 225 #ifdef NO_UNSETENV 226 #define unsetenv gitunsetenv 227 extern void gitunsetenv(const char *); 228 #endif 229 230 #ifdef NO_STRCASESTR 231 #define strcasestr gitstrcasestr 232 extern char *gitstrcasestr(const char *haystack, const char *needle); 233 #endif 234 235 #ifdef NO_STRLCPY 236 #define strlcpy gitstrlcpy 237 extern size_t gitstrlcpy(char *, const char *, size_t); 238 #endif 239 240 #ifdef NO_STRTOUMAX 241 #define strtoumax gitstrtoumax 242 extern uintmax_t gitstrtoumax(const char *, char **, int); 243 #endif 244 245 #ifdef NO_HSTRERROR 246 #define hstrerror githstrerror 247 extern const char *githstrerror(int herror); 248 #endif 249 250 #ifdef NO_MEMMEM 251 #define memmem gitmemmem 252 void *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) 261 extern FILE *git_fopen(const char*, const char*); 262 #endif 263 264 #ifdef SNPRINTF_RETURNS_BOGUS 265 #define snprintf git_snprintf 266 extern int git_snprintf(char *str, size_t maxsize, 267 const char *format, ...); 268 #define vsnprintf git_vsnprintf 269 extern 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 281 static 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 */ 292 extern char *xstrdup(const char *str); 293 extern void *xmalloc(size_t size) __attribute__((weak)); 294 extern void *xmemdupz(const void *data, size_t len); 295 extern char *xstrndup(const char *str, size_t len); 296 extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); 297 298 static inline void *zalloc(size_t size) 299 { 300 return calloc(1, size); 301 } 302 303 static inline size_t xsize_t(off_t len) 304 { 305 return (size_t)len; 306 } 307 308 static 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 325 extern 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 347 static 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 354 static 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 367 static 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 381 void 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 406 #endif 407