]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/macro.h
process-util: move PID related macros from macro.h to process-util.h
[thirdparty/systemd.git] / src / basic / macro.h
CommitLineData
03467c88 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
c2f1db8f 3#pragma once
60918275 4
a7334b09
LP
5/***
6 This file is part of systemd.
7
8 Copyright 2010 Lennart Poettering
9
10 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 18 Lesser General Public License for more details.
a7334b09 19
5430f7f2 20 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
60918275 24#include <assert.h>
6a39419f 25#include <sys/param.h>
60918275 26#include <sys/types.h>
c31e1495
LP
27#include <sys/uio.h>
28#include <inttypes.h>
c01ff965 29#include <stdbool.h>
60918275 30
44b601bc 31#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
750ef272 32#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
93a46b0b 33#define _sentinel_ __attribute__ ((sentinel))
93a46b0b
LP
34#define _unused_ __attribute__ ((unused))
35#define _destructor_ __attribute__ ((destructor))
36#define _pure_ __attribute__ ((pure))
37#define _const_ __attribute__ ((const))
38#define _deprecated_ __attribute__ ((deprecated))
39#define _packed_ __attribute__ ((packed))
40#define _malloc_ __attribute__ ((malloc))
41#define _weak_ __attribute__ ((weak))
42#define _likely_(x) (__builtin_expect(!!(x),1))
43#define _unlikely_(x) (__builtin_expect(!!(x),0))
40473a70
LP
44#define _public_ __attribute__ ((visibility("default")))
45#define _hidden_ __attribute__ ((visibility("hidden")))
ad780f19 46#define _weakref_(x) __attribute__((weakref(#x)))
19d1e4ee 47#define _alignas_(x) __attribute__((aligned(__alignof(x))))
dfb33a97 48#define _cleanup_(x) __attribute__((cleanup(x)))
60918275 49
7ebe131a
LP
50/* Temporarily disable some warnings */
51#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
52 _Pragma("GCC diagnostic push"); \
53 _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
54
bcfce235
LP
55#define DISABLE_WARNING_FORMAT_NONLITERAL \
56 _Pragma("GCC diagnostic push"); \
57 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
58
f0f2e63b
LP
59#define DISABLE_WARNING_MISSING_PROTOTYPES \
60 _Pragma("GCC diagnostic push"); \
61 _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
62
8fca4e30
LP
63#define DISABLE_WARNING_NONNULL \
64 _Pragma("GCC diagnostic push"); \
65 _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
66
d442e2ec
DH
67#define DISABLE_WARNING_SHADOW \
68 _Pragma("GCC diagnostic push"); \
69 _Pragma("GCC diagnostic ignored \"-Wshadow\"")
70
df99a9ef
ZJS
71#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \
72 _Pragma("GCC diagnostic push"); \
73 _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"")
74
7ebe131a
LP
75#define REENABLE_WARNING \
76 _Pragma("GCC diagnostic pop")
77
49e5de64
ZJS
78/* automake test harness */
79#define EXIT_TEST_SKIP 77
80
bef2733f
LP
81#define XSTRINGIFY(x) #x
82#define STRINGIFY(x) XSTRINGIFY(x)
83
ab9cbe34
LS
84#define XCONCATENATE(x, y) x ## y
85#define CONCATENATE(x, y) XCONCATENATE(x, y)
86
fb835651
DH
87#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
88#define UNIQ __COUNTER__
89
60918275 90/* Rounds up */
9be9c7cf
LP
91
92#define ALIGN4(l) (((l) + 3) & ~3)
93#define ALIGN8(l) (((l) + 7) & ~7)
94
95#if __SIZEOF_POINTER__ == 8
96#define ALIGN(l) ALIGN8(l)
97#elif __SIZEOF_POINTER__ == 4
98#define ALIGN(l) ALIGN4(l)
99#else
100#error "Wut? Pointers are neither 4 nor 8 bytes long?"
101#endif
102
5f86c1f4
LP
103#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p)))
104#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
105#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
e86b80b8 106
37f85e66 107static inline size_t ALIGN_TO(size_t l, size_t ali) {
108 return ((l + ali - 1) & ~(ali - 1));
22be093f
LP
109}
110
5f86c1f4 111#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
49aa47c7 112
625e870b
DH
113/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
114static inline unsigned long ALIGN_POWER2(unsigned long u) {
115 /* clz(0) is undefined */
116 if (u == 1)
117 return 1;
118
119 /* left-shift overflow is undefined */
120 if (__builtin_clzl(u - 1UL) < 1)
121 return 0;
122
123 return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
124}
125
7f39a210
MS
126#define ELEMENTSOF(x) \
127 __extension__ (__builtin_choose_expr( \
128 !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
129 sizeof(x)/sizeof((x)[0]), \
130 (void)0))
bbc98d32
KS
131/*
132 * container_of - cast a member of a structure out to the containing structure
133 * @ptr: the pointer to the member.
134 * @type: the type of the container struct this is embedded in.
135 * @member: the name of the member within the struct.
bbc98d32 136 */
fb835651
DH
137#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
138#define __container_of(uniq, ptr, type, member) \
fa70beaa 139 __extension__ ({ \
fb835651
DH
140 const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
141 (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
142 })
bbc98d32 143
9607d947 144#undef MAX
667a0377
DH
145#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
146#define __MAX(aq, a, bq, b) \
fdcba430 147 __extension__ ({ \
667a0377
DH
148 const typeof(a) UNIQ_T(A, aq) = (a); \
149 const typeof(b) UNIQ_T(B, bq) = (b); \
150 UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
151 })
60918275 152
7242d742
DH
153/* evaluates to (void) if _A or _B are not constant or of different types */
154#define CONST_MAX(_A, _B) \
155 __extension__ (__builtin_choose_expr( \
156 __builtin_constant_p(_A) && \
157 __builtin_constant_p(_B) && \
158 __builtin_types_compatible_p(typeof(_A), typeof(_B)), \
159 ((_A) > (_B)) ? (_A) : (_B), \
160 (void)0))
161
40a1eebd
DH
162/* takes two types and returns the size of the larger one */
163#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
164
fdcba430
DH
165#define MAX3(x,y,z) \
166 __extension__ ({ \
167 const typeof(x) _c = MAX(x,y); \
168 MAX(_c, z); \
9607d947 169 })
3b63d2d3 170
9607d947 171#undef MIN
667a0377
DH
172#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
173#define __MIN(aq, a, bq, b) \
fdcba430 174 __extension__ ({ \
667a0377
DH
175 const typeof(a) UNIQ_T(A, aq) = (a); \
176 const typeof(b) UNIQ_T(B, bq) = (b); \
177 UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
178 })
60918275 179
fdcba430
DH
180#define MIN3(x,y,z) \
181 __extension__ ({ \
182 const typeof(x) _c = MIN(x,y); \
183 MIN(_c, z); \
7df23077
DH
184 })
185
667a0377
DH
186#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
187#define __LESS_BY(aq, a, bq, b) \
fdcba430 188 __extension__ ({ \
667a0377
DH
189 const typeof(a) UNIQ_T(A, aq) = (a); \
190 const typeof(b) UNIQ_T(B, bq) = (b); \
191 UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \
192 })
348ced90 193
667a0377
DH
194#undef CLAMP
195#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
196#define __CLAMP(xq, x, lowq, low, highq, high) \
60918275 197 __extension__ ({ \
667a0377
DH
198 const typeof(x) UNIQ_T(X,xq) = (x); \
199 const typeof(low) UNIQ_T(LOW,lowq) = (low); \
200 const typeof(high) UNIQ_T(HIGH,highq) = (high); \
201 UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \
202 UNIQ_T(HIGH,highq) : \
203 UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \
204 UNIQ_T(LOW,lowq) : \
205 UNIQ_T(X,xq); \
206 })
60918275 207
180a60bc
DH
208/* [(x + y - 1) / y] suffers from an integer overflow, even though the
209 * computation should be possible in the given type. Therefore, we use
210 * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
211 * quotient and the remainder, so both should be equally fast. */
212#define DIV_ROUND_UP(_x, _y) \
213 __extension__ ({ \
214 const typeof(_x) __x = (_x); \
215 const typeof(_y) __y = (_y); \
216 (__x / __y + !!(__x % __y)); \
217 })
218
34c38d2a 219#define assert_message_se(expr, message) \
dd8f71ee 220 do { \
93a46b0b 221 if (_unlikely_(!(expr))) \
34c38d2a
MS
222 log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
223 } while (false)
224
225#define assert_se(expr) assert_message_se(expr, #expr)
dd8f71ee
LP
226
227/* We override the glibc assert() here. */
228#undef assert
229#ifdef NDEBUG
230#define assert(expr) do {} while(false)
231#else
34c38d2a 232#define assert(expr) assert_message_se(expr, #expr)
dd8f71ee 233#endif
60918275 234
dd8f71ee
LP
235#define assert_not_reached(t) \
236 do { \
b7f33638 237 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
dd8f71ee 238 } while (false)
60918275 239
f791c684 240#if defined(static_assert)
7ebe131a
LP
241/* static_assert() is sometimes defined in a way that trips up
242 * -Wdeclaration-after-statement, hence let's temporarily turn off
243 * this warning around it. */
244#define assert_cc(expr) \
245 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
246 static_assert(expr, #expr); \
247 REENABLE_WARNING
f791c684 248#else
7ebe131a
LP
249#define assert_cc(expr) \
250 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
6825a04d 251 struct CONCATENATE(_assert_struct_, __COUNTER__) { \
7ebe131a
LP
252 char x[(expr) ? 0 : -1]; \
253 }; \
254 REENABLE_WARNING
f791c684 255#endif
60918275 256
34c38d2a
MS
257#define assert_log(expr, message) ((_likely_(expr)) \
258 ? (true) \
259 : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
366e6411 260
80514f9c
LP
261#define assert_return(expr, r) \
262 do { \
34c38d2a 263 if (!assert_log(expr, #expr)) \
80514f9c 264 return (r); \
18387b59
LP
265 } while (false)
266
aa029628
TG
267#define assert_return_errno(expr, r, err) \
268 do { \
34c38d2a 269 if (!assert_log(expr, #expr)) { \
aa029628
TG
270 errno = err; \
271 return (r); \
272 } \
273 } while (false)
274
a3dc3547
KS
275#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
276#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
60918275 277#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
a3dc3547 278#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
60918275 279
a3dc3547
KS
280#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
281#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
c6c18be3 282#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
a3dc3547 283#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
c6c18be3 284
a3dc3547
KS
285#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
286#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
287#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
288#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
60918275 289
a3dc3547
KS
290#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
291#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
292#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
293#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
c6c18be3 294
74b2466e
LP
295#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
296#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
297
476fe607
LP
298#define memzero(x,l) (memset((x), 0, (l)))
299#define zero(x) (memzero(&(x), sizeof(x)))
300
a9c55a88
LP
301#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
302
034c6ed7
LP
303#define char_array_0(x) x[sizeof(x)-1] = 0;
304
bff7c062 305#define IOVEC_SET_STRING(i, s) \
2fa086a8 306 do { \
bff7c062
LP
307 struct iovec *_i = &(i); \
308 char *_s = (char *)(s); \
309 _i->iov_base = _s; \
310 _i->iov_len = strlen(_s); \
9b3c575e 311 } while(false)
2fa086a8 312
c31e1495
LP
313static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
314 unsigned j;
315 size_t r = 0;
316
317 for (j = 0; j < n; j++)
318 r += i[j].iov_len;
319
320 return r;
321}
322
323static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
324 unsigned j;
325
326 for (j = 0; j < n; j++) {
327 size_t sub;
328
329 if (_unlikely_(k <= 0))
330 break;
331
332 sub = MIN(i[j].iov_len, k);
333 i[j].iov_len -= sub;
334 i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
335 k -= sub;
336 }
337
338 return k;
339}
340
cecd32f6
LP
341#define VA_FORMAT_ADVANCE(format, ap) \
342do { \
343 int _argtypes[128]; \
963ddb91
LP
344 size_t _i, _k; \
345 _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
cecd32f6 346 assert(_k < ELEMENTSOF(_argtypes)); \
963ddb91
LP
347 for (_i = 0; _i < _k; _i++) { \
348 if (_argtypes[_i] & PA_FLAG_PTR) { \
349 (void) va_arg(ap, void*); \
350 continue; \
351 } \
352 \
353 switch (_argtypes[_i]) { \
354 case PA_INT: \
355 case PA_INT|PA_FLAG_SHORT: \
356 case PA_CHAR: \
357 (void) va_arg(ap, int); \
358 break; \
359 case PA_INT|PA_FLAG_LONG: \
360 (void) va_arg(ap, long int); \
361 break; \
362 case PA_INT|PA_FLAG_LONG_LONG: \
363 (void) va_arg(ap, long long int); \
364 break; \
365 case PA_WCHAR: \
366 (void) va_arg(ap, wchar_t); \
367 break; \
368 case PA_WSTRING: \
369 case PA_STRING: \
370 case PA_POINTER: \
371 (void) va_arg(ap, void*); \
372 break; \
373 case PA_FLOAT: \
374 case PA_DOUBLE: \
375 (void) va_arg(ap, double); \
376 break; \
377 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
378 (void) va_arg(ap, long double); \
379 break; \
380 default: \
381 assert_not_reached("Unknown format string argument."); \
382 } \
383 } \
384} while(false)
385
e5f476db 386 /* Because statfs.t_type can be int on some architectures, we have to cast
bdd29249
HH
387 * the const magic to the type, otherwise the compiler warns about
388 * signed/unsigned comparison, because the magic can be 32 bit unsigned.
389 */
c51cf056 390#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
bdd29249 391
fa70beaa
LP
392/* Returns the number of chars needed to format variables of the
393 * specified type as a decimal string. Adds in extra space for a
b7ce6b59
LP
394 * negative '-' prefix (hence works correctly on signed
395 * types). Includes space for the trailing NUL. */
fa70beaa 396#define DECIMAL_STR_MAX(type) \
5bcb0f2b 397 (2+(sizeof(type) <= 1 ? 3 : \
fa70beaa
LP
398 sizeof(type) <= 2 ? 5 : \
399 sizeof(type) <= 4 ? 10 : \
400 sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
401
264ad849
LP
402#define SET_FLAG(v, flag, b) \
403 (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
404
dc36d78e 405#define IN_SET(x, y, ...) \
059d9fbb 406 ({ \
77247cba 407 static const typeof(y) _array[] = { (y), __VA_ARGS__ }; \
249a2737 408 const typeof(y) _x = (x); \
059d9fbb
LP
409 unsigned _i; \
410 bool _found = false; \
249a2737
MS
411 for (_i = 0; _i < ELEMENTSOF(_array); _i++) \
412 if (_array[_i] == _x) { \
059d9fbb
LP
413 _found = true; \
414 break; \
415 } \
416 _found; \
cabb7806
LP
417 })
418
7f0a55d4
JT
419/* Return a nulstr for a standard cascade of configuration directories,
420 * suitable to pass to conf_files_list_nulstr or config_parse_many. */
421#define CONF_DIRS_NULSTR(n) \
422 "/etc/" n ".d\0" \
423 "/run/" n ".d\0" \
424 "/usr/local/lib/" n ".d\0" \
425 "/usr/lib/" n ".d\0" \
426 CONF_DIR_SPLIT_USR(n)
427
428#ifdef HAVE_SPLIT_USR
429#define CONF_DIR_SPLIT_USR(n) "/lib/" n ".d\0"
430#else
431#define CONF_DIR_SPLIT_USR(n)
432#endif
433
919ce0b7
SL
434/* Define C11 thread_local attribute even on older gcc compiler
435 * version */
ec202eae
SL
436#ifndef thread_local
437/*
438 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
439 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
440 */
441#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
442#define thread_local _Thread_local
443#else
444#define thread_local __thread
445#endif
446#endif
cabb7806 447
919ce0b7
SL
448/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
449 * compiler versions */
450#ifndef noreturn
451#if __STDC_VERSION__ >= 201112L
452#define noreturn _Noreturn
453#else
454#define noreturn __attribute__((noreturn))
455#endif
456#endif
457
fed1e721
LP
458#define MODE_INVALID ((mode_t) -1)
459
a2341f68
ZJS
460#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
461 static inline void func##p(type *p) { \
462 if (*p) \
463 func(*p); \
464 } \
465 struct __useless_struct_to_allow_trailing_semicolon__
466
2a1288ff
LP
467#define CMSG_FOREACH(cmsg, mh) \
468 for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
469
dd8f71ee 470#include "log.h"