+static inline void umaskp(mode_t *u) {
+ umask(*u);
+}
+
+static inline void journal_closep(sd_journal **j) {
+ sd_journal_close(*j);
+}
+
+_malloc_ static inline void *malloc_multiply(size_t a, size_t b) {
+ if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+ return NULL;
+
+ return malloc(a * b);
+}
+
+_malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
+ if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+ return NULL;
+
+ return memdup(p, a * b);
+}
+
+bool filename_is_safe(const char *p);
+bool path_is_safe(const char *p);
+bool string_is_safe(const char *p);
+bool string_has_cc(const char *p);
+
+void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar) (const void *, const void *, void *),
+ void *arg);
+
+bool is_locale_utf8(void);
+
+typedef enum DrawSpecialChar {
+ DRAW_TREE_VERT,
+ DRAW_TREE_BRANCH,
+ DRAW_TREE_RIGHT,
+ DRAW_TREE_SPACE,
+ DRAW_TRIANGULAR_BULLET,
+ _DRAW_SPECIAL_CHAR_MAX
+} DrawSpecialChar;
+const char *draw_special_char(DrawSpecialChar ch);
+
+char *strreplace(const char *text, const char *old_string, const char *new_string);
+
+char *strip_tab_ansi(char **p, size_t *l);
+
+int on_ac_power(void);
+
+int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
+int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
+int create_tmp_dir(char template[], char** dir_name);
+
+#define FOREACH_LINE(line, f, on_error) \
+ for (;;) \
+ if (!fgets(line, sizeof(line), f)) { \
+ if (ferror(f)) { \
+ on_error; \
+ } \
+ break; \
+ } else
+
+#define FOREACH_DIRENT(de, d, on_error) \
+ for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
+ if (!de) { \
+ if (errno > 0) { \
+ on_error; \
+ } \
+ break; \
+ } else if (ignore_file((de)->d_name)) \
+ continue; \
+ else
+
+static inline void *mempset(void *s, int c, size_t n) {
+ memset(s, c, n);
+ return (char*)s + n;
+}
+
+char *hexmem(const void *p, size_t l);
+void *unhexmem(const char *p, size_t l);
+
+char *strextend(char **x, ...);
+char *strrep(const char *s, unsigned n);
+
+void* greedy_realloc(void **p, size_t *allocated, size_t need);
+
+static inline void _reset_errno_(int *saved_errno) {
+ errno = *saved_errno;
+}
+
+#define PROTECT_ERRNO __attribute__((cleanup(_reset_errno_))) int _saved_errno_ = errno
+
+struct umask_struct {
+ mode_t mask;
+ bool quit;
+};
+
+static inline void _reset_umask_(struct umask_struct *s) {
+ umask(s->mask);
+};
+
+#define RUN_WITH_UMASK(mask) \
+ for (__attribute__((cleanup(_reset_umask_))) struct umask_struct _saved_umask_ = { umask(mask), false }; \
+ !_saved_umask_.quit ; \
+ _saved_umask_.quit = true)
+
+static inline unsigned u64log2(uint64_t n) {
+ return (n > 1) ? __builtin_clzll(n) ^ 63U : 0;
+}