Merge branch 'js/mingw-fallouts'
[git/dscho.git] / git-compat-util.h
blob74412331d885bf69e0872d1dab715e5a78ad8e38
1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
4 #define _FILE_OFFSET_BITS 64
6 #ifndef FLEX_ARRAY
7 #if defined(__GNUC__) && (__GNUC__ < 3)
8 #define FLEX_ARRAY 0
9 #else
10 #define FLEX_ARRAY /* empty */
11 #endif
12 #endif
14 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
16 #ifdef __GNUC__
17 #define TYPEOF(x) (__typeof__(x))
18 #else
19 #define TYPEOF(x)
20 #endif
22 #define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
24 /* Approximation of the length of the decimal representation of this type. */
25 #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
27 #if !defined(__APPLE__) && !defined(__FreeBSD__)
28 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
29 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
30 #endif
31 #define _ALL_SOURCE 1
32 #define _GNU_SOURCE 1
33 #define _BSD_SOURCE 1
35 #include <unistd.h>
36 #include <stdio.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <stddef.h>
40 #include <stdlib.h>
41 #include <stdarg.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <limits.h>
45 #include <sys/param.h>
46 #include <sys/types.h>
47 #include <dirent.h>
48 #include <sys/time.h>
49 #include <time.h>
50 #include <signal.h>
51 #include <fnmatch.h>
52 #ifndef __MINGW32__
53 #include <sys/wait.h>
54 #include <sys/poll.h>
55 #include <sys/socket.h>
56 #include <sys/ioctl.h>
57 #include <sys/select.h>
58 #else
59 int mkstemp (char *__template);
60 #endif
61 #include <assert.h>
62 #include <regex.h>
63 #ifndef __MINGW32__
64 #include <netinet/in.h>
65 #include <netinet/tcp.h>
66 #include <arpa/inet.h>
67 #include <netdb.h>
68 #include <pwd.h>
69 #include <inttypes.h>
70 #if defined(__CYGWIN__)
71 #undef _XOPEN_SOURCE
72 #include <grp.h>
73 #define _XOPEN_SOURCE 600
74 #else
75 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
76 #include <grp.h>
77 #define _ALL_SOURCE 1
78 #endif
79 #endif
81 #ifndef NO_ICONV
82 #include <iconv.h>
83 #endif
85 /* On most systems <limits.h> would have given us this, but
86 * not on some systems (e.g. GNU/Hurd).
88 #ifndef PATH_MAX
89 #define PATH_MAX 4096
90 #endif
92 #ifndef PRIuMAX
93 #ifndef __MINGW32__
94 #define PRIuMAX "llu"
95 #else
96 #define PRIuMAX "I64u"
97 #endif
98 #endif
100 #ifdef __GNUC__
101 #define NORETURN __attribute__((__noreturn__))
102 #else
103 #define NORETURN
104 #ifndef __attribute__
105 #define __attribute__(x)
106 #endif
107 #endif
109 /* General helper functions */
110 extern void usage(const char *err) NORETURN;
111 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
112 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
113 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
115 extern void set_usage_routine(void (*routine)(const char *err) NORETURN);
116 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
117 extern void set_error_routine(void (*routine)(const char *err, va_list params));
118 extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
120 #ifdef NO_MMAP
122 #ifndef PROT_READ
123 #define PROT_READ 1
124 #define PROT_WRITE 2
125 #define MAP_PRIVATE 1
126 #define MAP_FAILED ((void*)-1)
127 #endif
129 #define mmap git_mmap
130 #define munmap git_munmap
131 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
132 extern int git_munmap(void *start, size_t length);
134 /* This value must be multiple of (pagesize * 2) */
135 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
137 #else /* NO_MMAP */
139 #include <sys/mman.h>
141 /* This value must be multiple of (pagesize * 2) */
142 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
143 (sizeof(void*) >= 8 \
144 ? 1 * 1024 * 1024 * 1024 \
145 : 32 * 1024 * 1024)
147 #endif /* NO_MMAP */
149 #define DEFAULT_PACKED_GIT_LIMIT \
150 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
152 #ifdef NO_PREAD
153 #define pread git_pread
154 extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
155 #endif
156 /* Forward decl that will remind us if its twin in cache.h changes.
157 This function in used in compat/pread.c. But we can't include
158 cache.h there. */
159 extern int read_in_full(int fd, void *buf, size_t count);
161 #ifdef NO_SETENV
162 #define setenv gitsetenv
163 extern int gitsetenv(const char *, const char *, int);
164 #endif
166 #ifdef NO_MKDTEMP
167 #define mkdtemp gitmkdtemp
168 extern char *gitmkdtemp(char *);
169 #endif
171 #ifdef NO_UNSETENV
172 #define unsetenv gitunsetenv
173 extern void gitunsetenv(const char *);
174 #endif
176 #ifdef NO_STRCASESTR
177 #define strcasestr gitstrcasestr
178 extern char *gitstrcasestr(const char *haystack, const char *needle);
179 #endif
181 #ifdef NO_STRLCPY
182 #define strlcpy gitstrlcpy
183 extern size_t gitstrlcpy(char *, const char *, size_t);
184 #endif
186 #ifdef NO_STRTOUMAX
187 #define strtoumax gitstrtoumax
188 extern uintmax_t gitstrtoumax(const char *, char **, int);
189 #endif
191 #ifdef NO_HSTRERROR
192 #define hstrerror githstrerror
193 extern const char *githstrerror(int herror);
194 #endif
196 #ifdef NO_MEMMEM
197 #define memmem gitmemmem
198 void *gitmemmem(const void *haystack, size_t haystacklen,
199 const void *needle, size_t needlelen);
200 #endif
202 #ifdef __GLIBC_PREREQ
203 #if __GLIBC_PREREQ(2, 1)
204 #define HAVE_STRCHRNUL
205 #endif
206 #endif
208 #ifndef HAVE_STRCHRNUL
209 #define strchrnul gitstrchrnul
210 static inline char *gitstrchrnul(const char *s, int c)
212 while (*s && *s != c)
213 s++;
214 return (char *)s;
216 #endif
218 extern void release_pack_memory(size_t, int);
220 static inline char* xstrdup(const char *str)
222 char *ret = strdup(str);
223 if (!ret) {
224 release_pack_memory(strlen(str) + 1, -1);
225 ret = strdup(str);
226 if (!ret)
227 die("Out of memory, strdup failed");
229 return ret;
232 static inline void *xmalloc(size_t size)
234 void *ret = malloc(size);
235 if (!ret && !size)
236 ret = malloc(1);
237 if (!ret) {
238 release_pack_memory(size, -1);
239 ret = malloc(size);
240 if (!ret && !size)
241 ret = malloc(1);
242 if (!ret)
243 die("Out of memory, malloc failed");
245 #ifdef XMALLOC_POISON
246 memset(ret, 0xA5, size);
247 #endif
248 return ret;
251 static inline void *xmemdupz(const void *data, size_t len)
253 char *p = xmalloc(len + 1);
254 memcpy(p, data, len);
255 p[len] = '\0';
256 return p;
259 static inline char *xstrndup(const char *str, size_t len)
261 char *p = memchr(str, '\0', len);
262 return xmemdupz(str, p ? p - str : len);
265 static inline void *xrealloc(void *ptr, size_t size)
267 void *ret = realloc(ptr, size);
268 if (!ret && !size)
269 ret = realloc(ptr, 1);
270 if (!ret) {
271 release_pack_memory(size, -1);
272 ret = realloc(ptr, size);
273 if (!ret && !size)
274 ret = realloc(ptr, 1);
275 if (!ret)
276 die("Out of memory, realloc failed");
278 return ret;
281 static inline void *xcalloc(size_t nmemb, size_t size)
283 void *ret = calloc(nmemb, size);
284 if (!ret && (!nmemb || !size))
285 ret = calloc(1, 1);
286 if (!ret) {
287 release_pack_memory(nmemb * size, -1);
288 ret = calloc(nmemb, size);
289 if (!ret && (!nmemb || !size))
290 ret = calloc(1, 1);
291 if (!ret)
292 die("Out of memory, calloc failed");
294 return ret;
297 static inline void *xmmap(void *start, size_t length,
298 int prot, int flags, int fd, off_t offset)
300 void *ret = mmap(start, length, prot, flags, fd, offset);
301 if (ret == MAP_FAILED) {
302 if (!length)
303 return NULL;
304 release_pack_memory(length, fd);
305 ret = mmap(start, length, prot, flags, fd, offset);
306 if (ret == MAP_FAILED)
307 die("Out of memory? mmap failed: %s", strerror(errno));
309 return ret;
312 static inline ssize_t xread(int fd, void *buf, size_t len)
314 ssize_t nr;
315 while (1) {
316 nr = read(fd, buf, len);
317 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
318 continue;
319 return nr;
323 static inline ssize_t xwrite(int fd, const void *buf, size_t len)
325 ssize_t nr;
326 while (1) {
327 nr = write(fd, buf, len);
328 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
329 continue;
330 return nr;
334 static inline int xdup(int fd)
336 int ret = dup(fd);
337 if (ret < 0)
338 die("dup failed: %s", strerror(errno));
339 return ret;
342 static inline FILE *xfdopen(int fd, const char *mode)
344 FILE *stream = fdopen(fd, mode);
345 if (stream == NULL)
346 die("Out of memory? fdopen failed: %s", strerror(errno));
347 return stream;
350 static inline int xmkstemp(char *template)
352 int fd;
354 fd = mkstemp(template);
355 if (fd < 0)
356 die("Unable to create temporary file: %s", strerror(errno));
357 return fd;
360 static inline size_t xsize_t(off_t len)
362 return (size_t)len;
365 static inline int has_extension(const char *filename, const char *ext)
367 size_t len = strlen(filename);
368 size_t extlen = strlen(ext);
369 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
372 /* Sane ctype - no locale, and works with signed chars */
373 #undef isspace
374 #undef isdigit
375 #undef isalpha
376 #undef isalnum
377 #undef tolower
378 #undef toupper
379 extern unsigned char sane_ctype[256];
380 #define GIT_SPACE 0x01
381 #define GIT_DIGIT 0x02
382 #define GIT_ALPHA 0x04
383 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
384 #define isspace(x) sane_istest(x,GIT_SPACE)
385 #define isdigit(x) sane_istest(x,GIT_DIGIT)
386 #define isalpha(x) sane_istest(x,GIT_ALPHA)
387 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
388 #define tolower(x) sane_case((unsigned char)(x), 0x20)
389 #define toupper(x) sane_case((unsigned char)(x), 0)
391 static inline int sane_case(int x, int high)
393 if (sane_istest(x, GIT_ALPHA))
394 x = (x & ~0x20) | high;
395 return x;
398 static inline int prefixcmp(const char *str, const char *prefix)
400 return strncmp(str, prefix, strlen(prefix));
403 static inline int strtoul_ui(char const *s, int base, unsigned int *result)
405 unsigned long ul;
406 char *p;
408 errno = 0;
409 ul = strtoul(s, &p, base);
410 if (errno || *p || p == s || (unsigned int) ul != ul)
411 return -1;
412 *result = ul;
413 return 0;
416 static inline int strtol_i(char const *s, int base, int *result)
418 long ul;
419 char *p;
421 errno = 0;
422 ul = strtol(s, &p, base);
423 if (errno || *p || p == s || (int) ul != ul)
424 return -1;
425 *result = ul;
426 return 0;
429 #ifdef __MINGW32__
431 #include <winsock2.h>
433 #define S_IFLNK 0120000 /* Symbolic link */
434 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
435 #define S_ISSOCK(x) 0
436 #define S_IRGRP 0
437 #define S_IWGRP 0
438 #define S_IXGRP 0
439 #define S_ISGID 0
440 #define S_IROTH 0
441 #define S_IXOTH 0
443 static inline int readlink(const char *path, char *buf, size_t bufsiz)
444 { errno = ENOSYS; return -1; }
445 static inline int symlink(const char *oldpath, const char *newpath)
446 { errno = ENOSYS; return -1; }
447 static inline int link(const char *oldpath, const char *newpath)
448 { errno = ENOSYS; return -1; }
449 static inline int fchmod(int fildes, mode_t mode)
450 { errno = ENOSYS; return -1; }
451 static inline int fork(void)
452 { errno = ENOSYS; return -1; }
453 static inline int kill(pid_t pid, int sig)
454 { errno = ENOSYS; return -1; }
455 static inline unsigned int alarm(unsigned int seconds)
456 { return 0; }
458 void mingw_execve(const char *cmd, char *const *argv, char * const *env);
459 #define execve mingw_execve
460 extern void mingw_execvp(const char *cmd, char *const *argv);
461 #define execvp mingw_execvp
462 typedef int pid_t;
463 static inline int waitpid(pid_t pid, unsigned *status, unsigned options)
465 if (options == 0)
466 return _cwait(status, pid, 0);
467 else
468 return errno = EINVAL, -1;
471 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
472 #define WEXITSTATUS(x) ((x) & 0xff)
473 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
474 #define WTERMSIG(x) (x)
475 #define WNOHANG 1
476 #define SIGKILL 0
477 #define SIGCHLD 0
478 #define SIGPIPE 0
480 char **copy_environ();
481 char **copy_env(char **env);
482 void env_unsetenv(char **env, const char *name);
484 unsigned int sleep (unsigned int __seconds);
485 const char *inet_ntop(int af, const void *src,
486 char *dst, size_t cnt);
487 int gettimeofday(struct timeval *tv, void *tz);
488 int pipe(int filedes[2]);
490 struct pollfd {
491 int fd; /* file descriptor */
492 short events; /* requested events */
493 short revents; /* returned events */
495 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
496 #define POLLIN 1
497 #define POLLHUP 2
499 static inline int git_mkdir(const char *path, int mode)
501 return mkdir(path);
503 #define mkdir git_mkdir
505 static inline int git_unlink(const char *pathname) {
506 /* read-only files cannot be removed */
507 chmod(pathname, 0666);
508 return unlink(pathname);
510 #define unlink git_unlink
512 int mingw_open (const char *filename, int oflags, ...);
513 #define open mingw_open
515 #include <time.h>
516 struct tm *gmtime_r(const time_t *timep, struct tm *result);
517 struct tm *localtime_r(const time_t *timep, struct tm *result);
518 #define hstrerror strerror
520 char *mingw_getcwd(char *pointer, int len);
521 #define getcwd mingw_getcwd
523 int mingw_socket(int domain, int type, int protocol);
524 #define socket mingw_socket
526 int mingw_rename(const char*, const char*);
527 #define rename mingw_rename
529 static inline int fsync(int fd) { return 0; }
530 static inline int getppid(void) { return 1; }
531 static inline void sync(void) {}
532 extern int getpagesize(void); /* defined in MinGW's libgcc.a */
534 extern void quote_argv(const char **dst, const char *const *src);
535 extern const char *parse_interpreter(const char *cmd);
536 extern char *mingw_path_lookup(const char *cmd, char **path);
537 extern char **mingw_get_path_split(void);
538 extern void mingw_free_path_split(char **path);
540 /* Use mingw_lstat() instead of lstat()/stat() and
541 * mingw_fstat() instead of fstat() on Windows.
542 * struct stat is redefined because it lacks the st_blocks member.
544 struct mingw_stat {
545 unsigned st_mode;
546 time_t st_mtime, st_atime, st_ctime;
547 unsigned st_dev, st_ino, st_uid, st_gid;
548 size_t st_size;
549 size_t st_blocks;
551 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
552 int mingw_fstat(int fd, struct mingw_stat *buf);
553 #define fstat mingw_fstat
554 #define lstat mingw_lstat
555 #define stat mingw_stat
556 static inline int mingw_stat(const char *file_name, struct mingw_stat *buf)
557 { return mingw_lstat(file_name, buf); }
559 int mingw_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
560 #define vsnprintf mingw_vsnprintf
562 struct passwd {
563 char *pw_name;
564 char *pw_gecos;
565 char *pw_dir;
567 struct passwd *mingw_getpwuid(int uid);
568 #define getpwuid mingw_getpwuid
569 static inline int getuid() { return 1; }
570 static inline struct passwd *getpwnam(const char *name) { return NULL; }
572 struct itimerval {
573 struct timeval it_value, it_interval;
575 int setitimer(int type, struct itimerval *in, struct itimerval *out);
576 #define ITIMER_REAL 0
578 typedef void (__cdecl *sig_handler_t)(int);
579 struct sigaction {
580 sig_handler_t sa_handler;
581 unsigned sa_flags;
583 int sigaction(int sig, struct sigaction *in, struct sigaction *out);
584 #define sigemptyset(x) (void)0
585 #define SA_RESTART 0
586 #define SIGALRM 100
587 sig_handler_t mingw_signal(int sig, sig_handler_t handler);
588 #define signal mingw_signal
590 #define F_GETFD 1
591 #define F_SETFD 2
592 #define FD_CLOEXEC 0x1
593 static inline int mingw_fcntl(int fd, int cmd, long arg)
594 { return cmd == F_GETFD || cmd == F_SETFD ? 0 : (errno = EINVAL, -1); }
595 #define fcntl mingw_fcntl
597 static inline unsigned int git_ntohl(unsigned int x)
598 { return (unsigned int)ntohl(x); }
599 #define ntohl git_ntohl
601 #endif /* __MINGW32__ */
603 #endif