Remove now unused spawn-pipe.c with spawnvpe_pipe() function.
[git/dscho.git] / git-compat-util.h
blob768e7fc696d8651060272d54ecfd82b888e45470
1 #ifndef GIT_COMPAT_UTIL_H
2 #define GIT_COMPAT_UTIL_H
4 #define _FILE_OFFSET_BITS 64
6 #ifndef FLEX_ARRAY
7 #if defined(__GNUC__) && (__GNUC__ < 3)
8 #define FLEX_ARRAY 0
9 #else
10 #define FLEX_ARRAY /* empty */
11 #endif
12 #endif
14 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
16 #ifdef __GNUC__
17 #define TYPEOF(x) (__typeof__(x))
18 #else
19 #define TYPEOF(x)
20 #endif
22 #define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
24 /* Approximation of the length of the decimal representation of this type. */
25 #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
27 #if !defined(__APPLE__) && !defined(__FreeBSD__)
28 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
29 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
30 #endif
31 #define _ALL_SOURCE 1
32 #define _GNU_SOURCE 1
33 #define _BSD_SOURCE 1
35 #include <unistd.h>
36 #include <stdio.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <stddef.h>
40 #include <stdlib.h>
41 #include <stdarg.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <limits.h>
45 #include <sys/param.h>
46 #include <sys/types.h>
47 #include <dirent.h>
48 #include <sys/time.h>
49 #include <time.h>
50 #include <signal.h>
51 #include <fnmatch.h>
52 #ifndef __MINGW32__
53 #include <sys/wait.h>
54 #include <sys/poll.h>
55 #include <sys/socket.h>
56 #include <sys/ioctl.h>
57 #include <sys/select.h>
58 #else
59 int mkstemp (char *__template);
60 #endif
61 #include <assert.h>
62 #include <regex.h>
63 #ifndef __MINGW32__
64 #include <netinet/in.h>
65 #include <netinet/tcp.h>
66 #include <arpa/inet.h>
67 #include <netdb.h>
68 #include <pwd.h>
69 #include <inttypes.h>
70 #if defined(__CYGWIN__)
71 #undef _XOPEN_SOURCE
72 #include <grp.h>
73 #define _XOPEN_SOURCE 600
74 #else
75 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
76 #include <grp.h>
77 #define _ALL_SOURCE 1
78 #endif
79 #endif
81 #ifndef NO_ICONV
82 #include <iconv.h>
83 #endif
85 /* On most systems <limits.h> would have given us this, but
86 * not on some systems (e.g. GNU/Hurd).
88 #ifndef PATH_MAX
89 #define PATH_MAX 4096
90 #endif
92 #ifndef PRIuMAX
93 #ifndef __MINGW32__
94 #define PRIuMAX "llu"
95 #else
96 #define PRIuMAX "I64u"
97 #endif
98 #endif
100 #ifdef __GNUC__
101 #define NORETURN __attribute__((__noreturn__))
102 #else
103 #define NORETURN
104 #ifndef __attribute__
105 #define __attribute__(x)
106 #endif
107 #endif
109 /* General helper functions */
110 extern void usage(const char *err) NORETURN;
111 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
112 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
113 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
115 extern void set_usage_routine(void (*routine)(const char *err) NORETURN);
116 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
117 extern void set_error_routine(void (*routine)(const char *err, va_list params));
118 extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
120 #ifdef NO_MMAP
122 #ifndef PROT_READ
123 #define PROT_READ 1
124 #define PROT_WRITE 2
125 #define MAP_PRIVATE 1
126 #define MAP_FAILED ((void*)-1)
127 #endif
129 #define mmap git_mmap
130 #define munmap git_munmap
131 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
132 extern int git_munmap(void *start, size_t length);
134 /* This value must be multiple of (pagesize * 2) */
135 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
137 #else /* NO_MMAP */
139 #include <sys/mman.h>
141 /* This value must be multiple of (pagesize * 2) */
142 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
143 (sizeof(void*) >= 8 \
144 ? 1 * 1024 * 1024 * 1024 \
145 : 32 * 1024 * 1024)
147 #endif /* NO_MMAP */
149 #define DEFAULT_PACKED_GIT_LIMIT \
150 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
152 #ifdef NO_PREAD
153 #define pread git_pread
154 extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
155 #endif
157 #ifdef NO_SETENV
158 #define setenv gitsetenv
159 extern int gitsetenv(const char *, const char *, int);
160 #endif
162 #ifdef NO_MKDTEMP
163 #define mkdtemp gitmkdtemp
164 extern char *gitmkdtemp(char *);
165 #endif
167 #ifdef NO_UNSETENV
168 #define unsetenv gitunsetenv
169 extern void gitunsetenv(const char *);
170 #endif
172 #ifdef NO_STRCASESTR
173 #define strcasestr gitstrcasestr
174 extern char *gitstrcasestr(const char *haystack, const char *needle);
175 #endif
177 #ifdef NO_STRLCPY
178 #define strlcpy gitstrlcpy
179 extern size_t gitstrlcpy(char *, const char *, size_t);
180 #endif
182 #ifdef NO_STRTOUMAX
183 #define strtoumax gitstrtoumax
184 extern uintmax_t gitstrtoumax(const char *, char **, int);
185 #endif
187 #ifdef NO_HSTRERROR
188 #define hstrerror githstrerror
189 extern const char *githstrerror(int herror);
190 #endif
192 #ifdef NO_MEMMEM
193 #define memmem gitmemmem
194 void *gitmemmem(const void *haystack, size_t haystacklen,
195 const void *needle, size_t needlelen);
196 #endif
198 #ifdef __GLIBC_PREREQ
199 #if __GLIBC_PREREQ(2, 1)
200 #define HAVE_STRCHRNUL
201 #endif
202 #endif
204 #ifndef HAVE_STRCHRNUL
205 #define strchrnul gitstrchrnul
206 static inline char *gitstrchrnul(const char *s, int c)
208 while (*s && *s != c)
209 s++;
210 return (char *)s;
212 #endif
214 extern void release_pack_memory(size_t, int);
216 static inline char* xstrdup(const char *str)
218 char *ret = strdup(str);
219 if (!ret) {
220 release_pack_memory(strlen(str) + 1, -1);
221 ret = strdup(str);
222 if (!ret)
223 die("Out of memory, strdup failed");
225 return ret;
228 static inline void *xmalloc(size_t size)
230 void *ret = malloc(size);
231 if (!ret && !size)
232 ret = malloc(1);
233 if (!ret) {
234 release_pack_memory(size, -1);
235 ret = malloc(size);
236 if (!ret && !size)
237 ret = malloc(1);
238 if (!ret)
239 die("Out of memory, malloc failed");
241 #ifdef XMALLOC_POISON
242 memset(ret, 0xA5, size);
243 #endif
244 return ret;
247 static inline void *xmemdupz(const void *data, size_t len)
249 char *p = xmalloc(len + 1);
250 memcpy(p, data, len);
251 p[len] = '\0';
252 return p;
255 static inline char *xstrndup(const char *str, size_t len)
257 char *p = memchr(str, '\0', len);
258 return xmemdupz(str, p ? p - str : len);
261 static inline void *xrealloc(void *ptr, size_t size)
263 void *ret = realloc(ptr, size);
264 if (!ret && !size)
265 ret = realloc(ptr, 1);
266 if (!ret) {
267 release_pack_memory(size, -1);
268 ret = realloc(ptr, size);
269 if (!ret && !size)
270 ret = realloc(ptr, 1);
271 if (!ret)
272 die("Out of memory, realloc failed");
274 return ret;
277 static inline void *xcalloc(size_t nmemb, size_t size)
279 void *ret = calloc(nmemb, size);
280 if (!ret && (!nmemb || !size))
281 ret = calloc(1, 1);
282 if (!ret) {
283 release_pack_memory(nmemb * size, -1);
284 ret = calloc(nmemb, size);
285 if (!ret && (!nmemb || !size))
286 ret = calloc(1, 1);
287 if (!ret)
288 die("Out of memory, calloc failed");
290 return ret;
293 static inline void *xmmap(void *start, size_t length,
294 int prot, int flags, int fd, off_t offset)
296 void *ret = mmap(start, length, prot, flags, fd, offset);
297 if (ret == MAP_FAILED) {
298 if (!length)
299 return NULL;
300 release_pack_memory(length, fd);
301 ret = mmap(start, length, prot, flags, fd, offset);
302 if (ret == MAP_FAILED)
303 die("Out of memory? mmap failed: %s", strerror(errno));
305 return ret;
308 static inline ssize_t xread(int fd, void *buf, size_t len)
310 ssize_t nr;
311 while (1) {
312 nr = read(fd, buf, len);
313 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
314 continue;
315 return nr;
319 static inline ssize_t xwrite(int fd, const void *buf, size_t len)
321 ssize_t nr;
322 while (1) {
323 nr = write(fd, buf, len);
324 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
325 continue;
326 return nr;
330 static inline int xdup(int fd)
332 int ret = dup(fd);
333 if (ret < 0)
334 die("dup failed: %s", strerror(errno));
335 return ret;
338 static inline FILE *xfdopen(int fd, const char *mode)
340 FILE *stream = fdopen(fd, mode);
341 if (stream == NULL)
342 die("Out of memory? fdopen failed: %s", strerror(errno));
343 return stream;
346 static inline int xmkstemp(char *template)
348 int fd;
350 fd = mkstemp(template);
351 if (fd < 0)
352 die("Unable to create temporary file: %s", strerror(errno));
353 return fd;
356 static inline size_t xsize_t(off_t len)
358 return (size_t)len;
361 static inline int has_extension(const char *filename, const char *ext)
363 size_t len = strlen(filename);
364 size_t extlen = strlen(ext);
365 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
368 /* Sane ctype - no locale, and works with signed chars */
369 #undef isspace
370 #undef isdigit
371 #undef isalpha
372 #undef isalnum
373 #undef tolower
374 #undef toupper
375 extern unsigned char sane_ctype[256];
376 #define GIT_SPACE 0x01
377 #define GIT_DIGIT 0x02
378 #define GIT_ALPHA 0x04
379 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
380 #define isspace(x) sane_istest(x,GIT_SPACE)
381 #define isdigit(x) sane_istest(x,GIT_DIGIT)
382 #define isalpha(x) sane_istest(x,GIT_ALPHA)
383 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
384 #define tolower(x) sane_case((unsigned char)(x), 0x20)
385 #define toupper(x) sane_case((unsigned char)(x), 0)
387 static inline int sane_case(int x, int high)
389 if (sane_istest(x, GIT_ALPHA))
390 x = (x & ~0x20) | high;
391 return x;
394 static inline int prefixcmp(const char *str, const char *prefix)
396 return strncmp(str, prefix, strlen(prefix));
399 static inline int strtoul_ui(char const *s, int base, unsigned int *result)
401 unsigned long ul;
402 char *p;
404 errno = 0;
405 ul = strtoul(s, &p, base);
406 if (errno || *p || p == s || (unsigned int) ul != ul)
407 return -1;
408 *result = ul;
409 return 0;
412 static inline int strtol_i(char const *s, int base, int *result)
414 long ul;
415 char *p;
417 errno = 0;
418 ul = strtol(s, &p, base);
419 if (errno || *p || p == s || (int) ul != ul)
420 return -1;
421 *result = ul;
422 return 0;
425 #ifdef __MINGW32__
427 #include <winsock2.h>
429 #define S_IFLNK 0120000 /* Symbolic link */
430 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
431 #define S_ISSOCK(x) 0
432 #define S_IRGRP 0
433 #define S_IWGRP 0
434 #define S_IXGRP 0
435 #define S_ISGID 0
436 #define S_IROTH 0
437 #define S_IXOTH 0
439 static inline int readlink(const char *path, char *buf, size_t bufsiz)
440 { errno = ENOSYS; return -1; }
441 static inline int symlink(const char *oldpath, const char *newpath)
442 { errno = ENOSYS; return -1; }
443 static inline int link(const char *oldpath, const char *newpath)
444 { errno = ENOSYS; return -1; }
445 static inline int fchmod(int fildes, mode_t mode)
446 { errno = ENOSYS; return -1; }
447 static inline int fork(void)
448 { errno = ENOSYS; return -1; }
449 static inline int kill(pid_t pid, int sig)
450 { errno = ENOSYS; return -1; }
451 static inline unsigned int alarm(unsigned int seconds)
452 { return 0; }
454 void mingw_execve(const char *cmd, const char **argv, const char **env);
455 #define execve mingw_execve
456 extern void mingw_execvp(const char *cmd, const char **argv);
457 #define execvp mingw_execvp
458 typedef int pid_t;
459 static inline int waitpid(pid_t pid, unsigned *status, unsigned options)
461 if (options == 0)
462 return _cwait(status, pid, 0);
463 else
464 return errno = EINVAL, -1;
467 #define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
468 #define WEXITSTATUS(x) ((x) & 0xff)
469 #define WIFSIGNALED(x) ((unsigned)(x) > 259)
470 #define WTERMSIG(x) (x)
471 #define WNOHANG 1
472 #define SIGKILL 0
473 #define SIGCHLD 0
474 #define SIGPIPE 0
476 char **copy_environ();
477 char **copy_env(char **env);
478 void env_unsetenv(char **env, const char *name);
480 unsigned int sleep (unsigned int __seconds);
481 const char *inet_ntop(int af, const void *src,
482 char *dst, size_t cnt);
483 int gettimeofday(struct timeval *tv, void *tz);
484 int pipe(int filedes[2]);
486 struct pollfd {
487 int fd; /* file descriptor */
488 short events; /* requested events */
489 short revents; /* returned events */
491 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
492 #define POLLIN 1
493 #define POLLHUP 2
495 static inline int git_mkdir(const char *path, int mode)
497 return mkdir(path);
499 #define mkdir git_mkdir
501 static inline int git_unlink(const char *pathname) {
502 /* read-only files cannot be removed */
503 chmod(pathname, 0666);
504 return unlink(pathname);
506 #define unlink git_unlink
508 int mingw_open (const char *filename, int oflags, ...);
509 #define open mingw_open
511 #include <time.h>
512 struct tm *gmtime_r(const time_t *timep, struct tm *result);
513 struct tm *localtime_r(const time_t *timep, struct tm *result);
514 #define hstrerror strerror
516 char *mingw_getcwd(char *pointer, int len);
517 #define getcwd mingw_getcwd
519 int mingw_socket(int domain, int type, int protocol);
520 #define socket mingw_socket
522 int mingw_rename(const char*, const char*);
523 #define rename mingw_rename
525 static inline int fsync(int fd) { return 0; }
526 static inline int getppid(void) { return 1; }
527 static inline void sync(void) {}
528 extern int getpagesize(void); /* defined in MinGW's libgcc.a */
530 extern void quote_argv(const char **dst, const char **src);
531 extern const char *parse_interpreter(const char *cmd);
532 extern char *mingw_path_lookup(const char *cmd, char **path);
533 extern char **mingw_get_path_split(void);
534 extern void mingw_free_path_split(char **path);
536 /* Use mingw_lstat() instead of lstat()/stat() and
537 * mingw_fstat() instead of fstat() on Windows.
538 * struct stat is redefined because it lacks the st_blocks member.
540 struct mingw_stat {
541 unsigned st_mode;
542 time_t st_mtime, st_atime, st_ctime;
543 unsigned st_dev, st_ino, st_uid, st_gid;
544 size_t st_size;
545 size_t st_blocks;
547 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
548 int mingw_fstat(int fd, struct mingw_stat *buf);
549 #define fstat mingw_fstat
550 #define lstat mingw_lstat
551 #define stat mingw_stat
552 static inline int mingw_stat(const char *file_name, struct mingw_stat *buf)
553 { return mingw_lstat(file_name, buf); }
555 int mingw_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
556 #define vsnprintf mingw_vsnprintf
558 struct passwd {
559 char *pw_name;
560 char *pw_gecos;
561 char *pw_dir;
563 struct passwd *mingw_getpwuid(int uid);
564 #define getpwuid mingw_getpwuid
565 static inline int getuid() { return 1; }
566 static inline struct passwd *getpwnam(const char *name) { return NULL; }
568 struct itimerval {
569 struct timeval it_value, it_interval;
571 int setitimer(int type, struct itimerval *in, struct itimerval *out);
572 #define ITIMER_REAL 0
574 typedef void (__cdecl *sig_handler_t)(int);
575 struct sigaction {
576 sig_handler_t sa_handler;
577 unsigned sa_flags;
579 int sigaction(int sig, struct sigaction *in, struct sigaction *out);
580 #define sigemptyset(x) (void)0
581 #define SA_RESTART 0
582 #define SIGALRM 100
583 sig_handler_t mingw_signal(int sig, sig_handler_t handler);
584 #define signal mingw_signal
586 #define F_GETFD 1
587 #define F_SETFD 2
588 #define FD_CLOEXEC 0x1
589 static inline int mingw_fcntl(int fd, int cmd, long arg)
590 { return cmd == F_GETFD || cmd == F_SETFD ? 0 : (errno = EINVAL, -1); }
591 #define fcntl mingw_fcntl
593 #endif /* __MINGW32__ */
595 #endif