]> git.ipfire.org Git - thirdparty/util-linux.git/blame - include/c.h
libmount: fix comment referring to passno field
[thirdparty/util-linux.git] / include / c.h
CommitLineData
4d0dbb8b
KZ
1/*
2 * Fundamental C definitions.
3 */
4
5#ifndef UTIL_LINUX_C_H
6#define UTIL_LINUX_C_H
7
8#include <limits.h>
aa1f95c3 9#include <stddef.h>
eb76ca98
FG
10#include <stdint.h>
11#include <stdio.h>
9199f5cd 12#include <unistd.h>
eb76ca98 13#include <stdarg.h>
4d498513 14#include <stdlib.h>
eb76ca98
FG
15#include <string.h>
16#include <errno.h>
17
2c656779
KZ
18#include <assert.h>
19
eb76ca98
FG
20#ifdef HAVE_ERR_H
21# include <err.h>
22#endif
4d0dbb8b 23
075d2c07
KZ
24#ifdef HAVE_SYS_SYSMACROS_H
25# include <sys/sysmacros.h> /* for major, minor */
26#endif
27
790119b8
KZ
28#ifndef LOGIN_NAME_MAX
29# define LOGIN_NAME_MAX 256
30#endif
31
7d5976f8
SJ
32#ifndef NAME_MAX
33# define NAME_MAX PATH_MAX
34#endif
35
4d0dbb8b 36/*
34b0a305
KZ
37 * __GNUC_PREREQ is deprecated in favour of __has_attribute() and
38 * __has_feature(). The __has macros are supported by clang and gcc>=5.
4d0dbb8b 39 */
40084d0d
KZ
40#ifndef __GNUC_PREREQ
41# if defined __GNUC__ && defined __GNUC_MINOR__
42# define __GNUC_PREREQ(maj, min) \
43 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
44# else
45# define __GNUC_PREREQ(maj, min) 0
46# endif
47#endif
48
4d0dbb8b
KZ
49#ifdef __GNUC__
50
51/* &a[0] degrades to a pointer: a different type from an array */
52# define __must_be_array(a) \
bfda68fd 53 UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
4d0dbb8b 54
2a0d2a8e 55# define ignore_result(x) __extension__ ({ \
c764e1a4 56 __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
c25dc28d 57})
2dd570ec 58
4d0dbb8b
KZ
59#else /* !__GNUC__ */
60# define __must_be_array(a) 0
61# define __attribute__(_arg_)
2dd570ec 62# define ignore_result(x) ((void) (x))
4d0dbb8b
KZ
63#endif /* !__GNUC__ */
64
34b0a305
KZ
65/*
66 * It evaluates to 1 if the attribute/feature is supported by the current
67 * compilation targed. Fallback for old compilers.
68 */
69#ifndef __has_attribute
70 #define __has_attribute(x) 0
71#endif
72
73#ifndef __has_feature
74 #define __has_feature(x) 0
75#endif
76
40084d0d
KZ
77/*
78 * Function attributes
79 */
80#ifndef __ul_alloc_size
34b0a305 81# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
c9678832 82# define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
40084d0d
KZ
83# else
84# define __ul_alloc_size(s)
85# endif
86#endif
87
88#ifndef __ul_calloc_size
34b0a305 89# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
c9678832 90# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
40084d0d
KZ
91# else
92# define __ul_calloc_size(n, s)
93# endif
94#endif
4d0dbb8b 95
34b0a305 96#if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9)
f1b327f8
SK
97# define __ul_returns_nonnull __attribute__((returns_nonnull))
98#else
99# define __ul_returns_nonnull
100#endif
101
68411ba2
BS
102/*
103 * Force a compilation error if condition is true, but also produce a
4d0dbb8b 104 * result (of value 0 and type size_t), so the expression can be used
68411ba2 105 * e.g. in a structure initializer (or wherever else comma expressions
4d0dbb8b
KZ
106 * aren't permitted).
107 */
2a0d2a8e 108#define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
4d0dbb8b
KZ
109#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
110
111#ifndef ARRAY_SIZE
112# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
113#endif
114
115#ifndef PATH_MAX
116# define PATH_MAX 4096
117#endif
118
119#ifndef TRUE
120# define TRUE 1
121#endif
122
123#ifndef FALSE
124# define FALSE 0
125#endif
126
70502c52 127#ifndef min
2a0d2a8e 128# define min(x, y) __extension__ ({ \
c764e1a4
SK
129 __typeof__(x) _min1 = (x); \
130 __typeof__(y) _min2 = (y); \
1cb1641d
KZ
131 (void) (&_min1 == &_min2); \
132 _min1 < _min2 ? _min1 : _min2; })
70502c52 133#endif
1cb1641d 134
70502c52 135#ifndef max
2a0d2a8e 136# define max(x, y) __extension__ ({ \
c764e1a4
SK
137 __typeof__(x) _max1 = (x); \
138 __typeof__(y) _max2 = (y); \
1cb1641d
KZ
139 (void) (&_max1 == &_max2); \
140 _max1 > _max2 ? _max1 : _max2; })
70502c52 141#endif
1cb1641d 142
19ff8ff7
KZ
143#ifndef cmp_numbers
144# define cmp_numbers(x, y) __extension__ ({ \
145 __typeof__(x) _a = (x); \
146 __typeof__(y) _b = (y); \
147 (void) (&_a == &_b); \
764b697c 148 _a == _b ? 0 : _a > _b ? 1 : -1; })
19ff8ff7
KZ
149#endif
150
5b9df028
DB
151#ifndef offsetof
152#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
153#endif
154
eb06d5d4
KZ
155/*
156 * container_of - cast a member of a structure out to the containing structure
157 * @ptr: the pointer to the member.
158 * @type: the type of the container struct this is embedded in.
159 * @member: the name of the member within the struct.
160 */
ae278c88 161#ifndef container_of
eb06d5d4 162#define container_of(ptr, type, member) __extension__ ({ \
1866fa6a
RM
163 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
164 (type *)( (char *)__mptr - offsetof(type,member) );})
ae278c88 165#endif
5b9df028 166
4b2b6716 167#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
168# ifdef HAVE___PROGNAME
169extern char *__progname;
170# define program_invocation_short_name __progname
171# else
172# ifdef HAVE_GETEXECNAME
4b2b6716 173# define program_invocation_short_name \
174 prog_inv_sh_nm_from_file(getexecname(), 0)
175# else
176# define program_invocation_short_name \
177 prog_inv_sh_nm_from_file(__FILE__, 1)
178# endif
179static char prog_inv_sh_nm_buf[256];
180static inline char *
181prog_inv_sh_nm_from_file(char *f, char stripext)
182{
183 char *t;
184
185 if ((t = strrchr(f, '/')) != NULL)
186 t++;
187 else
188 t = f;
189
190 strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
191 prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
192
193 if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
194 *t = '\0';
195
196 return prog_inv_sh_nm_buf;
197}
198# endif
199#endif
200
06ceeef8 201
eb76ca98
FG
202#ifndef HAVE_ERR_H
203static inline void
204errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
205{
206 fprintf(stderr, "%s: ", program_invocation_short_name);
207 if (fmt != NULL) {
208 va_list argp;
209 va_start(argp, fmt);
210 vfprintf(stderr, fmt, argp);
211 va_end(argp);
212 if (adderr)
213 fprintf(stderr, ": ");
214 }
215 if (adderr)
960cf573 216 fprintf(stderr, "%m");
eb76ca98
FG
217 fprintf(stderr, "\n");
218 if (doexit)
219 exit(excode);
220}
221
222#ifndef HAVE_ERR
223# define err(E, FMT...) errmsg(1, E, 1, FMT)
224#endif
225
226#ifndef HAVE_ERRX
227# define errx(E, FMT...) errmsg(1, E, 0, FMT)
228#endif
229
230#ifndef HAVE_WARN
231# define warn(FMT...) errmsg(0, 0, 1, FMT)
232#endif
233
234#ifndef HAVE_WARNX
235# define warnx(FMT...) errmsg(0, 0, 0, FMT)
236#endif
237#endif /* !HAVE_ERR_H */
238
239
3077b371
KZ
240/* Don't use inline function to avoid '#include "nls.h"' in c.h
241 */
242#define errtryhelp(eval) __extension__ ({ \
243 fprintf(stderr, _("Try '%s --help' for more information.\n"), \
244 program_invocation_short_name); \
245 exit(eval); \
246})
247
cf654e1c
KZ
248/* After failed execvp() */
249#define EX_EXEC_FAILED 126 /* Program located, but not usable. */
250#define EX_EXEC_ENOENT 127 /* Could not find program to exec. */
251#define errexec(name) err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \
252 _("failed to execute %s"), name)
253
3077b371 254
973af806
KZ
255static inline __attribute__((const)) int is_power_of_2(unsigned long num)
256{
257 return (num != 0 && ((num & (num - 1)) == 0));
258}
259
5be1c033
FG
260#ifndef HAVE_LOFF_T
261typedef int64_t loff_t;
262#endif
263
d58c47d9
FG
264#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD)
265#include <sys/types.h>
266#include <dirent.h>
267static inline int dirfd(DIR *d)
268{
269 return d->dd_fd;
270}
271#endif
272
7cf78990
DB
273/*
274 * Fallback defines for old versions of glibc
275 */
e9d00e66 276#include <fcntl.h>
2ffad204
KZ
277
278#ifdef O_CLOEXEC
279#define UL_CLOEXECSTR "e"
280#else
281#define UL_CLOEXECSTR ""
282#endif
283
4799c95f
KZ
284#ifndef O_CLOEXEC
285#define O_CLOEXEC 0
286#endif
973af806 287
f51275ee
GJ
288#ifdef __FreeBSD_kernel__
289#ifndef F_DUPFD_CLOEXEC
290#define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */
291#endif
292#endif
293
2ffad204 294
7cf78990
DB
295#ifndef AI_ADDRCONFIG
296#define AI_ADDRCONFIG 0x0020
297#endif
298
299#ifndef IUTF8
300#define IUTF8 0040000
301#endif
302
1ee4dff7
SK
303/*
304 * MAXHOSTNAMELEN replacement
305 */
306static inline size_t get_hostname_max(void)
307{
308 long len = sysconf(_SC_HOST_NAME_MAX);
309
310 if (0 < len)
311 return len;
312
313#ifdef MAXHOSTNAMELEN
314 return MAXHOSTNAMELEN;
315#elif HOST_NAME_MAX
316 return HOST_NAME_MAX;
317#endif
318 return 64;
319}
320
2a31396a 321/*
68411ba2
BS
322 * The usleep function was marked obsolete in POSIX.1-2001 and was removed
323 * in POSIX.1-2008. It was replaced with nanosleep() that provides more
324 * advantages (like no interaction with signals and other timer functions).
2a31396a 325 */
a5bd7939
KZ
326#include <time.h>
327
328static inline int xusleep(useconds_t usec)
2a31396a 329{
a5bd7939 330#ifdef HAVE_NANOSLEEP
2a31396a
KZ
331 struct timespec waittime = {
332 .tv_sec = usec / 1000000L,
333 .tv_nsec = (usec % 1000000L) * 1000
b33f24b2
WF
334 };
335 return nanosleep(&waittime, NULL);
a5bd7939
KZ
336#elif defined(HAVE_USLEEP)
337 return usleep(usec);
338#else
339# error "System with usleep() or nanosleep() required!"
2a31396a 340#endif
a5bd7939 341}
2a31396a 342
cd7accd4
SK
343/*
344 * Constant strings for usage() functions. For more info see
6e2d5a44 345 * Documentation/{howto-usage-function.txt,boilerplate.c}
cd7accd4
SK
346 */
347#define USAGE_HEADER _("\nUsage:\n")
348#define USAGE_OPTIONS _("\nOptions:\n")
513bfbef 349#define USAGE_FUNCTIONS _("\nFunctions:\n")
6e2d5a44 350#define USAGE_COMMANDS _("\nCommands:\n")
c3a4cfc5 351#define USAGE_COLUMNS _("\nAvailable output columns:\n")
82b219f7 352#define USAGE_SEPARATOR "\n"
b1a294c4 353
551b9cd3 354#define USAGE_OPTSTR_HELP _("display this help")
08e3c9e6 355#define USAGE_OPTSTR_VERSION _("display version")
b1a294c4 356
f45f3ec3 357#define USAGE_HELP_OPTIONS(marg_dsc) \
b1a294c4
RM
358 "%-" #marg_dsc "s%s\n" \
359 "%-" #marg_dsc "s%s\n" \
360 , " -h, --help", USAGE_OPTSTR_HELP \
f45f3ec3 361 , " -V, --version", USAGE_OPTSTR_VERSION
b1a294c4 362
6f162034 363#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
cd7accd4
SK
364
365#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
366
2c308875
KZ
367#define print_version(eval) __extension__ ({ \
368 printf(UTIL_LINUX_VERSION); \
369 exit(eval); \
370})
371
640fc1b8
KZ
372/*
373 * scanf modifiers for "strings allocation"
374 */
375#ifdef HAVE_SCANF_MS_MODIFIER
376#define UL_SCNsA "%ms"
377#elif defined(HAVE_SCANF_AS_MODIFIER)
378#define UL_SCNsA "%as"
379#endif
380
9199f5cd
KZ
381/*
382 * seek stuff
383 */
384#ifndef SEEK_DATA
385# define SEEK_DATA 3
386#endif
387#ifndef SEEK_HOLE
388# define SEEK_HOLE 4
389#endif
390
ff1aaf99
SK
391
392/*
393 * Macros to convert #define'itions to strings, for example
394 * #define XYXXY 42
395 * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY));
396 */
397#define stringify_value(s) stringify(s)
398#define stringify(s) #s
399
d763c230
SK
400/*
401 * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
402 * instrumentation shipped with Clang and GCC) to not instrument the
403 * annotated function. Furthermore, it will prevent the compiler from
404 * inlining the function because inlining currently breaks the blacklisting
405 * mechanism of AddressSanitizer.
406 */
34b0a305
KZ
407#if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address)
408# define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address))
d763c230
SK
409#else
410# define UL_ASAN_BLACKLIST /* nothing */
411#endif
412
f7ac9e71
KZ
413/*
414 * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
415 * pwd buffer and in some cases it is not large enough. See POSIX and
416 * getpwnam_r man page for more details.
417 */
418#define UL_GETPW_BUFSIZ (16 * 1024)
419
40733239
RM
420/*
421 * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must
422 * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h.
423 */
424#if !defined MAP_ANONYMOUS && defined MAP_ANON
425# define MAP_ANONYMOUS (MAP_ANON)
426#endif
427
4d0dbb8b 428#endif /* UTIL_LINUX_C_H */