Make git compile under MinGW.
[git/mingw.git] / git-compat-util.h
blob2bdae6725daae34046f6fb919240730fb2cdab49
1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
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
12 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
14 #if !defined(__APPLE__) && !defined(__FreeBSD__)
15 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
16 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
17 #endif
18 #define _ALL_SOURCE 1
19 #define _GNU_SOURCE 1
20 #define _BSD_SOURCE 1
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <stddef.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <limits.h>
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <dirent.h>
35 #include <sys/time.h>
36 #include <time.h>
37 #include <signal.h>
38 //#include <sys/wait.h>
39 //#include <fnmatch.h>
40 //#include <sys/poll.h>
41 //#include <sys/socket.h>
42 #include <assert.h>
43 #include <regex.h>
44 //#include <netinet/in.h>
45 //#include <netinet/tcp.h>
46 //#include <arpa/inet.h>
47 #ifndef NO_ETC_PASSWD
48 #include <netdb.h>
49 #include <pwd.h>
50 #include <stdint.h>
51 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
52 #include <grp.h>
53 #define _ALL_SOURCE 1
54 #endif
56 #ifndef NO_ICONV
57 #include <iconv.h>
58 #endif
60 /* On most systems <limits.h> would have given us this, but
61 * not on some systems (e.g. GNU/Hurd).
63 #ifndef PATH_MAX
64 #define PATH_MAX 4096
65 #endif
67 #ifdef __GNUC__
68 #define NORETURN __attribute__((__noreturn__))
69 #else
70 #define NORETURN
71 #ifndef __attribute__
72 #define __attribute__(x)
73 #endif
74 #endif
76 /* General helper functions */
77 extern void usage(const char *err) NORETURN;
78 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
79 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
80 extern void warn(const char *err, ...) __attribute__((format (printf, 1, 2)));
82 extern void set_usage_routine(void (*routine)(const char *err) NORETURN);
83 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
84 extern void set_error_routine(void (*routine)(const char *err, va_list params));
85 extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
87 #ifdef NO_MMAP
89 #ifndef PROT_READ
90 #define PROT_READ 1
91 #define PROT_WRITE 2
92 #define MAP_PRIVATE 1
93 #define MAP_FAILED ((void*)-1)
94 #endif
96 #define mmap git_mmap
97 #define munmap git_munmap
98 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
99 extern int git_munmap(void *start, size_t length);
101 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
103 #else /* NO_MMAP */
105 #include <sys/mman.h>
106 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
107 (sizeof(void*) >= 8 \
108 ? 1 * 1024 * 1024 * 1024 \
109 : 32 * 1024 * 1024)
111 #endif /* NO_MMAP */
113 #define DEFAULT_PACKED_GIT_LIMIT \
114 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
116 #ifdef NO_PREAD
117 #define pread git_pread
118 extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
119 #endif
121 #ifdef NO_SETENV
122 #define setenv gitsetenv
123 extern int gitsetenv(const char *, const char *, int);
124 #endif
126 #ifdef NO_UNSETENV
127 #define unsetenv gitunsetenv
128 extern void gitunsetenv(const char *);
129 #endif
131 #ifdef NO_STRCASESTR
132 #define strcasestr gitstrcasestr
133 extern char *gitstrcasestr(const char *haystack, const char *needle);
134 #endif
136 #ifdef NO_STRLCPY
137 #define strlcpy gitstrlcpy
138 extern size_t gitstrlcpy(char *, const char *, size_t);
139 #endif
141 extern void release_pack_memory(size_t);
143 static inline char* xstrdup(const char *str)
145 char *ret = strdup(str);
146 if (!ret) {
147 release_pack_memory(strlen(str) + 1);
148 ret = strdup(str);
149 if (!ret)
150 die("Out of memory, strdup failed");
152 return ret;
155 static inline void *xmalloc(size_t size)
157 void *ret = malloc(size);
158 if (!ret && !size)
159 ret = malloc(1);
160 if (!ret) {
161 release_pack_memory(size);
162 ret = malloc(size);
163 if (!ret && !size)
164 ret = malloc(1);
165 if (!ret)
166 die("Out of memory, malloc failed");
168 #ifdef XMALLOC_POISON
169 memset(ret, 0xA5, size);
170 #endif
171 return ret;
174 static inline void *xrealloc(void *ptr, size_t size)
176 void *ret = realloc(ptr, size);
177 if (!ret && !size)
178 ret = realloc(ptr, 1);
179 if (!ret) {
180 release_pack_memory(size);
181 ret = realloc(ptr, size);
182 if (!ret && !size)
183 ret = realloc(ptr, 1);
184 if (!ret)
185 die("Out of memory, realloc failed");
187 return ret;
190 static inline void *xcalloc(size_t nmemb, size_t size)
192 void *ret = calloc(nmemb, size);
193 if (!ret && (!nmemb || !size))
194 ret = calloc(1, 1);
195 if (!ret) {
196 release_pack_memory(nmemb * size);
197 ret = calloc(nmemb, size);
198 if (!ret && (!nmemb || !size))
199 ret = calloc(1, 1);
200 if (!ret)
201 die("Out of memory, calloc failed");
203 return ret;
206 static inline void *xmmap(void *start, size_t length,
207 int prot, int flags, int fd, off_t offset)
209 void *ret = mmap(start, length, prot, flags, fd, offset);
210 if (ret == MAP_FAILED) {
211 if (!length)
212 return NULL;
213 release_pack_memory(length);
214 ret = mmap(start, length, prot, flags, fd, offset);
215 if (ret == MAP_FAILED)
216 die("Out of memory? mmap failed: %s", strerror(errno));
218 return ret;
221 static inline ssize_t xread(int fd, void *buf, size_t len)
223 ssize_t nr;
224 while (1) {
225 nr = read(fd, buf, len);
226 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
227 continue;
228 return nr;
232 static inline ssize_t xwrite(int fd, const void *buf, size_t len)
234 ssize_t nr;
235 while (1) {
236 nr = write(fd, buf, len);
237 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
238 continue;
239 return nr;
243 static inline int has_extension(const char *filename, const char *ext)
245 size_t len = strlen(filename);
246 size_t extlen = strlen(ext);
247 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
250 /* Sane ctype - no locale, and works with signed chars */
251 #undef isspace
252 #undef isdigit
253 #undef isalpha
254 #undef isalnum
255 #undef tolower
256 #undef toupper
257 extern unsigned char sane_ctype[256];
258 #define GIT_SPACE 0x01
259 #define GIT_DIGIT 0x02
260 #define GIT_ALPHA 0x04
261 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
262 #define isspace(x) sane_istest(x,GIT_SPACE)
263 #define isdigit(x) sane_istest(x,GIT_DIGIT)
264 #define isalpha(x) sane_istest(x,GIT_ALPHA)
265 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
266 #define tolower(x) sane_case((unsigned char)(x), 0x20)
267 #define toupper(x) sane_case((unsigned char)(x), 0)
269 static inline int sane_case(int x, int high)
271 if (sane_istest(x, GIT_ALPHA))
272 x = (x & ~0x20) | high;
273 return x;
276 // MinGW
278 #ifndef S_ISLNK
279 #define S_ISLNK(x) 0
280 #define S_IFLNK 0
281 #endif
283 #ifndef S_ISGRP
284 #define S_ISGRP(x) 0
285 #define S_IRGRP 0
286 #define S_IWGRP 0
287 #define S_IXGRP 0
288 #define S_ISGID 0
289 #define S_IROTH 0
290 #define S_IXOTH 0
291 #endif
293 int readlink(const char *path, char *buf, size_t bufsiz);
294 int symlink(const char *oldpath, const char *newpath);
295 #define link symlink
296 int fchmod(int fildes, mode_t mode);
297 int lstat(const char *file_name, struct stat *buf);
299 /* missing: link, mkstemp, fchmod, getuid (?), gettimeofday */
300 int socketpair(int d, int type, int protocol, int sv[2]);
301 #define AF_UNIX 0
302 #define SOCK_STREAM 0
303 int syslog(int type, char *bufp, ...);
304 #define LOG_ERR 1
305 #define LOG_INFO 2
306 #define LOG_DAEMON 4
307 unsigned int alarm(unsigned int seconds);
308 #include <winsock2.h>
309 int fork();
310 typedef int pid_t;
311 pid_t waitpid(pid_t pid, int *status, int options);
312 #define WIFEXITED(x) 0
313 #define WEXITSTATUS(x) 1
314 #define WIFSIGNALED(x) -1
315 #define WTERMSIG(x) 0
316 #define WNOHANG 0
317 #define SIGKILL 0
318 #define SIGCHLD 0
319 #define SIGALRM 0
320 #define ECONNABORTED 0
322 int kill(pid_t pid, int sig);
323 unsigned int sleep (unsigned int __seconds);
324 const char *inet_ntop(int af, const void *src,
325 char *dst, size_t cnt);
326 int mkstemp (char *__template);
327 int gettimeofday(struct timeval *tv, void *tz);
328 int pipe(int filedes[2]);
330 struct pollfd {
331 int fd; /* file descriptor */
332 short events; /* requested events */
333 short revents; /* returned events */
335 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
336 #define POLLIN 1
337 #define POLLHUP 2
338 int fnmatch(const char *pattern, const char *string, int flags);
339 #define FNM_PATHNAME 1
341 typedef int siginfo_t;
342 struct sigaction {
343 void (*sa_handler)(int);
344 void (*sa_sigaction)(int, siginfo_t *, void *);
345 sigset_t sa_mask;
346 int sa_flags;
347 void (*sa_restorer)(void);
349 #define SA_RESTART 0
350 #define ITIMER_REAL 0
352 struct itimerval { struct timeval it_interval, it_value; };
354 int git_mkdir(const char *path, int mode);
355 #define mkdir git_mkdir
357 #include <time.h>
358 struct tm *gmtime_r(const time_t *timep, struct tm *result);
359 struct tm *localtime_r(const time_t *timep, struct tm *result);
360 #define hstrerror strerror
362 char *mingw_getcwd(char *pointer, int len);
363 #define getcwd mingw_getcwd
365 #define setlinebuf(x)
366 #define fsync(x)
368 #endif