util.h revision 4b40bc38b495bb0c986e7accf5897b164ccfee4d
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering This file is part of systemd.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Copyright 2010 Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering (at your option) any later version.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is distributed in the hope that it will be useful, but
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Lesser General Public License for more details.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/* What is interpreted as whitespace? */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering/* What characters are special in the shell? */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/* must be escaped outside and inside double-quotes */
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering/* can be escaped or double-quoted */
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringbool streq_ptr(const char *a, const char *b) _pure_;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint strcmp_ptr(const char *a, const char *b) _pure_;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering#define new0(t, n) ((t*) calloc((n), sizeof(t)))
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
821b2e792159e237a1e5a1ea4bb6ae2e55d64be5Lukas Nykryn#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poetteringstatic inline const char* yes_no(bool b) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline const char* true_false(bool b) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline const char* one_zero(bool b) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline const char* strempty(const char *s) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return s ? s : "";
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline const char* strnull(const char *s) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return s ? s : "(null)";
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline const char *strna(const char *s) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering return s ? s : "n/a";
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline bool isempty(const char *p) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return !p || !p[0];
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidtstatic inline char *startswith(const char *s, const char *prefix) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return (char*) s + l;
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidtstatic inline char *startswith_no_case(const char *s, const char *prefix) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return (char*) s + l;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringchar *endswith(const char *s, const char *postfix) _pure_;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringchar *endswith_no_case(const char *s, const char *postfix) _pure_;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringchar *first_word(const char *s, const char *word) _pure_;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringvoid close_many(const int fds[], unsigned n_fd);
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mackint parse_size(const char *t, off_t base, off_t *size);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint parse_pid(const char *s, pid_t* ret_pid);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint parse_uid(const char *s, uid_t* ret_uid);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint safe_atou(const char *s, unsigned *ret_u);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint safe_atollu(const char *s, unsigned long long *ret_u);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringint safe_atolli(const char *s, long long int *ret_i);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint safe_atod(const char *s, double *ret_d);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint safe_atou8(const char *s, uint8_t *ret);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic inline int safe_atolu(const char *s, unsigned long *ret_u) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert_cc(sizeof(unsigned long) == sizeof(unsigned));
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline int safe_atoli(const char *s, long int *ret_u) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert_cc(sizeof(long int) == sizeof(int));
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline int safe_atolu(const char *s, unsigned long *ret_u) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return safe_atollu(s, (unsigned long long*) ret_u);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic inline int safe_atoli(const char *s, long int *ret_u) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert_cc(sizeof(long int) == sizeof(long long int));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return safe_atolli(s, (long long int*) ret_u);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline int safe_atou32(const char *s, uint32_t *ret_u) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert_cc(sizeof(uint32_t) == sizeof(unsigned));
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic inline int safe_atoi32(const char *s, int32_t *ret_i) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringstatic inline int safe_atou64(const char *s, uint64_t *ret_u) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return safe_atollu(s, (unsigned long long*) ret_u);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidtstatic inline int safe_atoi64(const char *s, int64_t *ret_i) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert_cc(sizeof(int64_t) == sizeof(long long int));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return safe_atolli(s, (long long int*) ret_i);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint safe_atou16(const char *s, uint16_t *ret);
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poetteringint safe_atoi16(const char *s, int16_t *ret);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringconst char* split(const char **state, size_t *l, const char *separator, bool quoted);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#define FOREACH_WORD(word, length, s, state) \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering _FOREACH_WORD(word, length, s, separator, false, state)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#define FOREACH_WORD_QUOTED(word, length, s, state) \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringchar *strappend(const char *s, const char *suffix);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringchar *strnappend(const char *s, const char *suffix, size_t length);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint readlinkat_malloc(int fd, const char *p, char **ret);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint readlink_malloc(const char *p, char **r);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint readlink_and_make_absolute(const char *p, char **r);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint readlink_and_canonicalize(const char *p, char **r);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poetteringchar *delete_chars(char *s, const char *bad);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringchar *file_in_same_dir(const char *path, const char *filename);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint rmdir_parents(const char *path, const char *stop);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieverschar *cescape(const char *s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint cunescape(const char *s, UnescapeFlags flags, char **ret);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool dirent_is_file(const struct dirent *de) _pure_;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool chars_intersect(const char *a, const char *b) _pure_;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering/* For basic lookup tables with strictly enumerated entries */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering scope const char *name##_to_string(type i) { \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmekssize_t string_table_lookup(const char * const *table, size_t len, const char *key);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering scope inline type name##_from_string(const char *s) { \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return (type)string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering struct __useless_struct_to_allow_trailing_semicolon__
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering/* For string conversions where numbers are also acceptable */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering int name##_to_string_alloc(type i, char **str) { \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (i < 0 || i > max) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (i < (type) ELEMENTSOF(name##_table)) { \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering type name##_from_string(const char *s) { \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering unsigned u = 0; \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers struct __useless_struct_to_allow_trailing_semicolon__
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint close_all_fds(const int except[], unsigned n_except);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint fopen_temporary(const char *path, FILE **_f, char **_temp_path);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool is_temporary_fs(const struct statfs *s) _pure_;
59512f21d77d984cf1363fb0d1770218c5e17020Kay SieversDEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers#define xsprintf(buf, fmt, ...) assert_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint files_same(const char *filea, const char *fileb);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieverschar *ellipsize(const char *s, size_t length, unsigned percent);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen /* bytes columns */
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenchar *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom GundersenDIR *xopendirat(int dirfd, const char *name, int flags);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenchar *fstab_node_to_udev_node(const char *p);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenvoid execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenbool nulstr_contains(const char*nulstr, const char *needle);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint symlink_idempotent(const char *from, const char *to);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint symlink_atomic(const char *from, const char *to);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint mknod_atomic(const char *path, mode_t mode, dev_t dev);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint mkfifo_atomic(const char *path, mode_t mode);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenbool display_is_local(const char *display) _pure_;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint socket_from_display(const char *display, char **path);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint get_group_creds(const char **groupname, gid_t *gid);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint glob_extend(char ***strv, const char *path);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint dirent_ensure_type(DIR *d, struct dirent *de);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint get_files_in_directory(const char *path, char ***list);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenstatic inline bool _pure_ in_charset(const char *s, const char* charset) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen#define NULSTR_FOREACH_PAIR(i, j, l) \
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint ioprio_class_to_string_alloc(int i, char **s);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint ioprio_class_from_string(const char *s);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenconst char *sigchld_code_to_string(int i) _const_;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint sigchld_code_from_string(const char *s) _pure_;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint log_facility_unshifted_to_string_alloc(int i, char **s);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenint log_facility_unshifted_from_string(const char *s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint log_level_to_string_alloc(int i, char **s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint log_level_from_string(const char *s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint sched_policy_to_string_alloc(int i, char **s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint sched_policy_from_string(const char *s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint ip_tos_to_string_alloc(int i, char **s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint ip_tos_from_string(const char *s);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieverschar *format_bytes(char *buf, size_t l, off_t t);
0b6b6787e3f0ae8906ce0212bd629edbe931b73dKay Sieversint fd_wait_for_event(int fd, int event, usec_t timeout);
0b6b6787e3f0ae8906ce0212bd629edbe931b73dKay Sieversvoid* memdup(const void *p, size_t l) _alloc_(2);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversint setrlimit_closest(int resource, const struct rlimit *rlim);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool documentation_url_is_valid(const char *url) _pure_;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic inline void freep(void *p) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers free(*(void**) p);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers#define _cleanup_endmntent_ _cleanup_(endmntentp)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers#define _cleanup_close_pair_ _cleanup_(close_pairp)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return malloc(a * b);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return realloc(p, a * b);
158df4b6a63c0d4e4f8de5210581619e7b693fb4Marius Thesing_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return memdup(p, a * b);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversbool string_has_cc(const char *p, const char *ok) _pure_;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering * Check if a string contains any glob patterns.
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek_pure_ static inline bool string_is_glob(const char *p) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return !!strpbrk(p, GLOB_CHARS);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversvoid *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int (*compar) (const void *, const void *, void *),
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekconst char *draw_special_char(DrawSpecialChar ch);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekchar *strreplace(const char *text, const char *old_string, const char *new_string);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekchar *strip_tab_ansi(char **p, size_t *l);
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poetteringint search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekint search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering#define FOREACH_DIRENT_ALL(de, d, on_error) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline void *mempset(void *s, int c, size_t n) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return (uint8_t*)s + n;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekchar *hexmem(const void *p, size_t l);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringint unhexmem(const char *p, size_t l, void **mem, size_t *len);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringchar *base32hexmem(const void *p, size_t l, bool padding);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringint unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringint unbase64mem(const char *p, size_t l, void **mem, size_t *len);
458a2f85e8ae08c534bf8d030fbeeb791893422bTom Gundersenchar *strrep(const char *s, unsigned n);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringvoid* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
458a2f85e8ae08c534bf8d030fbeeb791893422bTom Gundersenvoid* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek#define GREEDY_REALLOC(array, allocated, need) \
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering#define GREEDY_REALLOC0(array, allocated, need) \
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekstatic inline void _reset_errno_(int *saved_errno) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poetteringstatic inline int negative_errno(void) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* This helper should be used to shut up gcc if you know 'errno' is
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering * negative. Instead of "return -errno;", use "return negative_errno();"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering * It will suppress bogus gcc warnings in case it assumes 'errno' might
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering * be 0 and thus the caller's error-handling might not be triggered. */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline void _reset_umask_(struct _umask_struct_ *s) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic inline unsigned u64log2(uint64_t n) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline unsigned u32ctz(uint32_t n) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline unsigned log2i(int x) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline unsigned log2u(unsigned x) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline unsigned log2u_round_up(unsigned x) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic inline bool logind_running(void) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return access("/run/systemd/seats/", F_OK) >= 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers#define strjoina(a, ...) \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *_appendees_[] = { a, __VA_ARGS__ }; \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringint split_pair(const char *s, const char *sep, char **l, char **r);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering * Normal qsort requires base to be nonnull. Here were require
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering * that only if nmemb > 0.
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringstatic inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return (void*) haystack;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return memmem(haystack, haystacklen, needle, needlelen);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poetteringint parse_proc_cmdline(int (*parse_word)(const char *key, const char *value));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint get_proc_cmdline_key(const char *parameter, char **value);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint container_get_leader(const char *machine, pid_t *pid);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint getpeercred(int fd, struct ucred *ucred);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint writev_safe(int fd, const struct iovec *w, int j);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint mkostemp_safe(char *pattern, int flags);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint open_tmpfile(const char *path, int flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint fd_warn_permissions(const char *path, int fd);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering/* personality(7) documents that 0xffffffffUL is used for querying the
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering * current personality, hence let's use that here as error
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering * indicator. */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringunsigned long personality_from_string(const char *p);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringconst char *personality_to_string(unsigned long);
c51cf05646a11c65daf65c1123c77efb068f4f7bZbigniew Jędrzejewski-Szmekvoid hexdump(FILE *f, const void *p, size_t s);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint update_reboot_param_file(const char *param);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint umount_recursive(const char *target, int flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint bind_remount_recursive(const char *prefix, bool ro);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint tempfn_xxxxxx(const char *p, const char *extra, char **ret);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint tempfn_random(const char *p, const char *extra, char **ret);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint tempfn_random_child(const char *p, const char *extra, char **ret);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint is_dir(const char *path, bool follow);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringstatic inline void free_and_replace(char **s, char *v) {
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint free_and_strdup(char **p, const char *s);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint openpt_in_namespace(pid_t pid, int flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint path_getcrtime(const char *p, usec_t *usec);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint same_fd(int a, int b);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint chattr_fd(int fd, unsigned value, unsigned mask);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringint chattr_path(const char *p, unsigned value, unsigned mask);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint read_attr_path(const char *p, unsigned *ret);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekint syslog_parse_priority(const char **p, int *priority, bool with_facility);
8086ffacdb1bfec5ec115d24626538bda6cc372eZbigniew Jędrzejewski-Szmekvoid cmsg_close_all(struct msghdr *mh);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringchar *shell_escape(const char *s, const char *bad);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringchar *shell_maybe_quote(const char *s);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint parse_mode(const char *s, mode_t *ret);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint fgetxattr_malloc(int fd, const char *name, char **value);