1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
4 #define _FILE_OFFSET_BITS 64
8 * See if our compiler is known to support flexible array members.
10 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
11 # define FLEX_ARRAY /* empty */
12 #elif defined(__GNUC__)
14 # define FLEX_ARRAY /* empty */
16 # define FLEX_ARRAY 0 /* older GNU extension */
21 * Otherwise, default to safer but a bit wasteful traditional style
28 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
31 #define TYPEOF(x) (__typeof__(x))
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 */
60 #include <sys/param.h>
61 #include <sys/types.h>
72 #include <sys/socket.h>
73 #include <sys/ioctl.h>
74 #ifndef NO_SYS_SELECT_H
75 #include <sys/select.h>
77 #include <netinet/in.h>
78 #include <netinet/tcp.h>
79 #include <arpa/inet.h>
83 #if defined(__CYGWIN__)
86 #define _XOPEN_SOURCE 600
88 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
92 #endif /* !__MINGW32__ */
98 /* On most systems <limits.h> would have given us this, but
99 * not on some systems (e.g. GNU/Hurd).
102 #define PATH_MAX 4096
107 #define PRIuMAX "llu"
109 #define PRIuMAX "I64u"
114 #define NORETURN __attribute__((__noreturn__))
117 #ifndef __attribute__
118 #define __attribute__(x)
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
);
140 #define MAP_PRIVATE 1
141 #define MAP_FAILED ((void*)-1)
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)
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 \
164 #define DEFAULT_PACKED_GIT_LIMIT \
165 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
168 #define pread git_pread
169 extern ssize_t
git_pread(int fd
, void *buf
, size_t count
, off_t offset
);
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
174 extern int read_in_full(int fd
, void *buf
, size_t count
);
177 #define setenv gitsetenv
178 extern int gitsetenv(const char *, const char *, int);
182 #define mkdtemp gitmkdtemp
183 extern char *gitmkdtemp(char *);
187 #define unsetenv gitunsetenv
188 extern void gitunsetenv(const char *);
192 #define strcasestr gitstrcasestr
193 extern char *gitstrcasestr(const char *haystack
, const char *needle
);
197 #define strlcpy gitstrlcpy
198 extern size_t gitstrlcpy(char *, const char *, size_t);
202 #define strtoumax gitstrtoumax
203 extern uintmax_t gitstrtoumax(const char *, char **, int);
207 #define hstrerror githstrerror
208 extern const char *githstrerror(int herror
);
212 #define memmem gitmemmem
213 void *gitmemmem(const void *haystack
, size_t haystacklen
,
214 const void *needle
, size_t needlelen
);
217 #ifdef __GLIBC_PREREQ
218 #if __GLIBC_PREREQ(2, 1)
219 #define HAVE_STRCHRNUL
223 #ifndef HAVE_STRCHRNUL
224 #define strchrnul gitstrchrnul
225 static inline char *gitstrchrnul(const char *s
, int c
)
227 while (*s
&& *s
!= c
)
233 extern void release_pack_memory(size_t, int);
235 static inline char* xstrdup(const char *str
)
237 char *ret
= strdup(str
);
239 release_pack_memory(strlen(str
) + 1, -1);
242 die("Out of memory, strdup failed");
247 static inline void *xmalloc(size_t size
)
249 void *ret
= malloc(size
);
253 release_pack_memory(size
, -1);
258 die("Out of memory, malloc failed");
260 #ifdef XMALLOC_POISON
261 memset(ret
, 0xA5, size
);
266 static inline void *xmemdupz(const void *data
, size_t len
)
268 char *p
= xmalloc(len
+ 1);
269 memcpy(p
, data
, len
);
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
);
284 ret
= realloc(ptr
, 1);
286 release_pack_memory(size
, -1);
287 ret
= realloc(ptr
, size
);
289 ret
= realloc(ptr
, 1);
291 die("Out of memory, realloc failed");
296 static inline void *xcalloc(size_t nmemb
, size_t size
)
298 void *ret
= calloc(nmemb
, size
);
299 if (!ret
&& (!nmemb
|| !size
))
302 release_pack_memory(nmemb
* size
, -1);
303 ret
= calloc(nmemb
, size
);
304 if (!ret
&& (!nmemb
|| !size
))
307 die("Out of memory, calloc failed");
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
) {
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
));
327 static inline ssize_t
xread(int fd
, void *buf
, size_t len
)
331 nr
= read(fd
, buf
, len
);
332 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
338 static inline ssize_t
xwrite(int fd
, const void *buf
, size_t len
)
342 nr
= write(fd
, buf
, len
);
343 if ((nr
< 0) && (errno
== EAGAIN
|| errno
== EINTR
))
349 static inline int xdup(int fd
)
353 die("dup failed: %s", strerror(errno
));
357 static inline FILE *xfdopen(int fd
, const char *mode
)
359 FILE *stream
= fdopen(fd
, mode
);
361 die("Out of memory? fdopen failed: %s", strerror(errno
));
366 int mkstemp(char *template);
369 static inline int xmkstemp(char *template)
373 fd
= mkstemp(template);
375 die("Unable to create temporary file: %s", strerror(errno
));
379 static inline size_t xsize_t(off_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 */
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
;
417 static inline int strtoul_ui(char const *s
, int base
, unsigned int *result
)
423 ul
= strtoul(s
, &p
, base
);
424 if (errno
|| *p
|| p
== s
|| (unsigned int) ul
!= ul
)
430 static inline int strtol_i(char const *s
, int base
, int *result
)
436 ul
= strtol(s
, &p
, base
);
437 if (errno
|| *p
|| p
== s
|| (int) ul
!= ul
)
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
451 #include <winsock2.h>
454 * things that are not available in header files
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
470 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
471 #define WEXITSTATUS(x) ((x) & 0xff)
472 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
481 #define FD_CLOEXEC 0x1
490 int fd
; /* file descriptor */
491 short events
; /* requested events */
492 short revents
; /* returned events */
497 typedef void (__cdecl
*sig_handler_t
)(int);
499 sig_handler_t sa_handler
;
502 #define sigemptyset(x) (void)0
506 struct timeval it_value
, it_interval
;
508 #define ITIMER_REAL 0
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
)
526 static inline int fsync(int fd
)
528 static inline int getppid(void)
530 static inline void sync(void)
532 static inline int getuid()
534 static inline struct passwd
*getpwnam(const char *name
)
536 static inline int fcntl(int fd
, int cmd
, long arg
)
538 if (cmd
== F_GETFD
|| cmd
== F_SETFD
)
548 static inline int mingw_mkdir(const char *path
, int mode
)
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
)
565 return _cwait(status
, pid
, 0);
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.
613 time_t st_mtime
, st_atime
, st_ctime
;
614 unsigned st_dev
, st_ino
, st_uid
, st_gid
;
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
644 char **copy_environ(void);
645 void free_environ(char **env
);
646 char **env_setenv(char **env
, const char *name
);
648 #endif /* __MINGW32__ */