1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
4 #define _FILE_OFFSET_BITS 64
7 #if defined(__GNUC__) && (__GNUC__ < 3)
10 #define FLEX_ARRAY /* empty */
14 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
17 #define TYPEOF(x) (__typeof__(x))
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 */
45 #include <sys/param.h>
46 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/select.h>
58 int mkstemp (char *__template
);
63 #include <netinet/in.h>
64 #include <netinet/tcp.h>
65 #include <arpa/inet.h>
69 #if defined(__CYGWIN__)
72 #define _XOPEN_SOURCE 600
74 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
84 /* On most systems <limits.h> would have given us this, but
85 * not on some systems (e.g. GNU/Hurd).
95 #define PRIuMAX "I64u"
100 #define NORETURN __attribute__((__noreturn__))
103 #ifndef __attribute__
104 #define __attribute__(x)
108 /* General helper functions */
109 extern void usage(const char *err
) NORETURN
;
110 extern void die(const char *err
, ...) NORETURN
__attribute__((format (printf
, 1, 2)));
111 extern int error(const char *err
, ...) __attribute__((format (printf
, 1, 2)));
112 extern void warning(const char *err
, ...) __attribute__((format (printf
, 1, 2)));
114 extern void set_usage_routine(void (*routine
)(const char *err
) NORETURN
);
115 extern void set_die_routine(void (*routine
)(const char *err
, va_list params
) NORETURN
);
116 extern void set_error_routine(void (*routine
)(const char *err
, va_list params
));
117 extern void set_warn_routine(void (*routine
)(const char *warn
, va_list params
));
124 #define MAP_PRIVATE 1
125 #define MAP_FAILED ((void*)-1)
128 #define mmap git_mmap
129 #define munmap git_munmap
130 extern void *git_mmap(void *start
, size_t length
, int prot
, int flags
, int fd
, off_t offset
);
131 extern int git_munmap(void *start
, size_t length
);
133 /* This value must be multiple of (pagesize * 2) */
134 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
138 #include <sys/mman.h>
140 /* This value must be multiple of (pagesize * 2) */
141 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
142 (sizeof(void*) >= 8 \
143 ? 1 * 1024 * 1024 * 1024 \
148 #define DEFAULT_PACKED_GIT_LIMIT \
149 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
152 #define pread git_pread
153 extern ssize_t
git_pread(int fd
, void *buf
, size_t count
, off_t offset
);
157 #define setenv gitsetenv
158 extern int gitsetenv(const char *, const char *, int);
162 #define mkdtemp gitmkdtemp
163 extern char *gitmkdtemp(char *);
167 #define unsetenv gitunsetenv
168 extern void gitunsetenv(const char *);
172 #define strcasestr gitstrcasestr
173 extern char *gitstrcasestr(const char *haystack
, const char *needle
);
177 #define strlcpy gitstrlcpy
178 extern size_t gitstrlcpy(char *, const char *, size_t);
182 #define strtoumax gitstrtoumax
183 extern uintmax_t gitstrtoumax(const char *, char **, int);
187 #define hstrerror githstrerror
188 extern const char *githstrerror(int herror
);
192 #define memmem gitmemmem
193 void *gitmemmem(const void *haystack
, size_t haystacklen
,
194 const void *needle
, size_t needlelen
);
197 #ifdef __GLIBC_PREREQ
198 #if __GLIBC_PREREQ(2, 1)
199 #define HAVE_STRCHRNUL
203 #ifndef HAVE_STRCHRNUL
204 #define strchrnul gitstrchrnul
205 static inline char *gitstrchrnul(const char *s
, int c
)
207 while (*s
&& *s
!= c
)
213 extern void release_pack_memory(size_t, int);
215 static inline char* xstrdup(const char *str
)
217 char *ret
= strdup(str
);
219 release_pack_memory(strlen(str
) + 1, -1);
222 die("Out of memory, strdup failed");
227 static inline void *xmalloc(size_t size
)
229 void *ret
= malloc(size
);
233 release_pack_memory(size
, -1);
238 die("Out of memory, malloc failed");
240 #ifdef XMALLOC_POISON
241 memset(ret
, 0xA5, size
);
246 static inline void *xmemdupz(const void *data
, size_t len
)
248 char *p
= xmalloc(len
+ 1);
249 memcpy(p
, data
, len
);
254 static inline char *xstrndup(const char *str
, size_t len
)
256 char *p
= memchr(str
, '\0', len
);
257 return xmemdupz(str
, p
? p
- str
: len
);
260 static inline void *xrealloc(void *ptr
, size_t size
)
262 void *ret
= realloc(ptr
, size
);
264 ret
= realloc(ptr
, 1);
266 release_pack_memory(size
, -1);
267 ret
= realloc(ptr
, size
);
269 ret
= realloc(ptr
, 1);
271 die("Out of memory, realloc failed");
276 static inline void *xcalloc(size_t nmemb
, size_t size
)
278 void *ret
= calloc(nmemb
, size
);
279 if (!ret
&& (!nmemb
|| !size
))
282 release_pack_memory(nmemb
* size
, -1);
283 ret
= calloc(nmemb
, size
);
284 if (!ret
&& (!nmemb
|| !size
))
287 die("Out of memory, calloc failed");
292 static inline void *xmmap(void *start
, size_t length
,
293 int prot
, int flags
, int fd
, off_t offset
)
295 void *ret
= mmap(start
, length
, prot
, flags
, fd
, offset
);
296 if (ret
== MAP_FAILED
) {
299 release_pack_memory(length
, fd
);
300 ret
= mmap(start
, length
, prot
, flags
, fd
, offset
);
301 if (ret
== MAP_FAILED
)
302 die("Out of memory? mmap failed: %s", strerror(errno
));
307 static inline ssize_t
xread(int fd
, void *buf
, size_t len
)
311 nr
= read(fd
, buf
, len
);
312 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
318 static inline ssize_t
xwrite(int fd
, const void *buf
, size_t len
)
322 nr
= write(fd
, buf
, len
);
323 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
329 static inline int xdup(int fd
)
333 die("dup failed: %s", strerror(errno
));
337 static inline FILE *xfdopen(int fd
, const char *mode
)
339 FILE *stream
= fdopen(fd
, mode
);
341 die("Out of memory? fdopen failed: %s", strerror(errno
));
345 static inline int xmkstemp(char *template)
349 fd
= mkstemp(template);
351 die("Unable to create temporary file: %s", strerror(errno
));
355 static inline size_t xsize_t(off_t len
)
360 static inline int has_extension(const char *filename
, const char *ext
)
362 size_t len
= strlen(filename
);
363 size_t extlen
= strlen(ext
);
364 return len
> extlen
&& !memcmp(filename
+ len
- extlen
, ext
, extlen
);
367 /* Sane ctype - no locale, and works with signed chars */
374 extern unsigned char sane_ctype
[256];
375 #define GIT_SPACE 0x01
376 #define GIT_DIGIT 0x02
377 #define GIT_ALPHA 0x04
378 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
379 #define isspace(x) sane_istest(x,GIT_SPACE)
380 #define isdigit(x) sane_istest(x,GIT_DIGIT)
381 #define isalpha(x) sane_istest(x,GIT_ALPHA)
382 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
383 #define tolower(x) sane_case((unsigned char)(x), 0x20)
384 #define toupper(x) sane_case((unsigned char)(x), 0)
386 static inline int sane_case(int x
, int high
)
388 if (sane_istest(x
, GIT_ALPHA
))
389 x
= (x
& ~0x20) | high
;
393 static inline int prefixcmp(const char *str
, const char *prefix
)
395 return strncmp(str
, prefix
, strlen(prefix
));
398 static inline int strtoul_ui(char const *s
, int base
, unsigned int *result
)
404 ul
= strtoul(s
, &p
, base
);
405 if (errno
|| *p
|| p
== s
|| (unsigned int) ul
!= ul
)
411 static inline int strtol_i(char const *s
, int base
, int *result
)
417 ul
= strtol(s
, &p
, base
);
418 if (errno
|| *p
|| p
== s
|| (int) ul
!= ul
)
426 #include <winsock2.h>
428 #define S_IFLNK 0120000 /* Symbolic link */
429 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
430 #define S_ISSOCK(x) 0
438 static inline int readlink(const char *path
, char *buf
, size_t bufsiz
)
439 { errno
= ENOSYS
; return -1; }
440 static inline int symlink(const char *oldpath
, const char *newpath
)
441 { errno
= ENOSYS
; return -1; }
442 static inline int link(const char *oldpath
, const char *newpath
)
443 { errno
= ENOSYS
; return -1; }
444 static inline int fchmod(int fildes
, mode_t mode
)
445 { errno
= ENOSYS
; return -1; }
446 static inline int fork(void)
447 { errno
= ENOSYS
; return -1; }
448 static inline int kill(pid_t pid
, int sig
)
449 { errno
= ENOSYS
; return -1; }
450 static inline unsigned int alarm(unsigned int seconds
)
453 void mingw_execve(const char *cmd
, const char **argv
, const char **env
);
454 #define execve mingw_execve
455 extern void mingw_execvp(const char *cmd
, const char **argv
);
456 #define execvp mingw_execvp
458 static inline int waitpid(pid_t pid
, unsigned *status
, unsigned options
)
461 return _cwait(status
, pid
, 0);
463 return errno
= EINVAL
, -1;
466 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
467 #define WEXITSTATUS(x) ((x) & 0xff)
468 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
469 #define WTERMSIG(x) (x)
475 unsigned int sleep (unsigned int __seconds
);
476 const char *inet_ntop(int af
, const void *src
,
477 char *dst
, size_t cnt
);
478 int gettimeofday(struct timeval
*tv
, void *tz
);
479 int pipe(int filedes
[2]);
482 int fd
; /* file descriptor */
483 short events
; /* requested events */
484 short revents
; /* returned events */
486 int poll(struct pollfd
*ufds
, unsigned int nfds
, int timeout
);
490 static inline int git_mkdir(const char *path
, int mode
)
494 #define mkdir git_mkdir
496 static inline int git_unlink(const char *pathname
) {
497 /* read-only files cannot be removed */
498 chmod(pathname
, 0666);
499 return unlink(pathname
);
501 #define unlink git_unlink
503 #define open(P, F, M...) \
504 (__builtin_constant_p(*(P)) && !strcmp(P, "/dev/null") ? \
505 open("nul", F, ## M) : open(P, F, ## M))
508 struct tm
*gmtime_r(const time_t *timep
, struct tm
*result
);
509 struct tm
*localtime_r(const time_t *timep
, struct tm
*result
);
510 #define hstrerror strerror
512 char *mingw_getcwd(char *pointer
, int len
);
513 #define getcwd mingw_getcwd
515 int mingw_socket(int domain
, int type
, int protocol
);
516 #define socket mingw_socket
518 int mingw_rename(const char*, const char*);
519 #define rename mingw_rename
521 static inline int fsync(int fd
) { return 0; }
522 static inline int getppid(void) { return 1; }
523 static inline void sync(void) {}
524 extern int getpagesize(void); /* defined in MinGW's libgcc.a */
526 extern void quote_argv(const char **dst
, const char **src
);
527 extern const char *parse_interpreter(const char *cmd
);
528 extern char *mingw_path_lookup(const char *cmd
, char **path
);
529 extern char **mingw_get_path_split(void);
530 extern void mingw_free_path_split(char **path
);
532 /* Use mingw_lstat() instead of lstat()/stat() and
533 * mingw_fstat() instead of fstat() on Windows.
534 * struct stat is redefined because it lacks the st_blocks member.
538 time_t st_mtime
, st_atime
, st_ctime
;
539 unsigned st_dev
, st_ino
, st_uid
, st_gid
;
543 int mingw_lstat(const char *file_name
, struct mingw_stat
*buf
);
544 int mingw_fstat(int fd
, struct mingw_stat
*buf
);
545 #define fstat mingw_fstat
546 #define lstat mingw_lstat
547 #define stat mingw_stat
548 static inline int mingw_stat(const char *file_name
, struct mingw_stat
*buf
)
549 { return mingw_lstat(file_name
, buf
); }
551 int mingw_vsnprintf(char *buf
, size_t size
, const char *fmt
, va_list args
);
552 #define vsnprintf mingw_vsnprintf
559 struct passwd
*mingw_getpwuid(int uid
);
560 #define getpwuid mingw_getpwuid
561 static inline int getuid() { return 1; }
562 static inline struct passwd
*getpwnam(const char *name
) { return NULL
; }
565 struct timeval it_value
, it_interval
;
567 int setitimer(int type
, struct itimerval
*in
, struct itimerval
*out
);
568 #define ITIMER_REAL 0
570 typedef void (__cdecl
*sig_handler_t
)(int);
572 sig_handler_t sa_handler
;
575 int sigaction(int sig
, struct sigaction
*in
, struct sigaction
*out
);
576 #define sigemptyset(x) (void)0
579 sig_handler_t
mingw_signal(int sig
, sig_handler_t handler
);
580 #define signal mingw_signal
584 #define FD_CLOEXEC 0x1
585 static inline int mingw_fcntl(int fd
, int cmd
, long arg
)
586 { return cmd
== F_GETFD
|| cmd
== F_SETFD
? 0 : (errno
= EINVAL
, -1); }
587 #define fcntl mingw_fcntl
589 #endif /* __MINGW32__ */