]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/util.h
util-lib: split out globbing related calls into glob-util.[ch]
[thirdparty/systemd.git] / src / basic / util.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
31885cd5 24#include <alloca.h>
370c860f 25#include <fcntl.h>
60918275 26#include <inttypes.h>
f6c2284a
LP
27#include <limits.h>
28#include <locale.h>
ec2002f8 29#include <stdarg.h>
60918275 30#include <stdbool.h>
f6c2284a 31#include <stddef.h>
80876c20 32#include <stdio.h>
f6c2284a
LP
33#include <stdlib.h>
34#include <sys/inotify.h>
2c35d880 35#include <sys/socket.h>
00dc5d76 36#include <sys/stat.h>
c6878637 37#include <sys/statfs.h>
f6c2284a
LP
38#include <sys/types.h>
39#include <time.h>
40#include <unistd.h>
60918275 41
f6c2284a 42#include "formats-util.h"
a838e6a1 43#include "macro.h"
dced1557 44#include "missing.h"
9a98c7a1 45#include "time-util.h"
871d7de4 46
44d8db9e 47/* What is interpreted as whitespace? */
4a72ff34 48#define WHITESPACE " \t\n\r"
e3e0314b
ZJS
49#define NEWLINE "\n\r"
50#define QUOTES "\"\'"
51#define COMMENTS "#;"
52#define GLOB_CHARS "*?["
44d8db9e 53
2e857429 54size_t page_size(void) _pure_;
37f85e66 55#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
56
4b8772bf 57#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
60918275
LP
58
59#define new0(t, n) ((t*) calloc((n), sizeof(t)))
60
0f0dbc46
LP
61#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
62
7629889c
LP
63#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
64
4b8772bf 65#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
888c7102 66
f80bb1f7 67#define malloc0(n) (calloc(1, (n)))
60918275 68
97b11eed
DH
69static inline void *mfree(void *memory) {
70 free(memory);
71 return NULL;
72}
73
60918275
LP
74static inline const char* yes_no(bool b) {
75 return b ? "yes" : "no";
76}
77
5232c42e
LS
78static inline const char* true_false(bool b) {
79 return b ? "true" : "false";
80}
81
769d324c
LP
82static inline const char* one_zero(bool b) {
83 return b ? "1" : "0";
84}
85
42856c10
LP
86bool fstype_is_network(const char *fstype);
87
919ce0b7 88noreturn void freeze(void);
3c14d26c 89
e801700e 90void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
83cc030f 91
a88c8750
TG
92bool plymouth_running(void);
93
44a6b1b6 94bool display_is_local(const char *display) _pure_;
4d6d6518
LP
95int socket_from_display(const char *display, char **path);
96
94959f0f
LP
97int block_get_whole_disk(dev_t d, dev_t *ret);
98
e23a0ce8 99#define NULSTR_FOREACH(i, l) \
c4e2ceae
LP
100 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
101
5c0532d1
LP
102#define NULSTR_FOREACH_PAIR(i, j, l) \
103 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
104
f8b69d1d 105int ioprio_class_to_string_alloc(int i, char **s);
1dccbe19
LP
106int ioprio_class_from_string(const char *s);
107
44a6b1b6
ZJS
108const char *sigchld_code_to_string(int i) _const_;
109int sigchld_code_from_string(const char *s) _pure_;
1dccbe19 110
f8b69d1d 111int sched_policy_to_string_alloc(int i, char **s);
1dccbe19
LP
112int sched_policy_from_string(const char *s);
113
9a0e6896
LP
114extern int saved_argc;
115extern char **saved_argv;
116
65457142
FC
117bool kexec_loaded(void);
118
44a6b1b6 119int prot_from_flags(int flags) _const_;
87d2c1ff 120
750ef272 121void* memdup(const void *p, size_t l) _alloc_(2);
55d7bfc1 122
9bdc770c 123int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
6bb92a16 124
9be346c9 125bool in_initrd(void);
069cfc85 126
a740c14c
MS
127static inline void freep(void *p) {
128 free(*(void**) p);
129}
130
dfb33a97 131#define _cleanup_free_ _cleanup_(freep)
c84a9488 132
750ef272 133_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
368504f4 134 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
4b8772bf
LP
135 return NULL;
136
137 return malloc(a * b);
138}
139
9489490a
DH
140_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
141 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
142 return NULL;
143
144 return realloc(p, a * b);
145}
146
750ef272 147_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
368504f4 148 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
4b8772bf
LP
149 return NULL;
150
151 return memdup(p, a * b);
152}
0b507b17 153
a9e12476
KS
154void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
155 int (*compar) (const void *, const void *, void *),
156 void *arg);
09017585 157
240dbaa4 158int on_ac_power(void);
f74e605f 159
6282c859
MS
160static inline void *mempset(void *s, int c, size_t n) {
161 memset(s, c, n);
dfb33a97 162 return (uint8_t*)s + n;
6282c859 163}
66e35261 164
7d50b32a
LP
165#define memzero(x,l) (memset((x), 0, (l)))
166#define zero(x) (memzero(&(x), sizeof(x)))
167
ca2d3784
ZJS
168void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
169void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
170#define GREEDY_REALLOC(array, allocated, need) \
171 greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
172
173#define GREEDY_REALLOC0(array, allocated, need) \
174 greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
a1937e67 175
5c0d398d 176static inline void _reset_errno_(int *saved_errno) {
5c0aa72a
LP
177 errno = *saved_errno;
178}
179
2a371001 180#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
5c0d398d 181
44dd2c6e
DH
182static inline int negative_errno(void) {
183 /* This helper should be used to shut up gcc if you know 'errno' is
184 * negative. Instead of "return -errno;", use "return negative_errno();"
185 * It will suppress bogus gcc warnings in case it assumes 'errno' might
186 * be 0 and thus the caller's error-handling might not be triggered. */
187 assert_return(errno > 0, -EINVAL);
188 return -errno;
189}
190
144e51ec 191static inline unsigned u64log2(uint64_t n) {
ec417ccc 192#if __SIZEOF_LONG_LONG__ == 8
693eb9a2 193 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
ec417ccc
LP
194#else
195#error "Wut?"
196#endif
197}
198
199static inline unsigned u32ctz(uint32_t n) {
200#if __SIZEOF_INT__ == 4
201 return __builtin_ctz(n);
202#else
203#error "Wut?"
204#endif
144e51ec 205}
79d860fe 206
7d328b54 207static inline unsigned log2i(int x) {
8fe90522
ZJS
208 assert(x > 0);
209
210 return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
211}
212
b5de6d98
MS
213static inline unsigned log2u(unsigned x) {
214 assert(x > 0);
215
216 return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
217}
218
219static inline unsigned log2u_round_up(unsigned x) {
220 assert(x > 0);
221
222 if (x == 1)
223 return 0;
224
225 return log2u(x - 1) + 1;
226}
227
82da66fb
LP
228#define alloca0(n) \
229 ({ \
230 char *_new_; \
231 size_t _len_ = n; \
232 _new_ = alloca(_len_); \
233 (void *) memset(_new_, 0, _len_); \
ed5c5dbd 234 })
95d78c7e 235
257224b0 236/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
95d78c7e
DH
237#define alloca_align(size, align) \
238 ({ \
239 void *_ptr_; \
240 size_t _mask_ = (align) - 1; \
241 _ptr_ = alloca((size) + _mask_); \
242 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
243 })
244
245#define alloca0_align(size, align) \
246 ({ \
247 void *_new_; \
248 size_t _size_ = (size); \
249 _new_ = alloca_align(_size_, (align)); \
250 (void*)memset(_new_, 0, _size_); \
251 })
66060897 252
44a6b1b6 253bool id128_is_valid(const char *s) _pure_;
d4ac85c6 254
7ff7394d
ZJS
255/**
256 * Normal qsort requires base to be nonnull. Here were require
257 * that only if nmemb > 0.
258 */
aeb24f30 259static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
1dbd13d8 260 if (nmemb <= 1)
aeb24f30
LP
261 return;
262
263 assert(base);
264 qsort(base, nmemb, size, compar);
7ff7394d 265}
74df0fca 266
bc9fd78c
LP
267int container_get_leader(const char *machine, pid_t *pid);
268
671c3419
RM
269int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
270int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
bf108e55 271
050f7277
LP
272#ifndef PERSONALITY_INVALID
273/* personality(7) documents that 0xffffffffUL is used for querying the
274 * current personality, hence let's use that here as error
275 * indicator. */
276#define PERSONALITY_INVALID 0xffffffffLU
277#endif
278
ac45f971
LP
279unsigned long personality_from_string(const char *p);
280const char *personality_to_string(unsigned long);
1c231f56
LP
281
282uint64_t physical_memory(void);
6db615c1 283
370c860f 284union file_handle_union {
c5220a94
MO
285 struct file_handle handle;
286 char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
370c860f 287};
2695c5c4 288#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
c5220a94
MO
289
290int update_reboot_param_file(const char *param);
6d313367 291
f7c1ad4f
LP
292#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
293
294#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
0254e944
SL
295 for ((e) = &buffer.ev; \
296 (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
f7c1ad4f 297 (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
72648326 298
0254e944
SL
299union inotify_event_buffer {
300 struct inotify_event ev;
301 uint8_t raw[INOTIFY_EVENT_MAX];
302};
303
3f6fd1ba 304int version(void);
8dd4c05b
LP
305
306bool fdname_is_valid(const char *s);
257b0719
EV
307
308bool oom_score_adjust_is_valid(int oa);