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 #ifdef __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 #include <termios.h>
152 #ifndef NO_SYS_SELECT_H
153 #include <sys/select.h>
154 #endif
155 #include <netinet/in.h>
156 #include <netinet/tcp.h>
157 #include <arpa/inet.h>
158 #include <netdb.h>
159 #include <pwd.h>
160 #include <sys/un.h>
161 #ifndef NO_INTTYPES_H
162 #include <inttypes.h>
163 #else
164 #include <stdint.h>
165 #endif
166 #ifdef HAVE_ARC4RANDOM_LIBBSD
167 #include <bsd/stdlib.h>
168 #endif
169 #ifdef HAVE_GETRANDOM
170 #include <sys/random.h>
171 #endif
172 #ifdef NO_INTPTR_T
173 /*
174 * On I16LP32, ILP32 and LP64 "long" is the safe bet, however
175 * on LLP86, IL33LLP64 and P64 it needs to be "long long",
176 * while on IP16 and IP16L32 it is "int" (resp. "short")
177 * Size needs to match (or exceed) 'sizeof(void *)'.
178 * We can't take "long long" here as not everybody has it.
179 */
180 typedef long intptr_t;
181 typedef unsigned long uintptr_t;
182 #endif
183 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
184 #include <grp.h>
185 #define _ALL_SOURCE 1
186 #endif
187
188 #ifdef MKDIR_WO_TRAILING_SLASH
189 #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
190 int compat_mkdir_wo_trailing_slash(const char*, mode_t);
191 #endif
192
193 #ifdef time
194 #undef time
195 #endif
196 static inline time_t git_time(time_t *tloc)
197 {
198 struct timeval tv;
199
200 /*
201 * Avoid time(NULL), which can disagree with gettimeofday(2)
202 * and filesystem timestamps.
203 */
204 gettimeofday(&tv, NULL);
205
206 if (tloc)
207 *tloc = tv.tv_sec;
208 return tv.tv_sec;
209 }
210 #define time git_time
211
212 #ifdef NO_STRUCT_ITIMERVAL
213 struct itimerval {
214 struct timeval it_interval;
215 struct timeval it_value;
216 };
217 #endif
218
219 #ifdef NO_SETITIMER
220 static inline int git_setitimer(int which UNUSED,
221 const struct itimerval *value UNUSED,
222 struct itimerval *newvalue UNUSED) {
223 return 0; /* pretend success */
224 }
225 #undef setitimer
226 #define setitimer(which,value,ovalue) git_setitimer(which,value,ovalue)
227 #endif
228
229 #ifndef NO_LIBGEN_H
230 #include <libgen.h>
231 #else
232 #define basename gitbasename
233 char *gitbasename(char *);
234 #define dirname gitdirname
235 char *gitdirname(char *);
236 #endif
237
238 #ifndef NO_ICONV
239 #include <iconv.h>
240 #endif
241
242 /* On most systems <netdb.h> would have given us this, but
243 * not on some systems (e.g. z/OS).
244 */
245 #ifndef NI_MAXHOST
246 #define NI_MAXHOST 1025
247 #endif
248
249 #ifndef NI_MAXSERV
250 #define NI_MAXSERV 32
251 #endif
252
253 /* On most systems <limits.h> would have given us this, but
254 * not on some systems (e.g. GNU/Hurd).
255 */
256 #ifndef PATH_MAX
257 #define PATH_MAX 4096
258 #endif
259
260 #ifndef NAME_MAX
261 #define NAME_MAX 255
262 #endif
263
264 typedef uintmax_t timestamp_t;
265 #define PRItime PRIuMAX
266 #define parse_timestamp strtoumax
267 #define TIME_MAX UINTMAX_MAX
268 #define TIME_MIN 0
269
270 int lstat_cache_aware_rmdir(const char *path);
271 #if !defined(__MINGW32__) && !defined(_MSC_VER)
272 #define rmdir lstat_cache_aware_rmdir
273 #endif
274
275 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
276
277 #ifndef PROT_READ
278 #define PROT_READ 1
279 #define PROT_WRITE 2
280 #define MAP_PRIVATE 1
281 #endif
282
283 #define mmap git_mmap
284 #define munmap git_munmap
285 void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
286 int git_munmap(void *start, size_t length);
287
288 #else /* NO_MMAP || USE_WIN32_MMAP */
289
290 #include <sys/mman.h>
291
292 #endif /* NO_MMAP || USE_WIN32_MMAP */
293
294 #ifndef MAP_FAILED
295 #define MAP_FAILED ((void *)-1)
296 #endif
297
298 #ifdef NEEDS_MODE_TRANSLATION
299 #undef S_IFMT
300 #undef S_IFREG
301 #undef S_IFDIR
302 #undef S_IFLNK
303 #undef S_IFBLK
304 #undef S_IFCHR
305 #undef S_IFIFO
306 #undef S_IFSOCK
307 #define S_IFMT 0170000
308 #define S_IFREG 0100000
309 #define S_IFDIR 0040000
310 #define S_IFLNK 0120000
311 #define S_IFBLK 0060000
312 #define S_IFCHR 0020000
313 #define S_IFIFO 0010000
314 #define S_IFSOCK 0140000
315 #ifdef stat
316 #undef stat
317 #endif
318 #define stat(path, buf) git_stat(path, buf)
319 int git_stat(const char *, struct stat *);
320 #ifdef fstat
321 #undef fstat
322 #endif
323 #define fstat(fd, buf) git_fstat(fd, buf)
324 int git_fstat(int, struct stat *);
325 #ifdef lstat
326 #undef lstat
327 #endif
328 #define lstat(path, buf) git_lstat(path, buf)
329 int git_lstat(const char *, struct stat *);
330 #endif
331
332 #ifdef NO_PREAD
333 #define pread git_pread
334 ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
335 #endif
336
337 #ifdef NO_SETENV
338 #define setenv gitsetenv
339 int gitsetenv(const char *, const char *, int);
340 #endif
341
342 #ifdef NO_MKDTEMP
343 #define mkdtemp git_mkdtemp
344 #endif
345
346 #ifdef NO_UNSETENV
347 #define unsetenv gitunsetenv
348 int gitunsetenv(const char *);
349 #endif
350
351 #ifdef NO_STRCASESTR
352 #define strcasestr gitstrcasestr
353 char *gitstrcasestr(const char *haystack, const char *needle);
354 #endif
355
356 #ifdef NO_STRLCPY
357 #define strlcpy gitstrlcpy
358 size_t gitstrlcpy(char *, const char *, size_t);
359 #endif
360
361 #ifdef NO_STRTOUMAX
362 #define strtoumax gitstrtoumax
363 uintmax_t gitstrtoumax(const char *, char **, int);
364 #define strtoimax gitstrtoimax
365 intmax_t gitstrtoimax(const char *, char **, int);
366 #endif
367
368 #ifdef NO_HSTRERROR
369 #define hstrerror githstrerror
370 const char *githstrerror(int herror);
371 #endif
372
373 #ifdef NO_MEMMEM
374 #define memmem gitmemmem
375 void *gitmemmem(const void *haystack, size_t haystacklen,
376 const void *needle, size_t needlelen);
377 #endif
378
379 #ifdef OVERRIDE_STRDUP
380 #ifdef strdup
381 #undef strdup
382 #endif
383 #define strdup gitstrdup
384 char *gitstrdup(const char *s);
385 #endif
386
387 #ifdef NO_GETPAGESIZE
388 #define getpagesize() sysconf(_SC_PAGESIZE)
389 #endif
390
391 #ifndef O_CLOEXEC
392 #define O_CLOEXEC 0
393 #endif
394
395 #ifdef FREAD_READS_DIRECTORIES
396 # if !defined(SUPPRESS_FOPEN_REDEFINITION)
397 # ifdef fopen
398 # undef fopen
399 # endif
400 # define fopen(a,b) git_fopen(a,b)
401 # endif
402 FILE *git_fopen(const char*, const char*);
403 #endif
404
405 #ifdef SNPRINTF_RETURNS_BOGUS
406 #ifdef snprintf
407 #undef snprintf
408 #endif
409 #define snprintf git_snprintf
410 int git_snprintf(char *str, size_t maxsize,
411 const char *format, ...);
412 #ifdef vsnprintf
413 #undef vsnprintf
414 #endif
415 #define vsnprintf git_vsnprintf
416 int git_vsnprintf(char *str, size_t maxsize,
417 const char *format, va_list ap);
418 #endif
419
420 #ifdef OPEN_RETURNS_EINTR
421 #undef open
422 #define open git_open_with_retry
423 int git_open_with_retry(const char *path, int flag, ...);
424 #endif
425
426 #ifdef __GLIBC_PREREQ
427 #if __GLIBC_PREREQ(2, 1)
428 #define HAVE_STRCHRNUL
429 #endif
430 #endif
431
432 #ifndef HAVE_STRCHRNUL
433 #define strchrnul gitstrchrnul
434 static inline char *gitstrchrnul(const char *s, int c)
435 {
436 while (*s && *s != c)
437 s++;
438 return (char *)s;
439 }
440 #endif
441
442 #ifdef NO_INET_PTON
443 int inet_pton(int af, const char *src, void *dst);
444 #endif
445
446 #ifdef NO_INET_NTOP
447 const char *inet_ntop(int af, const void *src, char *dst, size_t size);
448 #endif
449
450 #ifdef NO_PTHREADS
451 #define atexit git_atexit
452 int git_atexit(void (*handler)(void));
453 #endif
454
455 #ifndef HOST_NAME_MAX
456 #define HOST_NAME_MAX 256
457 #endif
458
459 #include "../sane-ctype.h"
460
461 void git_stable_qsort(void *base, size_t nmemb, size_t size,
462 int(*compar)(const void *, const void *));
463 #ifdef INTERNAL_QSORT
464 #define qsort git_stable_qsort
465 #endif
466
467 #define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)
468 static inline void sane_qsort(void *base, size_t nmemb, size_t size,
469 int(*compar)(const void *, const void *))
470 {
471 if (nmemb > 1)
472 qsort(base, nmemb, size, compar);
473 }
474
475 #define STABLE_QSORT(base, n, compar) \
476 git_stable_qsort((base), (n), sizeof(*(base)), compar)
477
478 #ifndef HAVE_ISO_QSORT_S
479 int git_qsort_s(void *base, size_t nmemb, size_t size,
480 int (*compar)(const void *, const void *, void *), void *ctx);
481 #define qsort_s git_qsort_s
482 #endif
483
484 #define QSORT_S(base, n, compar, ctx) do { \
485 if (qsort_s((base), (n), sizeof(*(base)), compar, ctx)) \
486 BUG("qsort_s() failed"); \
487 } while (0)
488
489 #ifdef NO_NSEC
490 #undef USE_NSEC
491 #define ST_CTIME_NSEC(st) 0
492 #define ST_MTIME_NSEC(st) 0
493 #else
494 #ifdef USE_ST_TIMESPEC
495 #define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
496 #define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
497 #else
498 #define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
499 #define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
500 #endif
501 #endif
502
503 #ifndef va_copy
504 /*
505 * Since an obvious implementation of va_list would be to make it a
506 * pointer into the stack frame, a simple assignment will work on
507 * many systems. But let's try to be more portable.
508 */
509 #ifdef __va_copy
510 #define va_copy(dst, src) __va_copy(dst, src)
511 #else
512 #define va_copy(dst, src) ((dst) = (src))
513 #endif
514 #endif
515
516 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
517 static inline void git_flockfile(FILE *fh UNUSED)
518 {
519 ; /* nothing */
520 }
521 static inline void git_funlockfile(FILE *fh UNUSED)
522 {
523 ; /* nothing */
524 }
525 #undef flockfile
526 #undef funlockfile
527 #undef getc_unlocked
528 #define flockfile(fh) git_flockfile(fh)
529 #define funlockfile(fh) git_funlockfile(fh)
530 #define getc_unlocked(fh) getc(fh)
531 #endif
532
533 #ifdef FILENO_IS_A_MACRO
534 int git_fileno(FILE *stream);
535 # ifndef COMPAT_CODE_FILENO
536 # undef fileno
537 # define fileno(p) git_fileno(p)
538 # endif
539 #endif
540
541 #ifdef NEED_ACCESS_ROOT_HANDLER
542 int git_access(const char *path, int mode);
543 # ifndef COMPAT_CODE_ACCESS
544 # ifdef access
545 # undef access
546 # endif
547 # define access(path, mode) git_access(path, mode)
548 # endif
549 #endif
550
551 #endif /* COMPAT_POSIX_H */