1 /*
2 * Fundamental C definitions.
3 *
4 * No copyright is claimed. This code is in the public domain; do with
5 * it what you wish.
6 */
7 #ifndef UTIL_LINUX_C_H
8 #define UTIL_LINUX_C_H
9
10 #include <limits.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <stdarg.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <grp.h>
21
22 #include <assert.h>
23
24 #ifdef HAVE_ERR_H
25 # include <err.h>
26 #endif
27
28 #ifdef HAVE_SYS_SYSMACROS_H
29 # include <sys/sysmacros.h> /* for major, minor */
30 #endif
31
32 #ifndef LOGIN_NAME_MAX
33 # define LOGIN_NAME_MAX 256
34 #endif
35
36 #ifndef NAME_MAX
37 # define NAME_MAX PATH_MAX
38 #endif
39
40 /*
41 * __GNUC_PREREQ is deprecated in favour of __has_attribute() and
42 * __has_feature(). The __has macros are supported by clang and gcc>=5.
43 */
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
53 #ifdef __GNUC__
54
55 /* &a[0] degrades to a pointer: a different type from an array */
56 # define __must_be_array(a) \
57 UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
58
59 # define ignore_result(x) __extension__ ({ \
60 __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
61 })
62
63 #else /* !__GNUC__ */
64 # define __must_be_array(a) 0
65 # define __attribute__(_arg_)
66 # define ignore_result(x) ((void) (x))
67 #endif /* !__GNUC__ */
68
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
84 /*
85 * It evaluates to 1 if the attribute/feature is supported by the current
86 * compilation target. Fallback for old compilers.
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
96 /*
97 * Function attributes
98 */
99 #ifndef __ul_alloc_size
100 # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
101 # define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
102 # else
103 # define __ul_alloc_size(s)
104 # endif
105 #endif
106
107 #ifndef __ul_calloc_size
108 # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
109 # define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
110 # else
111 # define __ul_calloc_size(n, s)
112 # endif
113 #endif
114
115 #if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9)
116 # define __ul_returns_nonnull __attribute__((returns_nonnull))
117 #else
118 # define __ul_returns_nonnull
119 #endif
120
121 /*
122 * Force a compilation error if condition is true, but also produce a
123 * result (of value 0 and type size_t), so the expression can be used
124 * e.g. in a structure initializer (or wherever else comma expressions
125 * aren't permitted).
126 */
127 #define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
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
146 #ifndef min
147 # define min(x, y) __extension__ ({ \
148 __typeof__(x) _min1 = (x); \
149 __typeof__(y) _min2 = (y); \
150 (void) (&_min1 == &_min2); \
151 _min1 < _min2 ? _min1 : _min2; })
152 #endif
153
154 #ifndef max
155 # define max(x, y) __extension__ ({ \
156 __typeof__(x) _max1 = (x); \
157 __typeof__(y) _max2 = (y); \
158 (void) (&_max1 == &_max2); \
159 _max1 > _max2 ? _max1 : _max2; })
160 #endif
161
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
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); \
175 _a == _b ? 0 : _a > _b ? 1 : -1; })
176 #endif
177
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
196 #ifndef offsetof
197 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
198 #endif
199
200 #ifndef sizeof_member
201 #define sizeof_member(TYPE, MEMBER) sizeof(((TYPE *)0)->MEMBER)
202 #endif
203
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 */
210 #ifndef container_of
211 #define container_of(ptr, type, member) __extension__ ({ \
212 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
213 (type *)( (char *)__mptr - offsetof(type,member) );})
214 #endif
215
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
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
250
251 #ifndef HAVE_ERR_H
252 static inline void __attribute__ ((__format__ (__printf__, 4, 5)))
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)
265 fprintf(stderr, "%m");
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
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
297
298 /* Don't use inline function to avoid '#include "nls.h"' in c.h
299 */
300 #define errtryhelp(eval) __extension__ ({ \
301 fprintf(stderr, _("Try '%s --help' for more information.\n"), \
302 program_invocation_short_name); \
303 exit(eval); \
304 })
305
306 /* After failed execvp() */
307 #define EX_EXEC_FAILED 126 /* Program located, but not usable. */
308 #define EX_EXEC_ENOENT 127 /* Could not find program to exec. */
309 #define errexec(name) err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \
310 _("failed to execute %s"), name)
311
312 static inline __attribute__((const)) int is_power_of_2(unsigned long num)
313 {
314 return (num != 0 && ((num & (num - 1)) == 0));
315 }
316
317 #ifndef HAVE_LOFF_T
318 typedef int64_t loff_t;
319 #endif
320
321 #if !defined(HAVE_DIRFD) \
322 && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) \
323 && defined(HAVE_DIR_DD_FD)
324 #include <dirent.h>
325 static inline int dirfd(DIR *d)
326 {
327 return d->dd_fd;
328 }
329 #endif
330
331 /*
332 * Fallback defines for old versions of glibc
333 */
334 #include <fcntl.h>
335
336 #ifdef O_CLOEXEC
337 #define UL_CLOEXECSTR "e"
338 #else
339 #define UL_CLOEXECSTR ""
340 #endif
341
342 #ifndef O_CLOEXEC
343 #define O_CLOEXEC 0
344 #endif
345
346 #ifdef __FreeBSD_kernel__
347 #ifndef F_DUPFD_CLOEXEC
348 #define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */
349 #endif
350 #endif
351
352
353 #ifndef AI_ADDRCONFIG
354 #define AI_ADDRCONFIG 0x0020
355 #endif
356
357 #ifndef IUTF8
358 #define IUTF8 0040000
359 #endif
360
361 /*
362 * MAXHOSTNAMELEN replacement
363 */
364 static inline size_t get_hostname_max(void)
365 {
366 long len = sysconf(_SC_HOST_NAME_MAX);
367
368 if (0 < len)
369 return len;
370
371 #ifdef MAXHOSTNAMELEN
372 return MAXHOSTNAMELEN;
373 #elif HOST_NAME_MAX
374 return HOST_NAME_MAX;
375 #endif
376 return 64;
377 }
378
379
380 static inline int drop_permissions(void)
381 {
382 errno = 0;
383
384 /* drop GID */
385 if (setgid(getgid()) < 0)
386 goto fail;
387
388 /* drop UID */
389 if (setuid(getuid()) < 0)
390 goto fail;
391
392 return 0;
393 fail:
394 return errno ? -errno : -1;
395 }
396
397 /*
398 * The usleep function was marked obsolete in POSIX.1-2001 and was removed
399 * in POSIX.1-2008. It was replaced with nanosleep() that provides more
400 * advantages (like no interaction with signals and other timer functions).
401 */
402 #include <time.h>
403
404 static inline int xusleep(useconds_t usec)
405 {
406 #ifdef HAVE_NANOSLEEP
407 struct timespec waittime = {
408 .tv_sec = usec / 1000000L,
409 .tv_nsec = (usec % 1000000L) * 1000
410 };
411 return nanosleep(&waittime, NULL);
412 #elif defined(HAVE_USLEEP)
413 return usleep(usec);
414 #else
415 # error "System with usleep() or nanosleep() required!"
416 #endif
417 }
418
419
420 #define ul_err_write(_m) ignore_result( write(STDERR_FILENO, _m, strlen(_m)) )
421
422 /*
423 * warn() for signal handlers
424 */
425 static inline void ul_sig_warn(const char *mesg)
426 {
427 ul_err_write(program_invocation_short_name);
428 ul_err_write(": ");
429 ul_err_write(mesg);
430 ul_err_write("\n");
431 }
432
433 /*
434 * err() for signal handlers
435 */
436 static inline void __attribute__((__noreturn__)) ul_sig_err(int excode, const char *mesg)
437 {
438 ul_sig_warn(mesg);
439 _exit(excode);
440 }
441
442 /*
443 * Constant strings for usage() functions. For more info see
444 * Documentation/{howto-usage-function.txt,boilerplate.c}
445 */
446 #define USAGE_HEADER _("\nUsage:\n")
447 #define USAGE_OPTIONS _("\nOptions:\n")
448 #define USAGE_FUNCTIONS _("\nFunctions:\n")
449 #define USAGE_COMMANDS _("\nCommands:\n")
450 #define USAGE_ARGUMENTS _("\nArguments:\n")
451 #define USAGE_COLUMNS _("\nAvailable output columns:\n")
452 #define USAGE_SEPARATOR "\n"
453
454 #define USAGE_OPTSTR_HELP _("display this help")
455 #define USAGE_OPTSTR_VERSION _("display version")
456
457 #define USAGE_HELP_OPTIONS(marg_dsc) \
458 "%-" #marg_dsc "s%s\n" \
459 "%-" #marg_dsc "s%s\n" \
460 , " -h, --help", USAGE_OPTSTR_HELP \
461 , " -V, --version", USAGE_OPTSTR_VERSION
462
463 #define USAGE_ARG_SEPARATOR "\n"
464 #define USAGE_ARG_SIZE(_name) \
465 _(" %s arguments may be followed by the suffixes for\n" \
466 " GiB, TiB, PiB, EiB, ZiB, and YiB (the \"iB\" is optional)\n"), _name
467
468 #define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
469
470 #define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
471
472 #define print_version(eval) __extension__ ({ \
473 printf(UTIL_LINUX_VERSION); \
474 exit(eval); \
475 })
476
477 static inline void print_features(const char **features, const char *prefix)
478 {
479 if (features && *features) {
480 const char **p = features;
481 while (p && *p) {
482 if (prefix && p == features)
483 printf(" (%s ", prefix);
484 else
485 fputs(p == features ? " (" : ", ", stdout);
486 fputs(*p++, stdout);
487 }
488 fputc(')', stdout);
489 }
490 }
491
492 #define UTIL_LINUX_VERSION_NOBREAK _("%s from %s"), program_invocation_short_name, PACKAGE_STRING
493
494 #define print_version_with_features(eval, features) __extension__ ({ \
495 printf(UTIL_LINUX_VERSION_NOBREAK); \
496 print_features(features, _("features:")); \
497 fputc('\n', stdout); \
498 exit(eval); \
499 })
500
501 /*
502 * seek stuff
503 */
504 #ifndef SEEK_DATA
505 # define SEEK_DATA 3
506 #endif
507 #ifndef SEEK_HOLE
508 # define SEEK_HOLE 4
509 #endif
510
511
512 /*
513 * Macros to convert #define'itions to strings, for example
514 * #define XYXXY 42
515 * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY));
516 */
517 #define stringify_value(s) stringify(s)
518 #define stringify(s) #s
519
520 /* Detect if we're compiled with Address Sanitizer
521 * - gcc (__SANITIZE_ADDRESS__)
522 * - clang (__has_feature(address_sanitizer))
523 */
524 #if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
525 # ifdef __SANITIZE_ADDRESS__
526 # define HAS_FEATURE_ADDRESS_SANITIZER 1
527 # elif defined(__has_feature)
528 # if __has_feature(address_sanitizer)
529 # define HAS_FEATURE_ADDRESS_SANITIZER 1
530 # endif
531 # endif
532 # if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
533 # define HAS_FEATURE_ADDRESS_SANITIZER 0
534 # endif
535 #endif
536
537 /*
538 * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
539 * instrumentation shipped with Clang and GCC) to not instrument the
540 * annotated function. Furthermore, it will prevent the compiler from
541 * inlining the function because inlining currently breaks the blacklisting
542 * mechanism of AddressSanitizer.
543 */
544 #if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address)
545 # define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address))
546 #else
547 # define UL_ASAN_BLACKLIST /* nothing */
548 #endif
549
550 /*
551 * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
552 * pwd buffer and in some cases it is not large enough. See POSIX and
553 * getpwnam_r man page for more details.
554 */
555 #define UL_GETPW_BUFSIZ (16 * 1024)
556
557 /*
558 * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must
559 * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h.
560 */
561 #if !defined MAP_ANONYMOUS && defined MAP_ANON
562 # define MAP_ANONYMOUS (MAP_ANON)
563 #endif
564
565 #define SINT_MAX(t) (((t)1 << (sizeof(t) * 8 - 2)) - (t)1 + ((t)1 << (sizeof(t) * 8 - 2)))
566
567 #endif /* UTIL_LINUX_C_H */