]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/util.h
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / basic / util.h
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
c2f1db8f 2#pragma once
60918275 3
31885cd5 4#include <alloca.h>
11c3a366 5#include <errno.h>
370c860f 6#include <fcntl.h>
60918275 7#include <inttypes.h>
f6c2284a
LP
8#include <limits.h>
9#include <locale.h>
ec2002f8 10#include <stdarg.h>
60918275 11#include <stdbool.h>
f6c2284a 12#include <stddef.h>
11c3a366 13#include <stdint.h>
80876c20 14#include <stdio.h>
f6c2284a 15#include <stdlib.h>
11c3a366 16#include <string.h>
f6c2284a 17#include <sys/inotify.h>
2c35d880 18#include <sys/socket.h>
00dc5d76 19#include <sys/stat.h>
c6878637 20#include <sys/statfs.h>
27d13af7 21#include <sys/sysmacros.h>
f6c2284a
LP
22#include <sys/types.h>
23#include <time.h>
24#include <unistd.h>
60918275 25
f97b34a6 26#include "format-util.h"
a838e6a1 27#include "macro.h"
9a98c7a1 28#include "time-util.h"
871d7de4 29
2e857429 30size_t page_size(void) _pure_;
37f85e66 31#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
32
60918275
LP
33static inline const char* yes_no(bool b) {
34 return b ? "yes" : "no";
35}
36
5232c42e
LS
37static inline const char* true_false(bool b) {
38 return b ? "true" : "false";
39}
40
769d324c
LP
41static inline const char* one_zero(bool b) {
42 return b ? "1" : "0";
43}
44
2d37cd53
ZJS
45static inline const char* enable_disable(bool b) {
46 return b ? "enable" : "disable";
47}
48
a88c8750
TG
49bool plymouth_running(void);
50
44a6b1b6 51bool display_is_local(const char *display) _pure_;
4d6d6518 52
e23a0ce8 53#define NULSTR_FOREACH(i, l) \
c4e2ceae
LP
54 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
55
5c0532d1
LP
56#define NULSTR_FOREACH_PAIR(i, j, l) \
57 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
58
9a0e6896
LP
59extern int saved_argc;
60extern char **saved_argv;
61
65457142
FC
62bool kexec_loaded(void);
63
44a6b1b6 64int prot_from_flags(int flags) _const_;
87d2c1ff 65
9be346c9 66bool in_initrd(void);
dcd61450 67void in_initrd_force(bool value);
069cfc85 68
a9e12476 69void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
f0f6d791
YW
70 __compar_d_fn_t compar, void *arg);
71
72#define typesafe_bsearch_r(k, b, n, func, userdata) \
73 ({ \
74 const typeof(b[0]) *_k = k; \
75 int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \
76 xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \
77 })
09017585 78
d6c5d19b
ZJS
79/**
80 * Normal bsearch requires base to be nonnull. Here were require
81 * that only if nmemb > 0.
82 */
83static inline void* bsearch_safe(const void *key, const void *base,
f0f6d791 84 size_t nmemb, size_t size, __compar_fn_t compar) {
d6c5d19b
ZJS
85 if (nmemb <= 0)
86 return NULL;
87
88 assert(base);
89 return bsearch(key, base, nmemb, size, compar);
90}
91
f0f6d791
YW
92#define typesafe_bsearch(k, b, n, func) \
93 ({ \
94 const typeof(b[0]) *_k = k; \
95 int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \
96 bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \
97 })
98
b5efdb8a
LP
99/**
100 * Normal qsort requires base to be nonnull. Here were require
101 * that only if nmemb > 0.
102 */
5532395b 103static inline void qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) {
b5efdb8a
LP
104 if (nmemb <= 1)
105 return;
f74e605f 106
b5efdb8a
LP
107 assert(base);
108 qsort(base, nmemb, size, compar);
6282c859 109}
66e35261 110
1ce36081
LP
111/* A wrapper around the above, but that adds typesafety: the element size is automatically derived from the type and so
112 * is the prototype for the comparison function */
113#define typesafe_qsort(p, n, func) \
114 ({ \
115 int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
116 qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \
117 })
118
5532395b 119static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) {
adea407d
LP
120 if (nmemb <= 1)
121 return;
122
123 assert(base);
124 qsort_r(base, nmemb, size, compar, userdata);
125}
126
5532395b
YW
127#define typesafe_qsort_r(p, n, func, userdata) \
128 ({ \
129 int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \
130 qsort_r_safe((p), (n), sizeof((p)[0]), (__compar_d_fn_t) _func_, userdata); \
131 })
132
f30faf85 133/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
75f32f04
ZJS
134static inline void memcpy_safe(void *dst, const void *src, size_t n) {
135 if (n == 0)
136 return;
137 assert(src);
138 memcpy(dst, src, n);
139}
140
f30faf85
YW
141/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
142static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
143 if (n == 0)
144 return 0;
145 assert(s1);
146 assert(s2);
147 return memcmp(s1, s2, n);
148}
149
dc6bf94d
FB
150/* Compare s1 (length n1) with s2 (length n2) in lexicographic order. */
151static inline int memcmp_nn(const void *s1, size_t n1, const void *s2, size_t n2) {
152 return memcmp_safe(s1, s2, MIN(n1, n2))
153 ?: CMP(n1, n2);
154}
155
b5efdb8a
LP
156int on_ac_power(void);
157
65f95765
LP
158#define memzero(x,l) \
159 ({ \
160 size_t _l_ = (l); \
161 void *_x_ = (x); \
162 _l_ == 0 ? _x_ : memset(_x_, 0, _l_); \
163 })
164
7d50b32a
LP
165#define zero(x) (memzero(&(x), sizeof(x)))
166
7f6bfc56
ZJS
167bool memeqzero(const void *data, size_t length);
168
169#define eqzero(x) memeqzero(x, sizeof(x))
170
b5efdb8a
LP
171static inline void *mempset(void *s, int c, size_t n) {
172 memset(s, c, n);
173 return (uint8_t*)s + n;
174}
a1937e67 175
5c0d398d 176static inline void _reset_errno_(int *saved_errno) {
840f606d
LP
177 if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
178 return;
179
0192cbdb 180 errno = *saved_errno;
5c0aa72a
LP
181}
182
012c2f76 183#define PROTECT_ERRNO \
d34dae18 184 _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
5c0d398d 185
840f606d
LP
186#define UNPROTECT_ERRNO \
187 do { \
188 errno = _saved_errno_; \
189 _saved_errno_ = -1; \
190 } while (false)
191
44dd2c6e
DH
192static inline int negative_errno(void) {
193 /* This helper should be used to shut up gcc if you know 'errno' is
194 * negative. Instead of "return -errno;", use "return negative_errno();"
195 * It will suppress bogus gcc warnings in case it assumes 'errno' might
196 * be 0 and thus the caller's error-handling might not be triggered. */
197 assert_return(errno > 0, -EINVAL);
198 return -errno;
199}
200
144e51ec 201static inline unsigned u64log2(uint64_t n) {
ec417ccc 202#if __SIZEOF_LONG_LONG__ == 8
693eb9a2 203 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
ec417ccc
LP
204#else
205#error "Wut?"
206#endif
207}
208
209static inline unsigned u32ctz(uint32_t n) {
210#if __SIZEOF_INT__ == 4
1a359852 211 return n != 0 ? __builtin_ctz(n) : 32;
ec417ccc
LP
212#else
213#error "Wut?"
214#endif
144e51ec 215}
79d860fe 216
7d328b54 217static inline unsigned log2i(int x) {
8fe90522
ZJS
218 assert(x > 0);
219
220 return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
221}
222
b5de6d98
MS
223static inline unsigned log2u(unsigned x) {
224 assert(x > 0);
225
226 return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
227}
228
229static inline unsigned log2u_round_up(unsigned x) {
230 assert(x > 0);
231
232 if (x == 1)
233 return 0;
234
235 return log2u(x - 1) + 1;
236}
237
bc9fd78c
LP
238int container_get_leader(const char *machine, pid_t *pid);
239
671c3419
RM
240int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
241int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
bf108e55 242
1c231f56 243uint64_t physical_memory(void);
d8cf2ac7 244uint64_t physical_memory_scale(uint64_t v, uint64_t max);
6db615c1 245
83f8e808
LP
246uint64_t system_tasks_max(void);
247uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
248
3f6fd1ba 249int version(void);
68c58c67
LP
250
251int str_verscmp(const char *s1, const char *s2);
9ce17593 252
e557b1a6 253void disable_coredumps(void);