Raw
1 #ifndef COMPAT_POSIX_H
2 #define COMPAT_POSIX_H
3
4 #define _FILE_OFFSET_BITS 64
5
6 /*
7 * Convenience macros to test the versions of GCC (or a compatible compiler).
8 * Use them like this:
9 * #if GIT_GNUC_PREREQ (2,8)
10 * ... code requiring GCC 2.8 or later ...
11 * #endif
12 *
13 * Note that Clang and other compilers define __GNUC__ for compatibility; use
14 * GIT_CLANG_PREREQ() to check for specific Clang versions.
15 *
16 * This macro of course is not part of POSIX, but we need it for the UNUSED
17 * macro which is used by some of our POSIX compatibility wrappers.
18 */
19 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
20 # define GIT_GNUC_PREREQ(maj, min) \
21 ((__GNUC__ > (maj)) || \
22 (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min)))
23 #else
24 # define GIT_GNUC_PREREQ(maj, min) 0
25 #endif
26
27 /* Similar for Clang. */
28 #if defined(__clang__) && defined(__clang_minor__) && defined(__clang_major__)
29 # define GIT_CLANG_PREREQ(maj, min) \
30 ((__clang_major__ > (maj)) || \
31 (__clang_major__ == (maj) && __clang_minor__ >= (min)))
32 #else
33 # define GIT_CLANG_PREREQ(maj, min) 0
34 #endif
35
36 /*
37 * UNUSED marks a function parameter that is always unused. It also
38 * can be used to annotate a function, a variable, or a type that is
39 * always unused.
40 *
41 * A callback interface may dictate that a function accepts a
42 * parameter at that position, but the implementation of the function
43 * may not need to use the parameter. In such a case, mark the parameter
44 * with UNUSED.
45 *
46 * When a parameter may be used or unused, depending on conditional
47 * compilation, consider using MAYBE_UNUSED instead.
48 */
49 #if GIT_GNUC_PREREQ(4, 5) || GIT_CLANG_PREREQ(2, 9)
50 # define UNUSED __attribute__((unused)) \
51 __attribute__((deprecated("parameter declared as UNUSED")))
52 #elif defined(__GNUC__)
53 # define UNUSED __attribute__((unused)) \
54 __attribute__((deprecated))
55 #else
56 # define UNUSED
57 #endif
58
59 #if defined(__MINGW32__) || defined(__MINGW64__)
60 #define _POSIX_C_SOURCE 1
61 #elif defined(__sun__)
62 /*
63 * On Solaris, when _XOPEN_EXTENDED is set, its header file
64 * forces the programs to be XPG4v2, defeating any _XOPEN_SOURCE
65 * setting to say we are XPG5 or XPG6. Also on Solaris,
66 * XPG6 programs must be compiled with a c99 compiler, while
67 * non XPG6 programs must be compiled with a pre-c99 compiler.
68 */
69 # if __STDC_VERSION__ - 0 >= 199901L
70 # define _XOPEN_SOURCE 600
71 # else
72 # define _XOPEN_SOURCE 500
73 # endif
74 #elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
75 !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__MirBSD__) && \
76 !defined(__USLC__) && !defined(_M_UNIX) && !defined(__sgi) && \
77 !defined(__TANDEM) && !defined(__QNX__) && !defined(__CYGWIN__)
78 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500 */
79 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
80 #endif
81 #define _ALL_SOURCE 1
82 #define _GNU_SOURCE 1
83 #define _BSD_SOURCE 1
84 #define _DEFAULT_SOURCE 1
85 #define _NETBSD_SOURCE 1
86 #define _SGI_SOURCE 1
87
88 #if defined(WIN32) && !defined(__CYGWIN__) /* Both MinGW and MSVC */
89 # if !defined(_WIN32_WINNT)
90 # define _WIN32_WINNT 0x0603
91 # endif
92 #define WIN32_LEAN_AND_MEAN /* stops windows.h including winsock.h */
93 #include <winsock2.h>
94 #ifndef NO_UNIX_SOCKETS
95 #include <afunix.h>
96 #endif
97 #include <windows.h>
98 #define GIT_WINDOWS_NATIVE
99 #endif
100
101 #include <unistd.h>
102 #include <stdio.h>
103 #include <sys/stat.h>
104 #include <fcntl.h>
105 #include <stddef.h>
106 #include <stdlib.h>
107 #include <stdarg.h>
108 #include <stdbool.h>
109 #include <string.h>
110 #ifdef HAVE_STRINGS_H
111 #include <strings.h> /* for strcasecmp() */
112 #endif
113 #include <errno.h>
114 #include <limits.h>
115 #include <locale.h>
116 #ifdef NEEDS_SYS_PARAM_H
117 #include <sys/param.h>
118 #endif
119 #include <sys/types.h>
120 #include <dirent.h>
121 #include <sys/time.h>
122 #include <time.h>
123 #include <signal.h>
124 #include <assert.h>
125 #include <regex.h>
126 #include <utime.h>
127 #include <syslog.h>
128 #if !defined(NO_POLL_H)
129 #include <poll.h>
130 #elif !defined(NO_SYS_POLL_H)
131 #include <sys/poll.h>
132 #else
133 /* Pull the compat stuff */
134 #include <poll.h>
135 #endif
136 #ifdef HAVE_BSD_SYSCTL
137 #include <sys/sysctl.h>
138 #endif
139
140 #if defined(__MINGW32__)
141 #include "mingw-posix.h"
142 #elif defined(_MSC_VER)
143 #include "msvc-posix.h"
144 #else
145 #include <sys/utsname.h>
146 #include <sys/wait.h>
147 #include <sys/resource.h>
148 #include <sys/socket.h>
149 #include <sys/ioctl.h>
150 #include <sys/statvfs.h>
151 #ifndef NO_WRITEV
152 #include <sys/uio.h>
153 #endif
154 #include <termios.h>
155 #ifndef NO_SYS_SELECT_H
156 #include <sys/select.h>
157 #endif
158 #include <netinet/in.h>
159 #include <netinet/tcp.h>
160 #include <arpa/inet.h>
161 #include <netdb.h>
162 #include <pwd.h>
163 #include <sys/un.h>
164 #ifndef NO_INTTYPES_H
165 #include <inttypes.h>
166 #else
167 #include <stdint.h>
168 #endif
169 #ifdef HAVE_ARC4RANDOM_LIBBSD
170 #include <bsd/stdlib.h>
171 #endif
172 #ifdef HAVE_GETRANDOM
173 #include <sys/random.h>
174 #endif
175 #ifdef NO_INTPTR_T
176 /*
177 * On I16LP32, ILP32 and LP64 "long" is the safe bet, however
178 * on LLP86, IL33LLP64 and P64 it needs to be "long long",
179 * while on IP16 and IP16L32 it is "int" (resp. "short")
180 * Size needs to match (or exceed) 'sizeof(void *)'.
181 * We can't take "long long" here as not everybody has it.
182 */
183 typedef long intptr_t;
184 typedef unsigned long uintptr_t;
185 #endif
186 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
187 #include <grp.h>
188 #define _ALL_SOURCE 1
189 #endif
190
191 #ifdef MKDIR_WO_TRAILING_SLASH
192 #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
193 int compat_mkdir_wo_trailing_slash(const char*, mode_t);
194 #endif
195
196 #ifdef time
197 #undef time
198 #endif
199 static inline time_t git_time(time_t *tloc)
200 {
201 struct timeval tv;
202
203 /*
204 * Avoid time(NULL), which can disagree with gettimeofday(2)
205 * and filesystem timestamps.
206 */
207 gettimeofday(&tv, NULL);
208
209 if (tloc)
210 *tloc = tv.tv_sec;
211 return tv.tv_sec;
212 }
213 #define time git_time
214
215 #ifdef NO_STRUCT_ITIMERVAL
216 struct itimerval {
217 struct timeval it_interval;
218 struct timeval it_value;
219 };
220 #endif
221
222 #ifdef NO_SETITIMER
223 static inline int git_setitimer(int which UNUSED,
224 const struct itimerval *value UNUSED,
225 struct itimerval *newvalue UNUSED) {
226 return 0; /* pretend success */
227 }
228 #undef setitimer
229 #define setitimer(which,value,ovalue) git_setitimer(which,value,ovalue)
230 #endif
231
232 #ifndef NO_LIBGEN_H
233 #include <libgen.h>
234 #else
235 #define basename gitbasename
236 char *gitbasename(char *);
237 #define dirname gitdirname
238 char *gitdirname(char *);
239 #endif
240
241 #ifndef NO_ICONV
242 #include <iconv.h>
243 #endif
244
245 /* On most systems <netdb.h> would have given us this, but
246 * not on some systems (e.g. z/OS).
247 */
248 #ifndef NI_MAXHOST
249 #define NI_MAXHOST 1025
250 #endif
251
252 #ifndef NI_MAXSERV
253 #define NI_MAXSERV 32
254 #endif
255
256 /* On most systems <limits.h> would have given us this, but
257 * not on some systems (e.g. GNU/Hurd).
258 */
259 #ifndef PATH_MAX
260 #define PATH_MAX 4096
261 #endif
262
263 #ifndef NAME_MAX
264 #define NAME_MAX 255
265 #endif
266
267 typedef uintmax_t timestamp_t;
268 #define PRItime PRIuMAX
269 #define parse_timestamp strtoumax
270 #define TIME_MAX UINTMAX_MAX
271 #define TIME_MIN 0
272
273 int lstat_cache_aware_rmdir(const char *path);
274 #if !defined(__MINGW32__) && !defined(_MSC_VER)
275 #define rmdir lstat_cache_aware_rmdir
276 #endif
277
278 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
279
280 #ifndef PROT_READ
281 #define PROT_READ 1
282 #define PROT_WRITE 2
283 #define MAP_PRIVATE 1
284 #endif
285
286 #define mmap git_mmap
287 #define munmap git_munmap
288 void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
289 int git_munmap(void *start, size_t length);
290
291 #else /* NO_MMAP || USE_WIN32_MMAP */
292
293 #include <sys/mman.h>
294
295 #endif /* NO_MMAP || USE_WIN32_MMAP */
296
297 #ifndef MAP_FAILED
298 #define MAP_FAILED ((void *)-1)
299 #endif
300
301 #ifdef NEEDS_MODE_TRANSLATION
302 #undef S_IFMT
303 #undef S_IFREG
304 #undef S_IFDIR
305 #undef S_IFLNK
306 #undef S_IFBLK
307 #undef S_IFCHR
308 #undef S_IFIFO
309 #undef S_IFSOCK
310 #define S_IFMT 0170000
311 #define S_IFREG 0100000
312 #define S_IFDIR 0040000
313 #define S_IFLNK 0120000
314 #define S_IFBLK 0060000
315 #define S_IFCHR 0020000
316 #define S_IFIFO 0010000
317 #define S_IFSOCK 0140000
318 #ifdef stat
319 #undef stat
320 #endif
321 #define stat(path, buf) git_stat(path, buf)
322 int git_stat(const char *, struct stat *);
323 #ifdef fstat
324 #undef fstat
325 #endif
326 #define fstat(fd, buf) git_fstat(fd, buf)
327 int git_fstat(int, struct stat *);
328 #ifdef lstat
329 #undef lstat
330 #endif
331 #define lstat(path, buf) git_lstat(path, buf)
332 int git_lstat(const char *, struct stat *);
333 #endif
334
335 #ifdef NO_PREAD
336 #define pread git_pread
337 ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
338 #endif
339
340 #ifdef NO_WRITEV
341 #define writev git_writev
342 #define iovec git_iovec
343 struct git_iovec {
344 void *iov_base;
345 size_t iov_len;
346 };
347
348 ssize_t git_writev(int fd, const struct iovec *iov, int iovcnt);
349 #endif
350
351 #ifdef NO_SETENV
352 #define setenv gitsetenv
353 int gitsetenv(const char *, const char *, int);
354 #endif
355
356 #ifdef NO_MKDTEMP
357 #define mkdtemp git_mkdtemp
358 #endif
359
360 #ifdef NO_UNSETENV
361 #define unsetenv gitunsetenv
362 int gitunsetenv(const char *);
363 #endif
364
365 #ifdef NO_STRCASESTR
366 #define strcasestr gitstrcasestr
367 char *gitstrcasestr(const char *haystack, const char *needle);
368 #endif
369
370 #ifdef NO_STRLCPY
371 #define strlcpy gitstrlcpy
372 size_t gitstrlcpy(char *, const char *, size_t);
373 #endif
374
375 #ifdef NO_STRTOUMAX
376 #define strtoumax gitstrtoumax
377 uintmax_t gitstrtoumax(const char *, char **, int);
378 #define strtoimax gitstrtoimax
379 intmax_t gitstrtoimax(const char *, char **, int);
380 #endif
381
382 #ifdef NO_HSTRERROR
383 #define hstrerror githstrerror
384 const char *githstrerror(int herror);
385 #endif
386
387 #ifdef NO_MEMMEM
388 #define memmem gitmemmem
389 void *gitmemmem(const void *haystack, size_t haystacklen,
390 const void *needle, size_t needlelen);
391 #endif
392
393 #ifdef OVERRIDE_STRDUP
394 #ifdef strdup
395 #undef strdup
396 #endif
397 #define strdup gitstrdup
398 char *gitstrdup(const char *s);
399 #endif
400
401 #ifdef NO_GETPAGESIZE
402 #define getpagesize() sysconf(_SC_PAGESIZE)
403 #endif
404
405 #ifndef O_CLOEXEC
406 #define O_CLOEXEC 0
407 #endif
408
409 #ifdef FREAD_READS_DIRECTORIES
410 # if !defined(SUPPRESS_FOPEN_REDEFINITION)
411 # ifdef fopen
412 # undef fopen
413 # endif
414 # define fopen(a,b) git_fopen(a,b)
415 # endif
416 FILE *git_fopen(const char*, const char*);
417 #endif
418
419 #ifdef SNPRINTF_RETURNS_BOGUS
420 #ifdef snprintf
421 #undef snprintf
422 #endif
423 #define snprintf git_snprintf
424 int git_snprintf(char *str, size_t maxsize,
425 const char *format, ...);
426 #ifdef vsnprintf
427 #undef vsnprintf
428 #endif
429 #define vsnprintf git_vsnprintf
430 int git_vsnprintf(char *str, size_t maxsize,
431 const char *format, va_list ap);
432 #endif
433
434 #ifdef OPEN_RETURNS_EINTR
435 #undef open
436 #define open git_open_with_retry
437 int git_open_with_retry(const char *path, int flag, ...);
438 #endif
439
440 #ifdef __GLIBC_PREREQ
441 #if __GLIBC_PREREQ(2, 1)
442 #define HAVE_STRCHRNUL
443 #endif
444 #endif
445
446 #ifndef HAVE_STRCHRNUL
447 #define strchrnul gitstrchrnul
448 static inline char *gitstrchrnul(const char *s, int c)
449 {
450 while (*s && *s != c)
451 s++;
452 return (char *)s;
453 }
454 #endif
455
456 #ifdef NO_INET_PTON
457 int inet_pton(int af, const char *src, void *dst);
458 #endif
459
460 #ifdef NO_INET_NTOP
461 const char *inet_ntop(int af, const void *src, char *dst, size_t size);
462 #endif
463
464 #ifdef NO_PTHREADS
465 #define atexit git_atexit
466 int git_atexit(void (*handler)(void));
467 #endif
468
469 #ifndef HOST_NAME_MAX
470 #define HOST_NAME_MAX 256
471 #endif
472
473 #include "../sane-ctype.h"
474
475 void git_stable_qsort(void *base, size_t nmemb, size_t size,
476 int(*compar)(const void *, const void *));
477 #ifdef INTERNAL_QSORT
478 #define qsort git_stable_qsort
479 #endif
480
481 #define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)
482 static inline void sane_qsort(void *base, size_t nmemb, size_t size,
483 int(*compar)(const void *, const void *))
484 {
485 if (nmemb > 1)
486 qsort(base, nmemb, size, compar);
487 }
488
489 #define STABLE_QSORT(base, n, compar) \
490 git_stable_qsort((base), (n), sizeof(*(base)), compar)
491
492 #ifndef HAVE_ISO_QSORT_S
493 int git_qsort_s(void *base, size_t nmemb, size_t size,
494 int (*compar)(const void *, const void *, void *), void *ctx);
495 #define qsort_s git_qsort_s
496 #endif
497
498 #define QSORT_S(base, n, compar, ctx) do { \
499 if (qsort_s((base), (n), sizeof(*(base)), compar, ctx)) \
500 BUG("qsort_s() failed"); \
501 } while (0)
502
503 #ifdef NO_NSEC
504 #undef USE_NSEC
505 #define ST_CTIME_NSEC(st) 0
506 #define ST_MTIME_NSEC(st) 0
507 #else
508 #ifdef USE_ST_TIMESPEC
509 #define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
510 #define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
511 #else
512 #define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
513 #define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
514 #endif
515 #endif
516
517 #ifndef va_copy
518 /*
519 * Since an obvious implementation of va_list would be to make it a
520 * pointer into the stack frame, a simple assignment will work on
521 * many systems. But let's try to be more portable.
522 */
523 #ifdef __va_copy
524 #define va_copy(dst, src) __va_copy(dst, src)
525 #else
526 #define va_copy(dst, src) ((dst) = (src))
527 #endif
528 #endif
529
530 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
531 static inline void git_flockfile(FILE *fh UNUSED)
532 {
533 ; /* nothing */
534 }
535 static inline void git_funlockfile(FILE *fh UNUSED)
536 {
537 ; /* nothing */
538 }
539 #undef flockfile
540 #undef funlockfile
541 #undef getc_unlocked
542 #define flockfile(fh) git_flockfile(fh)
543 #define funlockfile(fh) git_funlockfile(fh)
544 #define getc_unlocked(fh) getc(fh)
545 #endif
546
547 #ifdef FILENO_IS_A_MACRO
548 int git_fileno(FILE *stream);
549 # ifndef COMPAT_CODE_FILENO
550 # undef fileno
551 # define fileno(p) git_fileno(p)
552 # endif
553 #endif
554
555 #ifdef NEED_ACCESS_ROOT_HANDLER
556 int git_access(const char *path, int mode);
557 # ifndef COMPAT_CODE_ACCESS
558 # ifdef access
559 # undef access
560 # endif
561 # define access(path, mode) git_access(path, mode)
562 # endif
563 #endif
564
565 #endif /* COMPAT_POSIX_H */