]> git.proxmox.com Git - systemd.git/blame - src/shared/util.h
Imported Upstream version 217
[systemd.git] / src / shared / util.h
CommitLineData
663996b3
MS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3#pragma once
4
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
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
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
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
24#include <alloca.h>
60f067b4 25#include <fcntl.h>
663996b3
MS
26#include <inttypes.h>
27#include <time.h>
28#include <sys/time.h>
29#include <stdarg.h>
30#include <stdbool.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <signal.h>
34#include <sched.h>
35#include <limits.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <dirent.h>
39#include <sys/resource.h>
40#include <stddef.h>
41#include <unistd.h>
42#include <locale.h>
60f067b4
JS
43#include <mntent.h>
44#include <sys/socket.h>
45
46#if SIZEOF_PID_T == 4
47# define PID_FMT "%" PRIu32
48#elif SIZEOF_PID_T == 2
49# define PID_FMT "%" PRIu16
50#else
51# error Unknown pid_t size
52#endif
53
54#if SIZEOF_UID_T == 4
55# define UID_FMT "%" PRIu32
56#elif SIZEOF_UID_T == 2
57# define UID_FMT "%" PRIu16
58#else
59# error Unknown uid_t size
60#endif
61
62#if SIZEOF_GID_T == 4
63# define GID_FMT "%" PRIu32
64#elif SIZEOF_GID_T == 2
65# define GID_FMT "%" PRIu16
66#else
67# error Unknown gid_t size
68#endif
69
70#if SIZEOF_TIME_T == 8
71# define PRI_TIME PRIu64
5eef597e 72#elif SIZEOF_TIME_T == 4
60f067b4
JS
73# define PRI_TIME PRIu32
74#else
75# error Unknown time_t size
76#endif
77
78#if SIZEOF_RLIM_T == 8
79# define RLIM_FMT "%" PRIu64
80#elif SIZEOF_RLIM_T == 4
81# define RLIM_FMT "%" PRIu32
82#else
83# error Unknown rlim_t size
84#endif
663996b3
MS
85
86#include "macro.h"
5eef597e 87#include "missing.h"
663996b3
MS
88#include "time-util.h"
89
663996b3
MS
90/* What is interpreted as whitespace? */
91#define WHITESPACE " \t\n\r"
60f067b4
JS
92#define NEWLINE "\n\r"
93#define QUOTES "\"\'"
94#define COMMENTS "#;"
95#define GLOB_CHARS "*?["
663996b3 96
5eef597e
MP
97/* What characters are special in the shell? */
98/* must be escaped outside and inside double-quotes */
99#define SHELL_NEED_ESCAPE "\"\\`$"
100/* can be escaped or double-quoted */
101#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
102
663996b3
MS
103#define FORMAT_BYTES_MAX 8
104
105#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
106#define ANSI_RED_ON "\x1B[31m"
107#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
108#define ANSI_GREEN_ON "\x1B[32m"
109#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
110#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
60f067b4 111#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m"
663996b3
MS
112#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
113#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
114
115size_t page_size(void);
116#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
117
118#define streq(a,b) (strcmp((a),(b)) == 0)
119#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
120#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
121#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
122
123bool streq_ptr(const char *a, const char *b) _pure_;
124
125#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
126
127#define new0(t, n) ((t*) calloc((n), sizeof(t)))
128
129#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
130
5eef597e
MP
131#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
132
663996b3
MS
133#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
134
135#define malloc0(n) (calloc((n), 1))
136
137static inline const char* yes_no(bool b) {
138 return b ? "yes" : "no";
139}
140
60f067b4
JS
141static inline const char* true_false(bool b) {
142 return b ? "true" : "false";
143}
144
663996b3
MS
145static inline const char* strempty(const char *s) {
146 return s ? s : "";
147}
148
149static inline const char* strnull(const char *s) {
150 return s ? s : "(null)";
151}
152
153static inline const char *strna(const char *s) {
154 return s ? s : "n/a";
155}
156
157static inline bool isempty(const char *p) {
158 return !p || !p[0];
159}
160
5eef597e
MP
161static inline char *startswith(const char *s, const char *prefix) {
162 size_t l;
163
164 l = strlen(prefix);
165 if (strncmp(s, prefix, l) == 0)
166 return (char*) s + l;
167
14228c0d
MB
168 return NULL;
169}
170
5eef597e
MP
171static inline char *startswith_no_case(const char *s, const char *prefix) {
172 size_t l;
173
174 l = strlen(prefix);
175 if (strncasecmp(s, prefix, l) == 0)
176 return (char*) s + l;
177
14228c0d
MB
178 return NULL;
179}
180
663996b3 181char *endswith(const char *s, const char *postfix) _pure_;
663996b3 182
5eef597e 183char *first_word(const char *s, const char *word) _pure_;
663996b3
MS
184
185int close_nointr(int fd);
60f067b4
JS
186int safe_close(int fd);
187void safe_close_pair(int p[]);
188
663996b3
MS
189void close_many(const int fds[], unsigned n_fd);
190
60f067b4
JS
191int parse_size(const char *t, off_t base, off_t *size);
192
663996b3 193int parse_boolean(const char *v) _pure_;
663996b3
MS
194int parse_pid(const char *s, pid_t* ret_pid);
195int parse_uid(const char *s, uid_t* ret_uid);
196#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
197
198int safe_atou(const char *s, unsigned *ret_u);
199int safe_atoi(const char *s, int *ret_i);
200
201int safe_atollu(const char *s, unsigned long long *ret_u);
202int safe_atolli(const char *s, long long int *ret_i);
203
204int safe_atod(const char *s, double *ret_d);
205
5eef597e
MP
206int safe_atou8(const char *s, uint8_t *ret);
207
208#if LONG_MAX == INT_MAX
663996b3
MS
209static inline int safe_atolu(const char *s, unsigned long *ret_u) {
210 assert_cc(sizeof(unsigned long) == sizeof(unsigned));
211 return safe_atou(s, (unsigned*) ret_u);
212}
213static inline int safe_atoli(const char *s, long int *ret_u) {
214 assert_cc(sizeof(long int) == sizeof(int));
215 return safe_atoi(s, (int*) ret_u);
216}
217#else
218static inline int safe_atolu(const char *s, unsigned long *ret_u) {
219 assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
220 return safe_atollu(s, (unsigned long long*) ret_u);
221}
222static inline int safe_atoli(const char *s, long int *ret_u) {
223 assert_cc(sizeof(long int) == sizeof(long long int));
224 return safe_atolli(s, (long long int*) ret_u);
225}
226#endif
227
228static inline int safe_atou32(const char *s, uint32_t *ret_u) {
229 assert_cc(sizeof(uint32_t) == sizeof(unsigned));
230 return safe_atou(s, (unsigned*) ret_u);
231}
232
233static inline int safe_atoi32(const char *s, int32_t *ret_i) {
234 assert_cc(sizeof(int32_t) == sizeof(int));
235 return safe_atoi(s, (int*) ret_i);
236}
237
238static inline int safe_atou64(const char *s, uint64_t *ret_u) {
239 assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
240 return safe_atollu(s, (unsigned long long*) ret_u);
241}
242
243static inline int safe_atoi64(const char *s, int64_t *ret_i) {
244 assert_cc(sizeof(int64_t) == sizeof(long long int));
245 return safe_atolli(s, (long long int*) ret_i);
246}
247
5eef597e 248const char* split(const char **state, size_t *l, const char *separator, bool quoted);
663996b3
MS
249
250#define FOREACH_WORD(word, length, s, state) \
60f067b4 251 _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
663996b3
MS
252
253#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
60f067b4 254 _FOREACH_WORD(word, length, s, separator, false, state)
663996b3
MS
255
256#define FOREACH_WORD_QUOTED(word, length, s, state) \
60f067b4
JS
257 _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
258
60f067b4 259#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
5eef597e 260 for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
663996b3
MS
261
262pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
263int get_starttime_of_pid(pid_t pid, unsigned long long *st);
264
265char *strappend(const char *s, const char *suffix);
266char *strnappend(const char *s, const char *suffix, size_t length);
267
268char *replace_env(const char *format, char **env);
269char **replace_env_argv(char **argv, char **env);
270
60f067b4 271int readlinkat_malloc(int fd, const char *p, char **ret);
663996b3
MS
272int readlink_malloc(const char *p, char **r);
273int readlink_and_make_absolute(const char *p, char **r);
274int readlink_and_canonicalize(const char *p, char **r);
275
276int reset_all_signal_handlers(void);
5eef597e 277int reset_signal_mask(void);
663996b3
MS
278
279char *strstrip(char *s);
280char *delete_chars(char *s, const char *bad);
281char *truncate_nl(char *s);
282
283char *file_in_same_dir(const char *path, const char *filename);
284
285int rmdir_parents(const char *path, const char *stop);
286
60f067b4 287int get_process_state(pid_t pid);
663996b3
MS
288int get_process_comm(pid_t pid, char **name);
289int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
290int get_process_exe(pid_t pid, char **name);
291int get_process_uid(pid_t pid, uid_t *uid);
292int get_process_gid(pid_t pid, gid_t *gid);
14228c0d 293int get_process_capeff(pid_t pid, char **capeff);
663996b3
MS
294
295char hexchar(int x) _const_;
296int unhexchar(char c) _const_;
297char octchar(int x) _const_;
298int unoctchar(char c) _const_;
299char decchar(int x) _const_;
300int undecchar(char c) _const_;
301
302char *cescape(const char *s);
303char *cunescape(const char *s);
304char *cunescape_length(const char *s, size_t length);
305char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix);
306
307char *xescape(const char *s, const char *bad);
308
663996b3
MS
309char *ascii_strlower(char *path);
310
311bool dirent_is_file(const struct dirent *de) _pure_;
312bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
313
314bool ignore_file(const char *filename) _pure_;
315
316bool chars_intersect(const char *a, const char *b) _pure_;
317
318int make_stdio(int fd);
319int make_null_stdio(void);
320int make_console_stdio(void);
321
60f067b4
JS
322int dev_urandom(void *p, size_t n);
323void random_bytes(void *p, size_t n);
324
325static inline uint64_t random_u64(void) {
326 uint64_t u;
327 random_bytes(&u, sizeof(u));
328 return u;
329}
330
331static inline uint32_t random_u32(void) {
332 uint32_t u;
333 random_bytes(&u, sizeof(u));
334 return u;
335}
663996b3
MS
336
337/* For basic lookup tables with strictly enumerated entries */
338#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
339 scope const char *name##_to_string(type i) { \
340 if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
341 return NULL; \
342 return name##_table[i]; \
343 } \
344 scope type name##_from_string(const char *s) { \
345 type i; \
60f067b4
JS
346 if (!s) \
347 return (type) -1; \
663996b3
MS
348 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
349 if (name##_table[i] && \
350 streq(name##_table[i], s)) \
351 return i; \
352 return (type) -1; \
353 } \
354 struct __useless_struct_to_allow_trailing_semicolon__
355
356#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,)
357#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static)
358
359/* For string conversions where numbers are also acceptable */
360#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
361 int name##_to_string_alloc(type i, char **str) { \
362 char *s; \
363 int r; \
364 if (i < 0 || i > max) \
365 return -ERANGE; \
366 if (i < (type) ELEMENTSOF(name##_table)) { \
367 s = strdup(name##_table[i]); \
368 if (!s) \
369 return log_oom(); \
370 } else { \
371 r = asprintf(&s, "%u", i); \
372 if (r < 0) \
373 return log_oom(); \
374 } \
375 *str = s; \
376 return 0; \
377 } \
378 type name##_from_string(const char *s) { \
379 type i; \
380 unsigned u = 0; \
381 assert(s); \
382 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
383 if (name##_table[i] && \
384 streq(name##_table[i], s)) \
385 return i; \
386 if (safe_atou(s, &u) >= 0 && u <= max) \
387 return (type) u; \
388 return (type) -1; \
389 } \
390 struct __useless_struct_to_allow_trailing_semicolon__
391
392int fd_nonblock(int fd, bool nonblock);
393int fd_cloexec(int fd, bool cloexec);
394
395int close_all_fds(const int except[], unsigned n_except);
396
397bool fstype_is_network(const char *fstype);
398
399int chvt(int vt);
400
401int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
5eef597e
MP
402int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
403int ask_string(char **ret, const char *text, ...) _printf_(2, 3);
663996b3
MS
404
405int reset_terminal_fd(int fd, bool switch_to_text);
406int reset_terminal(const char *name);
407
408int open_terminal(const char *name, int mode);
409int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
410int release_terminal(void);
411
412int flush_fd(int fd);
413
414int ignore_signals(int sig, ...);
415int default_signals(int sig, ...);
416int sigaction_many(const struct sigaction *sa, ...);
417
663996b3
MS
418int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
419
420ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
421ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
422
423bool is_device_path(const char *path);
424
425int dir_is_empty(const char *path);
426char* dirname_malloc(const char *path);
427
428void rename_process(const char name[8]);
429
430void sigset_add_many(sigset_t *ss, ...);
60f067b4 431int sigprocmask_many(int how, ...);
663996b3
MS
432
433bool hostname_is_set(void);
434
5eef597e 435char* lookup_uid(uid_t uid);
663996b3
MS
436char* gethostname_malloc(void);
437char* getlogname_malloc(void);
438char* getusername_malloc(void);
439
440int getttyname_malloc(int fd, char **r);
441int getttyname_harder(int fd, char **r);
442
443int get_ctty_devnr(pid_t pid, dev_t *d);
444int get_ctty(pid_t, dev_t *_devnr, char **r);
445
446int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
447int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
448
449int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
450int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
451int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
452int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
453
454int pipe_eof(int fd);
455
456cpu_set_t* cpu_set_malloc(unsigned *ncpus);
457
60f067b4
JS
458int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0);
459int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5);
663996b3
MS
460
461int fd_columns(int fd);
462unsigned columns(void);
463int fd_lines(int fd);
464unsigned lines(void);
465void columns_lines_cache_reset(int _unused_ signum);
466
467bool on_tty(void);
468
14228c0d
MB
469static inline const char *ansi_highlight(void) {
470 return on_tty() ? ANSI_HIGHLIGHT_ON : "";
471}
472
473static inline const char *ansi_highlight_red(void) {
474 return on_tty() ? ANSI_HIGHLIGHT_RED_ON : "";
475}
476
477static inline const char *ansi_highlight_green(void) {
478 return on_tty() ? ANSI_HIGHLIGHT_GREEN_ON : "";
479}
480
60f067b4
JS
481static inline const char *ansi_highlight_yellow(void) {
482 return on_tty() ? ANSI_HIGHLIGHT_YELLOW_ON : "";
483}
484
485static inline const char *ansi_highlight_blue(void) {
486 return on_tty() ? ANSI_HIGHLIGHT_BLUE_ON : "";
487}
488
14228c0d
MB
489static inline const char *ansi_highlight_off(void) {
490 return on_tty() ? ANSI_HIGHLIGHT_OFF : "";
491}
492
60f067b4
JS
493int files_same(const char *filea, const char *fileb);
494
663996b3
MS
495int running_in_chroot(void);
496
497char *ellipsize(const char *s, size_t length, unsigned percent);
60f067b4 498 /* bytes columns */
663996b3
MS
499char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
500
60f067b4 501int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
663996b3
MS
502int touch(const char *path);
503
504char *unquote(const char *s, const char *quotes);
505char *normalize_env_assignment(const char *s);
506
507int wait_for_terminate(pid_t pid, siginfo_t *status);
508int wait_for_terminate_and_warn(const char *name, pid_t pid);
509
60f067b4 510noreturn void freeze(void);
663996b3
MS
511
512bool null_or_empty(struct stat *st) _pure_;
513int null_or_empty_path(const char *fn);
5eef597e 514int null_or_empty_fd(int fd);
663996b3
MS
515
516DIR *xopendirat(int dirfd, const char *name, int flags);
517
518char *fstab_node_to_udev_node(const char *p);
519
520char *resolve_dev_console(char **active);
521bool tty_is_vc(const char *tty);
522bool tty_is_vc_resolve(const char *tty);
523bool tty_is_console(const char *tty) _pure_;
524int vtnr_from_tty(const char *tty);
525const char *default_term_for_tty(const char *tty);
526
60f067b4 527void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[]);
663996b3
MS
528
529int kill_and_sigcont(pid_t pid, int sig);
530
531bool nulstr_contains(const char*nulstr, const char *needle);
532
533bool plymouth_running(void);
534
535bool hostname_is_valid(const char *s) _pure_;
536char* hostname_cleanup(char *s, bool lowercase);
537
e842803a
MB
538bool machine_name_is_valid(const char *s) _pure_;
539
663996b3
MS
540char* strshorten(char *s, size_t l);
541
542int terminal_vhangup_fd(int fd);
543int terminal_vhangup(const char *name);
544
545int vt_disallocate(const char *name);
546
663996b3 547int symlink_atomic(const char *from, const char *to);
e842803a
MB
548int mknod_atomic(const char *path, mode_t mode, dev_t dev);
549int mkfifo_atomic(const char *path, mode_t mode);
663996b3
MS
550
551int fchmod_umask(int fd, mode_t mode);
552
553bool display_is_local(const char *display) _pure_;
554int socket_from_display(const char *display, char **path);
555
556int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
557int get_group_creds(const char **groupname, gid_t *gid);
558
559int in_gid(gid_t gid);
560int in_group(const char *name);
561
562char* uid_to_name(uid_t uid);
563char* gid_to_name(gid_t gid);
564
565int glob_exists(const char *path);
14228c0d 566int glob_extend(char ***strv, const char *path);
663996b3
MS
567
568int dirent_ensure_type(DIR *d, struct dirent *de);
569
663996b3
MS
570int get_files_in_directory(const char *path, char ***list);
571
572char *strjoin(const char *x, ...) _sentinel_;
573
574bool is_main_thread(void);
575
60f067b4
JS
576static inline bool _pure_ in_charset(const char *s, const char* charset) {
577 assert(s);
578 assert(charset);
579 return s[strspn(s, charset)] == '\0';
580}
663996b3
MS
581
582int block_get_whole_disk(dev_t d, dev_t *ret);
583
584int file_is_priv_sticky(const char *p);
585
663996b3
MS
586#define NULSTR_FOREACH(i, l) \
587 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
588
589#define NULSTR_FOREACH_PAIR(i, j, l) \
590 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
591
592int ioprio_class_to_string_alloc(int i, char **s);
593int ioprio_class_from_string(const char *s);
594
595const char *sigchld_code_to_string(int i) _const_;
596int sigchld_code_from_string(const char *s) _pure_;
597
598int log_facility_unshifted_to_string_alloc(int i, char **s);
599int log_facility_unshifted_from_string(const char *s);
600
601int log_level_to_string_alloc(int i, char **s);
602int log_level_from_string(const char *s);
603
604int sched_policy_to_string_alloc(int i, char **s);
605int sched_policy_from_string(const char *s);
606
607const char *rlimit_to_string(int i) _const_;
608int rlimit_from_string(const char *s) _pure_;
609
610int ip_tos_to_string_alloc(int i, char **s);
611int ip_tos_from_string(const char *s);
612
613const char *signal_to_string(int i) _const_;
614int signal_from_string(const char *s) _pure_;
615
616int signal_from_string_try_harder(const char *s);
617
618extern int saved_argc;
619extern char **saved_argv;
620
621bool kexec_loaded(void);
622
623int prot_from_flags(int flags) _const_;
624
625char *format_bytes(char *buf, size_t l, off_t t);
626
627int fd_wait_for_event(int fd, int event, usec_t timeout);
628
629void* memdup(const void *p, size_t l) _alloc_(2);
630
631int is_kernel_thread(pid_t pid);
632
633int fd_inc_sndbuf(int fd, size_t n);
634int fd_inc_rcvbuf(int fd, size_t n);
635
636int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
637
638int setrlimit_closest(int resource, const struct rlimit *rlim);
639
640int getenv_for_pid(pid_t pid, const char *field, char **_value);
641
642bool is_valid_documentation_url(const char *url) _pure_;
643
644bool in_initrd(void);
645
646void warn_melody(void);
647
648int get_home_dir(char **ret);
60f067b4 649int get_shell(char **_ret);
663996b3
MS
650
651static inline void freep(void *p) {
652 free(*(void**) p);
653}
654
60f067b4
JS
655#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
656 static inline void func##p(type *p) { \
657 if (*p) \
658 func(*p); \
659 } \
660 struct __useless_struct_to_allow_trailing_semicolon__
663996b3
MS
661
662static inline void closep(int *fd) {
60f067b4 663 safe_close(*fd);
663996b3
MS
664}
665
666static inline void umaskp(mode_t *u) {
667 umask(*u);
668}
669
60f067b4
JS
670static inline void close_pairp(int (*p)[2]) {
671 safe_close_pair(*p);
672}
673
674DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, fclose);
675DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose);
676DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir);
677DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent);
678
663996b3 679#define _cleanup_free_ _cleanup_(freep)
663996b3 680#define _cleanup_close_ _cleanup_(closep)
663996b3
MS
681#define _cleanup_umask_ _cleanup_(umaskp)
682#define _cleanup_globfree_ _cleanup_(globfree)
60f067b4
JS
683#define _cleanup_fclose_ _cleanup_(fclosep)
684#define _cleanup_pclose_ _cleanup_(pclosep)
685#define _cleanup_closedir_ _cleanup_(closedirp)
686#define _cleanup_endmntent_ _cleanup_(endmntentp)
687#define _cleanup_close_pair_ _cleanup_(close_pairp)
663996b3
MS
688
689_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
e842803a 690 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
663996b3
MS
691 return NULL;
692
693 return malloc(a * b);
694}
695
e842803a
MB
696_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
697 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
698 return NULL;
699
700 return realloc(p, a * b);
701}
702
663996b3 703_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
e842803a 704 if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
663996b3
MS
705 return NULL;
706
707 return memdup(p, a * b);
708}
709
710bool filename_is_safe(const char *p) _pure_;
711bool path_is_safe(const char *p) _pure_;
712bool string_is_safe(const char *p) _pure_;
5eef597e 713bool string_has_cc(const char *p, const char *ok) _pure_;
663996b3 714
60f067b4
JS
715/**
716 * Check if a string contains any glob patterns.
717 */
718_pure_ static inline bool string_is_glob(const char *p) {
719 return !!strpbrk(p, GLOB_CHARS);
720}
721
663996b3
MS
722void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
723 int (*compar) (const void *, const void *, void *),
724 void *arg);
725
726bool is_locale_utf8(void);
727
728typedef enum DrawSpecialChar {
60f067b4 729 DRAW_TREE_VERTICAL,
663996b3
MS
730 DRAW_TREE_BRANCH,
731 DRAW_TREE_RIGHT,
732 DRAW_TREE_SPACE,
733 DRAW_TRIANGULAR_BULLET,
60f067b4
JS
734 DRAW_BLACK_CIRCLE,
735 DRAW_ARROW,
736 DRAW_DASH,
663996b3
MS
737 _DRAW_SPECIAL_CHAR_MAX
738} DrawSpecialChar;
60f067b4 739
663996b3
MS
740const char *draw_special_char(DrawSpecialChar ch);
741
742char *strreplace(const char *text, const char *old_string, const char *new_string);
743
744char *strip_tab_ansi(char **p, size_t *l);
745
746int on_ac_power(void);
747
60f067b4
JS
748int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
749int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
663996b3
MS
750
751#define FOREACH_LINE(line, f, on_error) \
752 for (;;) \
753 if (!fgets(line, sizeof(line), f)) { \
754 if (ferror(f)) { \
755 on_error; \
756 } \
757 break; \
758 } else
759
760#define FOREACH_DIRENT(de, d, on_error) \
761 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
762 if (!de) { \
763 if (errno > 0) { \
764 on_error; \
765 } \
766 break; \
767 } else if (ignore_file((de)->d_name)) \
768 continue; \
769 else
770
771static inline void *mempset(void *s, int c, size_t n) {
772 memset(s, c, n);
773 return (uint8_t*)s + n;
774}
775
776char *hexmem(const void *p, size_t l);
777void *unhexmem(const char *p, size_t l);
778
779char *strextend(char **x, ...) _sentinel_;
780char *strrep(const char *s, unsigned n);
781
60f067b4
JS
782void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
783void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
784#define GREEDY_REALLOC(array, allocated, need) \
785 greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
786
787#define GREEDY_REALLOC0(array, allocated, need) \
788 greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
663996b3
MS
789
790static inline void _reset_errno_(int *saved_errno) {
791 errno = *saved_errno;
792}
793
794#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
795
796struct _umask_struct_ {
797 mode_t mask;
798 bool quit;
799};
800
801static inline void _reset_umask_(struct _umask_struct_ *s) {
802 umask(s->mask);
803};
804
805#define RUN_WITH_UMASK(mask) \
806 for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \
807 !_saved_umask_.quit ; \
808 _saved_umask_.quit = true)
809
810static inline unsigned u64log2(uint64_t n) {
60f067b4
JS
811#if __SIZEOF_LONG_LONG__ == 8
812 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
813#else
814#error "Wut?"
815#endif
816}
817
818static inline unsigned u32ctz(uint32_t n) {
819#if __SIZEOF_INT__ == 4
820 return __builtin_ctz(n);
821#else
822#error "Wut?"
823#endif
824}
825
826static inline int log2i(int x) {
827 assert(x > 0);
828
829 return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
663996b3
MS
830}
831
832static inline bool logind_running(void) {
833 return access("/run/systemd/seats/", F_OK) >= 0;
834}
835
836#define DECIMAL_STR_WIDTH(x) \
837 ({ \
838 typeof(x) _x_ = (x); \
839 unsigned ans = 1; \
840 while (_x_ /= 10) \
841 ans++; \
842 ans; \
843 })
844
845int unlink_noerrno(const char *path);
846
847#define alloca0(n) \
848 ({ \
849 char *_new_; \
850 size_t _len_ = n; \
851 _new_ = alloca(_len_); \
852 (void *) memset(_new_, 0, _len_); \
853 })
854
5eef597e
MP
855#define alloca_align(size, align) \
856 ({ \
857 void *_ptr_; \
858 size_t _mask_ = (align) - 1; \
859 _ptr_ = alloca((size) + _mask_); \
860 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
663996b3
MS
861 })
862
5eef597e
MP
863#define alloca0_align(size, align) \
864 ({ \
865 void *_new_; \
866 size_t _size_ = (size); \
867 _new_ = alloca_align(_size_, (align)); \
868 (void*)memset(_new_, 0, _size_); \
869 })
870
871#define strappenda(a, ...) \
872 ({ \
873 int _len = strlen(a); \
874 unsigned _i; \
875 char *_d_, *_p_; \
876 const char *_appendees_[] = { __VA_ARGS__ }; \
877 for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \
878 _len += strlen(_appendees_[_i]); \
879 _d_ = alloca(_len + 1); \
880 _p_ = stpcpy(_d_, a); \
881 for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \
882 _p_ = stpcpy(_p_, _appendees_[_i]); \
883 _d_; \
60f067b4
JS
884 })
885
663996b3
MS
886#define procfs_file_alloca(pid, field) \
887 ({ \
888 pid_t _pid_ = (pid); \
60f067b4
JS
889 const char *_r_; \
890 if (_pid_ == 0) { \
891 _r_ = ("/proc/self/" field); \
892 } else { \
893 _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
894 sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
895 } \
663996b3
MS
896 _r_; \
897 })
898
899struct _locale_struct_ {
900 locale_t saved_locale;
901 locale_t new_locale;
902 bool quit;
903};
904
905static inline void _reset_locale_(struct _locale_struct_ *s) {
906 PROTECT_ERRNO;
907 if (s->saved_locale != (locale_t) 0)
908 uselocale(s->saved_locale);
909 if (s->new_locale != (locale_t) 0)
910 freelocale(s->new_locale);
911}
912
913#define RUN_WITH_LOCALE(mask, loc) \
914 for (_cleanup_(_reset_locale_) struct _locale_struct_ _saved_locale_ = { (locale_t) 0, (locale_t) 0, false }; \
915 ({ \
916 if (!_saved_locale_.quit) { \
917 PROTECT_ERRNO; \
918 _saved_locale_.new_locale = newlocale((mask), (loc), (locale_t) 0); \
919 if (_saved_locale_.new_locale != (locale_t) 0) \
920 _saved_locale_.saved_locale = uselocale(_saved_locale_.new_locale); \
921 } \
922 !_saved_locale_.quit; }) ; \
923 _saved_locale_.quit = true)
924
925bool id128_is_valid(const char *s) _pure_;
14228c0d
MB
926
927int split_pair(const char *s, const char *sep, char **l, char **r);
60f067b4
JS
928
929int shall_restore_state(void);
930
931/**
932 * Normal qsort requires base to be nonnull. Here were require
933 * that only if nmemb > 0.
934 */
935static inline void qsort_safe(void *base, size_t nmemb, size_t size,
936 int (*compar)(const void *, const void *)) {
937 if (nmemb) {
938 assert(base);
939 qsort(base, nmemb, size, compar);
940 }
941}
942
943int proc_cmdline(char **ret);
944int parse_proc_cmdline(int (*parse_word)(const char *key, const char *value));
945
946int container_get_leader(const char *machine, pid_t *pid);
947
948int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd);
949int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd);
950
951bool pid_is_alive(pid_t pid);
952bool pid_is_unwaited(pid_t pid);
953
954int getpeercred(int fd, struct ucred *ucred);
955int getpeersec(int fd, char **ret);
956
957int writev_safe(int fd, const struct iovec *w, int j);
958
959int mkostemp_safe(char *pattern, int flags);
960int open_tmpfile(const char *path, int flags);
961
962int fd_warn_permissions(const char *path, int fd);
963
964unsigned long personality_from_string(const char *p);
965const char *personality_to_string(unsigned long);
966
967uint64_t physical_memory(void);
968
969char* mount_test_option(const char *haystack, const char *needle);
970
971void hexdump(FILE *f, const void *p, size_t s);
972
973union file_handle_union {
974 struct file_handle handle;
975 char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
976};
977
978int update_reboot_param_file(const char *param);
979
980int umount_recursive(const char *target, int flags);
981
982int bind_remount_recursive(const char *prefix, bool ro);
e842803a
MB
983
984int fflush_and_check(FILE *f);
985
986char *tempfn_xxxxxx(const char *p);
987char *tempfn_random(const char *p);
988
989bool is_localhost(const char *hostname);
5eef597e
MP
990
991int take_password_lock(const char *root);
992
993int is_symlink(const char *path);
994int is_dir(const char *path, bool follow);
995
996int unquote_first_word(const char **p, char **ret);
997int unquote_many_words(const char **p, ...) _sentinel_;
998
999int free_and_strdup(char **p, const char *s);
1000
1001int sethostname_idempotent(const char *s);