]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/shared/util.h
build-sys: prepare 201
[thirdparty/systemd.git] / src / shared / util.h
... / ...
CommitLineData
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 <inttypes.h>
25#include <time.h>
26#include <sys/time.h>
27#include <stdarg.h>
28#include <stdbool.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <signal.h>
32#include <sched.h>
33#include <limits.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <dirent.h>
37#include <sys/resource.h>
38#include <stddef.h>
39#include <unistd.h>
40
41#include <systemd/sd-journal.h>
42#include "macro.h"
43#include "time-util.h"
44
45union dirent_storage {
46 struct dirent de;
47 uint8_t storage[offsetof(struct dirent, d_name) +
48 ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))];
49};
50
51/* What is interpreted as whitespace? */
52#define WHITESPACE " \t\n\r"
53#define NEWLINE "\n\r"
54#define QUOTES "\"\'"
55#define COMMENTS "#;\n"
56
57#define FORMAT_BYTES_MAX 8
58
59#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
60#define ANSI_RED_ON "\x1B[31m"
61#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
62#define ANSI_GREEN_ON "\x1B[32m"
63#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
64#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
65#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
66#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
67
68size_t page_size(void);
69#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
70
71#define streq(a,b) (strcmp((a),(b)) == 0)
72#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
73#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
74#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
75
76bool streq_ptr(const char *a, const char *b);
77
78#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
79
80#define new0(t, n) ((t*) calloc((n), sizeof(t)))
81
82#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
83
84#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
85
86#define malloc0(n) (calloc((n), 1))
87
88static inline const char* yes_no(bool b) {
89 return b ? "yes" : "no";
90}
91
92static inline const char* strempty(const char *s) {
93 return s ? s : "";
94}
95
96static inline const char* strnull(const char *s) {
97 return s ? s : "(null)";
98}
99
100static inline const char *strna(const char *s) {
101 return s ? s : "n/a";
102}
103
104static inline bool isempty(const char *p) {
105 return !p || !p[0];
106}
107
108char *endswith(const char *s, const char *postfix);
109char *startswith(const char *s, const char *prefix);
110char *startswith_no_case(const char *s, const char *prefix);
111
112bool first_word(const char *s, const char *word);
113
114int close_nointr(int fd);
115void close_nointr_nofail(int fd);
116void close_many(const int fds[], unsigned n_fd);
117
118int parse_boolean(const char *v);
119int parse_bytes(const char *t, off_t *bytes);
120int parse_pid(const char *s, pid_t* ret_pid);
121int parse_uid(const char *s, uid_t* ret_uid);
122#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
123
124int safe_atou(const char *s, unsigned *ret_u);
125int safe_atoi(const char *s, int *ret_i);
126
127int safe_atollu(const char *s, unsigned long long *ret_u);
128int safe_atolli(const char *s, long long int *ret_i);
129
130int safe_atod(const char *s, double *ret_d);
131
132#if __WORDSIZE == 32
133static inline int safe_atolu(const char *s, unsigned long *ret_u) {
134 assert_cc(sizeof(unsigned long) == sizeof(unsigned));
135 return safe_atou(s, (unsigned*) ret_u);
136}
137static inline int safe_atoli(const char *s, long int *ret_u) {
138 assert_cc(sizeof(long int) == sizeof(int));
139 return safe_atoi(s, (int*) ret_u);
140}
141#else
142static inline int safe_atolu(const char *s, unsigned long *ret_u) {
143 assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
144 return safe_atollu(s, (unsigned long long*) ret_u);
145}
146static inline int safe_atoli(const char *s, long int *ret_u) {
147 assert_cc(sizeof(long int) == sizeof(long long int));
148 return safe_atolli(s, (long long int*) ret_u);
149}
150#endif
151
152static inline int safe_atou32(const char *s, uint32_t *ret_u) {
153 assert_cc(sizeof(uint32_t) == sizeof(unsigned));
154 return safe_atou(s, (unsigned*) ret_u);
155}
156
157static inline int safe_atoi32(const char *s, int32_t *ret_i) {
158 assert_cc(sizeof(int32_t) == sizeof(int));
159 return safe_atoi(s, (int*) ret_i);
160}
161
162static inline int safe_atou64(const char *s, uint64_t *ret_u) {
163 assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
164 return safe_atollu(s, (unsigned long long*) ret_u);
165}
166
167static inline int safe_atoi64(const char *s, int64_t *ret_i) {
168 assert_cc(sizeof(int64_t) == sizeof(long long int));
169 return safe_atolli(s, (long long int*) ret_i);
170}
171
172char *split(const char *c, size_t *l, const char *separator, char **state);
173char *split_quoted(const char *c, size_t *l, char **state);
174
175#define FOREACH_WORD(word, length, s, state) \
176 for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state)))
177
178#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
179 for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state)))
180
181#define FOREACH_WORD_QUOTED(word, length, s, state) \
182 for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state)))
183
184pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
185int get_starttime_of_pid(pid_t pid, unsigned long long *st);
186
187char *strappend(const char *s, const char *suffix);
188char *strnappend(const char *s, const char *suffix, size_t length);
189
190char *replace_env(const char *format, char **env);
191char **replace_env_argv(char **argv, char **env);
192
193int readlink_malloc(const char *p, char **r);
194int readlink_and_make_absolute(const char *p, char **r);
195int readlink_and_canonicalize(const char *p, char **r);
196
197int reset_all_signal_handlers(void);
198
199char *strstrip(char *s);
200char *delete_chars(char *s, const char *bad);
201char *truncate_nl(char *s);
202
203char *file_in_same_dir(const char *path, const char *filename);
204
205int rmdir_parents(const char *path, const char *stop);
206
207int get_process_comm(pid_t pid, char **name);
208int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
209int get_process_exe(pid_t pid, char **name);
210int get_process_uid(pid_t pid, uid_t *uid);
211int get_process_gid(pid_t pid, gid_t *gid);
212
213char hexchar(int x);
214int unhexchar(char c);
215char octchar(int x);
216int unoctchar(char c);
217char decchar(int x);
218int undecchar(char c);
219
220char *cescape(const char *s);
221char *cunescape(const char *s);
222char *cunescape_length(const char *s, size_t length);
223char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix);
224
225char *xescape(const char *s, const char *bad);
226
227char *bus_path_escape(const char *s);
228char *bus_path_unescape(const char *s);
229
230char *ascii_strlower(char *path);
231
232bool dirent_is_file(const struct dirent *de);
233bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix);
234
235bool ignore_file(const char *filename);
236
237bool chars_intersect(const char *a, const char *b);
238
239int make_stdio(int fd);
240int make_null_stdio(void);
241int make_console_stdio(void);
242
243unsigned long long random_ull(void);
244
245/* For basic lookup tables with strictly enumerated entries */
246#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
247 scope const char *name##_to_string(type i) { \
248 if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
249 return NULL; \
250 return name##_table[i]; \
251 } \
252 scope type name##_from_string(const char *s) { \
253 type i; \
254 assert(s); \
255 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
256 if (name##_table[i] && \
257 streq(name##_table[i], s)) \
258 return i; \
259 return (type) -1; \
260 } \
261 struct __useless_struct_to_allow_trailing_semicolon__
262
263#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,)
264#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static)
265
266/* For string conversions where numbers are also acceptable */
267#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
268 int name##_to_string_alloc(type i, char **str) { \
269 char *s; \
270 int r; \
271 if (i < 0 || i > max) \
272 return -ERANGE; \
273 if (i < (type) ELEMENTSOF(name##_table)) { \
274 s = strdup(name##_table[i]); \
275 if (!s) \
276 return log_oom(); \
277 } else { \
278 r = asprintf(&s, "%u", i); \
279 if (r < 0) \
280 return log_oom(); \
281 } \
282 *str = s; \
283 return 0; \
284 } \
285 type name##_from_string(const char *s) { \
286 type i; \
287 unsigned u = 0; \
288 assert(s); \
289 for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
290 if (name##_table[i] && \
291 streq(name##_table[i], s)) \
292 return i; \
293 if (safe_atou(s, &u) >= 0 && u <= max) \
294 return (type) u; \
295 return (type) -1; \
296 } \
297 struct __useless_struct_to_allow_trailing_semicolon__
298
299int fd_nonblock(int fd, bool nonblock);
300int fd_cloexec(int fd, bool cloexec);
301
302int close_all_fds(const int except[], unsigned n_except);
303
304bool fstype_is_network(const char *fstype);
305
306int chvt(int vt);
307
308int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
309int ask(char *ret, const char *replies, const char *text, ...);
310
311int reset_terminal_fd(int fd, bool switch_to_text);
312int reset_terminal(const char *name);
313
314int open_terminal(const char *name, int mode);
315int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
316int release_terminal(void);
317
318int flush_fd(int fd);
319
320int ignore_signals(int sig, ...);
321int default_signals(int sig, ...);
322int sigaction_many(const struct sigaction *sa, ...);
323
324int close_pipe(int p[]);
325int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
326
327ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
328ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
329
330bool is_device_path(const char *path);
331
332int dir_is_empty(const char *path);
333char* dirname_malloc(const char *path);
334
335void rename_process(const char name[8]);
336
337void sigset_add_many(sigset_t *ss, ...);
338
339bool hostname_is_set(void);
340
341char* gethostname_malloc(void);
342char* getlogname_malloc(void);
343char* getusername_malloc(void);
344
345int getttyname_malloc(int fd, char **r);
346int getttyname_harder(int fd, char **r);
347
348int get_ctty_devnr(pid_t pid, dev_t *d);
349int get_ctty(pid_t, dev_t *_devnr, char **r);
350
351int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
352int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
353
354int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
355int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
356int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
357int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
358
359int pipe_eof(int fd);
360
361cpu_set_t* cpu_set_malloc(unsigned *ncpus);
362
363int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap);
364int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...);
365int status_welcome(void);
366
367int fd_columns(int fd);
368unsigned columns(void);
369int fd_lines(int fd);
370unsigned lines(void);
371void columns_lines_cache_reset(int _unused_ signum);
372
373bool on_tty(void);
374
375int running_in_chroot(void);
376
377char *ellipsize(const char *s, size_t length, unsigned percent);
378char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
379
380int touch(const char *path);
381
382char *unquote(const char *s, const char *quotes);
383char *normalize_env_assignment(const char *s);
384
385int wait_for_terminate(pid_t pid, siginfo_t *status);
386int wait_for_terminate_and_warn(const char *name, pid_t pid);
387
388_noreturn_ void freeze(void);
389
390bool null_or_empty(struct stat *st);
391int null_or_empty_path(const char *fn);
392
393DIR *xopendirat(int dirfd, const char *name, int flags);
394
395char *fstab_node_to_udev_node(const char *p);
396
397char *resolve_dev_console(char **active);
398bool tty_is_vc(const char *tty);
399bool tty_is_vc_resolve(const char *tty);
400bool tty_is_console(const char *tty);
401int vtnr_from_tty(const char *tty);
402const char *default_term_for_tty(const char *tty);
403
404void execute_directory(const char *directory, DIR *_d, char *argv[]);
405
406int kill_and_sigcont(pid_t pid, int sig);
407
408bool nulstr_contains(const char*nulstr, const char *needle);
409
410bool plymouth_running(void);
411
412bool hostname_is_valid(const char *s);
413char* hostname_cleanup(char *s);
414
415char* strshorten(char *s, size_t l);
416
417int terminal_vhangup_fd(int fd);
418int terminal_vhangup(const char *name);
419
420int vt_disallocate(const char *name);
421
422int copy_file(const char *from, const char *to);
423
424int symlink_atomic(const char *from, const char *to);
425
426int fchmod_umask(int fd, mode_t mode);
427
428bool display_is_local(const char *display);
429int socket_from_display(const char *display, char **path);
430
431int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
432int get_group_creds(const char **groupname, gid_t *gid);
433
434int in_gid(gid_t gid);
435int in_group(const char *name);
436
437char* uid_to_name(uid_t uid);
438char* gid_to_name(gid_t gid);
439
440int glob_exists(const char *path);
441
442int dirent_ensure_type(DIR *d, struct dirent *de);
443
444int in_search_path(const char *path, char **search);
445int get_files_in_directory(const char *path, char ***list);
446
447char *strjoin(const char *x, ...) _sentinel_;
448
449bool is_main_thread(void);
450
451bool in_charset(const char *s, const char* charset);
452
453int block_get_whole_disk(dev_t d, dev_t *ret);
454
455int file_is_priv_sticky(const char *p);
456
457int strdup_or_null(const char *a, char **b);
458
459#define NULSTR_FOREACH(i, l) \
460 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
461
462#define NULSTR_FOREACH_PAIR(i, j, l) \
463 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
464
465int ioprio_class_to_string_alloc(int i, char **s);
466int ioprio_class_from_string(const char *s);
467
468const char *sigchld_code_to_string(int i);
469int sigchld_code_from_string(const char *s);
470
471int log_facility_unshifted_to_string_alloc(int i, char **s);
472int log_facility_unshifted_from_string(const char *s);
473
474int log_level_to_string_alloc(int i, char **s);
475int log_level_from_string(const char *s);
476
477int sched_policy_to_string_alloc(int i, char **s);
478int sched_policy_from_string(const char *s);
479
480const char *rlimit_to_string(int i);
481int rlimit_from_string(const char *s);
482
483int ip_tos_to_string_alloc(int i, char **s);
484int ip_tos_from_string(const char *s);
485
486const char *signal_to_string(int i);
487int signal_from_string(const char *s);
488
489int signal_from_string_try_harder(const char *s);
490
491extern int saved_argc;
492extern char **saved_argv;
493
494bool kexec_loaded(void);
495
496int prot_from_flags(int flags);
497
498char *format_bytes(char *buf, size_t l, off_t t);
499
500int fd_wait_for_event(int fd, int event, usec_t timeout);
501
502void* memdup(const void *p, size_t l) _malloc_;
503
504int is_kernel_thread(pid_t pid);
505
506int fd_inc_sndbuf(int fd, size_t n);
507int fd_inc_rcvbuf(int fd, size_t n);
508
509int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
510
511int setrlimit_closest(int resource, const struct rlimit *rlim);
512
513int getenv_for_pid(pid_t pid, const char *field, char **_value);
514
515int can_sleep(const char *type);
516int can_sleep_disk(const char *type);
517
518bool is_valid_documentation_url(const char *url);
519
520bool in_initrd(void);
521
522void warn_melody(void);
523
524int get_home_dir(char **ret);
525
526static inline void freep(void *p) {
527 free(*(void**) p);
528}
529
530void fclosep(FILE **f);
531void pclosep(FILE **f);
532void closep(int *fd);
533void closedirp(DIR **d);
534static inline void umaskp(mode_t *u) {
535 umask(*u);
536}
537
538static inline void journal_closep(sd_journal **j) {
539 sd_journal_close(*j);
540}
541
542#define _cleanup_globfree_ __attribute__((cleanup(globfree)))
543
544_malloc_ static inline void *malloc_multiply(size_t a, size_t b) {
545 if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
546 return NULL;
547
548 return malloc(a * b);
549}
550
551_malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
552 if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
553 return NULL;
554
555 return memdup(p, a * b);
556}
557
558bool filename_is_safe(const char *p);
559bool path_is_safe(const char *p);
560bool string_is_safe(const char *p);
561bool string_has_cc(const char *p);
562
563void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
564 int (*compar) (const void *, const void *, void *),
565 void *arg);
566
567bool is_locale_utf8(void);
568
569typedef enum DrawSpecialChar {
570 DRAW_TREE_VERT,
571 DRAW_TREE_BRANCH,
572 DRAW_TREE_RIGHT,
573 DRAW_TREE_SPACE,
574 DRAW_TRIANGULAR_BULLET,
575 _DRAW_SPECIAL_CHAR_MAX
576} DrawSpecialChar;
577const char *draw_special_char(DrawSpecialChar ch);
578
579char *strreplace(const char *text, const char *old_string, const char *new_string);
580
581char *strip_tab_ansi(char **p, size_t *l);
582
583int on_ac_power(void);
584
585int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
586int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
587int create_tmp_dir(char template[], char** dir_name);
588
589#define FOREACH_LINE(line, f, on_error) \
590 for (;;) \
591 if (!fgets(line, sizeof(line), f)) { \
592 if (ferror(f)) { \
593 on_error; \
594 } \
595 break; \
596 } else
597
598#define FOREACH_DIRENT(de, d, on_error) \
599 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
600 if (!de) { \
601 if (errno > 0) { \
602 on_error; \
603 } \
604 break; \
605 } else if (ignore_file((de)->d_name)) \
606 continue; \
607 else
608
609static inline void *mempset(void *s, int c, size_t n) {
610 memset(s, c, n);
611 return (char*)s + n;
612}
613
614char *hexmem(const void *p, size_t l);
615void *unhexmem(const char *p, size_t l);
616
617char *strextend(char **x, ...);
618char *strrep(const char *s, unsigned n);
619
620void* greedy_realloc(void **p, size_t *allocated, size_t need);
621
622static inline void _reset_errno_(int *saved_errno) {
623 errno = *saved_errno;
624}
625
626#define PROTECT_ERRNO __attribute__((cleanup(_reset_errno_))) int _saved_errno_ = errno
627
628struct umask_struct {
629 mode_t mask;
630 bool quit;
631};
632
633static inline void _reset_umask_(struct umask_struct *s) {
634 umask(s->mask);
635};
636
637#define RUN_WITH_UMASK(mask) \
638 for (__attribute__((cleanup(_reset_umask_))) struct umask_struct _saved_umask_ = { umask(mask), false }; \
639 !_saved_umask_.quit ; \
640 _saved_umask_.quit = true)
641
642static inline unsigned u64log2(uint64_t n) {
643 return (n > 1) ? __builtin_clzll(n) ^ 63U : 0;
644}
645
646static inline bool logind_running(void) {
647 return access("/run/systemd/seats/", F_OK) >= 0;
648}