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