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.
21 #include <sys/types.h>
23 #include "attributes.h"
26 # if defined(__va_copy)
27 # define va_copy(d, s) __va_copy(d, s)
29 # define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
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"
38 # define UID_MAX 65535
41 # define GID_MAX 65535
44 #if !defined(ROOT_UID)
45 # if defined(__TANDEM)
46 # define ROOT_UID 65535
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
58 # define PATH_MAX 4096
62 #if !defined(NGROUPS_MAX)
63 # define NGROUPS_MAX 65535
64 #endif /* NGROUPS_MAX */
66 #if !defined(LINE_MAX)
67 # define LINE_MAX 4096
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
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
;
95 #endif /* __STDC_VERSION__ >= 199901L */
97 #if __STDC_VERSION__ < 199901L
98 # if __GNUC__ >= 2 || defined(__clang__) || defined(__TINYC__) || defined(__PCC__)
99 # define inline __inline__
101 # define inline /* Nothing. */
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
115 # define restrict /* Nothing. */
119 #if !defined(HOST_NAME_MAX)
120 # if defined(_POSIX_HOST_NAME_MAX)
121 # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
123 # define HOST_NAME_MAX 512
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
);
136 #if !defined(_GNU_SOURCE)
137 extern int execvpe(char const *restrict file
,
138 char *const *restrict argv
,
139 char *const *restrict envp
);
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
);
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
;
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)) \
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
;
192 x
= HI(a
) * LO(b
) + HI(x
);
196 x
= s1
+ LO(a
) * HI(b
);
199 x
= s2
+ HI(a
) * HI(b
) + HI(x
);
203 result
= (s1
<< HALF_SIZE_BIT
) | s0
;
204 carry
= (s3
<< HALF_SIZE_BIT
) | s2
;
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), \
218 # define is_same_type(a, b) 0 /* (sizeof(a) == sizeof(b)) */
222 (sizeof(a) / sizeof((a)[0]) \
223 + BARF_IF_FAIL(!is_same_type((a), &(a)[0])))
227 #endif /* _COMPAT_H */