chiark / gitweb /
basic/strv: use SWAP_TWO() macro (#3602)
[elogind.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 "formats-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 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
65
66 #if 0 /// UNNEEDED by elogind
67 bool plymouth_running(void);
68 #endif // 0
69
70 bool display_is_local(const char *display) _pure_;
71 int socket_from_display(const char *display, char **path);
72
73 #if 0 /// UNNEEDED by elogind
74 int block_get_whole_disk(dev_t d, dev_t *ret);
75 #endif // 0
76
77 #define NULSTR_FOREACH(i, l)                                    \
78         for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
79
80 #define NULSTR_FOREACH_PAIR(i, j, l)                             \
81         for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
82
83 extern int saved_argc;
84 extern char **saved_argv;
85
86 #if 0 /// UNNEEDED by elogind
87 bool kexec_loaded(void);
88
89 int prot_from_flags(int flags) _const_;
90 #endif // 0
91
92 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
93
94 bool in_initrd(void);
95
96 #if 0 /// UNNEEDED by elogind
97 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
98                  int (*compar) (const void *, const void *, void *),
99                  void *arg);
100 #endif // 0
101
102 /**
103  * Normal qsort requires base to be nonnull. Here were require
104  * that only if nmemb > 0.
105  */
106 static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
107         if (nmemb <= 1)
108                 return;
109
110         assert(base);
111         qsort(base, nmemb, size, compar);
112 }
113
114 /**
115  * Normal memcpy requires src to be nonnull. We do nothing if n is 0.
116  */
117 static inline void memcpy_safe(void *dst, const void *src, size_t n) {
118         if (n == 0)
119                 return;
120         assert(src);
121         memcpy(dst, src, n);
122 }
123
124 #if 0 /// UNNEEDED by elogind
125 int on_ac_power(void);
126 #endif // 0
127
128 #define memzero(x,l) (memset((x), 0, (l)))
129 #define zero(x) (memzero(&(x), sizeof(x)))
130
131 static inline void *mempset(void *s, int c, size_t n) {
132         memset(s, c, n);
133         return (uint8_t*)s + n;
134 }
135
136 static inline void _reset_errno_(int *saved_errno) {
137         errno = *saved_errno;
138 }
139
140 #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
141
142 static inline int negative_errno(void) {
143         /* This helper should be used to shut up gcc if you know 'errno' is
144          * negative. Instead of "return -errno;", use "return negative_errno();"
145          * It will suppress bogus gcc warnings in case it assumes 'errno' might
146          * be 0 and thus the caller's error-handling might not be triggered. */
147         assert_return(errno > 0, -EINVAL);
148         return -errno;
149 }
150
151 static inline unsigned u64log2(uint64_t n) {
152 #if __SIZEOF_LONG_LONG__ == 8
153         return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
154 #else
155 #error "Wut?"
156 #endif
157 }
158
159 static inline unsigned u32ctz(uint32_t n) {
160 #if __SIZEOF_INT__ == 4
161         return __builtin_ctz(n);
162 #else
163 #error "Wut?"
164 #endif
165 }
166
167 static inline unsigned log2i(int x) {
168         assert(x > 0);
169
170         return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
171 }
172
173 static inline unsigned log2u(unsigned x) {
174         assert(x > 0);
175
176         return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
177 }
178
179 static inline unsigned log2u_round_up(unsigned x) {
180         assert(x > 0);
181
182         if (x == 1)
183                 return 0;
184
185         return log2u(x - 1) + 1;
186 }
187
188 #if 0 /// UNNEEDED by elogind
189 bool id128_is_valid(const char *s) _pure_;
190 #endif // 0
191
192 int container_get_leader(const char *machine, pid_t *pid);
193
194 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
195 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
196
197 uint64_t physical_memory(void);
198
199 #if 0 /// UNNEEDED by elogind
200 #endif // 0
201 int update_reboot_parameter_and_warn(const char *param);
202
203 int version(void);