Use spawn*_pipe() instead of fork()/exec() in send-pack and receive-pack.
[git/mingw.git] / git-compat-util.h
blob4c3250858b6f4a24fa9ff15a19188ca29475431a
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 void mingw_execve(const char *cmd, const char **argv, const char **env);
310 #define execve mingw_execve
311 int fork();
312 typedef int pid_t;
313 #define waitpid(pid, status, options) \
314 ((options == 0) ? _cwait((status), (pid), 0) \
315 : (errno = EINVAL, -1))
316 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
317 #define WEXITSTATUS(x) ((x) & 0xff)
318 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
319 #define WTERMSIG(x) (x)
320 #define WNOHANG 1
321 #define SIGKILL 0
322 #define SIGCHLD 0
323 #define SIGALRM 0
324 #define ECONNABORTED 0
326 int kill(pid_t pid, int sig);
327 unsigned int sleep (unsigned int __seconds);
328 const char *inet_ntop(int af, const void *src,
329 char *dst, size_t cnt);
330 int mkstemp (char *__template);
331 int gettimeofday(struct timeval *tv, void *tz);
332 int pipe(int filedes[2]);
334 struct pollfd {
335 int fd; /* file descriptor */
336 short events; /* requested events */
337 short revents; /* returned events */
339 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
340 #define POLLIN 1
341 #define POLLHUP 2
343 typedef int siginfo_t;
344 struct sigaction {
345 void (*sa_handler)(int);
346 void (*sa_sigaction)(int, siginfo_t *, void *);
347 sigset_t sa_mask;
348 int sa_flags;
349 void (*sa_restorer)(void);
351 #define SA_RESTART 0
352 #define ITIMER_REAL 0
354 struct itimerval { struct timeval it_interval, it_value; };
356 static inline int git_mkdir(const char *path, int mode)
358 return mkdir(path);
360 #define mkdir git_mkdir
362 static inline int git_unlink(const char *pathname) {
363 /* read-only files cannot be removed */
364 chmod(pathname, 0666);
365 return unlink(pathname);
367 #define unlink git_unlink
369 #include <time.h>
370 struct tm *gmtime_r(const time_t *timep, struct tm *result);
371 struct tm *localtime_r(const time_t *timep, struct tm *result);
372 #define hstrerror strerror
374 char *mingw_getcwd(char *pointer, int len);
375 #define getcwd mingw_getcwd
377 #define setlinebuf(x)
378 #define fsync(x)
380 extern void quote_argv(const char **dst, const char **src);
381 extern const char *parse_interpreter(const char *cmd);
383 #endif