Attempt to create .deps directory every time we build objects.
[doas.git] / compat.h
blob5716bebf86e301e70f94f41144c8bc5cc7661386
1 /*
2 * Copyright (c) 2021-2022 Sergey Sushilin <sergeysushilin@protonmail.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef _COMPAT_H
18 #define _COMPAT_H 1
20 #include <stdarg.h>
21 #include <sys/types.h>
23 #include "attributes.h"
25 #if !defined(va_copy)
26 # if defined(__va_copy)
27 # define va_copy(d, s) __va_copy(d, s)
28 # else
29 # define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
30 # endif
31 #endif /* !defined(va_copy) */
33 #if !defined(GLOBAL_PATH)
34 # define GLOBAL_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
35 #endif
37 #if !defined(UID_MAX)
38 # define UID_MAX 65535
39 #endif /* UID_MAX */
40 #if !defined(GID_MAX)
41 # define GID_MAX 65535
42 #endif /* GID_MAX */
44 #if !defined(ROOT_UID)
45 # if defined(__TANDEM)
46 # define ROOT_UID 65535
47 # else
48 # define ROOT_UID 0
49 # endif
50 #endif /* ROOT_UID */
52 #if !defined(PATH_MAX)
53 # if defined(MAX_PATH)
54 # define PATH_MAX MAX_PATH
55 # elif defined(MAXPATHLEN)
56 # define PATH_MAX MAXPATHLEN
57 # else
58 # define PATH_MAX 4096
59 # endif
60 #endif /* PATH_MAX */
62 #if !defined(NGROUPS_MAX)
63 # define NGROUPS_MAX 65535
64 #endif /* NGROUPS_MAX */
66 #if !defined(LINE_MAX)
67 # define LINE_MAX 4096
68 #endif /* LINE_MAX */
70 #if !defined(_PW_NAME_LEN)
71 # define _PW_NAME_LEN 32
72 #endif /* _PW_NAME_LEN */
74 #if !defined(SAFE_PATH)
75 # define SAFE_PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
76 #endif /* SAFE_PATH */
78 #if __STDC_VERSION__ >= 199901L
79 # include <stdbool.h>
80 #else
81 # undef _Bool
82 # undef bool
83 # undef true
84 # undef false
85 /* For the sake of symbolic names in gdb, define true and false as
86 enum constants, not only as macros.
87 It is tempting to write
88 typedef enum { false = 0, true = 1 } _Bool;
89 so that gdb prints values of type 'bool' symbolically. */
90 typedef enum { _False = 0, _True = 1 } __bool;
91 # define _Bool __bool
92 # define bool _Bool
93 # define true _True
94 # define false _False
95 #endif /* __STDC_VERSION__ >= 199901L */
97 #if __STDC_VERSION__ < 199901L
98 # if __GNUC__ >= 2 || defined(__clang__) || defined(__TINYC__) || defined(__PCC__)
99 # define inline __inline__
100 # else
101 # define inline /* Nothing. */
102 # endif
103 #endif
106 * GCC 2.95 provides `__restrict' as an extension to C90 to support the
107 * C99-specific `restrict' type qualifier. We happen to use `__restrict' as
108 * a way to define the `restrict' type qualifier without disturbing older
109 * software that is unaware of C99 keywords.
111 #if __STDC_VERSION__ < 199901L
112 # if __GNUC__ >= 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
113 # define restrict __restrict
114 # else
115 # define restrict /* Nothing. */
116 # endif
117 #endif
119 #if !defined(HOST_NAME_MAX)
120 # if defined(_POSIX_HOST_NAME_MAX)
121 # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
122 # else
123 # define HOST_NAME_MAX 512
124 # endif
125 #endif
127 extern size_t full_read(int fd, void *buf, size_t len)
128 __nonnull((2)) __warn_unused_result;
129 extern size_t full_write(int fd, void const *buf, size_t len)
130 __nonnull((2)) __warn_unused_result;
132 #if !defined(__NetBSD__)
133 extern void closefrom(int lowfd);
134 #endif
136 #if !defined(_GNU_SOURCE)
137 extern int execvpe(char const *restrict file,
138 char *const *restrict argv,
139 char *const *restrict envp);
140 #endif
142 extern char const *__progname;
144 extern void setprogname(char const *progname) __nonnull((1));
145 extern char const *getprogname(void) __warn_unused_result;
147 #if !defined(__NetBSD__)
148 extern void *reallocarray(void *pointer, size_t count, size_t size);
149 #endif
151 extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
152 extern int setresuid(gid_t rgid, gid_t egid, gid_t sgid);
154 extern size_t strlcpy(char *restrict dst, char const *restrict src, size_t dsize) __nonnull((1, 2));
155 extern size_t strlcat(char *restrict dst, char const *restrict src, size_t dsize) __nonnull((1, 2));
157 #if !defined(__FreeBSD__)
158 extern long long int strtonum(char const *restrict numstr,
159 long long int minval, long long int maxval,
160 char const *restrict *restrict errstrp)
161 __nonnull((1)) __warn_unused_result;
162 #endif
163 extern unsigned long long int strtounum(char const *restrict numstr,
164 unsigned long long int maxval,
165 char const *restrict *restrict errstrp)
166 __nonnull((1)) __warn_unused_result;
168 extern void vwarnc(int code, char const *fmt, va_list ap) __format_printf(2, 0);
169 extern void warnc(int code, char const *fmt, ...) __format_printf(2, 3);
171 extern void verrc(int eval, int code, char const *fmt, va_list ap) __format_printf(3, 0) __noreturn;
172 extern void errc(int eval, int code, char const *fmt, ...) __format_printf(3, 4) __noreturn;
174 extern char *strchrnul(char const *string, int character) __pure __nonnull((1)) __warn_unused_result;
176 #if (!defined(__GNUC__) || __GNUC__ < 5) \
177 && (!defined(__clang_major__) \
178 || (__clang_major__ < 3 || __clang_major__ == 3 && __clang_minor__ < 8)) \
179 || defined(__ICC)
180 #include <limits.h>
181 /* https://stackoverflow.com/a/1815371 */
182 static inline __nonnull((3)) __warn_unused_result __const bool __builtin_mul_overflow(size_t a, size_t b, size_t *c)
184 # define HALF_SIZE_BIT (sizeof(size_t) * CHAR_BIT / 2)
185 # define HI(x) (x >> HALF_SIZE_BIT)
186 # define LO(x) (x & ((1 << HALF_SIZE_BIT) - 1))
187 size_t s0, s1, s2, s3, x, result, carry;
189 x = LO(a) * LO(b);
190 s0 = LO(x);
192 x = HI(a) * LO(b) + HI(x);
193 s1 = LO(x);
194 s2 = HI(x);
196 x = s1 + LO(a) * HI(b);
197 s1 = LO(x);
199 x = s2 + HI(a) * HI(b) + HI(x);
200 s2 = LO(x);
201 s3 = HI(x);
203 result = (s1 << HALF_SIZE_BIT) | s0;
204 carry = (s3 << HALF_SIZE_BIT) | s2;
206 *c = result;
207 return (carry != 0);
209 #endif
211 #define BARF_IF_FAIL(e) (sizeof(char [1 - 2 * ((e) ? 0 : 1)]) - 1)
213 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) \
214 || defined(__clang__) || defined(__PCC__) || defined(__TINYC__)
215 # define is_same_type(a, b) __builtin_types_compatible_p(__typeof__(a), \
216 __typeof__(b))
217 #else
218 # define is_same_type(a, b) 0 /* (sizeof(a) == sizeof(b)) */
219 #endif
221 #define countof(a) \
222 (sizeof(a) / sizeof((a)[0]) \
223 + BARF_IF_FAIL(!is_same_type((a), &(a)[0])))
224 #define endof(a) \
225 (&(a)[countof(a)])
227 #endif /* _COMPAT_H */