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