]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/util.h
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / util.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <alloca.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <inttypes.h>
27 #include <limits.h>
28 #include <locale.h>
29 #include <stdarg.h>
30 #include <stdbool.h>
31 #include <stddef.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/inotify.h>
37 #include <sys/socket.h>
38 #include <sys/stat.h>
39 #include <sys/statfs.h>
40 #include <sys/sysmacros.h>
41 #include <sys/types.h>
42 #include <time.h>
43 #include <unistd.h>
44
45 #include "format-util.h"
46 #include "macro.h"
47 #include "missing.h"
48 #include "time-util.h"
49
50 size_t page_size(void) _pure_;
51 #define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
52
53 static inline const char* yes_no(bool b) {
54 return b ? "yes" : "no";
55 }
56
57 static inline const char* true_false(bool b) {
58 return b ? "true" : "false";
59 }
60
61 static inline const char* one_zero(bool b) {
62 return b ? "1" : "0";
63 }
64
65 static inline const char* enable_disable(bool b) {
66 return b ? "enable" : "disable";
67 }
68
69 bool plymouth_running(void);
70
71 bool display_is_local(const char *display) _pure_;
72 int socket_from_display(const char *display, char **path);
73
74 int block_get_whole_disk(dev_t d, dev_t *ret);
75
76 #define NULSTR_FOREACH(i, l) \
77 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
78
79 #define NULSTR_FOREACH_PAIR(i, j, l) \
80 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
81
82 extern int saved_argc;
83 extern char **saved_argv;
84
85 bool kexec_loaded(void);
86
87 int prot_from_flags(int flags) _const_;
88
89 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
90
91 bool in_initrd(void);
92 void in_initrd_force(bool value);
93
94 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
95 int (*compar) (const void *, const void *, void *),
96 void *arg);
97
98 /**
99 * Normal qsort requires base to be nonnull. Here were require
100 * that only if nmemb > 0.
101 */
102 static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
103 if (nmemb <= 1)
104 return;
105
106 assert(base);
107 qsort(base, nmemb, size, compar);
108 }
109
110 /**
111 * Normal memcpy requires src to be nonnull. We do nothing if n is 0.
112 */
113 static inline void memcpy_safe(void *dst, const void *src, size_t n) {
114 if (n == 0)
115 return;
116 assert(src);
117 memcpy(dst, src, n);
118 }
119
120 int on_ac_power(void);
121
122 #define memzero(x,l) (memset((x), 0, (l)))
123 #define zero(x) (memzero(&(x), sizeof(x)))
124
125 static inline void *mempset(void *s, int c, size_t n) {
126 memset(s, c, n);
127 return (uint8_t*)s + n;
128 }
129
130 static inline void _reset_errno_(int *saved_errno) {
131 errno = *saved_errno;
132 }
133
134 #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
135
136 static inline int negative_errno(void) {
137 /* This helper should be used to shut up gcc if you know 'errno' is
138 * negative. Instead of "return -errno;", use "return negative_errno();"
139 * It will suppress bogus gcc warnings in case it assumes 'errno' might
140 * be 0 and thus the caller's error-handling might not be triggered. */
141 assert_return(errno > 0, -EINVAL);
142 return -errno;
143 }
144
145 static inline unsigned u64log2(uint64_t n) {
146 #if __SIZEOF_LONG_LONG__ == 8
147 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
148 #else
149 #error "Wut?"
150 #endif
151 }
152
153 static inline unsigned u32ctz(uint32_t n) {
154 #if __SIZEOF_INT__ == 4
155 return __builtin_ctz(n);
156 #else
157 #error "Wut?"
158 #endif
159 }
160
161 static inline unsigned log2i(int x) {
162 assert(x > 0);
163
164 return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
165 }
166
167 static inline unsigned log2u(unsigned x) {
168 assert(x > 0);
169
170 return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
171 }
172
173 static inline unsigned log2u_round_up(unsigned x) {
174 assert(x > 0);
175
176 if (x == 1)
177 return 0;
178
179 return log2u(x - 1) + 1;
180 }
181
182 int container_get_leader(const char *machine, pid_t *pid);
183
184 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
185 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
186
187 uint64_t physical_memory(void);
188 uint64_t physical_memory_scale(uint64_t v, uint64_t max);
189
190 uint64_t system_tasks_max(void);
191 uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
192
193 int update_reboot_parameter_and_warn(const char *param);
194
195 int version(void);
196
197 int get_block_device(const char *path, dev_t *dev);
198 int get_block_device_harder(const char *path, dev_t *dev);