skip t5512 because remote does not yet work
[git/platforms/storm.git] / git-compat-util.h
blob5d3f82b974ccda4e24b39898cfa986ed326c0ae8
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 #ifndef __MINGW32__
68 #include <sys/wait.h>
69 #include <sys/poll.h>
70 #include <sys/socket.h>
71 #include <sys/ioctl.h>
72 #include <sys/select.h>
73 #else
74 int mkstemp (char *__template);
75 #endif
76 #include <assert.h>
77 #include <regex.h>
78 #ifndef __MINGW32__
79 #include <netinet/in.h>
80 #include <netinet/tcp.h>
81 #include <arpa/inet.h>
82 #include <netdb.h>
83 #include <pwd.h>
84 #include <inttypes.h>
85 #if defined(__CYGWIN__)
86 #undef _XOPEN_SOURCE
87 #include <grp.h>
88 #define _XOPEN_SOURCE 600
89 #else
90 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
91 #include <grp.h>
92 #define _ALL_SOURCE 1
93 #endif
94 #endif
96 #ifndef NO_ICONV
97 #include <iconv.h>
98 #endif
100 /* On most systems <limits.h> would have given us this, but
101 * not on some systems (e.g. GNU/Hurd).
103 #ifndef PATH_MAX
104 #define PATH_MAX 4096
105 #endif
107 #ifndef PRIuMAX
108 #ifndef __MINGW32__
109 #define PRIuMAX "llu"
110 #else
111 #define PRIuMAX "I64u"
112 #endif
113 #endif
115 #ifdef __GNUC__
116 #define NORETURN __attribute__((__noreturn__))
117 #else
118 #define NORETURN
119 #ifndef __attribute__
120 #define __attribute__(x)
121 #endif
122 #endif
124 /* General helper functions */
125 extern void usage(const char *err) NORETURN;
126 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
127 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
128 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
130 extern void set_usage_routine(void (*routine)(const char *err) NORETURN);
131 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
132 extern void set_error_routine(void (*routine)(const char *err, va_list params));
133 extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
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
368 static inline int xmkstemp(char *template)
370 int fd;
372 fd = mkstemp(template);
373 if (fd < 0)
374 die("Unable to create temporary file: %s", strerror(errno));
375 return fd;
378 static inline size_t xsize_t(off_t len)
380 return (size_t)len;
383 static inline int has_extension(const char *filename, const char *ext)
385 size_t len = strlen(filename);
386 size_t extlen = strlen(ext);
387 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
390 /* Sane ctype - no locale, and works with signed chars */
391 #undef isspace
392 #undef isdigit
393 #undef isalpha
394 #undef isalnum
395 #undef tolower
396 #undef toupper
397 extern unsigned char sane_ctype[256];
398 #define GIT_SPACE 0x01
399 #define GIT_DIGIT 0x02
400 #define GIT_ALPHA 0x04
401 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
402 #define isspace(x) sane_istest(x,GIT_SPACE)
403 #define isdigit(x) sane_istest(x,GIT_DIGIT)
404 #define isalpha(x) sane_istest(x,GIT_ALPHA)
405 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
406 #define tolower(x) sane_case((unsigned char)(x), 0x20)
407 #define toupper(x) sane_case((unsigned char)(x), 0)
409 static inline int sane_case(int x, int high)
411 if (sane_istest(x, GIT_ALPHA))
412 x = (x & ~0x20) | high;
413 return x;
416 static inline int prefixcmp(const char *str, const char *prefix)
418 return strncmp(str, prefix, strlen(prefix));
421 static inline int strtoul_ui(char const *s, int base, unsigned int *result)
423 unsigned long ul;
424 char *p;
426 errno = 0;
427 ul = strtoul(s, &p, base);
428 if (errno || *p || p == s || (unsigned int) ul != ul)
429 return -1;
430 *result = ul;
431 return 0;
434 static inline int strtol_i(char const *s, int base, int *result)
436 long ul;
437 char *p;
439 errno = 0;
440 ul = strtol(s, &p, base);
441 if (errno || *p || p == s || (int) ul != ul)
442 return -1;
443 *result = ul;
444 return 0;
447 #ifdef __MINGW32__
449 #include <winsock2.h>
451 #define S_IFLNK 0120000 /* Symbolic link */
452 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
453 #define S_ISSOCK(x) 0
454 #define S_IRGRP 0
455 #define S_IWGRP 0
456 #define S_IXGRP 0
457 #define S_ISGID 0
458 #define S_IROTH 0
459 #define S_IXOTH 0
461 static inline int readlink(const char *path, char *buf, size_t bufsiz)
462 { errno = ENOSYS; return -1; }
463 static inline int symlink(const char *oldpath, const char *newpath)
464 { errno = ENOSYS; return -1; }
465 static inline int link(const char *oldpath, const char *newpath)
466 { errno = ENOSYS; return -1; }
467 static inline int fchmod(int fildes, mode_t mode)
468 { errno = ENOSYS; return -1; }
469 static inline int fork(void)
470 { errno = ENOSYS; return -1; }
471 static inline int kill(pid_t pid, int sig)
472 { errno = ENOSYS; return -1; }
473 static inline unsigned int alarm(unsigned int seconds)
474 { return 0; }
476 typedef int pid_t;
477 extern pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env);
478 extern void mingw_execvp(const char *cmd, char *const *argv);
479 #define execvp mingw_execvp
480 static inline int waitpid(pid_t pid, unsigned *status, unsigned options)
482 if (options == 0)
483 return _cwait(status, pid, 0);
484 else
485 return errno = EINVAL, -1;
488 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
489 #define WEXITSTATUS(x) ((x) & 0xff)
490 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
491 #define WTERMSIG(x) (x)
492 #define WNOHANG 1
493 #define SIGKILL 0
494 #define SIGCHLD 0
495 #define SIGPIPE 0
497 char **copy_environ();
498 char **copy_env(char **env);
499 void env_unsetenv(char **env, const char *name);
501 unsigned int sleep (unsigned int __seconds);
502 const char *inet_ntop(int af, const void *src,
503 char *dst, size_t cnt);
504 int gettimeofday(struct timeval *tv, void *tz);
505 int pipe(int filedes[2]);
507 struct pollfd {
508 int fd; /* file descriptor */
509 short events; /* requested events */
510 short revents; /* returned events */
512 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
513 #define POLLIN 1
514 #define POLLHUP 2
516 static inline int git_mkdir(const char *path, int mode)
518 return mkdir(path);
520 #define mkdir git_mkdir
522 static inline int git_unlink(const char *pathname) {
523 /* read-only files cannot be removed */
524 chmod(pathname, 0666);
525 return unlink(pathname);
527 #define unlink git_unlink
529 int mingw_open (const char *filename, int oflags, ...);
530 #define open mingw_open
532 #include <time.h>
533 struct tm *gmtime_r(const time_t *timep, struct tm *result);
534 struct tm *localtime_r(const time_t *timep, struct tm *result);
535 #define hstrerror strerror
537 char *mingw_getcwd(char *pointer, int len);
538 #define getcwd mingw_getcwd
540 struct hostent *mingw_gethostbyname(const char *host);
541 #define gethostbyname mingw_gethostbyname
543 int mingw_socket(int domain, int type, int protocol);
544 #define socket mingw_socket
546 int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz);
547 #define connect mingw_connect
549 int mingw_rename(const char*, const char*);
550 #define rename mingw_rename
552 static inline int fsync(int fd) { return 0; }
553 static inline int getppid(void) { return 1; }
554 static inline void sync(void) {}
555 extern int getpagesize(void); /* defined in MinGW's libgcc.a */
557 /* Use mingw_lstat() instead of lstat()/stat() and
558 * mingw_fstat() instead of fstat() on Windows.
559 * struct stat is redefined because it lacks the st_blocks member.
561 struct mingw_stat {
562 unsigned st_mode;
563 time_t st_mtime, st_atime, st_ctime;
564 unsigned st_dev, st_ino, st_uid, st_gid;
565 size_t st_size;
566 size_t st_blocks;
568 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
569 int mingw_fstat(int fd, struct mingw_stat *buf);
570 #define fstat mingw_fstat
571 #define lstat mingw_lstat
572 #define stat mingw_stat
573 static inline int mingw_stat(const char *file_name, struct mingw_stat *buf)
574 { return mingw_lstat(file_name, buf); }
576 int mingw_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
577 #define vsnprintf mingw_vsnprintf
579 struct passwd {
580 char *pw_name;
581 char *pw_gecos;
582 char *pw_dir;
584 struct passwd *mingw_getpwuid(int uid);
585 #define getpwuid mingw_getpwuid
586 static inline int getuid() { return 1; }
587 static inline struct passwd *getpwnam(const char *name) { return NULL; }
589 struct itimerval {
590 struct timeval it_value, it_interval;
592 int setitimer(int type, struct itimerval *in, struct itimerval *out);
593 #define ITIMER_REAL 0
595 typedef void (__cdecl *sig_handler_t)(int);
596 struct sigaction {
597 sig_handler_t sa_handler;
598 unsigned sa_flags;
600 int sigaction(int sig, struct sigaction *in, struct sigaction *out);
601 #define sigemptyset(x) (void)0
602 #define SA_RESTART 0
603 #define SIGALRM 100
604 sig_handler_t mingw_signal(int sig, sig_handler_t handler);
605 #define signal mingw_signal
607 #define F_GETFD 1
608 #define F_SETFD 2
609 #define FD_CLOEXEC 0x1
610 static inline int mingw_fcntl(int fd, int cmd, long arg)
611 { return cmd == F_GETFD || cmd == F_SETFD ? 0 : (errno = EINVAL, -1); }
612 #define fcntl mingw_fcntl
614 static inline unsigned int git_ntohl(unsigned int x)
615 { return (unsigned int)ntohl(x); }
616 #define ntohl git_ntohl
618 extern __attribute__((noreturn)) int git_exit(int code);
619 #define exit git_exit
621 #endif /* __MINGW32__ */
623 #endif