]>
Commit | Line | Data |
---|---|---|
4d0dbb8b KZ |
1 | /* |
2 | * Fundamental C definitions. | |
40f8c5e4 KZ |
3 | * |
4 | * No copyright is claimed. This code is in the public domain; do with | |
5 | * it what you wish. | |
4d0dbb8b | 6 | */ |
4d0dbb8b KZ |
7 | #ifndef UTIL_LINUX_C_H |
8 | #define UTIL_LINUX_C_H | |
9 | ||
10 | #include <limits.h> | |
aa1f95c3 | 11 | #include <stddef.h> |
eb76ca98 FG |
12 | #include <stdint.h> |
13 | #include <stdio.h> | |
9199f5cd | 14 | #include <unistd.h> |
eb76ca98 | 15 | #include <stdarg.h> |
4d498513 | 16 | #include <stdlib.h> |
eb76ca98 FG |
17 | #include <string.h> |
18 | #include <errno.h> | |
17fc8693 KZ |
19 | #include <sys/types.h> |
20 | #include <grp.h> | |
eb76ca98 | 21 | |
2c656779 KZ |
22 | #include <assert.h> |
23 | ||
eb76ca98 FG |
24 | #ifdef HAVE_ERR_H |
25 | # include <err.h> | |
26 | #endif | |
4d0dbb8b | 27 | |
075d2c07 KZ |
28 | #ifdef HAVE_SYS_SYSMACROS_H |
29 | # include <sys/sysmacros.h> /* for major, minor */ | |
30 | #endif | |
31 | ||
790119b8 KZ |
32 | #ifndef LOGIN_NAME_MAX |
33 | # define LOGIN_NAME_MAX 256 | |
34 | #endif | |
35 | ||
7d5976f8 SJ |
36 | #ifndef NAME_MAX |
37 | # define NAME_MAX PATH_MAX | |
38 | #endif | |
39 | ||
4d0dbb8b | 40 | /* |
34b0a305 KZ |
41 | * __GNUC_PREREQ is deprecated in favour of __has_attribute() and |
42 | * __has_feature(). The __has macros are supported by clang and gcc>=5. | |
4d0dbb8b | 43 | */ |
40084d0d KZ |
44 | #ifndef __GNUC_PREREQ |
45 | # if defined __GNUC__ && defined __GNUC_MINOR__ | |
46 | # define __GNUC_PREREQ(maj, min) \ | |
47 | ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) | |
48 | # else | |
49 | # define __GNUC_PREREQ(maj, min) 0 | |
50 | # endif | |
51 | #endif | |
52 | ||
4d0dbb8b KZ |
53 | #ifdef __GNUC__ |
54 | ||
55 | /* &a[0] degrades to a pointer: a different type from an array */ | |
56 | # define __must_be_array(a) \ | |
bfda68fd | 57 | UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0]))) |
4d0dbb8b | 58 | |
2a0d2a8e | 59 | # define ignore_result(x) __extension__ ({ \ |
c764e1a4 | 60 | __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \ |
c25dc28d | 61 | }) |
2dd570ec | 62 | |
4d0dbb8b KZ |
63 | #else /* !__GNUC__ */ |
64 | # define __must_be_array(a) 0 | |
65 | # define __attribute__(_arg_) | |
2dd570ec | 66 | # define ignore_result(x) ((void) (x)) |
4d0dbb8b KZ |
67 | #endif /* !__GNUC__ */ |
68 | ||
7397f2c1 KZ |
69 | |
70 | /* "restrict" keyword fallback */ | |
71 | #if __STDC__ != 1 | |
72 | # define restrict __restrict /* use implementation __ format */ | |
73 | #else | |
74 | # ifndef __STDC_VERSION__ | |
75 | # define restrict __restrict /* use implementation __ format */ | |
76 | # else | |
77 | # if __STDC_VERSION__ < 199901L | |
78 | # define restrict __restrict /* use implementation __ format */ | |
79 | # endif | |
80 | # endif | |
81 | #endif | |
82 | ||
83 | ||
34b0a305 KZ |
84 | /* |
85 | * It evaluates to 1 if the attribute/feature is supported by the current | |
218b1dd6 | 86 | * compilation target. Fallback for old compilers. |
34b0a305 KZ |
87 | */ |
88 | #ifndef __has_attribute | |
89 | #define __has_attribute(x) 0 | |
90 | #endif | |
91 | ||
92 | #ifndef __has_feature | |
93 | #define __has_feature(x) 0 | |
94 | #endif | |
95 | ||
40084d0d KZ |
96 | /* |
97 | * Function attributes | |
98 | */ | |
99 | #ifndef __ul_alloc_size | |
34b0a305 | 100 | # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) |
c9678832 | 101 | # define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result)) |
40084d0d KZ |
102 | # else |
103 | # define __ul_alloc_size(s) | |
104 | # endif | |
105 | #endif | |
106 | ||
107 | #ifndef __ul_calloc_size | |
34b0a305 | 108 | # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) |
c9678832 | 109 | # define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result)) |
40084d0d KZ |
110 | # else |
111 | # define __ul_calloc_size(n, s) | |
112 | # endif | |
113 | #endif | |
4d0dbb8b | 114 | |
34b0a305 | 115 | #if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9) |
f1b327f8 SK |
116 | # define __ul_returns_nonnull __attribute__((returns_nonnull)) |
117 | #else | |
118 | # define __ul_returns_nonnull | |
119 | #endif | |
120 | ||
68411ba2 BS |
121 | /* |
122 | * Force a compilation error if condition is true, but also produce a | |
4d0dbb8b | 123 | * result (of value 0 and type size_t), so the expression can be used |
68411ba2 | 124 | * e.g. in a structure initializer (or wherever else comma expressions |
4d0dbb8b KZ |
125 | * aren't permitted). |
126 | */ | |
2a0d2a8e | 127 | #define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); })) |
4d0dbb8b KZ |
128 | #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) |
129 | ||
130 | #ifndef ARRAY_SIZE | |
131 | # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) | |
132 | #endif | |
133 | ||
134 | #ifndef PATH_MAX | |
135 | # define PATH_MAX 4096 | |
136 | #endif | |
137 | ||
138 | #ifndef TRUE | |
139 | # define TRUE 1 | |
140 | #endif | |
141 | ||
142 | #ifndef FALSE | |
143 | # define FALSE 0 | |
144 | #endif | |
145 | ||
70502c52 | 146 | #ifndef min |
2a0d2a8e | 147 | # define min(x, y) __extension__ ({ \ |
c764e1a4 SK |
148 | __typeof__(x) _min1 = (x); \ |
149 | __typeof__(y) _min2 = (y); \ | |
1cb1641d KZ |
150 | (void) (&_min1 == &_min2); \ |
151 | _min1 < _min2 ? _min1 : _min2; }) | |
70502c52 | 152 | #endif |
1cb1641d | 153 | |
70502c52 | 154 | #ifndef max |
2a0d2a8e | 155 | # define max(x, y) __extension__ ({ \ |
c764e1a4 SK |
156 | __typeof__(x) _max1 = (x); \ |
157 | __typeof__(y) _max2 = (y); \ | |
1cb1641d KZ |
158 | (void) (&_max1 == &_max2); \ |
159 | _max1 > _max2 ? _max1 : _max2; }) | |
70502c52 | 160 | #endif |
1cb1641d | 161 | |
adc21ee1 SA |
162 | #ifndef abs_diff |
163 | # define abs_diff(x, y) __extension__ ({ \ | |
164 | __typeof__(x) _a = (x); \ | |
165 | __typeof__(y) _b = (y); \ | |
166 | (void) (&_a == &_b); \ | |
167 | _a > _b ? _a - _b : _b - _a; }) | |
168 | #endif | |
169 | ||
19ff8ff7 KZ |
170 | #ifndef cmp_numbers |
171 | # define cmp_numbers(x, y) __extension__ ({ \ | |
172 | __typeof__(x) _a = (x); \ | |
173 | __typeof__(y) _b = (y); \ | |
174 | (void) (&_a == &_b); \ | |
764b697c | 175 | _a == _b ? 0 : _a > _b ? 1 : -1; }) |
19ff8ff7 KZ |
176 | #endif |
177 | ||
0cfb8c5c KZ |
178 | |
179 | #ifndef cmp_timespec | |
180 | # define cmp_timespec(a, b, CMP) \ | |
181 | (((a)->tv_sec == (b)->tv_sec) \ | |
182 | ? ((a)->tv_nsec CMP (b)->tv_nsec) \ | |
183 | : ((a)->tv_sec CMP (b)->tv_sec)) | |
184 | #endif | |
185 | ||
186 | ||
187 | #ifndef cmp_stat_mtime | |
188 | # ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC | |
189 | # define cmp_stat_mtime(_a, _b, CMP) cmp_timespec(&(_a)->st_mtim, &(_b)->st_mtim, CMP) | |
190 | # else | |
191 | # define cmp_stat_mtime(_a, _b, CMP) ((_a)->st_mtime CMP (_b)->st_mtime) | |
192 | # endif | |
193 | #endif | |
194 | ||
195 | ||
5b9df028 DB |
196 | #ifndef offsetof |
197 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | |
198 | #endif | |
199 | ||
643670d9 KZ |
200 | #ifndef sizeof_member |
201 | #define sizeof_member(TYPE, MEMBER) sizeof(((TYPE *)0)->MEMBER) | |
202 | #endif | |
203 | ||
eb06d5d4 KZ |
204 | /* |
205 | * container_of - cast a member of a structure out to the containing structure | |
206 | * @ptr: the pointer to the member. | |
207 | * @type: the type of the container struct this is embedded in. | |
208 | * @member: the name of the member within the struct. | |
209 | */ | |
ae278c88 | 210 | #ifndef container_of |
eb06d5d4 | 211 | #define container_of(ptr, type, member) __extension__ ({ \ |
1866fa6a RM |
212 | const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ |
213 | (type *)( (char *)__mptr - offsetof(type,member) );}) | |
ae278c88 | 214 | #endif |
5b9df028 | 215 | |
4b2b6716 | 216 | #ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME |
217 | # ifdef HAVE___PROGNAME | |
218 | extern char *__progname; | |
219 | # define program_invocation_short_name __progname | |
220 | # else | |
221 | # ifdef HAVE_GETEXECNAME | |
4b2b6716 | 222 | # define program_invocation_short_name \ |
223 | prog_inv_sh_nm_from_file(getexecname(), 0) | |
224 | # else | |
225 | # define program_invocation_short_name \ | |
226 | prog_inv_sh_nm_from_file(__FILE__, 1) | |
227 | # endif | |
228 | static char prog_inv_sh_nm_buf[256]; | |
229 | static inline char * | |
230 | prog_inv_sh_nm_from_file(char *f, char stripext) | |
231 | { | |
232 | char *t; | |
233 | ||
234 | if ((t = strrchr(f, '/')) != NULL) | |
235 | t++; | |
236 | else | |
237 | t = f; | |
238 | ||
239 | strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1); | |
240 | prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0'; | |
241 | ||
242 | if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL) | |
243 | *t = '\0'; | |
244 | ||
245 | return prog_inv_sh_nm_buf; | |
246 | } | |
247 | # endif | |
248 | #endif | |
249 | ||
06ceeef8 | 250 | |
eb76ca98 | 251 | #ifndef HAVE_ERR_H |
01085557 | 252 | static inline void __attribute__ ((__format__ (__printf__, 4, 5))) |
eb76ca98 FG |
253 | errmsg(char doexit, int excode, char adderr, const char *fmt, ...) |
254 | { | |
255 | fprintf(stderr, "%s: ", program_invocation_short_name); | |
256 | if (fmt != NULL) { | |
257 | va_list argp; | |
258 | va_start(argp, fmt); | |
259 | vfprintf(stderr, fmt, argp); | |
260 | va_end(argp); | |
261 | if (adderr) | |
262 | fprintf(stderr, ": "); | |
263 | } | |
264 | if (adderr) | |
960cf573 | 265 | fprintf(stderr, "%m"); |
eb76ca98 FG |
266 | fprintf(stderr, "\n"); |
267 | if (doexit) | |
268 | exit(excode); | |
269 | } | |
270 | ||
271 | #ifndef HAVE_ERR | |
272 | # define err(E, FMT...) errmsg(1, E, 1, FMT) | |
273 | #endif | |
274 | ||
275 | #ifndef HAVE_ERRX | |
276 | # define errx(E, FMT...) errmsg(1, E, 0, FMT) | |
277 | #endif | |
278 | ||
279 | #ifndef HAVE_WARN | |
280 | # define warn(FMT...) errmsg(0, 0, 1, FMT) | |
281 | #endif | |
282 | ||
283 | #ifndef HAVE_WARNX | |
284 | # define warnx(FMT...) errmsg(0, 0, 0, FMT) | |
285 | #endif | |
286 | #endif /* !HAVE_ERR_H */ | |
287 | ||
288 | ||
cb48f21e KZ |
289 | static inline |
290 | __attribute__((__noreturn__)) | |
291 | void __err_oom(const char *file, unsigned int line) | |
292 | { | |
293 | err(EXIT_FAILURE, "%s: %u: cannot allocate memory", file, line); | |
294 | } | |
295 | #define err_oom() __err_oom(__FILE__, __LINE__) | |
296 | ||
bb2b071f TW |
297 | #define err_nosys(exitcode, ...) \ |
298 | err(errno == ENOSYS ? EXIT_NOTSUPP : exitcode, __VA_ARGS__) | |
299 | ||
cb48f21e | 300 | |
3077b371 KZ |
301 | /* Don't use inline function to avoid '#include "nls.h"' in c.h |
302 | */ | |
303 | #define errtryhelp(eval) __extension__ ({ \ | |
304 | fprintf(stderr, _("Try '%s --help' for more information.\n"), \ | |
305 | program_invocation_short_name); \ | |
306 | exit(eval); \ | |
307 | }) | |
308 | ||
cf654e1c KZ |
309 | /* After failed execvp() */ |
310 | #define EX_EXEC_FAILED 126 /* Program located, but not usable. */ | |
311 | #define EX_EXEC_ENOENT 127 /* Could not find program to exec. */ | |
312 | #define errexec(name) err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \ | |
313 | _("failed to execute %s"), name) | |
314 | ||
973af806 KZ |
315 | static inline __attribute__((const)) int is_power_of_2(unsigned long num) |
316 | { | |
317 | return (num != 0 && ((num & (num - 1)) == 0)); | |
318 | } | |
319 | ||
5be1c033 FG |
320 | #ifndef HAVE_LOFF_T |
321 | typedef int64_t loff_t; | |
322 | #endif | |
323 | ||
8ae8b201 KZ |
324 | #if !defined(HAVE_DIRFD) \ |
325 | && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) \ | |
326 | && defined(HAVE_DIR_DD_FD) | |
d58c47d9 FG |
327 | #include <dirent.h> |
328 | static inline int dirfd(DIR *d) | |
329 | { | |
330 | return d->dd_fd; | |
331 | } | |
332 | #endif | |
333 | ||
7cf78990 DB |
334 | /* |
335 | * Fallback defines for old versions of glibc | |
336 | */ | |
e9d00e66 | 337 | #include <fcntl.h> |
2ffad204 KZ |
338 | |
339 | #ifdef O_CLOEXEC | |
340 | #define UL_CLOEXECSTR "e" | |
341 | #else | |
342 | #define UL_CLOEXECSTR "" | |
343 | #endif | |
344 | ||
4799c95f KZ |
345 | #ifndef O_CLOEXEC |
346 | #define O_CLOEXEC 0 | |
347 | #endif | |
973af806 | 348 | |
f51275ee GJ |
349 | #ifdef __FreeBSD_kernel__ |
350 | #ifndef F_DUPFD_CLOEXEC | |
351 | #define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */ | |
352 | #endif | |
353 | #endif | |
354 | ||
2ffad204 | 355 | |
7cf78990 DB |
356 | #ifndef AI_ADDRCONFIG |
357 | #define AI_ADDRCONFIG 0x0020 | |
358 | #endif | |
359 | ||
360 | #ifndef IUTF8 | |
361 | #define IUTF8 0040000 | |
362 | #endif | |
363 | ||
1ee4dff7 SK |
364 | /* |
365 | * MAXHOSTNAMELEN replacement | |
366 | */ | |
367 | static inline size_t get_hostname_max(void) | |
368 | { | |
369 | long len = sysconf(_SC_HOST_NAME_MAX); | |
370 | ||
371 | if (0 < len) | |
372 | return len; | |
373 | ||
374 | #ifdef MAXHOSTNAMELEN | |
375 | return MAXHOSTNAMELEN; | |
376 | #elif HOST_NAME_MAX | |
377 | return HOST_NAME_MAX; | |
378 | #endif | |
379 | return 64; | |
380 | } | |
381 | ||
17fc8693 KZ |
382 | |
383 | static inline int drop_permissions(void) | |
384 | { | |
385 | errno = 0; | |
386 | ||
17fc8693 | 387 | /* drop GID */ |
c6d0ea98 | 388 | if (setgid(getgid()) < 0) |
17fc8693 KZ |
389 | goto fail; |
390 | ||
391 | /* drop UID */ | |
392 | if (setuid(getuid()) < 0) | |
393 | goto fail; | |
394 | ||
395 | return 0; | |
396 | fail: | |
397 | return errno ? -errno : -1; | |
398 | } | |
399 | ||
2a31396a | 400 | /* |
68411ba2 BS |
401 | * The usleep function was marked obsolete in POSIX.1-2001 and was removed |
402 | * in POSIX.1-2008. It was replaced with nanosleep() that provides more | |
403 | * advantages (like no interaction with signals and other timer functions). | |
2a31396a | 404 | */ |
a5bd7939 KZ |
405 | #include <time.h> |
406 | ||
407 | static inline int xusleep(useconds_t usec) | |
2a31396a | 408 | { |
a5bd7939 | 409 | #ifdef HAVE_NANOSLEEP |
2a31396a KZ |
410 | struct timespec waittime = { |
411 | .tv_sec = usec / 1000000L, | |
412 | .tv_nsec = (usec % 1000000L) * 1000 | |
b33f24b2 WF |
413 | }; |
414 | return nanosleep(&waittime, NULL); | |
a5bd7939 KZ |
415 | #elif defined(HAVE_USLEEP) |
416 | return usleep(usec); | |
417 | #else | |
418 | # error "System with usleep() or nanosleep() required!" | |
2a31396a | 419 | #endif |
a5bd7939 | 420 | } |
2a31396a | 421 | |
32457b5e KZ |
422 | |
423 | #define ul_err_write(_m) ignore_result( write(STDERR_FILENO, _m, strlen(_m)) ) | |
424 | ||
425 | /* | |
426 | * warn() for signal handlers | |
427 | */ | |
428 | static inline void ul_sig_warn(const char *mesg) | |
429 | { | |
430 | ul_err_write(program_invocation_short_name); | |
431 | ul_err_write(": "); | |
432 | ul_err_write(mesg); | |
433 | ul_err_write("\n"); | |
434 | } | |
435 | ||
436 | /* | |
437 | * err() for signal handlers | |
438 | */ | |
439 | static inline void __attribute__((__noreturn__)) ul_sig_err(int excode, const char *mesg) | |
440 | { | |
441 | ul_sig_warn(mesg); | |
442 | _exit(excode); | |
443 | } | |
444 | ||
cd7accd4 SK |
445 | /* |
446 | * Constant strings for usage() functions. For more info see | |
6e2d5a44 | 447 | * Documentation/{howto-usage-function.txt,boilerplate.c} |
cd7accd4 SK |
448 | */ |
449 | #define USAGE_HEADER _("\nUsage:\n") | |
450 | #define USAGE_OPTIONS _("\nOptions:\n") | |
513bfbef | 451 | #define USAGE_FUNCTIONS _("\nFunctions:\n") |
6e2d5a44 | 452 | #define USAGE_COMMANDS _("\nCommands:\n") |
67f938bf | 453 | #define USAGE_ARGUMENTS _("\nArguments:\n") |
c3a4cfc5 | 454 | #define USAGE_COLUMNS _("\nAvailable output columns:\n") |
9d1714a3 | 455 | #define USAGE_DEFAULT_COLUMNS _("\nDefault columns:\n") |
82b219f7 | 456 | #define USAGE_SEPARATOR "\n" |
b1a294c4 | 457 | |
551b9cd3 | 458 | #define USAGE_OPTSTR_HELP _("display this help") |
08e3c9e6 | 459 | #define USAGE_OPTSTR_VERSION _("display version") |
b1a294c4 | 460 | |
f45f3ec3 | 461 | #define USAGE_HELP_OPTIONS(marg_dsc) \ |
b1a294c4 RM |
462 | "%-" #marg_dsc "s%s\n" \ |
463 | "%-" #marg_dsc "s%s\n" \ | |
464 | , " -h, --help", USAGE_OPTSTR_HELP \ | |
f45f3ec3 | 465 | , " -V, --version", USAGE_OPTSTR_VERSION |
b1a294c4 | 466 | |
f1970cc5 KZ |
467 | #define USAGE_ARG_SEPARATOR "\n" |
468 | #define USAGE_ARG_SIZE(_name) \ | |
469 | _(" %s arguments may be followed by the suffixes for\n" \ | |
470 | " GiB, TiB, PiB, EiB, ZiB, and YiB (the \"iB\" is optional)\n"), _name | |
471 | ||
6f162034 | 472 | #define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man |
cd7accd4 SK |
473 | |
474 | #define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING | |
475 | ||
2c308875 KZ |
476 | #define print_version(eval) __extension__ ({ \ |
477 | printf(UTIL_LINUX_VERSION); \ | |
478 | exit(eval); \ | |
479 | }) | |
480 | ||
6895cf92 | 481 | static inline void print_features(const char **features, const char *prefix) |
beafda18 KZ |
482 | { |
483 | if (features && *features) { | |
484 | const char **p = features; | |
485 | while (p && *p) { | |
6895cf92 KZ |
486 | if (prefix && p == features) |
487 | printf(" (%s ", prefix); | |
488 | else | |
489 | fputs(p == features ? " (" : ", ", stdout); | |
beafda18 KZ |
490 | fputs(*p++, stdout); |
491 | } | |
492 | fputc(')', stdout); | |
493 | } | |
494 | } | |
495 | ||
496 | #define UTIL_LINUX_VERSION_NOBREAK _("%s from %s"), program_invocation_short_name, PACKAGE_STRING | |
497 | ||
498 | #define print_version_with_features(eval, features) __extension__ ({ \ | |
499 | printf(UTIL_LINUX_VERSION_NOBREAK); \ | |
6895cf92 | 500 | print_features(features, _("features:")); \ |
beafda18 KZ |
501 | fputc('\n', stdout); \ |
502 | exit(eval); \ | |
503 | }) | |
504 | ||
9199f5cd KZ |
505 | /* |
506 | * seek stuff | |
507 | */ | |
508 | #ifndef SEEK_DATA | |
509 | # define SEEK_DATA 3 | |
510 | #endif | |
511 | #ifndef SEEK_HOLE | |
512 | # define SEEK_HOLE 4 | |
513 | #endif | |
514 | ||
ff1aaf99 SK |
515 | |
516 | /* | |
517 | * Macros to convert #define'itions to strings, for example | |
518 | * #define XYXXY 42 | |
519 | * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY)); | |
520 | */ | |
521 | #define stringify_value(s) stringify(s) | |
522 | #define stringify(s) #s | |
523 | ||
c40b3cd0 FS |
524 | /* Detect if we're compiled with Address Sanitizer |
525 | * - gcc (__SANITIZE_ADDRESS__) | |
526 | * - clang (__has_feature(address_sanitizer)) | |
527 | */ | |
528 | #if !defined(HAS_FEATURE_ADDRESS_SANITIZER) | |
529 | # ifdef __SANITIZE_ADDRESS__ | |
530 | # define HAS_FEATURE_ADDRESS_SANITIZER 1 | |
531 | # elif defined(__has_feature) | |
532 | # if __has_feature(address_sanitizer) | |
533 | # define HAS_FEATURE_ADDRESS_SANITIZER 1 | |
534 | # endif | |
535 | # endif | |
536 | # if !defined(HAS_FEATURE_ADDRESS_SANITIZER) | |
537 | # define HAS_FEATURE_ADDRESS_SANITIZER 0 | |
538 | # endif | |
539 | #endif | |
540 | ||
d763c230 SK |
541 | /* |
542 | * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time | |
543 | * instrumentation shipped with Clang and GCC) to not instrument the | |
544 | * annotated function. Furthermore, it will prevent the compiler from | |
545 | * inlining the function because inlining currently breaks the blacklisting | |
546 | * mechanism of AddressSanitizer. | |
547 | */ | |
34b0a305 KZ |
548 | #if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address) |
549 | # define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address)) | |
d763c230 SK |
550 | #else |
551 | # define UL_ASAN_BLACKLIST /* nothing */ | |
552 | #endif | |
553 | ||
f7ac9e71 KZ |
554 | /* |
555 | * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for | |
556 | * pwd buffer and in some cases it is not large enough. See POSIX and | |
557 | * getpwnam_r man page for more details. | |
558 | */ | |
559 | #define UL_GETPW_BUFSIZ (16 * 1024) | |
560 | ||
40733239 RM |
561 | /* |
562 | * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must | |
563 | * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h. | |
564 | */ | |
565 | #if !defined MAP_ANONYMOUS && defined MAP_ANON | |
566 | # define MAP_ANONYMOUS (MAP_ANON) | |
567 | #endif | |
568 | ||
1ef0be3a | 569 | #define SINT_MAX(t) (((t)1 << (sizeof(t) * 8 - 2)) - (t)1 + ((t)1 << (sizeof(t) * 8 - 2))) |
550d32c4 | 570 | |
4d0dbb8b | 571 | #endif /* UTIL_LINUX_C_H */ |