]> git.ipfire.org Git - thirdparty/util-linux.git/blame - include/c.h
libmount: check for linux/mount.h
[thirdparty/util-linux.git] / include / c.h
CommitLineData
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
218extern 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
228static char prog_inv_sh_nm_buf[256];
229static inline char *
230prog_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 252static inline void __attribute__ ((__format__ (__printf__, 4, 5)))
eb76ca98
FG
253errmsg(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
289static inline
290__attribute__((__noreturn__))
291void __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
315static 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
321typedef 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>
328static 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 */
367static 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
383static 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;
396fail:
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
407static 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 */
428static 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 */
439static 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 481static 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 */