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/ioctl.h>
57 #include <sys/select.h>
59 int mkstemp (char *__template
);
64 #include <netinet/in.h>
65 #include <netinet/tcp.h>
66 #include <arpa/inet.h>
70 #if defined(__CYGWIN__)
73 #define _XOPEN_SOURCE 600
75 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
85 /* On most systems <limits.h> would have given us this, but
86 * not on some systems (e.g. GNU/Hurd).
96 #define PRIuMAX "I64u"
101 #define NORETURN __attribute__((__noreturn__))
104 #ifndef __attribute__
105 #define __attribute__(x)
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
));
125 #define MAP_PRIVATE 1
126 #define MAP_FAILED ((void*)-1)
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)
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 \
149 #define DEFAULT_PACKED_GIT_LIMIT \
150 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
153 #define pread git_pread
154 extern ssize_t
git_pread(int fd
, void *buf
, size_t count
, off_t offset
);
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
159 extern int read_in_full(int fd
, void *buf
, size_t count
);
162 #define setenv gitsetenv
163 extern int gitsetenv(const char *, const char *, int);
167 #define mkdtemp gitmkdtemp
168 extern char *gitmkdtemp(char *);
172 #define unsetenv gitunsetenv
173 extern void gitunsetenv(const char *);
177 #define strcasestr gitstrcasestr
178 extern char *gitstrcasestr(const char *haystack
, const char *needle
);
182 #define strlcpy gitstrlcpy
183 extern size_t gitstrlcpy(char *, const char *, size_t);
187 #define strtoumax gitstrtoumax
188 extern uintmax_t gitstrtoumax(const char *, char **, int);
192 #define hstrerror githstrerror
193 extern const char *githstrerror(int herror
);
197 #define memmem gitmemmem
198 void *gitmemmem(const void *haystack
, size_t haystacklen
,
199 const void *needle
, size_t needlelen
);
202 #ifdef __GLIBC_PREREQ
203 #if __GLIBC_PREREQ(2, 1)
204 #define HAVE_STRCHRNUL
208 #ifndef HAVE_STRCHRNUL
209 #define strchrnul gitstrchrnul
210 static inline char *gitstrchrnul(const char *s
, int c
)
212 while (*s
&& *s
!= c
)
218 extern void release_pack_memory(size_t, int);
220 static inline char* xstrdup(const char *str
)
222 char *ret
= strdup(str
);
224 release_pack_memory(strlen(str
) + 1, -1);
227 die("Out of memory, strdup failed");
232 static inline void *xmalloc(size_t size
)
234 void *ret
= malloc(size
);
238 release_pack_memory(size
, -1);
243 die("Out of memory, malloc failed");
245 #ifdef XMALLOC_POISON
246 memset(ret
, 0xA5, size
);
251 static inline void *xmemdupz(const void *data
, size_t len
)
253 char *p
= xmalloc(len
+ 1);
254 memcpy(p
, data
, len
);
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
);
269 ret
= realloc(ptr
, 1);
271 release_pack_memory(size
, -1);
272 ret
= realloc(ptr
, size
);
274 ret
= realloc(ptr
, 1);
276 die("Out of memory, realloc failed");
281 static inline void *xcalloc(size_t nmemb
, size_t size
)
283 void *ret
= calloc(nmemb
, size
);
284 if (!ret
&& (!nmemb
|| !size
))
287 release_pack_memory(nmemb
* size
, -1);
288 ret
= calloc(nmemb
, size
);
289 if (!ret
&& (!nmemb
|| !size
))
292 die("Out of memory, calloc failed");
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
) {
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
));
312 static inline ssize_t
xread(int fd
, void *buf
, size_t len
)
316 nr
= read(fd
, buf
, len
);
317 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
323 static inline ssize_t
xwrite(int fd
, const void *buf
, size_t len
)
327 nr
= write(fd
, buf
, len
);
328 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
334 static inline int xdup(int fd
)
338 die("dup failed: %s", strerror(errno
));
342 static inline FILE *xfdopen(int fd
, const char *mode
)
344 FILE *stream
= fdopen(fd
, mode
);
346 die("Out of memory? fdopen failed: %s", strerror(errno
));
350 static inline int xmkstemp(char *template)
354 fd
= mkstemp(template);
356 die("Unable to create temporary file: %s", strerror(errno
));
360 static inline size_t xsize_t(off_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 */
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
;
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
)
409 ul
= strtoul(s
, &p
, base
);
410 if (errno
|| *p
|| p
== s
|| (unsigned int) ul
!= ul
)
416 static inline int strtol_i(char const *s
, int base
, int *result
)
422 ul
= strtol(s
, &p
, base
);
423 if (errno
|| *p
|| p
== s
|| (int) ul
!= ul
)
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
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
)
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
463 static inline int waitpid(pid_t pid
, unsigned *status
, unsigned options
)
466 return _cwait(status
, pid
, 0);
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)
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]);
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
);
499 static inline int git_mkdir(const char *path
, int mode
)
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
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.
546 time_t st_mtime
, st_atime
, st_ctime
;
547 unsigned st_dev
, st_ino
, st_uid
, st_gid
;
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
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
; }
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);
580 sig_handler_t sa_handler
;
583 int sigaction(int sig
, struct sigaction
*in
, struct sigaction
*out
);
584 #define sigemptyset(x) (void)0
587 sig_handler_t
mingw_signal(int sig
, sig_handler_t handler
);
588 #define signal mingw_signal
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__ */