]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/util.h
util-lib: split out IO related calls to io-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>
f6c2284a 25#include <dirent.h>
370c860f 26#include <fcntl.h>
60918275 27#include <inttypes.h>
f6c2284a
LP
28#include <limits.h>
29#include <locale.h>
30#include <mntent.h>
ec2002f8 31#include <stdarg.h>
60918275 32#include <stdbool.h>
f6c2284a 33#include <stddef.h>
80876c20 34#include <stdio.h>
f6c2284a
LP
35#include <stdlib.h>
36#include <sys/inotify.h>
2c35d880 37#include <sys/socket.h>
00dc5d76 38#include <sys/stat.h>
c6878637 39#include <sys/statfs.h>
f6c2284a
LP
40#include <sys/types.h>
41#include <time.h>
42#include <unistd.h>
60918275 43
f6c2284a 44#include "formats-util.h"
a838e6a1 45#include "macro.h"
dced1557 46#include "missing.h"
9a98c7a1 47#include "time-util.h"
871d7de4 48
44d8db9e 49/* What is interpreted as whitespace? */
4a72ff34 50#define WHITESPACE " \t\n\r"
e3e0314b
ZJS
51#define NEWLINE "\n\r"
52#define QUOTES "\"\'"
53#define COMMENTS "#;"
54#define GLOB_CHARS "*?["
44d8db9e 55
a7bc2c2a 56#define FORMAT_BYTES_MAX 8
8b6c7120 57
2e857429 58size_t page_size(void) _pure_;
37f85e66 59#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
60
4b8772bf 61#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
60918275
LP
62
63#define new0(t, n) ((t*) calloc((n), sizeof(t)))
64
0f0dbc46
LP
65#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
66
7629889c
LP
67#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
68
4b8772bf 69#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
888c7102 70
f80bb1f7 71#define malloc0(n) (calloc(1, (n)))
60918275 72
97b11eed
DH
73static inline void *mfree(void *memory) {
74 free(memory);
75 return NULL;
76}
77
60918275
LP
78static inline const char* yes_no(bool b) {
79 return b ? "yes" : "no";
80}
81
5232c42e
LS
82static inline const char* true_false(bool b) {
83 return b ? "true" : "false";
84}
85
769d324c
LP
86static inline const char* one_zero(bool b) {
87 return b ? "1" : "0";
88}
89
59f448cf 90int parse_size(const char *t, uint64_t base, uint64_t *size);
5556b5fe 91
44a6b1b6 92int parse_boolean(const char *v) _pure_;
3ba686c1 93int parse_pid(const char *s, pid_t* ret_pid);
034a2a52 94int parse_uid(const char *s, uid_t* ret_uid);
a1f686da
LP
95#define parse_gid(s, ret_gid) parse_uid(s, ret_gid)
96
97bool uid_is_valid(uid_t uid);
c077529b
LP
98
99static inline bool gid_is_valid(gid_t gid) {
100 return uid_is_valid((uid_t) gid);
101}
85261803
LP
102
103int safe_atou(const char *s, unsigned *ret_u);
104int safe_atoi(const char *s, int *ret_i);
105
8f75a603
LP
106int safe_atollu(const char *s, unsigned long long *ret_u);
107int safe_atolli(const char *s, long long int *ret_i);
108
f7900e25
TA
109int safe_atod(const char *s, double *ret_d);
110
b914e211
LP
111int safe_atou8(const char *s, uint8_t *ret);
112
8507eb20 113#if LONG_MAX == INT_MAX
8f75a603
LP
114static inline int safe_atolu(const char *s, unsigned long *ret_u) {
115 assert_cc(sizeof(unsigned long) == sizeof(unsigned));
116 return safe_atou(s, (unsigned*) ret_u);
117}
118static inline int safe_atoli(const char *s, long int *ret_u) {
119 assert_cc(sizeof(long int) == sizeof(int));
120 return safe_atoi(s, (int*) ret_u);
121}
122#else
123static inline int safe_atolu(const char *s, unsigned long *ret_u) {
124 assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
125 return safe_atollu(s, (unsigned long long*) ret_u);
126}
127static inline int safe_atoli(const char *s, long int *ret_u) {
128 assert_cc(sizeof(long int) == sizeof(long long int));
129 return safe_atolli(s, (long long int*) ret_u);
130}
131#endif
132
a838e6a1
LP
133static inline int safe_atou32(const char *s, uint32_t *ret_u) {
134 assert_cc(sizeof(uint32_t) == sizeof(unsigned));
135 return safe_atou(s, (unsigned*) ret_u);
136}
137
8f75a603 138static inline int safe_atoi32(const char *s, int32_t *ret_i) {
a838e6a1 139 assert_cc(sizeof(int32_t) == sizeof(int));
8f75a603 140 return safe_atoi(s, (int*) ret_i);
a838e6a1
LP
141}
142
8f75a603
LP
143static inline int safe_atou64(const char *s, uint64_t *ret_u) {
144 assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
145 return safe_atollu(s, (unsigned long long*) ret_u);
146}
034c6ed7 147
8f75a603
LP
148static inline int safe_atoi64(const char *s, int64_t *ret_i) {
149 assert_cc(sizeof(int64_t) == sizeof(long long int));
150 return safe_atolli(s, (long long int*) ret_i);
151}
034c6ed7 152
781fa938
LP
153int safe_atou16(const char *s, uint16_t *ret);
154int safe_atoi16(const char *s, int16_t *ret);
155
849958d1 156int readlinkat_malloc(int fd, const char *p, char **ret);
87f0e418 157int readlink_malloc(const char *p, char **r);
9a67bcf2 158int readlink_value(const char *p, char **ret);
2c7108c4 159int readlink_and_make_absolute(const char *p, char **r);
83096483 160int readlink_and_canonicalize(const char *p, char **r);
87f0e418 161
4a72ff34
LP
162char *file_in_same_dir(const char *path, const char *filename);
163
c32dd69b
LP
164int rmdir_parents(const char *path, const char *stop);
165
bcb92f48
CR
166char hexchar(int x) _const_;
167int unhexchar(char c) _const_;
168char octchar(int x) _const_;
169int unoctchar(char c) _const_;
170char decchar(int x) _const_;
171int undecchar(char c) _const_;
919a7f5f
TG
172char base32hexchar(int x) _const_;
173int unbase32hexchar(char c) _const_;
13a5d76b
TG
174char base64char(int x) _const_;
175int unbase64char(char c) _const_;
4fe88d28 176
44a6b1b6
ZJS
177bool dirent_is_file(const struct dirent *de) _pure_;
178bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
87d2c1ff 179
a34bf9db 180bool hidden_file(const char *filename) _pure_;
c85dc17b 181
f8b69d1d 182/* For basic lookup tables with strictly enumerated entries */
b9a5f858 183#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
4e240ab0 184 scope const char *name##_to_string(type i) { \
1dccbe19
LP
185 if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
186 return NULL; \
187 return name##_table[i]; \
b9a5f858
LP
188 }
189
9cad100e
BB
190ssize_t string_table_lookup(const char * const *table, size_t len, const char *key);
191
8c721f2b
LP
192#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
193 scope type name##_from_string(const char *s) { \
194 return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
b9a5f858
LP
195 }
196
197#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
198 _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
199 _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
1dccbe19
LP
200 struct __useless_struct_to_allow_trailing_semicolon__
201
b9a5f858
LP
202#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
203#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
204#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
205#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
1dccbe19 206
f8b69d1d
MS
207/* For string conversions where numbers are also acceptable */
208#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
209 int name##_to_string_alloc(type i, char **str) { \
210 char *s; \
f8b69d1d
MS
211 if (i < 0 || i > max) \
212 return -ERANGE; \
213 if (i < (type) ELEMENTSOF(name##_table)) { \
214 s = strdup(name##_table[i]); \
215 if (!s) \
8c721f2b 216 return -ENOMEM; \
f8b69d1d 217 } else { \
8c721f2b
LP
218 if (asprintf(&s, "%i", i) < 0) \
219 return -ENOMEM; \
f8b69d1d
MS
220 } \
221 *str = s; \
222 return 0; \
223 } \
224 type name##_from_string(const char *s) { \
225 type i; \
226 unsigned u = 0; \
8c721f2b
LP
227 if (!s) \
228 return (type) -1; \
229 for (i = 0; i < (type) ELEMENTSOF(name##_table); i++) \
230 if (streq_ptr(name##_table[i], s)) \
f8b69d1d 231 return i; \
8511dd18 232 if (safe_atou(s, &u) >= 0 && u <= max) \
f8b69d1d
MS
233 return (type) u; \
234 return (type) -1; \
235 } \
236 struct __useless_struct_to_allow_trailing_semicolon__
237
42856c10
LP
238bool fstype_is_network(const char *fstype);
239
5a3ab509 240int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
8d567588 241
8407a5d0
LP
242bool is_device_path(const char *path);
243
01f78473 244int dir_is_empty(const char *path);
844ec79b 245char* dirname_malloc(const char *path);
01f78473 246
ac7edd91
LP
247static inline int dir_is_populated(const char *path) {
248 int r;
249 r = dir_is_empty(path);
250 if (r < 0)
251 return r;
252 return !r;
253}
254
f1566e63 255char* lookup_uid(uid_t uid);
ef2f1067 256char* getlogname_malloc(void);
7c5f152a 257char* getusername_malloc(void);
fc116c6a 258
8c6db833 259int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
f4b47811 260int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
8c6db833 261
d1678248
ILG
262typedef long statfs_f_type_t;
263
264bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
265int fd_check_fstype(int fd, statfs_f_type_t magic_value);
266int path_check_fstype(const char *path, statfs_f_type_t magic_value);
267
c6878637
LP
268bool is_temporary_fs(const struct statfs *s) _pure_;
269int fd_is_temporary_fs(int fd);
ef2f1067 270
a8b62610
MS
271#define xsprintf(buf, fmt, ...) \
272 assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), \
273 "xsprintf: " #buf "[] must be big enough")
5ffa8c81 274
9d9951a4
HH
275int files_same(const char *filea, const char *fileb);
276
b4f10a5e
LP
277int running_in_chroot(void);
278
c38dfac9 279int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
f6144808
LP
280int touch(const char *path);
281
919ce0b7 282noreturn void freeze(void);
3c14d26c 283
44a6b1b6 284bool null_or_empty(struct stat *st) _pure_;
83096483 285int null_or_empty_path(const char *fn);
ed88bcfb 286int null_or_empty_fd(int fd);
00dc5d76 287
a247755d 288DIR *xopendirat(int dirfd, const char *name, int flags);
3b63d2d3 289
e23a0ce8
LP
290char *fstab_node_to_udev_node(const char *p);
291
e801700e 292void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
83cc030f 293
a88c8750
TG
294bool plymouth_running(void);
295
875e1014 296int symlink_idempotent(const char *from, const char *to);
6ea832a2 297
424a19f8 298int symlink_atomic(const char *from, const char *to);
1554afae
LP
299int mknod_atomic(const char *path, mode_t mode, dev_t dev);
300int mkfifo_atomic(const char *path, mode_t mode);
34ca941c
LP
301
302int fchmod_umask(int fd, mode_t mode);
303
44a6b1b6 304bool display_is_local(const char *display) _pure_;
4d6d6518
LP
305int socket_from_display(const char *display, char **path);
306
d05c5031 307int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
4b67834e 308int get_group_creds(const char **groupname, gid_t *gid);
1cccf435 309
4468addc 310int in_gid(gid_t gid);
43673799
LP
311int in_group(const char *name);
312
59164be4 313char* uid_to_name(uid_t uid);
4468addc 314char* gid_to_name(gid_t gid);
59164be4 315
8092a428 316int glob_exists(const char *path);
8d98da3f 317int glob_extend(char ***strv, const char *path);
8092a428 318
83096483
LP
319int dirent_ensure_type(DIR *d, struct dirent *de);
320
034a2a52 321int get_files_in_directory(const char *path, char ***list);
83096483 322
b636465b
LP
323bool is_main_thread(void);
324
94959f0f
LP
325int block_get_whole_disk(dev_t d, dev_t *ret);
326
e23a0ce8 327#define NULSTR_FOREACH(i, l) \
c4e2ceae
LP
328 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
329
5c0532d1
LP
330#define NULSTR_FOREACH_PAIR(i, j, l) \
331 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
332
f8b69d1d 333int ioprio_class_to_string_alloc(int i, char **s);
1dccbe19
LP
334int ioprio_class_from_string(const char *s);
335
44a6b1b6
ZJS
336const char *sigchld_code_to_string(int i) _const_;
337int sigchld_code_from_string(const char *s) _pure_;
1dccbe19 338
f8b69d1d 339int log_facility_unshifted_to_string_alloc(int i, char **s);
7d76f312 340int log_facility_unshifted_from_string(const char *s);
adb8ec96 341bool log_facility_unshifted_is_valid(int faciliy);
1dccbe19 342
f8b69d1d 343int log_level_to_string_alloc(int i, char **s);
1dccbe19 344int log_level_from_string(const char *s);
adb8ec96 345bool log_level_is_valid(int level);
1dccbe19 346
f8b69d1d 347int sched_policy_to_string_alloc(int i, char **s);
1dccbe19
LP
348int sched_policy_from_string(const char *s);
349
44a6b1b6
ZJS
350const char *rlimit_to_string(int i) _const_;
351int rlimit_from_string(const char *s) _pure_;
1dccbe19 352
f8b69d1d 353int ip_tos_to_string_alloc(int i, char **s);
4fd5948e
LP
354int ip_tos_from_string(const char *s);
355
9a0e6896
LP
356extern int saved_argc;
357extern char **saved_argv;
358
65457142
FC
359bool kexec_loaded(void);
360
44a6b1b6 361int prot_from_flags(int flags) _const_;
87d2c1ff 362
59f448cf 363char *format_bytes(char *buf, size_t l, uint64_t t);
babfc091 364
750ef272 365void* memdup(const void *p, size_t l) _alloc_(2);
55d7bfc1 366
bb99a35a
LP
367int fd_inc_sndbuf(int fd, size_t n);
368int fd_inc_rcvbuf(int fd, size_t n);
6bb92a16 369
9bdc770c 370int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
6bb92a16 371
68faf98c
LP
372int setrlimit_closest(int resource, const struct rlimit *rlim);
373
a2e03378
LP
374bool http_url_is_valid(const char *url) _pure_;
375bool documentation_url_is_valid(const char *url) _pure_;
49dbfa7b 376
3d7415f4
LP
377bool http_etag_is_valid(const char *etag);
378
9be346c9 379bool in_initrd(void);
069cfc85 380
7c5f152a 381int get_home_dir(char **ret);
2cfbd749 382int get_shell(char **_ret);
2fbe635a 383
a740c14c
MS
384static inline void freep(void *p) {
385 free(*(void**) p);
386}
387
dfb33a97
LP
388static inline void umaskp(mode_t *u) {
389 umask(*u);
763c7aa2
ZJS
390}
391
14bf2c9d 392DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent);
5862d652 393
dfb33a97 394#define _cleanup_free_ _cleanup_(freep)
dfb33a97
LP
395#define _cleanup_umask_ _cleanup_(umaskp)
396#define _cleanup_globfree_ _cleanup_(globfree)
5862d652 397#define _cleanup_endmntent_ _cleanup_(endmntentp)
c84a9488 398
750ef272 399_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
368504f4 400 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
4b8772bf
LP
401 return NULL;
402
403 return malloc(a * b);
404}
405
9489490a
DH
406_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
407 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
408 return NULL;
409
410 return realloc(p, a * b);
411}
412
750ef272 413_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
368504f4 414 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
4b8772bf
LP
415 return NULL;
416
417 return memdup(p, a * b);
418}
0b507b17 419
ae6c3cc0 420bool filename_is_valid(const char *p) _pure_;
44a6b1b6
ZJS
421bool path_is_safe(const char *p) _pure_;
422bool string_is_safe(const char *p) _pure_;
cfbc22ab 423
e3e0314b
ZJS
424/**
425 * Check if a string contains any glob patterns.
426 */
427_pure_ static inline bool string_is_glob(const char *p) {
428 return !!strpbrk(p, GLOB_CHARS);
429}
430
a9e12476
KS
431void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
432 int (*compar) (const void *, const void *, void *),
433 void *arg);
09017585 434
20f56fdd 435#define _(String) gettext (String)
88ced61b 436#define N_(String) String
20f56fdd 437void init_gettext(void);
09017585 438bool is_locale_utf8(void);
c339d977
MS
439
440typedef enum DrawSpecialChar {
6b01f1d3 441 DRAW_TREE_VERTICAL,
45a5ff0d
MS
442 DRAW_TREE_BRANCH,
443 DRAW_TREE_RIGHT,
55c0b89c 444 DRAW_TREE_SPACE,
c339d977 445 DRAW_TRIANGULAR_BULLET,
3deadb91 446 DRAW_BLACK_CIRCLE,
6b01f1d3 447 DRAW_ARROW,
13f8b8cb 448 DRAW_DASH,
c339d977
MS
449 _DRAW_SPECIAL_CHAR_MAX
450} DrawSpecialChar;
6b01f1d3 451
c339d977 452const char *draw_special_char(DrawSpecialChar ch);
409bc9c3 453
240dbaa4 454int on_ac_power(void);
f74e605f 455
4cf7ea55
MM
456int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
457int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
fabe5c0e 458
9db11a99
LP
459#define FOREACH_LINE(line, f, on_error) \
460 for (;;) \
f74e605f
LP
461 if (!fgets(line, sizeof(line), f)) { \
462 if (ferror(f)) { \
463 on_error; \
464 } \
465 break; \
466 } else
9db11a99
LP
467
468#define FOREACH_DIRENT(de, d, on_error) \
469 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
470 if (!de) { \
8333c77e 471 if (errno > 0) { \
9db11a99
LP
472 on_error; \
473 } \
474 break; \
a34bf9db 475 } else if (hidden_file((de)->d_name)) \
9db11a99
LP
476 continue; \
477 else
cd61c3bf
LP
478
479#define FOREACH_DIRENT_ALL(de, d, on_error) \
480 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
481 if (!de) { \
482 if (errno > 0) { \
483 on_error; \
484 } \
485 break; \
486 } else
6282c859
MS
487
488static inline void *mempset(void *s, int c, size_t n) {
489 memset(s, c, n);
dfb33a97 490 return (uint8_t*)s + n;
6282c859 491}
66e35261
LP
492
493char *hexmem(const void *p, size_t l);
30494563 494int unhexmem(const char *p, size_t l, void **mem, size_t *len);
2181a7f5 495
919a7f5f
TG
496char *base32hexmem(const void *p, size_t l, bool padding);
497int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len);
498
13a5d76b
TG
499char *base64mem(const void *p, size_t l);
500int unbase64mem(const char *p, size_t l, void **mem, size_t *len);
501
ca2d3784
ZJS
502void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
503void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
504#define GREEDY_REALLOC(array, allocated, need) \
505 greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
506
507#define GREEDY_REALLOC0(array, allocated, need) \
508 greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
a1937e67 509
5c0d398d 510static inline void _reset_errno_(int *saved_errno) {
5c0aa72a
LP
511 errno = *saved_errno;
512}
513
2a371001 514#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
5c0d398d 515
44dd2c6e
DH
516static inline int negative_errno(void) {
517 /* This helper should be used to shut up gcc if you know 'errno' is
518 * negative. Instead of "return -errno;", use "return negative_errno();"
519 * It will suppress bogus gcc warnings in case it assumes 'errno' might
520 * be 0 and thus the caller's error-handling might not be triggered. */
521 assert_return(errno > 0, -EINVAL);
522 return -errno;
523}
524
d6dd604b 525struct _umask_struct_ {
5c0d398d
LP
526 mode_t mask;
527 bool quit;
528};
529
d6dd604b 530static inline void _reset_umask_(struct _umask_struct_ *s) {
5c0d398d
LP
531 umask(s->mask);
532};
533
534#define RUN_WITH_UMASK(mask) \
d6dd604b 535 for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \
5c0d398d
LP
536 !_saved_umask_.quit ; \
537 _saved_umask_.quit = true)
144e51ec
CR
538
539static inline unsigned u64log2(uint64_t n) {
ec417ccc 540#if __SIZEOF_LONG_LONG__ == 8
693eb9a2 541 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
ec417ccc
LP
542#else
543#error "Wut?"
544#endif
545}
546
547static inline unsigned u32ctz(uint32_t n) {
548#if __SIZEOF_INT__ == 4
549 return __builtin_ctz(n);
550#else
551#error "Wut?"
552#endif
144e51ec 553}
79d860fe 554
7d328b54 555static inline unsigned log2i(int x) {
8fe90522
ZJS
556 assert(x > 0);
557
558 return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
559}
560
b5de6d98
MS
561static inline unsigned log2u(unsigned x) {
562 assert(x > 0);
563
564 return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
565}
566
567static inline unsigned log2u_round_up(unsigned x) {
568 assert(x > 0);
569
570 if (x == 1)
571 return 0;
572
573 return log2u(x - 1) + 1;
574}
575
82da66fb
LP
576#define DECIMAL_STR_WIDTH(x) \
577 ({ \
578 typeof(x) _x_ = (x); \
579 unsigned ans = 1; \
580 while (_x_ /= 10) \
581 ans++; \
582 ans; \
583 })
75add28a 584
4b73a0c0 585int unlink_noerrno(const char *path);
ed5c5dbd 586
82da66fb
LP
587#define alloca0(n) \
588 ({ \
589 char *_new_; \
590 size_t _len_ = n; \
591 _new_ = alloca(_len_); \
592 (void *) memset(_new_, 0, _len_); \
ed5c5dbd 593 })
95d78c7e 594
257224b0 595/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
95d78c7e
DH
596#define alloca_align(size, align) \
597 ({ \
598 void *_ptr_; \
599 size_t _mask_ = (align) - 1; \
600 _ptr_ = alloca((size) + _mask_); \
601 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
602 })
603
604#define alloca0_align(size, align) \
605 ({ \
606 void *_new_; \
607 size_t _size_ = (size); \
608 _new_ = alloca_align(_size_, (align)); \
609 (void*)memset(_new_, 0, _size_); \
610 })
66060897 611
44a6b1b6 612bool id128_is_valid(const char *s) _pure_;
d4ac85c6 613
74df0fca 614int shall_restore_state(void);
295edddf 615
7ff7394d
ZJS
616/**
617 * Normal qsort requires base to be nonnull. Here were require
618 * that only if nmemb > 0.
619 */
aeb24f30 620static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
1dbd13d8 621 if (nmemb <= 1)
aeb24f30
LP
622 return;
623
624 assert(base);
625 qsort(base, nmemb, size, compar);
7ff7394d 626}
74df0fca
LP
627
628int proc_cmdline(char **ret);
059cb385 629int parse_proc_cmdline(int (*parse_word)(const char *key, const char *value));
1a299299 630int get_proc_cmdline_key(const char *parameter, char **value);
bc9fd78c
LP
631
632int container_get_leader(const char *machine, pid_t *pid);
633
671c3419
RM
634int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
635int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
bf108e55 636
eff05270
LP
637int getpeercred(int fd, struct ucred *ucred);
638int getpeersec(int fd, char **ret);
8e33886e 639
65b3903f 640int mkostemp_safe(char *pattern, int flags);
8e33886e 641int open_tmpfile(const char *path, int flags);
fdb9161c
LP
642
643int fd_warn_permissions(const char *path, int fd);
6afc95b7 644
050f7277
LP
645#ifndef PERSONALITY_INVALID
646/* personality(7) documents that 0xffffffffUL is used for querying the
647 * current personality, hence let's use that here as error
648 * indicator. */
649#define PERSONALITY_INVALID 0xffffffffLU
650#endif
651
ac45f971
LP
652unsigned long personality_from_string(const char *p);
653const char *personality_to_string(unsigned long);
1c231f56
LP
654
655uint64_t physical_memory(void);
6db615c1 656
29bfbcd6 657void hexdump(FILE *f, const void *p, size_t s);
370c860f
DR
658
659union file_handle_union {
c5220a94
MO
660 struct file_handle handle;
661 char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
370c860f 662};
2695c5c4 663#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
c5220a94
MO
664
665int update_reboot_param_file(const char *param);
6d313367
LP
666
667int umount_recursive(const char *target, int flags);
d6797c92
LP
668
669int bind_remount_recursive(const char *prefix, bool ro);
1b992147
LP
670
671int fflush_and_check(FILE *f);
2e78fa79 672
14bcf25c
LP
673int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
674int tempfn_random(const char *p, const char *extra, char **ret);
675int tempfn_random_child(const char *p, const char *extra, char **ret);
fecc80c1 676
45035609 677int take_password_lock(const char *root);
5261ba90 678
7629889c 679int is_symlink(const char *path);
be57e297 680int is_dir(const char *path, bool follow);
ce5b3ad4 681int is_device_node(const char *path);
7629889c 682
f7c1ad4f
LP
683#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
684
685#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
0254e944
SL
686 for ((e) = &buffer.ev; \
687 (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
f7c1ad4f 688 (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
72648326 689
0254e944
SL
690union inotify_event_buffer {
691 struct inotify_event ev;
692 uint8_t raw[INOTIFY_EVENT_MAX];
693};
694
72648326 695#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
ee451d76 696
10f9c755
LP
697ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags);
698
4a4d89b6
LP
699int fd_setcrtime(int fd, usec_t usec);
700int fd_getcrtime(int fd, usec_t *usec);
701int path_getcrtime(const char *p, usec_t *usec);
10f9c755 702int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags);
a354329f 703
1ed8f8c1
LP
704int chattr_fd(int fd, unsigned value, unsigned mask);
705int chattr_path(const char *p, unsigned value, unsigned mask);
de45d726 706
01b72568
LP
707int read_attr_fd(int fd, unsigned *ret);
708int read_attr_path(const char *p, unsigned *ret);
709
de45d726 710#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
ff6a7460 711
3576d631
LP
712void sigkill_wait(pid_t *pid);
713#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
3d7415f4
LP
714
715int syslog_parse_priority(const char **p, int *priority, bool with_facility);
1c8da044 716
f85ef957 717int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
019c7fba 718
2ff7b0a5 719int parse_mode(const char *s, mode_t *ret);
6458ec20
LP
720
721int mount_move_root(const char *path);
b4da6d6b
LP
722
723int reset_uid_gid(void);
7b9c9ab8
WC
724
725int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
726int fgetxattr_malloc(int fd, const char *name, char **value);
d9603714 727
3ee897d6
LP
728int send_one_fd(int transport_fd, int fd, int flags);
729int receive_one_fd(int transport_fd, int flags);
189d5bac
LP
730
731void nop_signal_handler(int sig);
3f6fd1ba
LP
732
733int version(void);
8dd4c05b
LP
734
735bool fdname_is_valid(const char *s);
257b0719
EV
736
737bool oom_score_adjust_is_valid(int oa);