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>
70 #include <sys/socket.h>
71 #include <sys/ioctl.h>
72 #include <sys/select.h>
74 int mkstemp (char *__template
);
79 #include <netinet/in.h>
80 #include <netinet/tcp.h>
81 #include <arpa/inet.h>
85 #if defined(__CYGWIN__)
88 #define _XOPEN_SOURCE 600
90 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
100 /* On most systems <limits.h> would have given us this, but
101 * not on some systems (e.g. GNU/Hurd).
104 #define PATH_MAX 4096
109 #define PRIuMAX "llu"
111 #define PRIuMAX "I64u"
116 #define NORETURN __attribute__((__noreturn__))
119 #ifndef __attribute__
120 #define __attribute__(x)
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
));
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
);
368 static inline int xmkstemp(char *template)
372 fd
= mkstemp(template);
374 die("Unable to create temporary file: %s", strerror(errno
));
378 static inline size_t xsize_t(off_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 */
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
;
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
)
427 ul
= strtoul(s
, &p
, base
);
428 if (errno
|| *p
|| p
== s
|| (unsigned int) ul
!= ul
)
434 static inline int strtol_i(char const *s
, int base
, int *result
)
440 ul
= strtol(s
, &p
, base
);
441 if (errno
|| *p
|| p
== s
|| (int) ul
!= ul
)
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
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
)
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
)
483 return _cwait(status
, pid
, 0);
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)
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]);
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
);
516 static inline int git_mkdir(const char *path
, int mode
)
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
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.
563 time_t st_mtime
, st_atime
, st_ctime
;
564 unsigned st_dev
, st_ino
, st_uid
, st_gid
;
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
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
; }
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);
597 sig_handler_t sa_handler
;
600 int sigaction(int sig
, struct sigaction
*in
, struct sigaction
*out
);
601 #define sigemptyset(x) (void)0
604 sig_handler_t
mingw_signal(int sig
, sig_handler_t handler
);
605 #define signal mingw_signal
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__ */