1#ifndef GIT_COMPAT_UTIL_H
2#define GIT_COMPAT_UTIL_H
3
4#ifndef FLEX_ARRAY
5#if defined(__GNUC__) && (__GNUC__ < 3)
6#define FLEX_ARRAY 0
7#else
8#define FLEX_ARRAY /* empty */
9#endif
10#endif
11
12#include <unistd.h>
13#include <stdio.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#include <stddef.h>
17#include <stdlib.h>
18#include <stdarg.h>
19#include <string.h>
20#include <errno.h>
21#include <limits.h>
22#include <sys/param.h>
23#include <netinet/in.h>
24#include <sys/types.h>
25#include <dirent.h>
26
27#ifdef __GNUC__
28#define NORETURN __attribute__((__noreturn__))
29#else
30#define NORETURN
31#ifndef __attribute__
32#define __attribute__(x)
33#endif
34#endif
35
36/* General helper functions */
37extern void usage(const char *err) NORETURN;
38extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
39extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
40
41#ifdef NO_MMAP
42
43#ifndef PROT_READ
44#define PROT_READ 1
45#define PROT_WRITE 2
46#define MAP_PRIVATE 1
47#define MAP_FAILED ((void*)-1)
48#endif
49
50#define mmap gitfakemmap
51#define munmap gitfakemunmap
52extern void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
53extern int gitfakemunmap(void *start, size_t length);
54
55#else /* NO_MMAP */
56
57#include <sys/mman.h>
58
59#endif /* NO_MMAP */
60
61#ifdef NO_SETENV
62#define setenv gitsetenv
63extern int gitsetenv(const char *, const char *, int);
64#endif
65
66#ifdef NO_UNSETENV
67#define unsetenv gitunsetenv
68extern void gitunsetenv(const char *);
69#endif
70
71#ifdef NO_STRCASESTR
72#define strcasestr gitstrcasestr
73extern char *gitstrcasestr(const char *haystack, const char *needle);
74#endif
75
76static inline void *xmalloc(size_t size)
77{
78 void *ret = malloc(size);
79 if (!ret && !size)
80 ret = malloc(1);
81 if (!ret)
82 die("Out of memory, malloc failed");
83 return ret;
84}
85
86static inline void *xrealloc(void *ptr, size_t size)
87{
88 void *ret = realloc(ptr, size);
89 if (!ret && !size)
90 ret = realloc(ptr, 1);
91 if (!ret)
92 die("Out of memory, realloc failed");
93 return ret;
94}
95
96static inline void *xcalloc(size_t nmemb, size_t size)
97{
98 void *ret = calloc(nmemb, size);
99 if (!ret && (!nmemb || !size))
100 ret = calloc(1, 1);
101 if (!ret)
102 die("Out of memory, calloc failed");
103 return ret;
104}
105
106static inline ssize_t xread(int fd, void *buf, size_t len)
107{
108 ssize_t nr;
109 while (1) {
110 nr = read(fd, buf, len);
111 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
112 continue;
113 return nr;
114 }
115}
116
117static inline ssize_t xwrite(int fd, const void *buf, size_t len)
118{
119 ssize_t nr;
120 while (1) {
121 nr = write(fd, buf, len);
122 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
123 continue;
124 return nr;
125 }
126}
127
128/* Sane ctype - no locale, and works with signed chars */
129#undef isspace
130#undef isdigit
131#undef isalpha
132#undef isalnum
133#undef tolower
134#undef toupper
135extern unsigned char sane_ctype[256];
136#define GIT_SPACE 0x01
137#define GIT_DIGIT 0x02
138#define GIT_ALPHA 0x04
139#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
140#define isspace(x) sane_istest(x,GIT_SPACE)
141#define isdigit(x) sane_istest(x,GIT_DIGIT)
142#define isalpha(x) sane_istest(x,GIT_ALPHA)
143#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
144#define tolower(x) sane_case((unsigned char)(x), 0x20)
145#define toupper(x) sane_case((unsigned char)(x), 0)
146
147static inline int sane_case(int x, int high)
148{
149 if (sane_istest(x, GIT_ALPHA))
150 x = (x & ~0x20) | high;
151 return x;
152}
153
154#ifndef MAXPATHLEN
155#define MAXPATHLEN 256
156#endif
157#endif