Merge branch 'master' of git://repo.or.cz/alt-git
[git/dscho.git] / git-compat-util.h
blobbde06ca0d78de8c76b25a9b6048a5632f79610fd
1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
4 #define _FILE_OFFSET_BITS 64
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
21 * Otherwise, default to safer but a bit wasteful traditional style
23 #ifndef FLEX_ARRAY
24 # define FLEX_ARRAY 1
25 #endif
26 #endif
28 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
30 #ifdef __GNUC__
31 #define TYPEOF(x) (__typeof__(x))
32 #else
33 #define TYPEOF(x)
34 #endif
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 */
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)
42 #if !defined(__APPLE__) && !defined(__FreeBSD__)
43 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
44 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
45 #endif
46 #define _ALL_SOURCE 1
47 #define _GNU_SOURCE 1
48 #define _BSD_SOURCE 1
50 #include <unistd.h>
51 #include <stdio.h>
52 #include <sys/stat.h>
53 #include <fcntl.h>
54 #include <stddef.h>
55 #include <stdlib.h>
56 #include <stdarg.h>
57 #include <string.h>
58 #include <errno.h>
59 #include <limits.h>
60 #include <sys/param.h>
61 #include <sys/types.h>
62 #include <dirent.h>
63 #include <sys/time.h>
64 #include <time.h>
65 #include <signal.h>
66 #include <fnmatch.h>
67 #include <assert.h>
68 #include <regex.h>
69 #ifndef __MINGW32__
70 #include <sys/wait.h>
71 #include <sys/poll.h>
72 #include <sys/socket.h>
73 #include <sys/ioctl.h>
74 #ifndef NO_SYS_SELECT_H
75 #include <sys/select.h>
76 #endif
77 #include <netinet/in.h>
78 #include <netinet/tcp.h>
79 #include <arpa/inet.h>
80 #include <netdb.h>
81 #include <pwd.h>
82 #include <inttypes.h>
83 #if defined(__CYGWIN__)
84 #undef _XOPEN_SOURCE
85 #include <grp.h>
86 #define _XOPEN_SOURCE 600
87 #else
88 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
89 #include <grp.h>
90 #define _ALL_SOURCE 1
91 #endif
92 #endif /* !__MINGW32__ */
94 #ifndef NO_ICONV
95 #include <iconv.h>
96 #endif
98 /* On most systems <limits.h> would have given us this, but
99 * not on some systems (e.g. GNU/Hurd).
101 #ifndef PATH_MAX
102 #define PATH_MAX 4096
103 #endif
105 #ifndef PRIuMAX
106 #ifndef __MINGW32__
107 #define PRIuMAX "llu"
108 #else
109 #define PRIuMAX "I64u"
110 #endif
111 #endif
113 #ifdef __GNUC__
114 #define NORETURN __attribute__((__noreturn__))
115 #else
116 #define NORETURN
117 #ifndef __attribute__
118 #define __attribute__(x)
119 #endif
120 #endif
122 /* General helper functions */
123 extern void usage(const char *err) NORETURN;
124 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
125 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
126 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
128 extern void set_usage_routine(void (*routine)(const char *err) NORETURN);
129 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
130 extern void set_error_routine(void (*routine)(const char *err, va_list params));
131 extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
133 extern int prefixcmp(const char *str, const char *prefix);
135 #ifdef NO_MMAP
137 #ifndef PROT_READ
138 #define PROT_READ 1
139 #define PROT_WRITE 2
140 #define MAP_PRIVATE 1
141 #define MAP_FAILED ((void*)-1)
142 #endif
144 #define mmap git_mmap
145 #define munmap git_munmap
146 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
147 extern int git_munmap(void *start, size_t length);
149 /* This value must be multiple of (pagesize * 2) */
150 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
152 #else /* NO_MMAP */
154 #include <sys/mman.h>
156 /* This value must be multiple of (pagesize * 2) */
157 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
158 (sizeof(void*) >= 8 \
159 ? 1 * 1024 * 1024 * 1024 \
160 : 32 * 1024 * 1024)
162 #endif /* NO_MMAP */
164 #define DEFAULT_PACKED_GIT_LIMIT \
165 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
167 #ifdef NO_PREAD
168 #define pread git_pread
169 extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
170 #endif
171 /* Forward decl that will remind us if its twin in cache.h changes.
172 This function in used in compat/pread.c. But we can't include
173 cache.h there. */
174 extern int read_in_full(int fd, void *buf, size_t count);
176 #ifdef NO_SETENV
177 #define setenv gitsetenv
178 extern int gitsetenv(const char *, const char *, int);
179 #endif
181 #ifdef NO_MKDTEMP
182 #define mkdtemp gitmkdtemp
183 extern char *gitmkdtemp(char *);
184 #endif
186 #ifdef NO_UNSETENV
187 #define unsetenv gitunsetenv
188 extern void gitunsetenv(const char *);
189 #endif
191 #ifdef NO_STRCASESTR
192 #define strcasestr gitstrcasestr
193 extern char *gitstrcasestr(const char *haystack, const char *needle);
194 #endif
196 #ifdef NO_STRLCPY
197 #define strlcpy gitstrlcpy
198 extern size_t gitstrlcpy(char *, const char *, size_t);
199 #endif
201 #ifdef NO_STRTOUMAX
202 #define strtoumax gitstrtoumax
203 extern uintmax_t gitstrtoumax(const char *, char **, int);
204 #endif
206 #ifdef NO_HSTRERROR
207 #define hstrerror githstrerror
208 extern const char *githstrerror(int herror);
209 #endif
211 #ifdef NO_MEMMEM
212 #define memmem gitmemmem
213 void *gitmemmem(const void *haystack, size_t haystacklen,
214 const void *needle, size_t needlelen);
215 #endif
217 #ifdef __GLIBC_PREREQ
218 #if __GLIBC_PREREQ(2, 1)
219 #define HAVE_STRCHRNUL
220 #endif
221 #endif
223 #ifndef HAVE_STRCHRNUL
224 #define strchrnul gitstrchrnul
225 static inline char *gitstrchrnul(const char *s, int c)
227 while (*s && *s != c)
228 s++;
229 return (char *)s;
231 #endif
233 extern void release_pack_memory(size_t, int);
235 static inline char* xstrdup(const char *str)
237 char *ret = strdup(str);
238 if (!ret) {
239 release_pack_memory(strlen(str) + 1, -1);
240 ret = strdup(str);
241 if (!ret)
242 die("Out of memory, strdup failed");
244 return ret;
247 static inline void *xmalloc(size_t size)
249 void *ret = malloc(size);
250 if (!ret && !size)
251 ret = malloc(1);
252 if (!ret) {
253 release_pack_memory(size, -1);
254 ret = malloc(size);
255 if (!ret && !size)
256 ret = malloc(1);
257 if (!ret)
258 die("Out of memory, malloc failed");
260 #ifdef XMALLOC_POISON
261 memset(ret, 0xA5, size);
262 #endif
263 return ret;
266 static inline void *xmemdupz(const void *data, size_t len)
268 char *p = xmalloc(len + 1);
269 memcpy(p, data, len);
270 p[len] = '\0';
271 return p;
274 static inline char *xstrndup(const char *str, size_t len)
276 char *p = memchr(str, '\0', len);
277 return xmemdupz(str, p ? p - str : len);
280 static inline void *xrealloc(void *ptr, size_t size)
282 void *ret = realloc(ptr, size);
283 if (!ret && !size)
284 ret = realloc(ptr, 1);
285 if (!ret) {
286 release_pack_memory(size, -1);
287 ret = realloc(ptr, size);
288 if (!ret && !size)
289 ret = realloc(ptr, 1);
290 if (!ret)
291 die("Out of memory, realloc failed");
293 return ret;
296 static inline void *xcalloc(size_t nmemb, size_t size)
298 void *ret = calloc(nmemb, size);
299 if (!ret && (!nmemb || !size))
300 ret = calloc(1, 1);
301 if (!ret) {
302 release_pack_memory(nmemb * size, -1);
303 ret = calloc(nmemb, size);
304 if (!ret && (!nmemb || !size))
305 ret = calloc(1, 1);
306 if (!ret)
307 die("Out of memory, calloc failed");
309 return ret;
312 static inline void *xmmap(void *start, size_t length,
313 int prot, int flags, int fd, off_t offset)
315 void *ret = mmap(start, length, prot, flags, fd, offset);
316 if (ret == MAP_FAILED) {
317 if (!length)
318 return NULL;
319 release_pack_memory(length, fd);
320 ret = mmap(start, length, prot, flags, fd, offset);
321 if (ret == MAP_FAILED)
322 die("Out of memory? mmap failed: %s", strerror(errno));
324 return ret;
327 static inline ssize_t xread(int fd, void *buf, size_t len)
329 ssize_t nr;
330 while (1) {
331 nr = read(fd, buf, len);
332 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
333 continue;
334 return nr;
338 static inline ssize_t xwrite(int fd, const void *buf, size_t len)
340 ssize_t nr;
341 while (1) {
342 nr = write(fd, buf, len);
343 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
344 continue;
345 return nr;
349 static inline int xdup(int fd)
351 int ret = dup(fd);
352 if (ret < 0)
353 die("dup failed: %s", strerror(errno));
354 return ret;
357 static inline FILE *xfdopen(int fd, const char *mode)
359 FILE *stream = fdopen(fd, mode);
360 if (stream == NULL)
361 die("Out of memory? fdopen failed: %s", strerror(errno));
362 return stream;
365 #ifdef __MINGW32__
366 int mkstemp(char *template);
367 #endif
369 static inline int xmkstemp(char *template)
371 int fd;
373 fd = mkstemp(template);
374 if (fd < 0)
375 die("Unable to create temporary file: %s", strerror(errno));
376 return fd;
379 static inline size_t xsize_t(off_t len)
381 return (size_t)len;
384 static inline int has_extension(const char *filename, const char *ext)
386 size_t len = strlen(filename);
387 size_t extlen = strlen(ext);
388 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
391 /* Sane ctype - no locale, and works with signed chars */
392 #undef isspace
393 #undef isdigit
394 #undef isalpha
395 #undef isalnum
396 #undef tolower
397 #undef toupper
398 extern unsigned char sane_ctype[256];
399 #define GIT_SPACE 0x01
400 #define GIT_DIGIT 0x02
401 #define GIT_ALPHA 0x04
402 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
403 #define isspace(x) sane_istest(x,GIT_SPACE)
404 #define isdigit(x) sane_istest(x,GIT_DIGIT)
405 #define isalpha(x) sane_istest(x,GIT_ALPHA)
406 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
407 #define tolower(x) sane_case((unsigned char)(x), 0x20)
408 #define toupper(x) sane_case((unsigned char)(x), 0)
410 static inline int sane_case(int x, int high)
412 if (sane_istest(x, GIT_ALPHA))
413 x = (x & ~0x20) | high;
414 return x;
417 static inline int strtoul_ui(char const *s, int base, unsigned int *result)
419 unsigned long ul;
420 char *p;
422 errno = 0;
423 ul = strtoul(s, &p, base);
424 if (errno || *p || p == s || (unsigned int) ul != ul)
425 return -1;
426 *result = ul;
427 return 0;
430 static inline int strtol_i(char const *s, int base, int *result)
432 long ul;
433 char *p;
435 errno = 0;
436 ul = strtol(s, &p, base);
437 if (errno || *p || p == s || (int) ul != ul)
438 return -1;
439 *result = ul;
440 return 0;
443 #ifdef INTERNAL_QSORT
444 void git_qsort(void *base, size_t nmemb, size_t size,
445 int(*compar)(const void *, const void *));
446 #define qsort git_qsort
447 #endif
449 #ifdef __MINGW32__
451 #include <winsock2.h>
454 * things that are not available in header files
457 typedef int pid_t;
458 #define hstrerror strerror
460 #define S_IFLNK 0120000 /* Symbolic link */
461 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
462 #define S_ISSOCK(x) 0
463 #define S_IRGRP 0
464 #define S_IWGRP 0
465 #define S_IXGRP 0
466 #define S_ISGID 0
467 #define S_IROTH 0
468 #define S_IXOTH 0
470 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
471 #define WEXITSTATUS(x) ((x) & 0xff)
472 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
474 #define SIGKILL 0
475 #define SIGCHLD 0
476 #define SIGPIPE 0
477 #define SIGALRM 100
479 #define F_GETFD 1
480 #define F_SETFD 2
481 #define FD_CLOEXEC 0x1
483 struct passwd {
484 char *pw_name;
485 char *pw_gecos;
486 char *pw_dir;
489 struct pollfd {
490 int fd; /* file descriptor */
491 short events; /* requested events */
492 short revents; /* returned events */
494 #define POLLIN 1
495 #define POLLHUP 2
497 typedef void (__cdecl *sig_handler_t)(int);
498 struct sigaction {
499 sig_handler_t sa_handler;
500 unsigned sa_flags;
502 #define sigemptyset(x) (void)0
503 #define SA_RESTART 0
505 struct itimerval {
506 struct timeval it_value, it_interval;
508 #define ITIMER_REAL 0
511 * trivial stubs
514 static inline int readlink(const char *path, char *buf, size_t bufsiz)
515 { errno = ENOSYS; return -1; }
516 static inline int symlink(const char *oldpath, const char *newpath)
517 { errno = ENOSYS; return -1; }
518 static inline int link(const char *oldpath, const char *newpath)
519 { errno = ENOSYS; return -1; }
520 static inline int fchmod(int fildes, mode_t mode)
521 { errno = ENOSYS; return -1; }
522 static inline int fork(void)
523 { errno = ENOSYS; return -1; }
524 static inline unsigned int alarm(unsigned int seconds)
525 { return 0; }
526 static inline int fsync(int fd)
527 { return 0; }
528 static inline int getppid(void)
529 { return 1; }
530 static inline void sync(void)
532 static inline int getuid()
533 { return 1; }
534 static inline struct passwd *getpwnam(const char *name)
535 { return NULL; }
536 static inline int fcntl(int fd, int cmd, long arg)
538 if (cmd == F_GETFD || cmd == F_SETFD)
539 return 0;
540 errno = EINVAL;
541 return -1;
545 * simple adaptors
548 static inline int mingw_mkdir(const char *path, int mode)
550 return mkdir(path);
552 #define mkdir mingw_mkdir
554 static inline int mingw_unlink(const char *pathname)
556 /* read-only files cannot be removed */
557 chmod(pathname, 0666);
558 return unlink(pathname);
560 #define unlink mingw_unlink
562 static inline int waitpid(pid_t pid, unsigned *status, unsigned options)
564 if (options == 0)
565 return _cwait(status, pid, 0);
566 errno = EINVAL;
567 return -1;
571 * implementations of missing functions
574 int pipe(int filedes[2]);
575 unsigned int sleep (unsigned int seconds);
576 int gettimeofday(struct timeval *tv, void *tz);
577 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
578 struct tm *gmtime_r(const time_t *timep, struct tm *result);
579 struct tm *localtime_r(const time_t *timep, struct tm *result);
580 int getpagesize(void); /* defined in MinGW's libgcc.a */
581 struct passwd *getpwuid(int uid);
582 int setitimer(int type, struct itimerval *in, struct itimerval *out);
583 int sigaction(int sig, struct sigaction *in, struct sigaction *out);
586 * replacements of existing functions
589 int mingw_open (const char *filename, int oflags, ...);
590 #define open mingw_open
592 char *mingw_getcwd(char *pointer, int len);
593 #define getcwd mingw_getcwd
595 struct hostent *mingw_gethostbyname(const char *host);
596 #define gethostbyname mingw_gethostbyname
598 int mingw_socket(int domain, int type, int protocol);
599 #define socket mingw_socket
601 int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz);
602 #define connect mingw_connect
604 int mingw_rename(const char*, const char*);
605 #define rename mingw_rename
607 /* Use mingw_lstat() instead of lstat()/stat() and
608 * mingw_fstat() instead of fstat() on Windows.
609 * struct stat is redefined because it lacks the st_blocks member.
611 struct mingw_stat {
612 unsigned st_mode;
613 time_t st_mtime, st_atime, st_ctime;
614 unsigned st_dev, st_ino, st_uid, st_gid;
615 size_t st_size;
616 size_t st_blocks;
618 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
619 int mingw_fstat(int fd, struct mingw_stat *buf);
620 #define fstat mingw_fstat
621 #define lstat mingw_lstat
622 #define stat mingw_stat
623 static inline int mingw_stat(const char *file_name, struct mingw_stat *buf)
624 { return mingw_lstat(file_name, buf); }
626 int mingw_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
627 #define vsnprintf mingw_vsnprintf
629 pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env);
630 void mingw_execvp(const char *cmd, char *const *argv);
631 #define execvp mingw_execvp
633 static inline unsigned int git_ntohl(unsigned int x)
634 { return (unsigned int)ntohl(x); }
635 #define ntohl git_ntohl
637 sig_handler_t mingw_signal(int sig, sig_handler_t handler);
638 #define signal mingw_signal
641 * helpers
644 char **copy_environ(void);
645 void free_environ(char **env);
646 char **env_setenv(char **env, const char *name);
648 #endif /* __MINGW32__ */
650 #endif