]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/util.h
build-sys: properly mkdir for GENERAL_ALIASES
[thirdparty/systemd.git] / src / shared / 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>
60918275
LP
25#include <inttypes.h>
26#include <time.h>
27#include <sys/time.h>
ec2002f8 28#include <stdarg.h>
60918275 29#include <stdbool.h>
5cb5a6ff 30#include <stdlib.h>
80876c20 31#include <stdio.h>
9a34ec5f 32#include <signal.h>
82c121a4 33#include <sched.h>
8f75a603 34#include <limits.h>
25ea79fe 35#include <sys/types.h>
00dc5d76 36#include <sys/stat.h>
3b63d2d3 37#include <dirent.h>
68faf98c 38#include <sys/resource.h>
7d5e9c0f 39#include <stddef.h>
79d860fe 40#include <unistd.h>
d6dd604b 41#include <locale.h>
60918275 42
a838e6a1 43#include "macro.h"
9a98c7a1 44#include "time-util.h"
871d7de4 45
7d5e9c0f
LP
46union dirent_storage {
47 struct dirent de;
48 uint8_t storage[offsetof(struct dirent, d_name) +
49 ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))];
50};
51
44d8db9e 52/* What is interpreted as whitespace? */
4a72ff34 53#define WHITESPACE " \t\n\r"
7072ced8 54#define NEWLINE "\n\r"
97c4a07d 55#define QUOTES "\"\'"
d3b6d0c2 56#define COMMENTS "#;"
44d8db9e 57
a7bc2c2a 58#define FORMAT_BYTES_MAX 8
8b6c7120 59
c1072ea0 60#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
03b717a3 61#define ANSI_RED_ON "\x1B[31m"
281605bf 62#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
076a24ad 63#define ANSI_GREEN_ON "\x1B[32m"
2ee68f72 64#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
5f23d5b1 65#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
61cbdc4b 66#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
984a2be4 67#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
61cbdc4b 68
37f85e66 69size_t page_size(void);
70#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
71
60918275 72#define streq(a,b) (strcmp((a),(b)) == 0)
3846aeeb 73#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
b43d1d01
TA
74#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
75#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
60918275 76
44a6b1b6 77bool streq_ptr(const char *a, const char *b) _pure_;
e05797fb 78
4b8772bf 79#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
60918275
LP
80
81#define new0(t, n) ((t*) calloc((n), sizeof(t)))
82
0f0dbc46
LP
83#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
84
4b8772bf 85#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
888c7102 86
60918275
LP
87#define malloc0(n) (calloc((n), 1))
88
89static inline const char* yes_no(bool b) {
90 return b ? "yes" : "no";
91}
92
93static inline const char* strempty(const char *s) {
94 return s ? s : "";
95}
96
97static inline const char* strnull(const char *s) {
98 return s ? s : "(null)";
99}
100
04fd6fe4
LP
101static inline const char *strna(const char *s) {
102 return s ? s : "n/a";
103}
104
9beb3f4d
LP
105static inline bool isempty(const char *p) {
106 return !p || !p[0];
107}
108
44a6b1b6
ZJS
109char *endswith(const char *s, const char *postfix) _pure_;
110char *startswith(const char *s, const char *prefix) _pure_;
111char *startswith_no_case(const char *s, const char *prefix) _pure_;
60918275 112
44a6b1b6 113bool first_word(const char *s, const char *word) _pure_;
79d6d816 114
42f4e3c4 115int close_nointr(int fd);
85f136b5 116void close_nointr_nofail(int fd);
5b6319dc 117void close_many(const int fds[], unsigned n_fd);
60918275 118
44a6b1b6 119int parse_boolean(const char *v) _pure_;
ab1f0633 120int parse_bytes(const char *t, off_t *bytes);
3ba686c1 121int parse_pid(const char *s, pid_t* ret_pid);
034a2a52
LP
122int parse_uid(const char *s, uid_t* ret_uid);
123#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
85261803
LP
124
125int safe_atou(const char *s, unsigned *ret_u);
126int safe_atoi(const char *s, int *ret_i);
127
8f75a603
LP
128int safe_atollu(const char *s, unsigned long long *ret_u);
129int safe_atolli(const char *s, long long int *ret_i);
130
f7900e25
TA
131int safe_atod(const char *s, double *ret_d);
132
8f75a603
LP
133#if __WORDSIZE == 32
134static inline int safe_atolu(const char *s, unsigned long *ret_u) {
135 assert_cc(sizeof(unsigned long) == sizeof(unsigned));
136 return safe_atou(s, (unsigned*) ret_u);
137}
138static inline int safe_atoli(const char *s, long int *ret_u) {
139 assert_cc(sizeof(long int) == sizeof(int));
140 return safe_atoi(s, (int*) ret_u);
141}
142#else
143static inline int safe_atolu(const char *s, unsigned long *ret_u) {
144 assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
145 return safe_atollu(s, (unsigned long long*) ret_u);
146}
147static inline int safe_atoli(const char *s, long int *ret_u) {
148 assert_cc(sizeof(long int) == sizeof(long long int));
149 return safe_atolli(s, (long long int*) ret_u);
150}
151#endif
152
a838e6a1
LP
153static inline int safe_atou32(const char *s, uint32_t *ret_u) {
154 assert_cc(sizeof(uint32_t) == sizeof(unsigned));
155 return safe_atou(s, (unsigned*) ret_u);
156}
157
8f75a603 158static inline int safe_atoi32(const char *s, int32_t *ret_i) {
a838e6a1 159 assert_cc(sizeof(int32_t) == sizeof(int));
8f75a603 160 return safe_atoi(s, (int*) ret_i);
a838e6a1
LP
161}
162
8f75a603
LP
163static inline int safe_atou64(const char *s, uint64_t *ret_u) {
164 assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
165 return safe_atollu(s, (unsigned long long*) ret_u);
166}
034c6ed7 167
8f75a603
LP
168static inline int safe_atoi64(const char *s, int64_t *ret_i) {
169 assert_cc(sizeof(int64_t) == sizeof(long long int));
170 return safe_atolli(s, (long long int*) ret_i);
171}
034c6ed7 172
65d2ebdc 173char *split(const char *c, size_t *l, const char *separator, char **state);
034c6ed7 174char *split_quoted(const char *c, size_t *l, char **state);
a41e8209 175
034c6ed7 176#define FOREACH_WORD(word, length, s, state) \
f62c0e4f 177 for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state)))
65d2ebdc
LP
178
179#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
f62c0e4f 180 for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state)))
a41e8209 181
034c6ed7 182#define FOREACH_WORD_QUOTED(word, length, s, state) \
f62c0e4f 183 for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state)))
034c6ed7 184
034c6ed7 185pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
7640a5de 186int get_starttime_of_pid(pid_t pid, unsigned long long *st);
034c6ed7 187
44d8db9e 188char *strappend(const char *s, const char *suffix);
fab56fc5
LP
189char *strnappend(const char *s, const char *suffix, size_t length);
190
191char *replace_env(const char *format, char **env);
192char **replace_env_argv(char **argv, char **env);
44d8db9e 193
87f0e418 194int readlink_malloc(const char *p, char **r);
2c7108c4 195int readlink_and_make_absolute(const char *p, char **r);
83096483 196int readlink_and_canonicalize(const char *p, char **r);
87f0e418 197
2a987ee8
LP
198int reset_all_signal_handlers(void);
199
4a72ff34 200char *strstrip(char *s);
ee9b5e01 201char *delete_chars(char *s, const char *bad);
7072ced8 202char *truncate_nl(char *s);
ee9b5e01 203
4a72ff34
LP
204char *file_in_same_dir(const char *path, const char *filename);
205
c32dd69b
LP
206int rmdir_parents(const char *path, const char *stop);
207
87d2c1ff
LP
208int get_process_comm(pid_t pid, char **name);
209int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
210int get_process_exe(pid_t pid, char **name);
7e4ab3c5 211int get_process_uid(pid_t pid, uid_t *uid);
901c3d0d 212int get_process_gid(pid_t pid, gid_t *gid);
7072ced8 213
bcb92f48
CR
214char hexchar(int x) _const_;
215int unhexchar(char c) _const_;
216char octchar(int x) _const_;
217int unoctchar(char c) _const_;
218char decchar(int x) _const_;
219int undecchar(char c) _const_;
4fe88d28
LP
220
221char *cescape(const char *s);
222char *cunescape(const char *s);
6febfd0d 223char *cunescape_length(const char *s, size_t length);
5b4c61cd 224char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix);
6febfd0d
LP
225
226char *xescape(const char *s, const char *bad);
227
228char *bus_path_escape(const char *s);
229char *bus_path_unescape(const char *s);
4fe88d28 230
4fe88d28
LP
231char *ascii_strlower(char *path);
232
44a6b1b6
ZJS
233bool dirent_is_file(const struct dirent *de) _pure_;
234bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
87d2c1ff 235
44a6b1b6 236bool ignore_file(const char *filename) _pure_;
c85dc17b 237
44a6b1b6 238bool chars_intersect(const char *a, const char *b) _pure_;
db12775d 239
843d2643 240int make_stdio(int fd);
ade509ce 241int make_null_stdio(void);
cd3bd60a 242int make_console_stdio(void);
843d2643 243
d3782d60
LP
244unsigned long long random_ull(void);
245
f8b69d1d 246/* For basic lookup tables with strictly enumerated entries */
4e240ab0
MS
247#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
248 scope const char *name##_to_string(type i) { \
1dccbe19
LP
249 if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
250 return NULL; \
251 return name##_table[i]; \
252 } \
4e240ab0 253 scope type name##_from_string(const char *s) { \
1dccbe19
LP
254 type i; \
255 assert(s); \
256 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
4fd5948e
LP
257 if (name##_table[i] && \
258 streq(name##_table[i], s)) \
1dccbe19
LP
259 return i; \
260 return (type) -1; \
261 } \
262 struct __useless_struct_to_allow_trailing_semicolon__
263
4e240ab0
MS
264#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,)
265#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static)
1dccbe19 266
f8b69d1d
MS
267/* For string conversions where numbers are also acceptable */
268#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
269 int name##_to_string_alloc(type i, char **str) { \
270 char *s; \
271 int r; \
272 if (i < 0 || i > max) \
273 return -ERANGE; \
274 if (i < (type) ELEMENTSOF(name##_table)) { \
275 s = strdup(name##_table[i]); \
276 if (!s) \
277 return log_oom(); \
278 } else { \
279 r = asprintf(&s, "%u", i); \
280 if (r < 0) \
281 return log_oom(); \
282 } \
283 *str = s; \
284 return 0; \
285 } \
286 type name##_from_string(const char *s) { \
287 type i; \
288 unsigned u = 0; \
289 assert(s); \
290 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
291 if (name##_table[i] && \
292 streq(name##_table[i], s)) \
293 return i; \
8511dd18 294 if (safe_atou(s, &u) >= 0 && u <= max) \
f8b69d1d
MS
295 return (type) u; \
296 return (type) -1; \
297 } \
298 struct __useless_struct_to_allow_trailing_semicolon__
299
3a0ecb08
LP
300int fd_nonblock(int fd, bool nonblock);
301int fd_cloexec(int fd, bool cloexec);
302
a0d40ac5
LP
303int close_all_fds(const int except[], unsigned n_except);
304
42856c10
LP
305bool fstype_is_network(const char *fstype);
306
601f6a1e
LP
307int chvt(int vt);
308
8f2d43a0 309int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
44a6b1b6 310int ask(char *ret, const char *replies, const char *text, ...) _printf_attr_(3, 4);
80876c20 311
512947d4 312int reset_terminal_fd(int fd, bool switch_to_text);
6ea832a2
LP
313int reset_terminal(const char *name);
314
80876c20 315int open_terminal(const char *name, int mode);
af6da548 316int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
80876c20
LP
317int release_terminal(void);
318
319int flush_fd(int fd);
320
9a34ec5f
LP
321int ignore_signals(int sig, ...);
322int default_signals(int sig, ...);
323int sigaction_many(const struct sigaction *sa, ...);
a337c6fc 324
8d567588 325int close_pipe(int p[]);
5a3ab509 326int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
8d567588 327
eb22ac37
LP
328ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
329ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
8d567588 330
8407a5d0
LP
331bool is_device_path(const char *path);
332
01f78473 333int dir_is_empty(const char *path);
844ec79b 334char* dirname_malloc(const char *path);
01f78473 335
5b6319dc 336void rename_process(const char name[8]);
2d368c14 337
7d793605
LP
338void sigset_add_many(sigset_t *ss, ...);
339
344de609 340bool hostname_is_set(void);
7c5f152a
LP
341
342char* gethostname_malloc(void);
ef2f1067 343char* getlogname_malloc(void);
7c5f152a 344char* getusername_malloc(void);
fc116c6a
LP
345
346int getttyname_malloc(int fd, char **r);
347int getttyname_harder(int fd, char **r);
348
4d6d6518
LP
349int get_ctty_devnr(pid_t pid, dev_t *d);
350int get_ctty(pid_t, dev_t *_devnr, char **r);
8c6db833
LP
351
352int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
f4b47811 353int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
8c6db833 354
597f43c7 355int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
f56d5db9 356int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
ad293f5a 357int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
f56d5db9 358int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
ef2f1067 359
1325aa42
LP
360int pipe_eof(int fd);
361
82c121a4
LP
362cpu_set_t* cpu_set_malloc(unsigned *ncpus);
363
b1e2b33c
CR
364int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_attr_(4,0);
365int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_attr_(4,5);
669bec5d 366int status_welcome(void);
9e58ff9c 367
81beb750 368int fd_columns(int fd);
72f59706 369unsigned columns(void);
8f2d43a0
LP
370int fd_lines(int fd);
371unsigned lines(void);
ed757c0c
LP
372void columns_lines_cache_reset(int _unused_ signum);
373
374bool on_tty(void);
8f2d43a0 375
b4f10a5e
LP
376int running_in_chroot(void);
377
72f59706
LP
378char *ellipsize(const char *s, size_t length, unsigned percent);
379char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
8fe914ec 380
f6144808
LP
381int touch(const char *path);
382
97c4a07d 383char *unquote(const char *s, const char *quotes);
5f7c426e 384char *normalize_env_assignment(const char *s);
11ce3427 385
8e12a6ae 386int wait_for_terminate(pid_t pid, siginfo_t *status);
97c4a07d 387int wait_for_terminate_and_warn(const char *name, pid_t pid);
2e78aa99 388
3c14d26c
LP
389_noreturn_ void freeze(void);
390
44a6b1b6 391bool null_or_empty(struct stat *st) _pure_;
83096483 392int null_or_empty_path(const char *fn);
00dc5d76 393
a247755d 394DIR *xopendirat(int dirfd, const char *name, int flags);
3b63d2d3 395
e23a0ce8
LP
396char *fstab_node_to_udev_node(const char *p);
397
21baf21a 398char *resolve_dev_console(char **active);
f212ac12 399bool tty_is_vc(const char *tty);
3043935f 400bool tty_is_vc_resolve(const char *tty);
44a6b1b6 401bool tty_is_console(const char *tty) _pure_;
98a28fef 402int vtnr_from_tty(const char *tty);
e3aa71c3
LP
403const char *default_term_for_tty(const char *tty);
404
83cc030f
LP
405void execute_directory(const char *directory, DIR *_d, char *argv[]);
406
430c18ed
LP
407int kill_and_sigcont(pid_t pid, int sig);
408
05feefe0
LP
409bool nulstr_contains(const char*nulstr, const char *needle);
410
6faa1114
LP
411bool plymouth_running(void);
412
44a6b1b6 413bool hostname_is_valid(const char *s) _pure_;
9beb3f4d
LP
414char* hostname_cleanup(char *s);
415
416char* strshorten(char *s, size_t l);
417
6ea832a2
LP
418int terminal_vhangup_fd(int fd);
419int terminal_vhangup(const char *name);
420
421int vt_disallocate(const char *name);
422
34ca941c 423int copy_file(const char *from, const char *to);
424a19f8
LP
424
425int symlink_atomic(const char *from, const char *to);
34ca941c
LP
426
427int fchmod_umask(int fd, mode_t mode);
428
44a6b1b6 429bool display_is_local(const char *display) _pure_;
4d6d6518
LP
430int socket_from_display(const char *display, char **path);
431
d05c5031 432int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
4b67834e 433int get_group_creds(const char **groupname, gid_t *gid);
1cccf435 434
4468addc 435int in_gid(gid_t gid);
43673799
LP
436int in_group(const char *name);
437
59164be4 438char* uid_to_name(uid_t uid);
4468addc 439char* gid_to_name(gid_t gid);
59164be4 440
8092a428
LP
441int glob_exists(const char *path);
442
83096483
LP
443int dirent_ensure_type(DIR *d, struct dirent *de);
444
445int in_search_path(const char *path, char **search);
034a2a52 446int get_files_in_directory(const char *path, char ***list);
83096483 447
b7def684 448char *strjoin(const char *x, ...) _sentinel_;
911a4828 449
b636465b
LP
450bool is_main_thread(void);
451
44a6b1b6 452bool in_charset(const char *s, const char* charset) _pure_;
ab1f0633 453
94959f0f
LP
454int block_get_whole_disk(dev_t d, dev_t *ret);
455
8d53b453 456int file_is_priv_sticky(const char *p);
ad293f5a 457
fb9de93d
LP
458int strdup_or_null(const char *a, char **b);
459
e23a0ce8 460#define NULSTR_FOREACH(i, l) \
c4e2ceae
LP
461 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
462
5c0532d1
LP
463#define NULSTR_FOREACH_PAIR(i, j, l) \
464 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
465
f8b69d1d 466int ioprio_class_to_string_alloc(int i, char **s);
1dccbe19
LP
467int ioprio_class_from_string(const char *s);
468
44a6b1b6
ZJS
469const char *sigchld_code_to_string(int i) _const_;
470int sigchld_code_from_string(const char *s) _pure_;
1dccbe19 471
f8b69d1d 472int log_facility_unshifted_to_string_alloc(int i, char **s);
7d76f312 473int log_facility_unshifted_from_string(const char *s);
1dccbe19 474
f8b69d1d 475int log_level_to_string_alloc(int i, char **s);
1dccbe19
LP
476int log_level_from_string(const char *s);
477
f8b69d1d 478int sched_policy_to_string_alloc(int i, char **s);
1dccbe19
LP
479int sched_policy_from_string(const char *s);
480
44a6b1b6
ZJS
481const char *rlimit_to_string(int i) _const_;
482int rlimit_from_string(const char *s) _pure_;
1dccbe19 483
f8b69d1d 484int ip_tos_to_string_alloc(int i, char **s);
4fd5948e
LP
485int ip_tos_from_string(const char *s);
486
44a6b1b6
ZJS
487const char *signal_to_string(int i) _const_;
488int signal_from_string(const char *s) _pure_;
2e22afe9 489
8a0867d6
LP
490int signal_from_string_try_harder(const char *s);
491
9a0e6896
LP
492extern int saved_argc;
493extern char **saved_argv;
494
65457142
FC
495bool kexec_loaded(void);
496
44a6b1b6 497int prot_from_flags(int flags) _const_;
87d2c1ff 498
babfc091
LP
499char *format_bytes(char *buf, size_t l, off_t t);
500
8f2d43a0 501int fd_wait_for_event(int fd, int event, usec_t timeout);
df50185b 502
750ef272 503void* memdup(const void *p, size_t l) _alloc_(2);
55d7bfc1 504
1e5678d0
LP
505int is_kernel_thread(pid_t pid);
506
bb99a35a
LP
507int fd_inc_sndbuf(int fd, size_t n);
508int fd_inc_rcvbuf(int fd, size_t n);
6bb92a16 509
9bdc770c 510int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
6bb92a16 511
68faf98c
LP
512int setrlimit_closest(int resource, const struct rlimit *rlim);
513
ab94af92
LP
514int getenv_for_pid(pid_t pid, const char *field, char **_value);
515
44a6b1b6 516bool is_valid_documentation_url(const char *url) _pure_;
49dbfa7b 517
9be346c9 518bool in_initrd(void);
069cfc85
LP
519
520void warn_melody(void);
521
7c5f152a 522int get_home_dir(char **ret);
2fbe635a 523
a740c14c
MS
524static inline void freep(void *p) {
525 free(*(void**) p);
526}
527
dfb33a97
LP
528static inline void fclosep(FILE **f) {
529 if (*f)
530 fclose(*f);
531}
532
533static inline void pclosep(FILE **f) {
534 if (*f)
535 pclose(*f);
536}
537
538static inline void closep(int *fd) {
539 if (*fd >= 0)
540 close_nointr_nofail(*fd);
541}
542
543static inline void closedirp(DIR **d) {
544 if (*d)
545 closedir(*d);
a740c14c 546}
4b8772bf 547
dfb33a97
LP
548static inline void umaskp(mode_t *u) {
549 umask(*u);
763c7aa2
ZJS
550}
551
dfb33a97
LP
552#define _cleanup_free_ _cleanup_(freep)
553#define _cleanup_fclose_ _cleanup_(fclosep)
554#define _cleanup_pclose_ _cleanup_(pclosep)
555#define _cleanup_close_ _cleanup_(closep)
556#define _cleanup_closedir_ _cleanup_(closedirp)
557#define _cleanup_umask_ _cleanup_(umaskp)
558#define _cleanup_globfree_ _cleanup_(globfree)
c84a9488 559
750ef272 560_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
aa408e77 561 if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
4b8772bf
LP
562 return NULL;
563
564 return malloc(a * b);
565}
566
750ef272 567_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
aa408e77 568 if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
4b8772bf
LP
569 return NULL;
570
571 return memdup(p, a * b);
572}
0b507b17 573
44a6b1b6
ZJS
574bool filename_is_safe(const char *p) _pure_;
575bool path_is_safe(const char *p) _pure_;
576bool string_is_safe(const char *p) _pure_;
577bool string_has_cc(const char *p) _pure_;
cfbc22ab 578
a9e12476
KS
579void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
580 int (*compar) (const void *, const void *, void *),
581 void *arg);
09017585
MS
582
583bool is_locale_utf8(void);
c339d977
MS
584
585typedef enum DrawSpecialChar {
45a5ff0d
MS
586 DRAW_TREE_VERT,
587 DRAW_TREE_BRANCH,
588 DRAW_TREE_RIGHT,
55c0b89c 589 DRAW_TREE_SPACE,
c339d977
MS
590 DRAW_TRIANGULAR_BULLET,
591 _DRAW_SPECIAL_CHAR_MAX
592} DrawSpecialChar;
593const char *draw_special_char(DrawSpecialChar ch);
409bc9c3
LP
594
595char *strreplace(const char *text, const char *old_string, const char *new_string);
e8bc0ea2
LP
596
597char *strip_tab_ansi(char **p, size_t *l);
240dbaa4
LP
598
599int on_ac_power(void);
f74e605f 600
fabe5c0e
LP
601int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
602int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
d34cd374 603int create_tmp_dir(char template[], char** dir_name);
fabe5c0e 604
9db11a99
LP
605#define FOREACH_LINE(line, f, on_error) \
606 for (;;) \
f74e605f
LP
607 if (!fgets(line, sizeof(line), f)) { \
608 if (ferror(f)) { \
609 on_error; \
610 } \
611 break; \
612 } else
9db11a99
LP
613
614#define FOREACH_DIRENT(de, d, on_error) \
615 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
616 if (!de) { \
8333c77e 617 if (errno > 0) { \
9db11a99
LP
618 on_error; \
619 } \
620 break; \
621 } else if (ignore_file((de)->d_name)) \
622 continue; \
623 else
6282c859
MS
624
625static inline void *mempset(void *s, int c, size_t n) {
626 memset(s, c, n);
dfb33a97 627 return (uint8_t*)s + n;
6282c859 628}
66e35261
LP
629
630char *hexmem(const void *p, size_t l);
2181a7f5
LP
631void *unhexmem(const char *p, size_t l);
632
a432cb69 633char *strextend(char **x, ...) _sentinel_;
9a17484d 634char *strrep(const char *s, unsigned n);
392d5b37
LP
635
636void* greedy_realloc(void **p, size_t *allocated, size_t need);
2244a6fb 637#define GREEDY_REALLOC(array, allocated, need) \
dfb33a97 638 greedy_realloc((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
5c0aa72a 639
5c0d398d 640static inline void _reset_errno_(int *saved_errno) {
5c0aa72a
LP
641 errno = *saved_errno;
642}
643
2a371001 644#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
5c0d398d 645
d6dd604b 646struct _umask_struct_ {
5c0d398d
LP
647 mode_t mask;
648 bool quit;
649};
650
d6dd604b 651static inline void _reset_umask_(struct _umask_struct_ *s) {
5c0d398d
LP
652 umask(s->mask);
653};
654
655#define RUN_WITH_UMASK(mask) \
d6dd604b 656 for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \
5c0d398d
LP
657 !_saved_umask_.quit ; \
658 _saved_umask_.quit = true)
144e51ec
CR
659
660static inline unsigned u64log2(uint64_t n) {
661 return (n > 1) ? __builtin_clzll(n) ^ 63U : 0;
662}
79d860fe
MP
663
664static inline bool logind_running(void) {
665 return access("/run/systemd/seats/", F_OK) >= 0;
666}
4b73a0c0 667
82da66fb
LP
668#define DECIMAL_STR_WIDTH(x) \
669 ({ \
670 typeof(x) _x_ = (x); \
671 unsigned ans = 1; \
672 while (_x_ /= 10) \
673 ans++; \
674 ans; \
675 })
75add28a 676
4b73a0c0 677int unlink_noerrno(const char *path);
ed5c5dbd 678
82da66fb
LP
679#define alloca0(n) \
680 ({ \
681 char *_new_; \
682 size_t _len_ = n; \
683 _new_ = alloca(_len_); \
684 (void *) memset(_new_, 0, _len_); \
ed5c5dbd 685 })
66060897
LP
686
687#define strappenda(a, b) \
688 ({ \
689 const char *_a_ = (a), *_b_ = (b); \
690 char *_c_; \
691 size_t _x_, _y_; \
692 _x_ = strlen(_a_); \
693 _y_ = strlen(_b_); \
694 _c_ = alloca(_x_ + _y_ + 1); \
695 strcpy(stpcpy(_c_, _a_), _b_); \
696 _c_; \
697 })
31885cd5
ZJS
698
699#define procfs_file_alloca(pid, field) \
700 ({ \
701 pid_t _pid_ = (pid); \
702 char *_r_; \
703 _r_ = alloca(sizeof("/proc/") -1 + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
704 sprintf(_r_, "/proc/%lu/" field, (unsigned long) _pid_); \
705 _r_; \
706 })
d6dd604b
LP
707
708struct _locale_struct_ {
709 locale_t saved_locale;
710 locale_t new_locale;
711 bool quit;
712};
713
714static inline void _reset_locale_(struct _locale_struct_ *s) {
715 PROTECT_ERRNO;
716 if (s->saved_locale != (locale_t) 0)
717 uselocale(s->saved_locale);
718 if (s->new_locale != (locale_t) 0)
719 freelocale(s->new_locale);
720}
721
722#define RUN_WITH_LOCALE(mask, loc) \
723 for (_cleanup_(_reset_locale_) struct _locale_struct_ _saved_locale_ = { (locale_t) 0, (locale_t) 0, false }; \
724 ({ \
725 if (!_saved_locale_.quit) { \
726 PROTECT_ERRNO; \
727 _saved_locale_.new_locale = newlocale((mask), (loc), (locale_t) 0); \
728 if (_saved_locale_.new_locale != (locale_t) 0) \
729 _saved_locale_.saved_locale = uselocale(_saved_locale_.new_locale); \
730 } \
731 !_saved_locale_.quit; }) ; \
732 _saved_locale_.quit = true)
aa96c6cb 733
44a6b1b6 734bool id128_is_valid(const char *s) _pure_;